ฝึกฝน CSS Subgrid ให้เชี่ยวชาญด้วยคู่มือฉบับสมบูรณ์นี้ เรียนรู้วิธีสร้างเว็บเลย์เอาต์ที่ซับซ้อน จัดวางได้อย่างสมบูรณ์แบบ และดูแลรักษาง่ายสำหรับผู้ชมทั่วโลก พร้อมตัวอย่างที่ใช้งานได้จริงและแนวทางปฏิบัติที่ดีที่สุด
CSS Grid Subgrid: การเจาะลึกการจัดองค์ประกอบเลย์เอาต์ขั้นสูง
เป็นเวลาหลายปีที่นักพัฒนาและนักออกแบบเว็บได้ใช้ประโยชน์จากพลังของ CSS Grid เพื่อสร้างเลย์เอาต์สองมิติที่ซับซ้อน พร้อมการควบคุมและความยืดหยุ่นที่ไม่เคยมีมาก่อน Grid ได้ปฏิวัติวิธีคิดเกี่ยวกับโครงสร้างหน้าเว็บของเรา ทำให้เราหลุดพ้นจากข้อจำกัดของ floats และธรรมชาติแบบหนึ่งมิติของ Flexbox อย่างไรก็ตาม แม้จะมีพลังมากเพียงใด ความท้าทายที่ยังคงอยู่คือการจัดตำแหน่งไอเท็มภายในกริดที่ซ้อนกันให้ตรงกับกริดหลักของผู้ปกครอง มันเป็นสาเหตุของความหงุดหงิดบ่อยครั้ง และมักนำไปสู่วิธีแก้ปัญหาที่ซับซ้อน การคำนวณด้วยตนเอง หรือการละทิ้งโครงสร้างกริดที่ซ้อนกันไปเลย ขอแนะนำ CSS Subgrid ฟีเจอร์ที่รอคอยมานานซึ่งช่วยแก้ปัญหานี้ได้อย่างงดงาม ปลดล็อกระดับใหม่ของความแม่นยำและความซับซ้อนในการจัดองค์ประกอบเลย์เอาต์
คู่มือฉบับสมบูรณ์นี้ออกแบบมาสำหรับผู้ชมทั่วโลกที่เป็นนักพัฒนา front-end, นักออกแบบเว็บ และวิศวกร UI เราจะสำรวจว่า CSS Subgrid คืออะไร ทำไมต้องใช้ และใช้อย่างไร โดยเริ่มจากแนวคิดพื้นฐานไปจนถึงการประยุกต์ใช้จริงขั้นสูง เมื่ออ่านจบ คุณจะไม่เพียงแต่เข้าใจ Subgrid แต่ยังพร้อมที่จะนำไปใช้สร้างเลย์เอาต์ที่แข็งแกร่งขึ้น ดูแลรักษาง่ายขึ้น และจัดวางได้อย่างสวยงาม
ความท้าทายก่อนมี Subgrid: ปริศนาของกริดที่ซ้อนกัน
เพื่อให้เข้าใจถึงสิ่งที่ Subgrid นำเสนอได้อย่างเต็มที่ เราต้องเข้าใจโลกที่ไม่มีมันก่อน ลองจินตนาการว่าคุณมีเลย์เอาต์กริดหลักสำหรับเนื้อหาในหน้าเว็บของคุณ ภายในหนึ่งในไอเท็มของกริด คุณต้องการสร้างกริดอีกอันหนึ่ง—ซึ่งก็คือกริดที่ซ้อนกัน นี่เป็นรูปแบบที่พบบ่อยมาก โดยเฉพาะในการออกแบบที่ใช้คอมโพเนนต์เป็นหลัก
ลองพิจารณาเลย์เอาต์แบบการ์ดทั่วไป คุณมีคอนเทนเนอร์ที่เก็บการ์ดหลายใบ และคอนเทนเนอร์นั้นเป็น CSS Grid การ์ดแต่ละใบเป็นไอเท็มของกริด ภายในแต่ละการ์ด คุณก็ต้องการใช้กริดเพื่อจัดโครงสร้างเนื้อหาของมัน—ส่วนหัว, เนื้อหาหลัก และส่วนท้าย
หากไม่มี Subgrid กริดที่ซ้อนกันภายในการ์ดจะไม่รับรู้ถึงเส้นกริดของคอนเทนเนอร์หลัก มันจะสร้างบริบทการจัดรูปแบบกริดของตัวเองที่เป็นอิสระ ซึ่งหมายความว่าแทร็ก (คอลัมน์และแถว) ที่คุณกำหนดภายในการ์ดจะถูกแยกออกจากแทร็กของคอนเทนเนอร์หลักโดยสิ้นเชิง
ตัวอย่างปัญหาที่เห็นภาพชัดเจน
ลองจินตนาการถึงหน้ารายการสินค้าที่แต่ละสินค้าเป็นการ์ด คุณต้องการให้ชื่อสินค้าจัดเรียงในแนวนอนตรงกันทุกการ์ด และปุ่ม "เพิ่มลงตะกร้า" ที่ด้านล่างของการ์ดแต่ละใบก็จัดเรียงตรงกันด้วย โดยไม่คำนึงถึงความยาวของคำอธิบายที่อยู่ตรงกลาง ด้วยกริดที่ซ้อนกันแบบมาตรฐาน การทำเช่นนี้แทบจะเป็นไปไม่ได้เลยหากไม่ใช้ความสูงคงที่หรือการคำนวณด้วย JavaScript
นี่คือตัวอย่างโค้ดแบบง่ายของสถานการณ์นี้:
โครงสร้าง HTML:
<div class="card-container">
<div class="card">
<h3>Product A</h3>
<p>A short, concise description.</p>
<button>Add to Cart</button>
</div>
<div class="card">
<h3>Product B</h3>
<p>This product has a much longer description that will wrap onto multiple lines, causing alignment issues for the elements below it.</p>
<button>Add to Cart</button>
</div>
<div class="card">
<h3>Product C</h3>
<p>Another description.</p>
<button>Add to Cart</button>
</div>
</div>
CSS (ไม่มี Subgrid):
.card-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.card {
border: 1px solid #ccc;
padding: 15px;
display: grid;
grid-template-rows: auto 1fr auto; /* Header, Body (stretches), Footer */
gap: 10px;
}
.card h3 {
/* No special styling needed for position */
}
.card p {
/* This will stretch due to 1fr */
}
.card button {
align-self: end; /* Tries to push button to the bottom of its grid area */
}
ในตัวอย่างนี้ ปุ่มในการ์ดใบที่สองจะอยู่ต่ำกว่าปุ่มในการ์ดอื่นๆ เพราะข้อความคำอธิบายใช้พื้นที่มากกว่า กริดภายในของการ์ดแต่ละใบเป็นอิสระต่อกันโดยสมบูรณ์ หน่วย `1fr` สำหรับแถวของย่อหน้าจะใช้ได้เฉพาะในบริบทความสูงที่มีอยู่ของการ์ดใบนั้นๆ เท่านั้น ไม่มีเส้นกริดร่วมกันให้ปุ่มต่างๆ จัดตำแหน่งตามได้ นี่คือปัญหาที่ Subgrid ถูกออกแบบมาเพื่อแก้ไขโดยเฉพาะ
ขอแนะนำ CSS Subgrid: ส่วนที่ขาดหายไปเพื่อการจัดตำแหน่งที่สมบูรณ์แบบ
CSS Subgrid คือค่าสำหรับ `grid-template-columns` และ `grid-template-rows` เมื่อนำไปใช้กับไอเท็มของกริด (ซึ่งตัวมันเองกลายเป็นคอนเทนเนอร์ของกริด) มันจะสั่งให้ไอเท็มนั้น ไม่ สร้างรายการแทร็กใหม่ของตัวเอง แต่จะยืมและนำแทร็กกริดจากแม่ของมันโดยตรงมาใช้แทน
ในทางเทคนิคแล้ว Subgrid คืออะไร?
โดยพื้นฐานแล้ว Subgrid สร้างการเชื่อมโยงโดยตรงระหว่างกริดที่ซ้อนกันกับกริดแม่ของมัน กริดที่ซ้อนกันจะกลายเป็นส่วนหนึ่งในบริบทการจัดรูปแบบกริดของแม่สำหรับมิติที่ระบุ (แถว, คอลัมน์, หรือทั้งสองอย่าง) จากนั้นองค์ประกอบลูกของไอเท็มที่เป็น subgrid จะสามารถวางลงบนกริดที่สืบทอดมานี้ได้ ทำให้พวกมันสามารถจัดตำแหน่งให้ตรงกับองค์ประกอบอื่นๆ ที่อยู่นอกแม่ของมันได้โดยตรง แต่อยู่ภายในกริดหลักเดียวกัน
ประเด็นสำคัญคือ: Subgrid ไม่ได้กำหนดแทร็กของตัวเอง แต่ใช้แทร็กของแม่
คีย์เวิร์ด `subgrid`: ไวยากรณ์และการใช้งาน
ไวยากรณ์นั้นเรียบง่ายอย่างสวยงาม คุณใช้คีย์เวิร์ด `subgrid` เป็นค่าสำหรับ `grid-template-columns`, `grid-template-rows` หรือทั้งสองอย่าง บนองค์ประกอบที่เป็นทั้งไอเท็มของกริดและคอนเทนเนอร์ของกริด
สมมติว่าองค์ประกอบลูก `.nested-grid` เป็นไอเท็มภายใน `.parent-grid` หากต้องการทำให้มันเป็น subgrid:
.parent-grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* Example parent tracks */
grid-template-rows: 100px auto 200px; /* Example parent tracks */
}
.nested-grid {
/* This item must span the tracks it wants to use */
grid-column: 1 / 4; /* Spans all 3 columns of the parent */
grid-row: 2 / 3; /* Sits in the second row of the parent */
/* Now, we activate subgrid */
display: grid;
grid-template-columns: subgrid; /* Inherits the 3 column tracks from parent */
grid-template-rows: subgrid; /* Inherits the single 'auto' row track from parent */
}
จุดสำคัญที่ต้องจำคือ: subgrid จะสืบทอดแทร็กได้ก็ต่อเมื่อมันครอบครองพื้นที่ของแทร็กนั้นๆ ก่อน ในตัวอย่างข้างต้น `.nested-grid` ครอบคลุมทั้งสามคอลัมน์ของแม่ของมัน ดังนั้นเมื่อเราตั้งค่า `grid-template-columns: subgrid;` มันจึงเข้าถึงแทร็กทั้งสามนั้นได้ ตอนนี้องค์ประกอบลูกของมันสามารถวางโดยใช้เส้นกริดที่ 1 ถึง 4 ของกริดคอลัมน์ของแม่ได้
การรองรับของเบราว์เซอร์และการเพิ่มประสิทธิภาพแบบก้าวหน้า
ณ เวลาที่เขียนบทความนี้ Subgrid ได้รับการสนับสนุนอย่างดีในเบราว์เซอร์สมัยใหม่ ซึ่งรวมถึง Firefox, Chrome, Edge และ Safari ทำให้มันเป็นเครื่องมือที่ใช้งานได้จริงสำหรับเว็บไซต์ที่เผยแพร่สู่ผู้ใช้งานทั่วโลก อย่างไรก็ตาม เช่นเดียวกับฟีเจอร์ CSS สมัยใหม่ใดๆ ควรพิจารณาถึงผู้ใช้ที่ใช้เบราว์เซอร์รุ่นเก่าด้วย
Progressive enhancement (การเพิ่มประสิทธิภาพแบบก้าวหน้า) เป็นกลยุทธ์ที่สมบูรณ์แบบในกรณีนี้ เราสามารถใช้ at-rule `@supports` ใน CSS เพื่อจัดเตรียมเลย์เอาต์สำรองที่ใช้งานได้ดีสำหรับเบราว์เซอร์ที่ไม่เข้าใจ Subgrid จากนั้นจึงใช้เลย์เอาต์ที่ขับเคลื่อนด้วย Subgrid สำหรับเบราว์เซอร์ที่รองรับ
/* --- Fallback for older browsers --- */
.card {
display: flex;
flex-direction: column;
justify-content: space-between; /* A good flex fallback */
}
/* --- Subgrid enhancement for modern browsers --- */
@supports (grid-template-rows: subgrid) {
.card {
display: grid;
grid-template-rows: subgrid; /* Override the flex display */
grid-row: span 3; /* Assumes parent grid has 3 rows for header, content, footer */
}
}
แนวทางนี้ช่วยให้ทุกคนได้รับประสบการณ์ที่ใช้งานได้และยอมรับได้ ในขณะที่ผู้ใช้ส่วนใหญ่ที่ใช้เบราว์เซอร์สมัยใหม่จะได้รับเลย์เอาต์ที่เหนือกว่าและจัดวางอย่างสมบูรณ์แบบ
เจาะลึกภาคปฏิบัติ: Subgrid ในการใช้งานจริง
ทฤษฎีเป็นสิ่งจำเป็น แต่การได้เห็น Subgrid แก้ปัญหาในโลกแห่งความเป็นจริงคือสิ่งที่ทำให้พลังของมันชัดเจนอย่างแท้จริง ลองกลับไปดูตัวอย่างคอมโพเนนต์การ์ดของเราและแก้ไขมันด้วย Subgrid
ตัวอย่างที่ 1: คอมโพเนนต์การ์ดที่จัดวางอย่างสมบูรณ์แบบ
เป้าหมายของเราคือการทำให้ส่วนหัว, พื้นที่เนื้อหา และส่วนท้ายของการ์ดจัดเรียงตรงกันทุกใบ สร้างเส้นแนวนอนที่สะอาดตา โดยไม่คำนึงถึงความยาวของเนื้อหา
ก่อนอื่น เราต้องปรับกริดหลักของเรา แทนที่จะกำหนดแค่คอลัมน์ เราจะกำหนดแถวที่สอดคล้องกับส่วนต่างๆ ที่ต้องการของการ์ดของเราด้วย (ส่วนหัว, เนื้อหา, ส่วนท้าย)
HTML ใหม่ (ไม่จำเป็นต้องเปลี่ยนแปลง):
<div class="card-container">
<!-- Cards go here, same as before -->
</div>
CSS ใหม่ (พร้อม Subgrid):
.card-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* Define rows for our card structure */
grid-template-rows: auto 1fr auto; /* Row for headers, flexible body, row for footers */
gap: 20px;
}
.card {
border: 1px solid #ccc;
padding: 15px;
/* --- The Subgrid Magic --- */
display: grid;
/* The card itself needs to span all the rows it will use */
grid-row: 1 / 4; /* Span all three rows defined in the parent */
/* Now, inherit those rows */
grid-template-rows: subgrid;
}
/* Place the card's children onto the inherited parent grid */
.card h3 {
grid-row: 1; /* Place in the first row of the parent's grid */
}
.card p {
grid-row: 2; /* Place in the second (flexible) row */
}
.card button {
grid-row: 3; /* Place in the third row */
align-self: end; /* Optional: align to bottom within that row */
}
เกิดอะไรขึ้น?
- `.card-container` ตอนนี้กำหนดกริดสามแถว: แถวขนาด `auto` สำหรับส่วนหัว, แถว `1fr` ที่ยืดหยุ่นสำหรับเนื้อหาหลัก และอีกแถวขนาด `auto` สำหรับปุ่ม
- `.card` แต่ละใบถูกสั่งให้ครอบคลุมทั้งสามแถวนี้ (`grid-row: 1 / 4`)
- ที่สำคัญที่สุด เราตั้งค่า `display: grid` และ `grid-template-rows: subgrid` บน `.card` สิ่งนี้บอกการ์ดว่า "อย่าสร้างแถวของตัวเอง ให้ใช้สามแถวที่คุณกำลังครอบครองจากแม่ของคุณ"
- ตอนนี้ `h3`, `p`, และ `button` ภายใน ทุกๆ การ์ดกำลังถูกวางบน กริดเดียวกันที่ใช้ร่วมกัน `h3` จากการ์ดที่ 1 อยู่ในแทร็กเดียวกับ `h3` จากการ์ดที่ 2 `button` จากการ์ดที่ 1 อยู่ในแทร็กเดียวกับปุ่มจากการ์ดที่ 2 ผลลัพธ์คืออะไร? การจัดตำแหน่งแนวนอนที่สมบูรณ์แบบทั่วทั้งคอมโพเนนต์
นี่คือการเปลี่ยนแปลงที่ปฏิวัติวงการ เราบรรลุเป้าหมายการจัดตำแหน่งที่ซับซ้อนด้วย CSS ที่เรียบง่ายและเป็นแบบประกาศ โดยไม่ต้องใช้เทคนิคพิเศษ และยังคงรักษาโครงสร้าง HTML ที่สะอาดและมีความหมาย
ตัวอย่างที่ 2: การจัดตำแหน่งช่องฟอร์มในเลย์เอาต์ที่ซับซ้อน
ฟอร์มเป็นอีกหนึ่งส่วนที่การจัดตำแหน่งมีความสำคัญต่อประสบการณ์ผู้ใช้ที่ดี ลองจินตนาการถึงส่วนหนึ่งของหน้าเว็บที่เป็นไอเท็มของกริด และภายในส่วนนั้นมีฟอร์มที่มีป้ายกำกับและช่องป้อนข้อมูลที่คุณต้องการจัดให้ตรงกับองค์ประกอบอื่นๆ ในหน้า
โครงสร้าง HTML:
<div class="page-layout">
<aside>... sidebar content ...</aside>
<main>
<h1>Profile Settings</h1>
<form class="profile-form">
<label for="name">Full Name</label>
<input type="text" id="name" />
<label for="email">Email Address</label>
<input type="email" id="email" />
<label for="country">Country/Region</label>
<input type="text" id="country" />
</form>
</main>
</div>
CSS โดยใช้ Subgrid แบบคอลัมน์:
.page-layout {
display: grid;
/* A common layout: sidebar, main content with two sub-columns */
grid-template-columns: 200px [main-start] 150px 1fr [main-end];
gap: 30px;
}
main {
grid-column: main-start / main-end; /* Span the two main content columns */
display: grid;
/* This is the key: inherit the parent's columns */
grid-template-columns: subgrid;
/* We can define our own rows as needed */
grid-auto-rows: min-content;
align-content: start;
}
main h1 {
/* Let the heading span both inherited columns */
grid-column: 1 / 3;
}
.profile-form {
/* This form is also a grid item within 'main' */
grid-column: 1 / 3;
display: grid;
/* And we make IT a subgrid too! */
grid-template-columns: subgrid;
gap: 15px;
grid-auto-rows: min-content;
}
/* Now place labels and inputs on the inherited page-level grid */
.profile-form label {
grid-column: 1; /* Align to the first column (150px from .page-layout) */
text-align: right;
}
.profile-form input {
grid-column: 2; /* Align to the second column (1fr from .page-layout) */
}
ในตัวอย่างขั้นสูงนี้ เรามี subgrid ที่ซ้อนกัน องค์ประกอบ `main` กลายเป็น subgrid เพื่อสืบทอดแทร็กคอลัมน์จาก `.page-layout` จากนั้น `form` ที่อยู่ภายในก็กลายเป็น subgrid ด้วยเช่นกัน โดยสืบทอดแทร็กเดียวกันนั้นอีกครั้ง ซึ่งช่วยให้ป้ายกำกับและช่องป้อนข้อมูลของฟอร์มสามารถวางลงบนกริดหลักของหน้าได้โดยตรง ทำให้มั่นใจได้ว่าพวกมันจะจัดตำแหน่งได้อย่างสมบูรณ์แบบกับโครงสร้างโดยรวมของหน้าที่กำหนดไว้ในคอนเทนเนอร์ระดับบนสุด การควบคุมองค์ประกอบในระดับนี้เคยเป็นสิ่งที่จินตนาการไม่ได้ด้วย CSS เพียงอย่างเดียว
Subgrid สำหรับแถวและคอลัมน์: การสืบทอดแบบหนึ่งมิติเทียบกับสองมิติ
คุณไม่จำเป็นต้องใช้ Subgrid สำหรับทั้งสองแกนพร้อมกัน คุณสามารถเลือกที่จะสืบทอดแทร็กสำหรับคอลัมน์เท่านั้น, แถวเท่านั้น, หรือทั้งสองอย่างได้ ซึ่งให้การควบคุมเลย์เอาต์ของคุณอย่างละเอียด
Subgrid แบบคอลัมน์: `grid-template-columns: subgrid;`
วิธีนี้เหมาะอย่างยิ่งสำหรับการจัดตำแหน่งไอเท็มในแนวนอนข้ามคอมโพเนนต์ต่างๆ เช่นตัวอย่างฟอร์มด้านบน เมื่อคุณใช้ `grid-template-columns: subgrid;` คุณยังคงต้องกำหนดแทร็กแถวของคุณเองโดยใช้ค่ามาตรฐานเช่น `auto`, `1fr` หรือค่าพิกเซล (เช่น `grid-template-rows: auto 1fr;`) กริดที่ซ้อนกันจะสืบทอดคอลัมน์ แต่ต้องรับผิดชอบการกำหนดขนาดและจำนวนแถวของตัวเอง
Subgrid แบบแถว: `grid-template-rows: subgrid;`
วิธีนี้เหมาะสำหรับการจัดตำแหน่งไอเท็มในแนวตั้ง ดังที่เราทำในตัวอย่างคอมโพเนนต์การ์ด เหมาะอย่างยิ่งสำหรับการทำให้แน่ใจว่าส่วนแนวนอนของคอมโพเนนต์ต่างๆ อยู่ในแนวเดียวกัน เมื่อใช้ `grid-template-rows: subgrid;` คุณต้องกำหนดแทร็กคอลัมน์ของคุณเอง (เช่น `grid-template-columns: 1fr 1fr;`)
การรวมทั้งสองอย่าง: การสืบทอดแบบเต็มรูปแบบ
เมื่อคุณตั้งค่าทั้ง `grid-template-columns: subgrid;` และ `grid-template-rows: subgrid;` กริดที่ซ้อนกันจะกลายเป็นตัวแทนของกริดหลักอย่างแท้จริงภายในพื้นที่ที่กำหนด มันไม่ได้กำหนดแทร็กของตัวเองเลย นี่เป็นวิธีที่ทรงพลังสำหรับคอมโพเนนต์ที่ต้องถูกจำกัดอยู่แค่ในส่วนของกริดหลักอย่างเคร่งครัด ในขณะที่ให้องค์ประกอบลูกมีอิสระเต็มที่ในการวางตำแหน่งบนโครงสร้างกริดที่สืบทอดมานั้น
ลองพิจารณาวิดเจ็ตบนแดชบอร์ด ตัววิดเจ็ตเองอาจครอบคลุม 3 คอลัมน์และ 2 แถวของกริดแดชบอร์ดหลัก การทำให้วิดเจ็ตเป็น subgrid แบบเต็มรูปแบบจะทำให้องค์ประกอบภายในวิดเจ็ต (เช่น ชื่อแผนภูมิ, ตัวแผนภูมิเอง และคำอธิบายสัญลักษณ์) สามารถวางตำแหน่งได้อย่างแม่นยำบน 3 คอลัมน์และ 2 แถวนั้น เพื่อให้สอดคล้องกับองค์ประกอบในวิดเจ็ตที่อยู่ติดกัน
แนวคิดขั้นสูงและรายละเอียดปลีกย่อย
เมื่อคุณคุ้นเคยกับ Subgrid มากขึ้น คุณจะพบกับแง่มุมที่ละเอียดอ่อนและทรงพลังยิ่งขึ้นของมัน
Subgrid และ `gap`
คุณสมบัติ `gap` บนกริดหลักจะถูกสืบทอดโดย subgrid ช่องว่างระหว่างแทร็กเป็นส่วนหนึ่งของคำจำกัดความของกริด ซึ่งโดยปกติแล้วเป็นสิ่งที่คุณต้องการ เพราะมันช่วยรักษาระยะห่างที่สม่ำเสมอตลอดทั้งเลย์เอาต์ อย่างไรก็ตาม คุณสามารถระบุ `gap` บนคอนเทนเนอร์ของ subgrid เองได้ ซึ่งจะ เพิ่ม เข้าไปใน gap ที่สืบทอดมา ซึ่งเป็นพฤติกรรมที่ควรทราบไว้ ในกรณีส่วนใหญ่ คุณจะต้องการกำหนด gap บนกริดหลักและปล่อยให้ subgrid สืบทอดไปเพื่อความสอดคล้องกันอย่างสมบูรณ์แบบ
การกำหนดขนาดและการขยาย (Spanning) ในบริบทของ Subgrid
นี่เป็นหนึ่งในฟีเจอร์ที่ทรงพลังที่สุด เมื่อคุณวางไอเท็มภายใน subgrid และสั่งให้มันขยายครอบคลุมหลายแทร็ก (เช่น `grid-column: span 2;`) มันจะขยายครอบคลุมแทร็กของ กริดหลักดั้งเดิม ไม่ได้ขยายสองแทร็ก ของคอนเทนเนอร์ subgrid; แต่เป็นการขยายสองแทร็กที่ subgrid สืบทอดมา
สิ่งนี้ช่วยให้เกิดความยืดหยุ่นในการจัดองค์ประกอบอย่างไม่น่าเชื่อ องค์ประกอบที่อยู่ลึกลงไปใน DOM tree สามารถถูกทำให้จัดตำแหน่งและขยายข้ามโครงสร้างหน้าระดับสูงได้ โดยทะลุขอบเขตการมองเห็นของคอนเทนเนอร์ของมันเองในลักษณะที่ควบคุมได้และคาดเดาได้ นี่เป็นสิ่งที่ยอดเยี่ยมสำหรับการสร้างเลย์เอาต์สไตล์นิตยสารแบบไดนามิก ที่รูปภาพอาจขยายครอบคลุมหลายคอลัมน์ของกริดบทความหลัก แม้ว่ามันจะซ้อนอยู่ภายในองค์ประกอบ `figure` ก็ตาม
ข้อควรพิจารณาด้านการเข้าถึง (Accessibility)
หนึ่งในประโยชน์ที่ยอดเยี่ยมของ CSS Grid ซึ่งขยายมาถึง Subgrid คือการแยกแยะลำดับของซอร์สโค้ดออกจากการนำเสนอทางสายตา ด้วย Subgrid คุณสามารถรักษาโครงสร้างเอกสาร HTML ที่มีเหตุผลและเข้าถึงได้ (เช่น หัวเรื่องตามด้วยเนื้อหา) ในขณะที่ใช้กริดเพื่อให้ได้เลย์เอาต์ทางสายตาที่ซับซ้อนหรือสร้างสรรค์มากขึ้น
เนื่องจาก Subgrid ช่วยให้คุณหลีกเลี่ยงเทคนิคการจัดเลย์เอาต์ที่ไม่พึงประสงค์ จึงมักจะนำไปสู่ HTML ที่สะอาดขึ้น โปรแกรมอ่านหน้าจอ (screen reader) จะอ่านเอกสารตามลำดับตรรกะ ในขณะที่ผู้ใช้ที่มองเห็นจะเห็นการออกแบบที่จัดวางอย่างสมบูรณ์แบบ ตัวอย่างเช่น ในเลย์เอาต์การ์ดของเรา HTML สำหรับการ์ดแต่ละใบยังคงเป็นหน่วยตรรกะที่สมบูรณ์ในตัวเอง (`h3` -> `p` -> `button`) Subgrid เพียงแค่ประสานงานการจัดตำแหน่งทางสายตาระหว่างหน่วยเหล่านี้โดยไม่เปลี่ยนแปลงลำดับของเอกสาร ซึ่งเป็นชัยชนะที่ยิ่งใหญ่สำหรับการเข้าถึงและเป็นหลักการสำคัญของการพัฒนาเว็บสมัยใหม่
อนาคตของ CSS Layout: ตำแหน่งของ Subgrid ในระบบนิเวศ
Subgrid ไม่ได้มาแทนที่ Flexbox หรือ CSS Grid แบบปกติ มันเป็นส่วนเสริมที่ทรงพลังที่เข้ามาเติมเต็มช่องว่างที่สำคัญและเฉพาะเจาะจง ระบบนิเวศของ CSS layout สมัยใหม่คือการใช้เครื่องมือที่เหมาะสมกับงาน:
- Flexbox: เหมาะที่สุดสำหรับเลย์เอาต์แบบหนึ่งมิติ การกระจายพื้นที่ตามแกนเดียว และการจัดตำแหน่งไอเท็มภายในคอนเทนเนอร์ เหมาะสำหรับแถบนำทาง, กลุ่มปุ่ม และส่วนประกอบภายในที่เรียบง่าย
- CSS Grid: เหมาะที่สุดสำหรับเลย์เอาต์ระดับหน้าเว็บแบบสองมิติ การสร้างความสัมพันธ์ระหว่างแถวและคอลัมน์ เป็นรากฐานสำหรับโครงสร้างหน้าเว็บโดยรวมของคุณ
- CSS Subgrid: เป็นสะพานเชื่อมระหว่างคอมโพเนนต์ที่ซ้อนกันกับกริดหลักของหน้าเว็บ เป็นเครื่องมือที่คุณจะนึกถึงเมื่อไอเท็ม ภายใน ไอเท็มของกริดต้องการจัดตำแหน่งให้ตรงกับไอเท็ม ภายนอก
ในอนาคต Subgrid ทำงานร่วมกับฟีเจอร์ CSS สมัยใหม่อื่นๆ ได้อย่างสวยงาม เช่น Container Queries คุณอาจมีคอมโพเนนต์ที่ใช้เลย์เอาต์ subgrid เมื่อคอนเทนเนอร์ของมันกว้าง แต่จะเรียงซ้อนกันเป็น block หรือ flex layout อย่างง่ายในคอนเทนเนอร์ที่แคบ การผสมผสานระหว่างเลย์เอาต์ระดับมหภาค (Grid), การจัดตำแหน่งระดับคอมโพเนนต์ (Subgrid) และการตอบสนองตามขนาดคอนเทนเนอร์ (Container Queries) ทำให้นักพัฒนา front-end มีชุดเครื่องมือที่ทรงพลังและแสดงออกได้อย่างน่าทึ่งสำหรับสร้างเว็บอินเทอร์เฟซรุ่นต่อไป
สรุป: โอบรับพลังแห่งการจัดองค์ประกอบที่สอดคล้อง
CSS Subgrid เป็นมากกว่าฟีเจอร์ใหม่ มันคือการเปลี่ยนแปลงกระบวนทัศน์ในวิธีที่เราสามารถจัดองค์ประกอบเลย์เอาต์ที่ซับซ้อนบนเว็บได้ มันแก้ปัญหาที่มีมาอย่างยาวนานด้วยโซลูชันที่งดงามและเข้าใจง่าย ส่งเสริมโค้ดที่สะอาดขึ้น สไตล์ชีตที่ดูแลรักษาง่ายขึ้น และการออกแบบที่สมบูรณ์แบบทางสายตา
ด้วยการอนุญาตให้กริดที่ซ้อนกันมีส่วนร่วมในเลย์เอาต์ของแม่ของมัน Subgrid ช่วยให้เราสามารถ:
- บรรลุการจัดตำแหน่งที่สมบูรณ์แบบ: ทำให้องค์ประกอบในคอมโพเนนต์ที่แยกจากกันจัดตำแหน่งได้อย่างไร้ที่ติตโดยไม่ต้องใช้เทคนิคพิเศษหรือ JavaScript
- เขียนโค้ดแบบ DRY (Don't Repeat Yourself) มากขึ้น: กำหนดโครงสร้างกริดหลักของคุณเพียงครั้งเดียวและให้องค์ประกอบที่ซ้อนกันสืบทอดไป หลีกเลี่ยงการกำหนดแทร็กซ้ำๆ
- ปรับปรุงความสามารถในการบำรุงรักษา: ตรรกะของเลย์เอาต์จะรวมศูนย์อยู่ที่กริดหลัก ทำให้การอัปเดตและการปรับแก้แบบ responsive ง่ายขึ้นมาก
- เพิ่มประสิทธิภาพการเข้าถึง: สร้างเลย์เอาต์ทางสายตาที่ซับซ้อนในขณะที่ยังคงรักษาลำดับของซอร์สโค้ดที่มีเหตุผลและมีความหมาย
ด้วยการสนับสนุนจากเบราว์เซอร์อย่างกว้างขวาง ตอนนี้เป็นเวลาที่สมบูรณ์แบบสำหรับนักพัฒนาและนักออกแบบทั่วโลกที่จะนำ Subgrid มาใช้ในขั้นตอนการทำงานของตน เริ่มต้นด้วยการระบุคอมโพเนนต์ที่จะได้รับประโยชน์จากการจัดตำแหน่งข้ามองค์ประกอบ ทดลองกับการสืบทอดแถวและคอลัมน์ และสัมผัสกับความพึงพอใจในการสร้างเลย์เอาต์ที่แข็งแกร่งและมีเหตุผลทั้งเบื้องหลังและสวยงามบนหน้าจอ ยุคของเลย์เอาต์ที่ซ้อนกันแบบประนีประนอมได้สิ้นสุดลงแล้ว ยุคแห่งการจัดองค์ประกอบขั้นสูงที่สอดคล้องกันได้เริ่มต้นขึ้นอย่างแท้จริง