Guest Adventurer 🥉 Lv.1
🪙 50
🔷 10
← กลับคลังเนื้อหา
Article · programming

HTML และ CSS EP18: CSS Grid Layout — สร้างเลย์เอาต์เว็บไซต์แบบหลายคอลัมน์อย่างมืออาชีพ

HTML & CSS

บทเรียน EP18 เรียนรู้ CSS Grid ตั้งแต่แนวคิดแถวและคอลัมน์ การกำหนดพื้นที่ การสร้างการ์ดสินค้าแบบ Responsive การใช้ minmax(), repeat(), auto-fit และ grid-template-areas พร้อมตัวอย่าง HTML เต็มหน้าและแบบฝึกหัดที่นำไปทดลองได้ทันที

EP18 — CSS Grid Layout: วางโครงสร้างเว็บไซต์ด้วยแถวและคอลัมน์

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

1. CSS Grid คืออะไร และต่างจาก Flexbox อย่างไร

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

2. คำศัพท์พื้นฐานที่ต้องเข้าใจ

- **Grid Container:** องค์ประกอบแม่ที่กำหนด `display: grid`\n- **Grid Item:** องค์ประกอบลูกโดยตรงภายใน Grid Container\n- **Grid Track:** ช่องว่างตามแนวแถวหรือคอลัมน์ที่กริดสร้างขึ้น\n- **Grid Line:** เส้นแบ่งขอบเขตของแถวหรือคอลัมน์\n- **Grid Cell:** ช่องหนึ่งช่องที่เกิดจากจุดตัดของแถวและคอลัมน์\n- **Grid Area:** พื้นที่ที่ครอบคลุมหนึ่งช่องหรือหลายช่องในกริด\n- **Gap:** ระยะห่างระหว่างแถวและคอลัมน์
<!DOCTYPE html>
<html lang="th">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Grid พื้นฐาน</title>
  <style>
    * { box-sizing: border-box; }
    body { margin: 0; padding: 24px; font-family: system-ui, sans-serif; background: #f1f5f9; color: #172033; }
    h1 { font-size: 1.5rem; }
    .grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
    .item { padding: 24px 12px; text-align: center; color: #fff; background: #2563eb; border-radius: 10px; font-weight: 700; }
    .item:nth-child(even) { background: #0f766e; }
    @media (max-width: 520px) { .grid { grid-template-columns: 1fr 1fr; } }
  </style>
</head>
<body>
  <h1>ตัวอย่าง Grid 3 คอลัมน์</h1>
  <p>ทดลองปรับความกว้างหน้าต่างเพื่อดูจำนวนคอลัมน์เปลี่ยนไป</p>
  <div class="grid">
    <div class="item">รายการ 1</div>
    <div class="item">รายการ 2</div>
    <div class="item">รายการ 3</div>
    <div class="item">รายการ 4</div>
    <div class="item">รายการ 5</div>
    <div class="item">รายการ 6</div>
  </div>
</body>
</html>

3. เริ่มต้นสร้าง Grid ด้วย display: grid

ขั้นแรกกำหนด `display: grid` ให้กับองค์ประกอบแม่ จากนั้นใช้ `grid-template-columns` เพื่อกำหนดคอลัมน์ ตัวอย่าง `grid-template-columns: 200px 1fr 1fr;` จะสร้างคอลัมน์แรกกว้าง 200 พิกเซล และแบ่งพื้นที่ที่เหลือให้คอลัมน์ที่สองกับสามเท่า ๆ กัน ค่า `fr` หมายถึงส่วนแบ่งของพื้นที่ว่างในกริด ไม่ใช่หน่วยพิกเซลตายตัว
.layout {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;
  gap: 16px;
}

/* คอลัมน์กว้างเท่ากัน 3 คอลัมน์ */
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

/* แถวที่มีความสูงอย่างน้อย 120px */
.cards {
  grid-auto-rows: minmax(120px, auto);
}

4. repeat(), minmax() และ auto-fit: หัวใจของ Responsive Grid

การเขียนจำนวนคอลัมน์ตายตัวอาจไม่เหมาะกับทุกขนาดหน้าจอ เราสามารถใช้ `repeat()` ลดการเขียนซ้ำ ใช้ `minmax()` ระบุขนาดต่ำสุดและสูงสุด และใช้ `auto-fit` เพื่อให้เบราว์เซอร์จัดจำนวนคอลัมน์ตามพื้นที่ที่มีอยู่ รูปแบบที่ใช้บ่อยคือ `grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));` ซึ่งพยายามสร้างคอลัมน์ที่มีความกว้างอย่างน้อย 220 พิกเซล แล้วแบ่งพื้นที่ว่างให้เหมาะสม
เทคนิคที่ใช้ได้จริงสำหรับกริดการ์ดสินค้า การ์ดบทความ หรือแกลเลอรีที่ไม่จำเป็นต้องมีจำนวนคอลัมน์เท่ากันทุกอุปกรณ์ ให้เริ่มทดลองจาก repeat(auto-fit, minmax(220px, 1fr)) แล้วปรับค่าความกว้างขั้นต่ำตามเนื้อหาและการออกแบบ
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}

.product-card {
  min-width: 0;
  padding: 20px;
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  background: #fff;
}

.product-card img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 10px;
}

5. จัดระยะด้วย gap และกำหนดแถว

คุณสมบัติ `gap` ใช้กำหนดระยะห่างระหว่างรายการโดยไม่ต้องเพิ่ม margin ให้ลูกทุกชิ้น สามารถระบุค่าเดียวสำหรับทั้งสองทิศทาง หรือใช้ `row-gap` และ `column-gap` แยกกันได้ ส่วน `grid-template-rows` ใช้กำหนดขนาดแถวที่ต้องการอย่างชัดเจน หากจำนวนเนื้อหาเปลี่ยนไปบ่อย `grid-auto-rows` จะช่วยกำหนดขนาดของแถวที่เบราว์เซอร์สร้างเพิ่มอัตโนมัติ
.dashboard {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  column-gap: 24px;
  row-gap: 16px;
}

.gallery {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  row-gap: 24px;
  column-gap: 16px;
}

.gallery-item {
  min-width: 0;
  overflow-wrap: anywhere;
}

6. วางองค์ประกอบด้วย grid-column และ grid-row

นอกจากการวางรายการตามลำดับปกติแล้ว เรายังสั่งให้รายการกินพื้นที่หลายคอลัมน์หรือหลายแถวได้ เช่น `grid-column: span 2;` หมายถึงให้องค์ประกอบครอบคลุมสองคอลัมน์ ส่วน `grid-row: span 2;` หมายถึงครอบคลุมสองแถว ควรใช้เมื่อมีเหตุผลด้านโครงสร้างหรือการเน้นเนื้อหา และตรวจสอบการแสดงผลบนหน้าจอแคบด้วยเสมอ
.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.feature-card:first-child {
  grid-column: span 2;
  grid-row: span 2;
}

@media (max-width: 640px) {
  .feature-grid { grid-template-columns: 1fr; }
  .feature-card:first-child {
    grid-column: auto;
    grid-row: auto;
  }
}

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

`grid-template-areas` ช่วยตั้งชื่อพื้นที่ในเลย์เอาต์ ทำให้มองภาพรวมได้ง่าย เช่น header, sidebar, main และ footer ชื่อเดียวกันที่ปรากฏติดกันจะรวมเป็นพื้นที่เดียวกัน หากใช้จุด (`.`) จะหมายถึงช่องที่ไม่ได้กำหนดชื่อ พื้นที่ชื่อช่วยให้โค้ดอ่านง่าย แต่ไม่ได้เปลี่ยนลำดับการอ่านของเอกสาร HTML ดังนั้นควรวาง HTML ให้มีลำดับที่เหมาะสมต่อการอ่านและเทคโนโลยีช่วยเหลือด้วย
.page {
  display: grid;
  grid-template-columns: 240px 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 {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
  }
}
ภาพอุปกรณ์อิเล็กทรอนิกส์และเทคโนโลยีที่สื่อถึงการพัฒนาเว็บไซต์
การวางเลย์เอาต์เว็บไซต์เป็นระบบช่วยให้พัฒนาและดูแลหน้าเว็บที่มีหลายส่วนได้ง่ายขึ้น

8. จัดแนวรายการภายในกริด

คุณสมบัติ `justify-items` ใช้จัดแนวรายการตามแกนแนวนอนของเซลล์กริด ส่วน `align-items` ใช้จัดแนวตามแกนแนวตั้ง และ `place-items` เป็นทางลัดที่รวมสองคุณสมบัตินี้ไว้ด้วยกัน สำหรับการจัดแนวกริดทั้งชุดภายในพื้นที่ว่าง สามารถใช้ `justify-content` และ `align-content` ได้ ทั้งนี้การจัดแนวจะเห็นผลชัดเมื่อมีพื้นที่เหลือให้จัดสรร
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  justify-items: stretch;
  align-items: center;
}

