Guest Adventurer 🥉 Lv.1
🪙 50
🔷 10
← Back to library
Article · programming

HTML & CSS EP9: CSS Grid — สร้างเลย์เอาต์เว็บไซต์แบบสองมิติอย่างมืออาชีพ

HTML & CSS

บทเรียน HTML และ CSS ตอนที่ 9 เรียนรู้ CSS Grid ตั้งแต่แนวคิดแถวและคอลัมน์ การกำหนด grid-template-columns การจัดระยะห่าง การรวมพื้นที่ การสร้างการ์ด และการทำเลย์เอาต์ Responsive พร้อมตัวอย่าง Full-page HTML ที่ทดลองได้ทันที

EP9: CSS Grid คืออะไร และทำไมจึงสำคัญกับการออกแบบเว็บไซต์

CSS Grid เป็นระบบจัดเลย์เอาต์ของ CSS ที่ช่วยจัดองค์ประกอบในรูปแบบแถวและคอลัมน์พร้อมกัน จึงเหมาะกับหน้ารวมสินค้า แกลเลอรีภาพ แดชบอร์ด หน้าเว็บไซต์ข่าว และหน้า Landing Page ที่ต้องควบคุมตำแหน่งของเนื้อหาหลายส่วนอย่างเป็นระบบ ต่างจาก Flexbox ซึ่งมักใช้จัดองค์ประกอบตามแกนหลักเพียงทิศทางเดียว Grid ช่วยวางโครงสร้างแบบสองมิติได้สะดวก อย่างไรก็ตาม ทั้งสองระบบสามารถทำงานร่วมกันได้ดี โดยใช้ Grid จัดโครงสร้างใหญ่ของหน้า และใช้ Flexbox จัดองค์ประกอบภายในแต่ละส่วน
💡 แนวคิดสำคัญGrid Container คือกล่องแม่ที่กำหนดระบบ Grid ส่วน Grid Items คือองค์ประกอบลูกที่อยู่ภายในกล่องนั้น เมื่อเข้าใจความสัมพันธ์นี้ คุณจะสามารถควบคุมแถว คอลัมน์ ช่องว่าง และพื้นที่ของแต่ละรายการได้อย่างมีประสิทธิภาพ

1. เริ่มต้นด้วย display: grid

การเปิดใช้งาน CSS Grid เริ่มจากกำหนด `display: grid` ให้กับองค์ประกอบแม่ จากนั้นจึงกำหนดจำนวนคอลัมน์ด้วย `grid-template-columns` องค์ประกอบลูกจะถูกจัดลงในช่อง Grid โดยอัตโนมัติตามลำดับเอกสาร หากไม่ได้ระบุแถวอย่างชัดเจน ระบบจะสร้างแถวเพิ่มเติมเมื่อมีรายการเกินจำนวนช่องที่กำหนดไว้
<div class="grid-container">
  <div class="item">รายการ 1</div>
  <div class="item">รายการ 2</div>
  <div class="item">รายการ 3</div>
  <div class="item">รายการ 4</div>
</div>

<style>
  .grid-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
  }

  .item {
    padding: 24px;
    text-align: center;
    background: #dbeafe;
    border-radius: 10px;
  }
</style>
ตัวอย่างนี้สร้างสองคอลัมน์ที่มีขนาดเท่ากัน รายการทั้งสี่จะแสดงเป็นสองแถว โดย `gap: 12px` กำหนดระยะห่างระหว่างช่อง ทั้งแนวแถวและคอลัมน์ หากต้องการกำหนดระยะห่างแยกกัน สามารถใช้ `row-gap` และ `column-gap` ได้

2. ทำความเข้าใจหน่วย fr และขนาดคอลัมน์

หน่วย `fr` ย่อมาจาก fraction เป็นหน่วยที่ใช้แบ่งพื้นที่ว่างภายใน Grid ตามสัดส่วน เช่น `1fr 1fr` แบ่งพื้นที่เป็นสองส่วนเท่ากัน ส่วน `2fr 1fr` แบ่งพื้นที่เป็นสองส่วนต่อหนึ่งส่วน โดยการคำนวณจะพิจารณาพื้นที่ที่เหลือหลังจากหักขนาดคงที่และช่องว่างที่เกี่ยวข้องแล้ว
.equal-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.sidebar-layout {
  display: grid;
  grid-template-columns: 280px 1fr;
}

