Coding Gun

จัดวาง layout ด้วย CSS Grid

CSS grid คือ CSS module ที่ใช้ออกแบบ layout โดยแบ่งเป็น row และ column ซึ่งจะลดปัญหาของการใช้ float

ซึ่งการใช้ float: left จะมีปัญหากับ margin ค่อนข้างเยอะ เราจะเจอปัญหากล่องตกลงไปด้านล่าง หรือไม่ยอมชิดซ้ายอยู่บ่อยๆ ถ้าเราเลือกใช้ CSS Grid จะไม่เจอกับปัญหาเหล่านี้

CSS Grid vs Flex

หลายยคนมักจะสับสนกับ CSS Grid และ Flex อาจเป็นด้วย Flex ออกมาก่อน Grid จึงทำให้มีคนนำ Flex ไปใช้ในการจัด layout ซึ่งก็เป็นสิ่งที่ทำได้เหมือนกัน แต่ถ้าคุณลองใช้ Grid แล้วคุณจะรู้ว่ามันเหมาะกับการจัด layout มากกว่า Flex แต่แน่นอนถ้าคุณใช้ได้ทั้ง Flex และ Grid การจัด layout จะเป็นเรื่องที่ง่ายมากๆ

Flex ถูกออกแบบมาสำหรับการจัดเรียง element เพราะฉะนั้น Flex จะเน้นที่ alignment สามารถดูตัวอย่างการใช้ Flex ได้ที่นี่

การใช้งาน CSS Grid

สิ่งที่เราต้องเริ่มสร้าง grid layout คือ เราต้องมี

  1. container ต้องมี display เป็น grid
  2. container ต้องกำหนดจำนวน columns

การใช้งาน Grid Template Columns

ตัวอย่าง เราจะกำหนดจำนวน columns ด้วย grid-template-columns ให้แบ่ง grid item ออกเป็น 3 columns

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
.grid-container {
  display: grid;
  grid-template-columns: auto auto auto;
  margin: 10px;
}
.grid-item {
  background-color: rgba(255, 255, 255, 0.8);
  border: 1px solid rgba(0, 0, 0, 0.8);
  padding: 20px;
  font-size: 30px;
  text-align: center;
}

ในบรรทัดที่ 2 จะเป็นการบอกให้ container นี้ใช้ display เป็น grid ซึ่งสิ่งที่อยู่ภายในจะถูกจัดเรียงเป็น column ซึ่งเราจะกำหนด columns ด้วย grid-template-columns เป็น auto 3 ตัวในบรรทัดที่ 3 ซึ่งจะทำให้ grid นี้จัดเรียงเป็น 3 columns

สังเกตุว่าเราจะกำหนด display และ grid-template-columns ที่ container เหมือนกับ flex

หลังจากนั้นนำ class grid-container และ grid-item ไปใส่ใน html แบบนี้

<div class="grid-container">
    <div class="grid-item">1</div>
    <div class="grid-item">2</div>
    <div class="grid-item">3</div>  
    <div class="grid-item">4</div>
    <div class="grid-item">5</div>
    <div class="grid-item">6</div>  
    <div class="grid-item">7</div>
    <div class="grid-item">8</div>
    <div class="grid-item">9</div>  
</div>

ผลลัพธ์จะออกมาเป็นแบบนี้่

1
2
3
4
5
6
7
8
9

กำหนดความกว้างของแต่ละ column ได้

เราสามารถกำหนดความกว้างของแต่ละ column ได้โดยใส่ขนาดเข้าไปแทนคำว่า auto ได้เลย เช่น

.grid-container {
  display: grid;
  grid-template-columns: 50% auto auto;
  margin: 10px;
}

เราเปลี่ยนจาก auto ตัวแรกเป็น 50% หมายความว่าให้ความกว้างของ column แรกเป็นครึ่งหนึ่งของพื้นที่ทั้งหมด ผลลัพธ์จะออกมาเป็นแบบนี้

1
2
3
4
5
6
7
8
9

เพิ่ม Gap ระหว่าง item

เราจะเพิ่มพื้นที่ระหว่าง item ด้วยการกำหนด Gap แบบนี้

เพิ่ม Gap รอบ item

กำหนด Gap รอบ item ทั้งหมดเราจะใช้

.grid-container {
  display: grid;
  gap: 16px;
}

ผลลัพธ์จะออกมาเป็นแบบนี้

1
2
3
4
5
6
7
8
9

เพิ่ม Gap เฉพาะแนวตั้ง

ถ้าเราต้องการเพิ่มพื้นที่ระหว่าง item ในแนวตั้งให้เปลี่ยนจาก gap มาเป็น column-gap แทน

.grid-container {
  display: grid;
  column-gap: 16px;
}

ผลลัพธ์จะออกมาเป็นแบบนี้

1
2
3
4
5
6
7
8
9

เพิ่ม Gap เฉพาะแนวนอน

ถ้าเราต้องการเพิ่มพื้นที่ระหว่าง item ในแนวแนวนอน ให้เปลี่ยนจาก gap มาเป็น row-gap แทน

.grid-container {
  display: grid;
  row-gap: 16px;
}

ผลลัพธ์จะออกมาเป็นแบบนี้

1
2
3
4
5
6
7
8
9

การ Merge Row หรือ Merge Column เข้าด้วยกัน

ถ้าเราใช้ grid แบบปกติ 1 item จะอยู่ใน 1 แถวและ 1 column แต่ถ้าเราต้องการให้ 1 item ของเราใช้พื้นที่มากกว่า 1 แถวหรือ 1 column เราจะต้องใช้ grid-row และ grid-column ถ้านึกภาพไม่ออกให้นึกถึงการ merge cell ใน excel เอาไว้

Grid Column