.grid-item {
  min-width: 0;
  padding: 20px;
}

/* ทางลัดสำหรับกำหนดทั้งสองแกน */
.grid-centered {
  display: grid;
  place-items: center;
}

9. ตัวอย่างโปรเจกต์: สร้างหน้าแสดงการ์ดคอร์สแบบ Responsive

ตัวอย่างต่อไปนี้เป็นหน้า HTML เต็มรูปแบบที่สามารถบันทึกเป็น `index.html` แล้วเปิดในเบราว์เซอร์ได้ทันที ใช้ CSS Grid สร้างการ์ดคอร์สที่ปรับจำนวนคอลัมน์ตามพื้นที่จริง มีป้ายระดับบทเรียน ปุ่มดูรายละเอียด และตัวอย่างเลย์เอาต์ที่ปรับสำหรับมือถือ โดยไม่ต้องติดตั้งไลบรารีภายนอก
<!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="ตัวอย่างหน้าแสดงคอร์สเรียนด้วย CSS Grid">
  <title>ศูนย์รวมคอร์สเรียน</title>
  <style>
    :root {
      color-scheme: light;
      --page-bg: #f1f5f9;
      --surface: #ffffff;
      --text: #172033;
      --muted: #526176;
      --border: #dbe3ee;
      --primary: #1d4ed8;
      --primary-hover: #1e40af;
      --badge-bg: #dbeafe;
      --badge-text: #1e40af;
      --radius: 16px;
    }

    * { box-sizing: border-box; }
    body {
      margin: 0;
      font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      background: var(--page-bg);
      color: var(--text);
      line-height: 1.6;
    }
    .site-header {
      padding: 28px 20px;
      background: var(--surface);
      border-bottom: 1px solid var(--border);
    }
    .header-inner, main, .site-footer {
      width: min(1120px, calc(100% - 32px));
      margin-inline: auto;
    }
    .header-inner {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      gap: 16px;
    }
    h1 { margin: 0; font-size: clamp(1.5rem, 3vw, 2.2rem); }
    .intro { max-width: 680px; margin: 8px 0 0; color: var(--muted); }
    .theme-button {
      padding: 10px 14px;
      border: 1px solid var(--border);
      border-radius: 10px;
      background: var(--surface);
      color: var(--text);
      font: inherit;
      font-weight: 700;
      cursor: pointer;
    }
    .theme-button:focus-visible, .course-link:focus-visible {
      outline: 3px solid #f59e0b;
      outline-offset: 3px;
    }
    main { padding-block: 28px 40px; }
    .section-heading {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      align-items: end;
      gap: 12px;
      margin-bottom: 18px;
    }
    .section-heading h2 { margin: 0; font-size: 1.4rem; }
    .section-heading p { margin: 0; color: var(--muted); }
    .course-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 245px), 1fr));
      gap: 18px;
      align-items: stretch;
    }
    .course-card {
      display: flex;
      flex-direction: column;
      min-width: 0;
      padding: 20px;
      border: 1px solid var(--border);
      border-radius: var(--radius);
      background: var(--surface);
      box-shadow: 0 5px 18px rgb(15 23 42 / 5%);
    }
    .course-card h3 { margin: 14px 0 8px; font-size: 1.12rem; }
    .course-card p { margin: 0 0 16px; color: var(--muted); }
    .course-badge {
      align-self: flex-start;
      padding: 4px 9px;
      border-radius: 999px;
      background: var(--badge-bg);
      color: var(--badge-text);
      font-size: .8rem;
      font-weight: 700;
    }
    .course-meta {
      display: flex;
      flex-wrap: wrap;
      gap: 8px 12px;
      margin-top: auto;
      padding-top: 14px;
      border-top: 1px solid var(--border);
      color: var(--muted);
      font-size: .9rem;
    }
    .course-link {
      display: inline-block;
      margin-top: 16px;
      padding: 10px 14px;
      border-radius: 10px;
      background: var(--primary);
      color: #fff;
      text-align: center;
      text-decoration: none;
      font-weight: 700;
    }
    .course-link:hover { background: var(--primary-hover); }
    .site-footer { padding-block: 0 28px; color: var(--muted); font-size: .9rem; }

    html[data-theme="dark"] {
      color-scheme: dark;
      --page-bg: #0f172a;
      --surface: #1e293b;
      --text: #f1f5f9;
      --muted: #c0ccdc;
      --border: #475569;
      --primary: #2563eb;
      --primary-hover: #3b82f6;
      --badge-bg: #1e3a8a;
      --badge-text: #dbeafe;
    }

    @media (prefers-reduced-motion: no-preference) {
      .course-card { transition: transform .18s ease, box-shadow .18s ease; }
      .course-card:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgb(15 23 42 / 12%); }
    }
  </style>