.proportional-layout {
  display: grid;
  grid-template-columns: 2fr 1fr;
}
เลือกหน่วยให้เหมาะกับงาน: ใช้ `px` เมื่อต้องการขนาดคงที่ เช่น Sidebar ที่มีความกว้างกำหนดไว้ ใช้ `fr` เพื่อแบ่งพื้นที่ที่เหลือ และใช้ `minmax()` เมื่อจำเป็นต้องกำหนดขนาดต่ำสุดและสูงสุดให้แทร็กของ Grid

3. สร้างเลย์เอาต์ที่ปรับจำนวนคอลัมน์ได้ด้วย repeat() และ minmax()

หน้าแสดงสินค้าและแกลเลอรีมักมีจำนวนรายการไม่แน่นอน การกำหนดคอลัมน์ทีละช่องอาจไม่สะดวก CSS Grid มี `repeat()` สำหรับลดการเขียนซ้ำ และ `minmax()` สำหรับกำหนดช่วงขนาดของแต่ละคอลัมน์
.product-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.auto-product-grid {
  display: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(100%, 220px), 1fr)
  );
  gap: 16px;
}
`repeat(3, minmax(0, 1fr))` สร้างสามคอลัมน์ที่แบ่งพื้นที่เท่ากัน ส่วนรูปแบบ `repeat(auto-fit, minmax(min(100%, 220px), 1fr))` ช่วยให้จำนวนคอลัมน์ปรับตามพื้นที่ที่มี โดยแต่ละช่องพยายามรักษาความกว้างขั้นต่ำประมาณ 220 พิกเซลเมื่อพื้นที่รองรับ และสามารถย่อลงเมื่อจำเป็นเพื่อป้องกันการล้นในพื้นที่แคบ
✅ เคล็ดลับ Responsiveสำหรับการ์ดที่มีเนื้อหาและขนาดใกล้เคียงกัน ให้ทดลองใช้ `repeat(auto-fit, minmax(...))` ก่อนเพิ่ม Media Query หลายชุด วิธีนี้ช่วยลด CSS ที่ซ้ำซ้อนและทำให้เลย์เอาต์ยืดหยุ่นตามความกว้างของพื้นที่

4. จัดระยะห่างและตำแหน่งด้วย gap, justify-items และ align-items

CSS Grid มีคุณสมบัติสำหรับควบคุมระยะห่างและการจัดตำแหน่งหลายระดับ `gap` กำหนดช่องว่างระหว่างแทร็ก `justify-items` จัดรายการภายในช่องตามแนวนอน และ `align-items` จัดรายการภายในช่องตามแนวตั้งในระบบเขียนข้อความทั่วไป การตั้งค่าพื้นฐานของรายการมักยืดให้เต็มพื้นที่ช่อง แต่สามารถเปลี่ยนเป็น `start`, `center` หรือ `end` ได้ตามความต้องการ
.grid {
  display: grid;
  gap: 20px;
  justify-items: stretch;
  align-items: start;
}

.centered-grid {
  display: grid;
  place-items: center;
  min-height: 240px;
}
`place-items: center` เป็นรูปแบบย่อที่กำหนดทั้ง `align-items` และ `justify-items` ให้เป็น `center` เหมาะกับการจัดข้อความหรือไอคอนให้อยู่กลางช่อง อย่างไรก็ตาม การจัดตำแหน่งรายการภายในช่องไม่เหมือนกับการจัดวางแทร็กทั้งหมดภายใน Container ซึ่งใช้คุณสมบัติอีกชุดหนึ่ง เช่น `justify-content` และ `align-content`

5. รวมพื้นที่หลายช่องด้วย grid-column และ grid-row

บางเลย์เอาต์ต้องการให้การ์ดหนึ่งกินพื้นที่กว้างกว่ารายการอื่น เช่น การ์ดแนะนำที่มีขนาดใหญ่ หรือภาพเด่นในแกลเลอรี สามารถกำหนดช่วงเส้น Grid ที่รายการจะครอบคลุมด้วย `grid-column` และ `grid-row`
.feature-card {
  grid-column: span 2;
}

.tall-card {
  grid-row: span 2;
}