ถ้าเราต้องการให้ 1 item ของเราใช้พื้นที่มากกว่า 1 column(การ merge cell ในแนวนอน) เราจะเพิ่ม grid-column เข้าไปใน item แบบนี้

.item1 {
  /* เริ่มต้นที่ column ที่ 1 และจบที่ column ที่ 3 แต่ไม่รวม collumn ที่ 3*/
  grid-column: 1 / 3;
}

เราจะกำหนดความยาวของ item นี้ได้ 2 รูปแบบดังนี้

  1. ระบุ column เริ่มต้นและสิ้นสุด เหมือนในตัวอย่างนี้เราเริ่มต้นที่ column ที่ 1 และสิ้นสุดที่ column ที่ 3(จะไม่รวม column ที่ 3 เข้าไปด้วย)
    .item1 {
        grid-column: 1 / 3;
    }
    
  2. ระบุ column เริ่มต้นและ span(จะให้กินพื้นที่กี่ column) เราจะเขียนแบบนี้
    .item1 {
        grid-column: 1 / span 2;
    }
    

ข้อสังเกตุ เราจะกำหนด grid-row และ grid-column ใน item หรือ element ลูก

ผลลัพธ์จะออกมาเป็นแบบนี้

1
2
3
4
5
6
7
8

Grid Row

เหมือนกับ grid-column ถ้าเราต้องการให้ 1 item ของเราใช้พื้นที่มากกว่า 1 แถว(merge cell ในแนวตั้ง) ให้เราใช้ grid-row โดยจะมีวิธีการกำหนดจำนวนแถวที่จะ merge เข้าไปได้ 2 วิธีเหมือนกับ grid-column

  1. n / m เริ่มต้นแถวที่ n และจบแถวที่ m(ไม่รวมแถว m)
  2. n / span m เริ่มต้นแถวที่ n แล้วใช้พื้นที่อีก m แถว

ตัวอย่าง เราจะกำหนดให้ item 1 ใช้พื้นที่ใน column แรกทั้งหมดเราจะเขียน CSS แบบนี้

.item1 {
    grid-row: 1 / span 3;
}

ผลลัพธ์จะออกมาเป็นแบบนี้

1
2
3
4
5
6
7

CSS Grid Generator

ถ้าเรายังไม่คล่องกับ CSS Grid เราสามารถใช้ CSS Grid generator ช่วยเราได้ซึ่ง web เหล่านี้จะช่วย generate css ให้เราโดยอัตโนมัติ ในตัวอย่างนี้เราจะใช้ https://cssgrid-generator.netlify.app เป็นตัวช่วย generate CSS grid ให้เรา

CSS grid generator
หน้าแรกของ https://cssgrid-generator.netlify.app

กำหนดจำนวน columns และ rows ที่เราต้องการ ในตัวย่างนี้ผมจะกำหนด

หลังจากนั้นกดปุ่ม Please may I have some code เราจะได้ CSS นี้ออกมา

1
2
3
4
5
6
7
.parent { 
    display: grid; 
    grid-template-columns: repeat(3, 1fr); 
    grid-template-rows: repeat(4, 1fr); 
    grid-column-gap: 1px;
    grid-row-gap: 1px; 
}

หลังจากนั้นกดปุ่ม Show HTML เพื่ิอให้ได้ html ออกมา แต่เนื่องจากเราไม่ได้สร้าง content ขึ้นมาเลยมีแค่ parent ออกมาแค่นี้

1
2
3
<div class="parent"> 

</div>

หลังจากนี้เราสามารถใส่ content เข้าไปได้เลย div แต่ละตัวจะถูกแบ่งออกเป็น 3 columns และ 4 แถว และถ้าเราไม่อยากกำหนดแถว ให้ลบ CSS บรรทัดที่ 3 ออก

ถ้าเราอยากให้ generate div ที่เป็น item ภายใน grid ให้ด้วย ให้กด click ที่ cell แต่ละช่อง เราจะได้ div ที่ generate ขึ้นมาเป็น ลำดับแบบนี้

.div1 { grid-area: 1 / 1 / 2 / 2; } 
.div2 { grid-area: 1 / 2 / 2 / 3; } 
.div3 { grid-area: 1 / 3 / 2 / 4; } 
.div4 { grid-area: 2 / 1 / 3 / 2; } 
.div5 { grid-area: 2 / 2 / 3 / 3; } 
.div6 { grid-area: 2 / 3 / 3 / 4; }

ใน CSS ที่ generator ทำการสร้างขึ้นมาให้จะใช้ grid-area ในการกำหนดพื้นที่ ซึ่งค่าที่กำหนดใน grid-area แต่ละตัวหมายถึง

  1. grid-row-start หมายถึง เริ่มต้นที่ row ไหน
  2. grid-column-start หมายถึง เริ่มต้นที่ column ไหน
  3. grid-row-end หมายถึง สิ้นสุดที่ row ไหน
  4. gris column-end หมายถึง สิ้นสุดที่ column ไหน

ยกตัวอย่างเช่น .div1 { grid-area: 1 / 1 / 2 / 2; } หมายถึง

และถ้ากดปุ่ม Show HTML ก็จะwfh html ออกมาแบบนี้

<div class="parent"> 
    <div class="div1"> </div> 
    <div class="div2"> </div> 
    <div class="div3"> </div> 
    <div class="div4"> </div> 
    <div class="div5"> </div> 
    <div class="div6"> </div>
</div>

ซึ่งก็จะเห็นว่า ไม่ได้จำเป็นต้อง ใส่ content ซักเท่าไหร่เพราะ CSS ของแต่ละ item จะเป็น CSS ที่เราเคยใช้ใน web ปกติอยู่แล้ว

อ่านต่อเพิ่มเติมได้ที่

Phanupong Permpimol
Follow me