</head>
<body>
  <header class="site-header">
    <div class="header-inner">
      <div>
        <h1>ศูนย์รวมคอร์สเรียน</h1>
        <p class="intro">เลือกหัวข้อที่สนใจ แล้วเรียนรู้ทักษะใหม่ได้ตามจังหวะของคุณ</p>
      </div>
      <button class="theme-button" id="themeToggle" type="button" aria-pressed="false">เปลี่ยนเป็นโหมดมืด</button>
    </div>
  </header>

  <main>
    <section aria-labelledby="coursesTitle">
      <div class="section-heading">
        <h2 id="coursesTitle">คอร์สแนะนำ</h2>
        <p>ตัวอย่างเลย์เอาต์ที่ใช้ CSS Grid</p>
      </div>
      <div class="course-grid">
        <article class="course-card">
          <span class="course-badge">เริ่มต้น</span>
          <h3>HTML สำหรับผู้เริ่มต้น</h3>
          <p>เรียนรู้โครงสร้างเอกสาร การสร้างหัวข้อ ลิงก์ รูปภาพ และแบบฟอร์มพื้นฐาน</p>
          <div class="course-meta"><span>8 บทเรียน</span><span>พื้นฐาน</span></div>
          <a class="course-link" href="#html-course">ดูรายละเอียดคอร์ส</a>
        </article>
        <article class="course-card">
          <span class="course-badge">ออกแบบ</span>
          <h3>CSS Layout และ Responsive</h3>
          <p>ฝึกจัดวางองค์ประกอบด้วย Flexbox, Grid และ Media Queries สำหรับทุกหน้าจอ</p>
          <div class="course-meta"><span>12 บทเรียน</span><span>ระดับกลาง</span></div>
          <a class="course-link" href="#css-course">ดูรายละเอียดคอร์ส</a>
        </article>
        <article class="course-card">
          <span class="course-badge">ลงมือทำ</span>
          <h3>สร้างหน้าเว็บโปรเจกต์แรก</h3>
          <p>นำความรู้มาประกอบเป็นหน้าเว็บจริง พร้อมตรวจสอบการใช้งานบนมือถือ</p>
          <div class="course-meta"><span>6 บทเรียน</span><span>โปรเจกต์</span></div>
          <a class="course-link" href="#project-course">ดูรายละเอียดคอร์ส</a>
        </article>
        <article class="course-card">
          <span class="course-badge">ต่อยอด</span>
          <h3>จัดการธีมด้วย CSS Variables</h3>
          <p>สร้างชุดสีที่ดูแลได้ง่าย และทดลองเปลี่ยนธีมสว่างหรือธีมมืด</p>
          <div class="course-meta"><span>5 บทเรียน</span><span>ระดับกลาง</span></div>
          <a class="course-link" href="#theme-course">ดูรายละเอียดคอร์ส</a>
        </article>
      </div>
    </section>
  </main>

  <footer class="site-footer">
    <p>ตัวอย่างเพื่อการเรียนรู้ สามารถแก้ข้อความ สี ระยะห่าง และจำนวนการ์ดได้ตามต้องการ</p>
  </footer>

  <script>
    const toggle = document.querySelector('#themeToggle');
    toggle.addEventListener('click', () => {
      const isDark = document.documentElement.dataset.theme !== 'dark';
      document.documentElement.dataset.theme = isDark ? 'dark' : 'light';
      toggle.setAttribute('aria-pressed', String(isDark));
      toggle.textContent = isDark ? 'เปลี่ยนเป็นโหมดสว่าง' : 'เปลี่ยนเป็นโหมดมืด';
    });
  </script>