.full-width-card {
  grid-column: 1 / -1;
}
`span 2` หมายถึงให้รายการครอบคลุมสองแทร็ก ส่วน `grid-column: 1 / -1` ใช้เริ่มที่เส้นแรกและสิ้นสุดที่เส้นสุดท้ายของ Grid ที่เกี่ยวข้อง จึงเหมาะกับแถบประกาศหรือเนื้อหาที่ต้องเต็มความกว้างของเลย์เอาต์ ควรตรวจสอบการแสดงผลบนหน้าจอแคบ เพราะรายการที่ครอบคลุมสองคอลัมน์อาจทำให้เกิดการล้นหากไม่ได้ปรับรูปแบบให้เหมาะสม

6. สร้างโครงสร้างหน้าเว็บด้วย grid-template-areas

`grid-template-areas` ช่วยตั้งชื่อพื้นที่ของเลย์เอาต์ ทำให้มองภาพโครงสร้างได้ง่าย เช่น Header อยู่ด้านบน Sidebar อยู่ด้านซ้าย Main อยู่ตรงกลาง และ Footer อยู่ด้านล่าง ชื่อพื้นที่ในแต่ละแถวต้องจัดให้เป็นรูปสี่เหลี่ยมผืนผ้าต่อเนื่องกัน หากต้องการเว้นช่องโดยไม่กำหนดชื่อพื้นที่ สามารถใช้จุด (`.`) แทนได้
.page-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  gap: 16px;
}

.site-header { grid-area: header; }
.site-sidebar { grid-area: sidebar; }
.site-main { grid-area: main; }
.site-footer { grid-area: footer; }

@media (max-width: 700px) {
  .page-layout {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
  }
}
ตัวอย่างนี้เปลี่ยนจากเลย์เอาต์สองคอลัมน์เป็นหนึ่งคอลัมน์เมื่อหน้าจอกว้างไม่เกิน 700 พิกเซล โดยเปลี่ยนทั้งจำนวนคอลัมน์และการเรียงพื้นที่ การนำ Sidebar ไปไว้หลังเนื้อหาหลักใน CSS ไม่ได้เปลี่ยนลำดับใน DOM ดังนั้นควรตรวจสอบลำดับการอ่านด้วยโปรแกรมอ่านหน้าจอและการใช้งานคีย์บอร์ดให้สอดคล้องกับความหมายของเนื้อหา

7. เปรียบเทียบ CSS Grid กับ Flexbox

หัวข้อCSS GridFlexbox
แนวทางการจัดวางจัดการแถวและคอลัมน์ร่วมกันแบบสองมิติจัดองค์ประกอบตามแกนหลักและแกนขวาง
งานที่เหมาะสมโครงสร้างหน้าเว็บ แดชบอร์ด แกลเลอรี และการ์ดหลายคอลัมน์เมนูนำทาง แถบปุ่ม กลุ่มไอคอน และการจัดเนื้อหาในแถวหรือคอลัมน์
การควบคุมช่องกำหนดแทร็กและพื้นที่ของ Grid ได้โดยตรงกระจายพื้นที่ของรายการตามแนวแกนและคุณสมบัติของ Flex
การทำงานร่วมกันสามารถใช้ Flexbox ภายใน Grid Item ได้สามารถใช้ Grid ภายใน Flex Item ได้
ข้อควรระวังต้องตรวจสอบการล้นและการจัดวางรายการที่ครอบคลุมหลายแทร็กการจัดหลายแถวหรือคอลัมน์พร้อมกันอาจควบคุมได้ไม่ตรงเท่า Grid
ไม่จำเป็นต้องเลือกใช้เพียงระบบเดียว ในเว็บไซต์จริง Grid มักทำหน้าที่วางโครงสร้างหน้าหลัก ส่วน Flexbox ใช้จัดปุ่ม ชื่อสินค้า ราคา หรือเมนูภายในแต่ละการ์ด การเลือกเครื่องมือจากรูปแบบของปัญหาจะช่วยให้ CSS อ่านง่ายและดูแลรักษาได้ดีขึ้น

8. ตัวอย่างใช้งานจริง: Product Grid สำหรับร้านค้าออนไลน์

