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 Grid | Flexbox |
|---|---|---|
| แนวทางการจัดวาง | จัดการแถวและคอลัมน์ร่วมกันแบบสองมิติ | จัดองค์ประกอบตามแกนหลักและแกนขวาง |
| งานที่เหมาะสม | โครงสร้างหน้าเว็บ แดชบอร์ด แกลเลอรี และการ์ดหลายคอลัมน์ | เมนูนำทาง แถบปุ่ม กลุ่มไอคอน และการจัดเนื้อหาในแถวหรือคอลัมน์ |
| การควบคุมช่อง | กำหนดแทร็กและพื้นที่ของ 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 ได้เหมาะสม คุณจะสร้างส่วนติดต่อผู้ใช้ที่ยืดหยุ่น อ่านง่าย และดูแลรักษาได้ง่ายขึ้น
เลย์เอาต์ที่ดีไม่ใช่แค่การจัดองค์ประกอบให้สวยงาม แต่คือการทำให้ข้อมูลมีลำดับและใช้งานได้ดีในทุกขนาดหน้าจอ
Reach within 500px of the page end and stay for at least 5 minutes to earn EXP once per day.
⏳ Reading timer is running...