</body>
</html>

10. ตรวจสอบ Responsive และการเข้าถึง

การทำ Grid ให้ดูดีบนจอใหญ่ไม่ได้รับประกันว่าจะใช้งานได้ดีบนมือถือ ควรตรวจสอบว่าการ์ดไม่แคบจนข้อความอ่านยาก ไม่มีแถบเลื่อนแนวนอนโดยไม่จำเป็น รูปภาพไม่บิดสัดส่วน และปุ่มยังใช้งานได้ด้วยการแตะหรือคีย์บอร์ด ใช้ `minmax(0, 1fr)` กับคอลัมน์ที่ต้องยืดหยุ่น และกำหนด `min-width: 0` ให้ลูกบางประเภทเมื่อเนื้อหายาวหรือมี URL ที่ไม่ตัดบรรทัด
ระวังการใช้ Grid จัดลำดับเนื้อหาการเปลี่ยนตำแหน่งด้วย CSS ไม่ได้เปลี่ยนลำดับ DOM ที่โปรแกรมอ่านหน้าจอหรือการนำทางด้วยคีย์บอร์ดรับรู้ ควรจัดลำดับ HTML ให้สมเหตุสมผลตั้งแต่ต้น และใช้ CSS เพื่อจัดหน้าตา ไม่ใช่แก้ปัญหาโครงสร้างเนื้อหาที่ไม่ถูกต้อง