ลองพิจารณาหน้ารวมสินค้า ซึ่งต้องแสดงภาพ ชื่อ รายละเอียดสั้น และราคาในแต่ละการ์ด Grid ช่วยจัดรายการให้เป็นระเบียบ ส่วน Flexbox สามารถช่วยวางราคาและปุ่มไว้ด้านล่างของการ์ดได้ หากใช้ `auto-fit` ร่วมกับ `minmax()` จำนวนคอลัมน์จะปรับตามพื้นที่โดยไม่จำเป็นต้องเขียน Media Query สำหรับทุกขนาดหน้าจอ
พื้นที่ทำงานสำหรับพัฒนาเว็บไซต์ด้วยโค้ด
การพัฒนาเลย์เอาต์และส่วนติดต่อผู้ใช้สำหรับเว็บไซต์สมัยใหม่
การออกแบบส่วนติดต่อผู้ใช้บนหน้าจอ
ตัวอย่างแนวคิดการออกแบบประสบการณ์ผู้ใช้และหน้าร้านดิจิทัล

9. ทดลองสร้างหน้าเว็บ CSS Grid แบบเต็มหน้า

ตัวอย่างต่อไปเป็นไฟล์ HTML แบบสมบูรณ์ สามารถบันทึกเป็น `index.html` แล้วเปิดในเบราว์เซอร์ได้ทันที ประกอบด้วยส่วนหัว คำอธิบาย Grid การ์ดตัวอย่าง และปุ่มทดลองเปลี่ยนรูปแบบการจัดวางระหว่าง Grid แบบปรับคอลัมน์อัตโนมัติกับ Grid แบบสามคอลัมน์คงที่
⚠️ ก่อนทดลองโค้ดนี้เป็นตัวอย่างฝั่ง Frontend และไม่ต้องใช้เซิร์ฟเวอร์หรือฐานข้อมูล ปุ่มเปลี่ยนรูปแบบมีผลเฉพาะหน้าเดโม หากนำไปใช้ในระบบจริง ควรปรับสี ระยะห่าง ข้อความ และการจัดการข้อมูลให้ตรงกับผลิตภัณฑ์ของคุณ
<!DOCTYPE html>
<html lang="th">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="ตัวอย่างการสร้างเลย์เอาต์ Responsive ด้วย CSS Grid">
  <title>CSS Grid — Responsive Layout Demo</title>
  <style>
    :root {
      color-scheme: light;
      --ink: #172033;
      --muted: #64748b;
      --brand: #4f46e5;
      --surface: #ffffff;
      --page: #f1f5f9;
      --border: #e2e8f0;
    }

    * { box-sizing: border-box; }

    body {
      margin: 0;
      font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
      color: var(--ink);
      background: var(--page);
      line-height: 1.6;
    }

    .site-header {
      padding: 28px 20px;
      color: white;
      background: linear-gradient(135deg, #312e81, #4f46e5);
    }

    .header-inner, main, .site-footer {
      width: min(1100px, calc(100% - 32px));
      margin-inline: auto;
    }

    .site-header h1 {
      margin: 0 0 8px;
      font-size: clamp(1.6rem, 4vw, 2.4rem);
      line-height: 1.2;
    }

    .site-header p { margin: 0; color: #e0e7ff; }

    main { padding-block: 28px 40px; }

    .intro {
      padding: 22px;
      margin-bottom: 20px;
      border: 1px solid var(--border);
      border-radius: 16px;
      background: var(--surface);
    }

    .intro h2 { margin-top: 0; }
    .intro p { margin-bottom: 0; color: var(--muted); }

    .toolbar {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      margin-bottom: 16px;
    }

    .toolbar h2 { margin: 0; font-size: 1.25rem; }

    .toolbar button {
      border: 0;
      border-radius: 10px;
      padding: 11px 16px;
      color: white;
      background: var(--brand);
      font: inherit;
      font-weight: 700;
      cursor: pointer;
    }

    .toolbar button:hover { background: #3730a3; }
    .toolbar button:focus-visible { outline: 3px solid #a5b4fc; outline-offset: 3px; }

    .product-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
      gap: 18px;
    }

    .product-grid.fixed-columns {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .product-card {
      display: flex;
      flex-direction: column;
      min-width: 0;
      padding: 20px;
      border: 1px solid var(--border);
      border-radius: 16px;
      background: var(--surface);
      box-shadow: 0 5px 16px rgb(15 23 42 / 5%);
      transition: transform 180ms ease, box-shadow 180ms ease;
    }

    .product-card:hover {
      transform: translateY(-3px);
      box-shadow: 0 12px 26px rgb(15 23 42 / 10%);
    }

    .product-icon {
      display: grid;
      place-items: center;
      width: 54px;
      height: 54px;
      margin-bottom: 14px;
      border-radius: 14px;
      background: #eef2ff;
      font-size: 1.7rem;
    }

    .product-card h3 { margin: 0 0 8px; font-size: 1.1rem; }
    .product-card p { margin: 0 0 18px; color: var(--muted); }

    .product-bottom {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      margin-top: auto;
      padding-top: 14px;
      border-top: 1px solid var(--border);
    }

    .price { font-weight: 800; color: #4338ca; }
    .tag { padding: 4px 8px; border-radius: 999px; background: #f1f5f9; color: #475569; font-size: .8rem; }

    .site-footer {
      padding-block: 20px 30px;
      color: var(--muted);
      text-align: center;
      font-size: .9rem;
    }

    @media (max-width: 760px) {
      .product-grid.fixed-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    }

    @media (max-width: 480px) {
      .product-grid.fixed-columns { grid-template-columns: minmax(0, 1fr); }
      .intro { padding: 18px; }
    }

    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after {
        scroll-behavior: auto !important;
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
      }
    }
  </style>
</head>
<body>
  <header class="site-header">
    <div class="header-inner">
      <h1>CSS Grid Workshop</h1>
      <p>เรียนรู้การจัดเลย์เอาต์ด้วยแถวและคอลัมน์ที่ยืดหยุ่น</p>
    </div>
  </header>

  <main>
    <section class="intro" aria-labelledby="intro-title">
      <h2 id="intro-title">สร้างหน้ารวมสินค้าอย่างเป็นระบบ</h2>
      <p>การ์ดแต่ละใบจะถูกจัดลงใน Grid โดยอัตโนมัติ ลองเปลี่ยนรูปแบบเพื่อเปรียบเทียบการจัดคอลัมน์แบบยืดหยุ่นกับแบบกำหนดจำนวนคอลัมน์</p>
    </section>

    <section aria-labelledby="products-title">
      <div class="toolbar">
        <h2 id="products-title">ตัวอย่างสินค้า</h2>
        <button id="layout-toggle" type="button" aria-pressed="false">เปลี่ยนเป็น 3 คอลัมน์</button>
      </div>

      <div class="product-grid" id="product-grid">
        <article class="product-card">
          <div class="product-icon" aria-hidden="true">💻</div>
          <h3>Starter Website</h3>
          <p>เว็บไซต์เริ่มต้นสำหรับธุรกิจขนาดเล็ก พร้อมส่วนแสดงข้อมูลสำคัญ</p>
          <div class="product-bottom"><span class="price">เริ่มต้น ฿990</span><span class="tag">เว็บไซต์</span></div>
        </article>
        <article class="product-card">
          <div class="product-icon" aria-hidden="true">🛍️</div>
          <h3>Online Store</h3>
          <p>เลย์เอาต์หน้าร้านที่จัดหมวดหมู่สินค้าและข้อมูลให้อ่านง่าย</p>
          <div class="product-bottom"><span class="price">เริ่มต้น ฿1,990</span><span class="tag">อีคอมเมิร์ซ</span></div>
        </article>
        <article class="product-card">
          <div class="product-icon" aria-hidden="true">📊</div>
          <h3>Business Dashboard</h3>
          <p>จัดกลุ่มข้อมูลสำคัญเป็นการ์ดเพื่อช่วยให้มองเห็นภาพรวมได้รวดเร็ว</p>
          <div class="product-bottom"><span class="price">เริ่มต้น ฿2,490</span><span class="tag">แดชบอร์ด</span></div>
        </article>
        <article class="product-card">
          <div class="product-icon" aria-hidden="true">📱</div>
          <h3>Mobile Landing</h3>
          <p>หน้าแนะนำบริการที่ปรับการแสดงผลให้เหมาะกับหน้าจอหลายขนาด</p>
          <div class="product-bottom"><span class="price">เริ่มต้น ฿790</span><span class="tag">Responsive</span></div>
        </article>
        <article class="product-card">
          <div class="product-icon" aria-hidden="true">🎨</div>
          <h3>Portfolio Design</h3>
          <p>พื้นที่แสดงผลงานที่เน้นลำดับสายตาและความสม่ำเสมอของการ์ด</p>
          <div class="product-bottom"><span class="price">เริ่มต้น ฿1,290</span><span class="tag">Portfolio</span></div>
        </article>
        <article class="product-card">
          <div class="product-icon" aria-hidden="true">⚙️</div>
          <h3>Admin Interface</h3>
          <p>ส่วนติดต่อผู้ดูแลระบบที่จัดวางเนื้อหาให้เป็นระเบียบและขยายต่อได้</p>
          <div class="product-bottom"><span class="price">เริ่มต้น ฿2,990</span><span class="tag">ระบบงาน</span></div>
        </article>
      </div>
    </section>
  </main>

  <footer class="site-footer">ตัวอย่างเพื่อการเรียนรู้ HTML และ CSS Grid</footer>

  <script>
    const grid = document.querySelector('#product-grid');
    const toggle = document.querySelector('#layout-toggle');

    toggle.addEventListener('click', () => {
      const fixed = grid.classList.toggle('fixed-columns');
      toggle.setAttribute('aria-pressed', String(fixed));
      toggle.textContent = fixed
        ? 'เปลี่ยนเป็นคอลัมน์อัตโนมัติ'
        : 'เปลี่ยนเป็น 3 คอลัมน์';
    });
  </script>
</body>
</html>

10. ข้อผิดพลาดที่พบบ่อยเมื่อใช้ CSS Grid

ข้อผิดพลาดแรกคือกำหนดคอลัมน์ด้วยขนาดคงที่ทั้งหมดโดยไม่พิจารณาหน้าจอขนาดเล็ก ซึ่งอาจทำให้เกิดแถบเลื่อนแนวนอน ข้อที่สองคือเข้าใจว่า `align-items` ใช้จัดตำแหน่งแทร็กทั้งหมด ทั้งที่จริงใช้จัดรายการภายในพื้นที่ของตนเอง ข้อที่สามคือใช้ `grid-column: span 2` กับรายการโดยไม่ตรวจสอบว่าหน้าจอมีพื้นที่เพียงพอหรือไม่ และข้อสุดท้ายคือใส่ `min-width` หรือเนื้อหาที่กว้างเกินไปจนทำให้ช่อง Grid ขยายออกนอก Container
  • ตรวจสอบความกว้างขั้นต่ำ พิจารณาใช้ `minmax(0, 1fr)` เพื่อป้องกันแทร็กบางประเภทขยายตามขนาดเนื้อหามากเกินไป
  • จัดการข้อความและรูปภาพ ใช้ `overflow-wrap: anywhere` กับข้อความที่อาจยาวผิดปกติ และกำหนด `max-width: 100%` ให้รูปภาพตามความเหมาะสม
  • ทดสอบหน้าจอหลายขนาด ทดลองทั้งหน้าจอเดสก์ท็อป แท็บเล็ต และมือถือ รวมถึงทดสอบการซูมและข้อความที่ยาวกว่าตัวอย่าง
  • รักษาลำดับเนื้อหา อย่าใช้การเปลี่ยนตำแหน่งด้วย CSS จนทำให้ลำดับการอ่านหรือการใช้งานคีย์บอร์ดสับสน

11. แนวทางฝึกฝนด้วยตนเอง

เริ่มจากปรับตัวอย่างด้านบนทีละค่า โดยเปลี่ยนจำนวนคอลัมน์จากสามเป็นสี่ เปลี่ยน `gap` ให้กว้างขึ้นหรือแคบลง ทดลองใช้ `minmax(180px, 1fr)` และสังเกตว่าแต่ละรายการเปลี่ยนขนาดอย่างไร จากนั้นเพิ่มการ์ดใหม่เพื่อทดสอบว่าระบบจัดวางรายการที่เกินจำนวนช่องเดิมอย่างไร เมื่อทำได้คล่องแล้ว ให้สร้างหน้าแดชบอร์ดที่มีพื้นที่สรุปตัวเลข การแจ้งเตือน และรายการข้อมูลโดยใช้ `grid-template-areas`
คำถามที่พบบ่อย: ควรใช้ Grid หรือ Flexbox ก่อน
หากกำลังวางโครงสร้างที่ต้องควบคุมทั้งแถวและคอลัมน์ ให้เริ่มพิจารณา Grid หากต้องจัดรายการเป็นแถวหรือคอลัมน์ตามเนื้อหา เช่น ปุ่ม เมนู หรือกลุ่มไอคอน Flexbox มักจะตรงไปตรงมากว่า ทั้งสองสามารถใช้ร่วมกันได้ ไม่จำเป็นต้องเลือกเพียงอย่างเดียว
คำถามที่พบบ่อย: auto-fit ต่างจาก auto-fill อย่างไร
`auto-fit` สามารถยุบแทร็กว่างที่ไม่จำเป็นเมื่อมีพื้นที่เหลือ เพื่อให้รายการที่มีอยู่ขยายได้ ส่วน `auto-fill` พยายามรักษาแทร็กที่สามารถใส่ได้ตามขนาดที่กำหนด แม้บางแทร็กจะไม่มีรายการอยู่ก็ตาม ผลลัพธ์จริงขึ้นอยู่กับขนาด Container และนิยามของแทร็ก
คำถามที่พบบ่อย: ต้องใช้ Media Query ทุกครั้งหรือไม่
ไม่จำเป็นเสมอไป เลย์เอาต์ที่ใช้ `repeat(auto-fit, minmax(...))` อาจปรับจำนวนคอลัมน์ได้เอง แต่ Media Query ยังมีประโยชน์เมื่อจำเป็นต้องเปลี่ยนโครงสร้างหน้า ลำดับพื้นที่ ขนาดตัวอักษร หรือการแสดงองค์ประกอบตามช่วงความกว้างที่กำหนด
คำถามที่พบบ่อย: ทำไมการ์ดจึงดัน Grid ให้กว้างเกินหน้าจอ
สาเหตุอาจมาจากข้อความยาวที่ตัดบรรทัดไม่ได้ รูปภาพที่ไม่มีข้อจำกัดความกว้าง หรือขนาดขั้นต่ำโดยปริยายของ Grid Item ลองใช้ `minmax(0, 1fr)` กับแทร็กที่ต้องย่อได้ เพิ่ม `min-width: 0` ให้รายการที่เหมาะสม และกำหนดขนาดรูปภาพให้ไม่เกินพื้นที่ที่มี
คำถามที่พบบ่อย: CSS Grid ใช้กับเบราว์เซอร์รุ่นใหม่ได้หรือไม่
CSS Grid รองรับในเบราว์เซอร์สมัยใหม่โดยทั่วไป แต่ถ้าระบบต้องรองรับเบราว์เซอร์เก่าหรืออุปกรณ์เฉพาะ ควรตรวจสอบตารางความเข้ากันได้ตามคุณสมบัติที่ใช้จริง และทดสอบหน้าจอเป้าหมายก่อนนำขึ้นใช้งาน

สรุป: วางโครงสร้างให้ดี แล้วค่อยเติมรายละเอียด

CSS Grid เป็นเครื่องมือสำคัญสำหรับสร้างเลย์เอาต์ที่มีโครงสร้างชัดเจน ตั้งแต่การ์ดสินค้าไปจนถึงหน้าระบบบริหารจัดการ เริ่มจาก `display: grid` และ `grid-template-columns` ทำความเข้าใจ `fr`, `repeat()`, `minmax()`, `gap` และการกำหนดพื้นที่ด้วย `grid-template-areas` จากนั้นจึงทดสอบ Responsive และการเข้าถึงอย่างสม่ำเสมอ เมื่อจับคู่ Grid กับ Flexbox ได้เหมาะสม คุณจะสร้างส่วนติดต่อผู้ใช้ที่ยืดหยุ่น อ่านง่าย และดูแลรักษาได้ง่ายขึ้น
เลย์เอาต์ที่ดีไม่ใช่แค่การจัดองค์ประกอบให้สวยงาม แต่คือการทำให้ข้อมูลมีลำดับและใช้งานได้ดีในทุกขนาดหน้าจอ

เริ่มทดลองเขียน CSS Grid

Reach within 500px of the page end and stay for at least 5 minutes to earn EXP once per day.

⏳ Reading timer is running...

🌐
Select Language
21 World Languages Supported