11. ปัญหาที่พบบ่อยและวิธีแก้

ปัญหาสาเหตุที่เป็นไปได้แนวทางแก้ไข
คอลัมน์ล้นหน้าจอกำหนดความกว้างตายตัวหรือเนื้อหาไม่ยอมตัดบรรทัดใช้ minmax(0, 1fr), min-width: 0 และตรวจสอบเนื้อหาที่ยาว
การ์ดมีความกว้างไม่เหมาะสมกำหนดจำนวนคอลัมน์ตายตัวทุกขนาดหน้าจอทดลอง repeat(auto-fit, minmax(220px, 1fr))
พื้นที่ชื่อไม่ทำงานจำนวนชื่อในแต่ละแถวไม่สอดคล้องกันตรวจสอบจำนวนคอลัมน์และรูปแบบ grid-template-areas
รายการกินพื้นที่เกินที่ต้องการใช้ span โดยไม่ตรวจสอบจุดตัดของกริดลด span หรือปรับกฎใน media query
ข้อความยาวดันเลย์เอาต์คำยาวหรือลิงก์ไม่มีจุดตัดใช้ overflow-wrap: anywhere กับบริเวณที่เหมาะสม

12. แบบฝึกหัดลงมือทำ

ลองแก้ไฟล์ `index.html` จากตัวอย่างให้เป็นหน้าแสดงสินค้าในร้านค้าออนไลน์ โดยใช้ข้อมูลสินค้าสมมติของคุณเอง แล้วทดสอบบนหน้าจอขนาดต่าง ๆ
1. เพิ่มการ์ดสินค้าอีก 4 รายการ และกำหนดชื่อ ราคา และคำอธิบายให้แตกต่างกัน\n2. เปลี่ยนความกว้างขั้นต่ำของการ์ดจาก 245px เป็น 280px แล้วสังเกตจำนวนคอลัมน์\n3. เพิ่มป้ายสถานะ เช่น สินค้าใหม่ หรือสินค้าขายดี โดยใช้สีที่อ่านง่าย\n4. เพิ่มส่วนหัวและส่วนท้ายให้มีพื้นหลังและระยะห่างสอดคล้องกัน\n5. ทดลองสร้างเลย์เอาต์ด้วย grid-template-areas สำหรับ header, sidebar, main และ footer\n6. ตรวจสอบด้วยคีย์บอร์ดว่าปุ่มและลิงก์ทุกตัวมี focus ที่มองเห็นได้\n7. ปรับธีมสีให้มีความแตกต่างเพียงพอระหว่างข้อความและพื้นหลัง
เกณฑ์ตรวจผลงานผลงานที่ดีควรแสดงการ์ดครบทุกชิ้น ไม่มีเนื้อหาล้นหน้าจอโดยไม่ตั้งใจ จำนวนคอลัมน์เปลี่ยนตามพื้นที่ได้ ปุ่มอ่านง่ายและใช้งานได้ และลำดับเนื้อหาใน HTML ยังสมเหตุสมผลเมื่อปิด CSS

13. คำถามที่พบบ่อย

CSS Grid ใช้แทน Flexbox ได้ทั้งหมดหรือไม่?
ไม่จำเป็นต้องแทนกันทั้งหมด Grid เหมาะกับโครงสร้างที่ต้องควบคุมแถวและคอลัมน์ ส่วน Flexbox เหมาะกับการจัดองค์ประกอบตามแกนเดียวเป็นหลัก เลือกตามลักษณะของงาน และสามารถใช้ร่วมกันได้
auto-fit กับ auto-fill ต่างกันอย่างไร?
ทั้งสองคำใช้สร้างจำนวนแทร็กตามพื้นที่ที่มี แต่ auto-fill พยายามคงแทร็กที่สร้างได้ไว้แม้บางแทร็กจะไม่มีรายการ ส่วน auto-fit จะยุบแทร็กว่างเพื่อให้แทร็กที่มีรายการขยายได้มากขึ้นเมื่อมีพื้นที่เหลือ พฤติกรรมที่เห็นจริงขึ้นอยู่กับขนาดแทร็กและเนื้อหา
จำเป็นต้องใช้ Media Query เมื่อใช้ CSS Grid หรือไม่?
ไม่เสมอไป กริดที่ใช้ repeat(auto-fit, minmax(...)) สามารถปรับจำนวนคอลัมน์ตามพื้นที่ได้เอง แต่ Media Query ยังมีประโยชน์เมื่อจำเป็นต้องเปลี่ยนโครงสร้าง ลำดับการนำเสนอ หรือระยะห่างในบางช่วงความกว้าง
ทำไมบางครั้งคอลัมน์จึงกว้างเกินกว่าที่กำหนด?
เนื้อหาภายในอาจมีขนาดขั้นต่ำที่ทำให้คอลัมน์ขยาย เช่น URL ยาวหรือรูปภาพที่ไม่จำกัดขนาด ลองใช้ minmax(0, 1fr), min-width: 0, max-width: 100% และ overflow-wrap: anywhere ในตำแหน่งที่เหมาะสม

14. สรุปบทเรียน EP18

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

โปรเจกต์ท้ายบท: นำ CSS Grid ไปใช้กับเว็บไซต์ของคุณ

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

เริ่มทดลองสร้างเลย์เอาต์ CSS Grid

อ่านจนถึงระยะ 500px ก่อนท้ายหน้าและอยู่ในหน้านี้อย่างน้อย 5 นาที เพื่อรับ EXP วันละครั้ง

⏳ กำลังจับเวลาอ่าน...

🌐
เลือกภาษา / Select Language
21 World Languages Supported