ตารางกริด CSS – เลย์เอาต์ตารางกลับมาแล้ว รับรู้และทั่วถึง

สรุปคร่าวๆ

หากคุณคุ้นเคยกับ Flexbox ก็น่าจะรู้สึกคุ้นเคยดีกับ Flexbox นะ Rachel Andrew มีเว็บไซต์เกี่ยวกับ CSS Grid ที่ยอดเยี่ยมเพื่อช่วยคุณเริ่มต้น Grid พร้อมใช้งานใน Google Chrome แล้ว

Flexbox ใช่ไหม ตารางกริด

ในช่วง 2-3 ปีที่ผ่านมา CSS Flexbox เริ่มมีการใช้อย่างแพร่หลายและการรองรับเบราว์เซอร์ก็ทำได้ดีเยี่ยม (ยกเว้นคุณเป็นคนยากไร้ที่ต้องรองรับ IE9 และต่ำกว่า) Flexbox ทำให้งานเลย์เอาต์ที่ซับซ้อนหลายๆ งานง่ายขึ้น เช่น การเว้นระยะห่างระหว่างองค์ประกอบที่ห่างกันเท่ากัน เลย์เอาต์จากบนลงล่าง หรือโครงสร้างศักดิ์สิทธิ์ของเวทมนตร์ CSS ซึ่งก็คือการอยู่ตรงกลางแนวตั้ง

คุณไม่สามารถปรับแนวองค์ประกอบในคอนเทนเนอร์ Flexbox หลายรายการได้

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

CSS Grid อยู่ระหว่างการพัฒนา โดยมีการแจ้งว่าไม่เหมาะสมในเบราว์เซอร์ส่วนใหญ่มานานกว่า 5 ปี และใช้เวลาเพิ่มเติมไปกับความสามารถในการทำงานร่วมกันเพื่อหลีกเลี่ยงการเปิดตัวที่มีข้อบกพร่องเหมือนอย่าง Flexbox ดังนั้นถ้าคุณใช้ "ตารางกริด" เพื่อนำเลย์เอาต์ใน Chrome มาใช้ คุณก็มีโอกาสที่จะได้ผลลัพธ์เดียวกันใน Firefox และ Safari ในขณะที่เขียน การใช้งาน Grid ของ Microsoft Edge ล้าสมัย (อันเดียวกับที่มีอยู่ใน IE11 แล้ว) และการอัปเดตนั้น "อยู่ระหว่างการพิจารณา"

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

การกำหนดตารางกริด

เพื่อทำความคุ้นเคยกับคุณสมบัติต่างๆ ของ Grid เราขอแนะนำ Grid By Example หรือ CSS Tricks Cheat Sheet ของ Rachel Andrew หากคุณ คุ้นเคยกับ Flexbox แล้ว คุณสมบัติจำนวนมากและความหมายของคุณสมบัติเหล่านั้นควรมีความคุ้นเคยอยู่แล้ว

มาดูเลย์เอาต์แบบตารางกริดมาตรฐานแบบ 12 คอลัมน์กัน รูปแบบ 12 คอลัมน์แบบคลาสสิกได้รับความนิยมมากเนื่องจากหมายเลข 12 หารด้วย 2, 3, 4 และ 6 และมีประโยชน์สำหรับการออกแบบจำนวนมาก เราจะใช้เลย์เอาต์นี้แทน

คุณไม่สามารถปรับแนวองค์ประกอบในคอนเทนเนอร์ Flexbox หลายรายการได้

เรามาเริ่มกันด้วยโค้ดมาร์กอัป

<!DOCTYPE html>
<body>
    <header></header>
    <nav></nav>
    <main></main>
    <footer></footer>
</body>

ในสไตล์ชีต เราจะเริ่มด้วยการขยาย body เพื่อให้ครอบคลุมทั้งวิวพอร์ตและเปลี่ยนให้เป็นคอนเทนเนอร์ตารางกริด ดังนี้

html, body {
    width: 100vw;
    min-height: 100vh;
    margin: 0;
    padding: 0;
}
body {
    display: grid;
}

ตอนนี้เราใช้ CSS Grid. ไชโย

ขั้นตอนถัดไปคือการนำแถวและคอลัมน์ของตารางกริดไปใช้ เราสามารถนำทั้ง 12 คอลัมน์มาใช้ในแบบจำลองของเราได้ แต่เนื่องจากเราไม่ได้ใช้ทุกคอลัมน์ การทำเช่นนั้นจะทำให้ CSS ของเรายุ่งเหยิงโดยไม่จำเป็น เพื่อให้เข้าใจง่าย เราจะใช้เลย์เอาต์แบบนี้

ตัวอย่างเลย์เอาต์แบบง่าย

ส่วนหัวและส่วนท้ายมีความกว้างต่างกันไป และเนื้อหามีการแปรผันในขนาดทั้ง 2 ขนาด การนำทางจะแตกต่างกันทั้งสองด้านเช่นกัน แต่เรา จะกำหนดความกว้างขั้นต่ำที่ 200px (เพราะเหตุใด แน่นอนว่าเราจะแสดงฟีเจอร์ ของตารางกริด CSS)

ในตาราง CSS ชุดคอลัมน์และแถวจะเรียกว่าแทร็ก มาเริ่มต้นด้วย การกำหนดแทร็กชุดแรกของเรา นั่นคือแถว

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
}

grid-template-rows จะใช้ลำดับขนาดที่กำหนดแถวแต่ละแถว ในกรณีนี้ เราจะให้แถวแรกมีความสูง 150px และแถวสุดท้ายคือ 100px มีการตั้งค่าแถวกลางเป็น auto ซึ่งหมายความว่าระบบจะปรับตามความสูงที่จำเป็นเพื่อรองรับรายการในตารางกริด (รายการย่อยของคอนเทนเนอร์ตารางกริด) ในแถวนั้น เนื่องจากเนื้อหาของเราขยายไปทั่ววิวพอร์ต แทร็กที่มีเนื้อหา (สีเหลืองในรูปภาพด้านบน) จะเต็มพื้นที่ทั้งหมดที่มีอยู่เป็นอย่างน้อย แต่จะเพิ่มขึ้น (และทำให้เอกสารเลื่อนได้) หากจำเป็น

สำหรับคอลัมน์ เราต้องการใช้แนวทางแบบไดนามิกมากขึ้น เราต้องการให้ทั้งการนำทางและเนื้อหาเพิ่มขึ้น (และย่อลง) แต่เราต้องการให้การนำทางไม่ย่อลงต่ำกว่า 200px และต้องการให้เนื้อหามีขนาดใหญ่กว่า Nav ใน Flexbox เราจะใช้ Flex-grow และ Flex-Srink แต่ใน Grid จะมีความแตกต่างเล็กน้อย

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
}

เรากำลังกำหนด 2 คอลัมน์ คอลัมน์แรกจะกำหนดโดยใช้ฟังก์ชัน minmax() ซึ่งมีค่า 2 ค่า ได้แก่ ขนาดต่ำสุดและสูงสุดของแทร็กนั้น (เหมือนกับ min-width และ max-width ใน 1 จุด) ความกว้างขั้นต่ำคือ 200px ตามที่เรา พูดถึงก่อนหน้านี้ ความกว้างสูงสุดคือ 3fr fr เป็นหน่วยเฉพาะตารางกริดที่ช่วยให้คุณกระจายพื้นที่ว่างไปยังองค์ประกอบตารางกริด fr อาจย่อมาจาก "fraction unit" แต่อาจหมายถึงหน่วยฟรีด้วยในไม่ช้า ค่าของเราหมายความว่าทั้ง 2 คอลัมน์จะขยายเต็มหน้าจอ แต่คอลัมน์เนื้อหาจะกว้างกว่าคอลัมน์การนำทาง 3 เท่าเสมอ (หากคอลัมน์การนำทางกว้างกว่า 200 พิกเซล)

แม้ว่าตำแหน่งของรายการบนตารางกริดจะยังไม่ถูกต้อง แต่ขนาดของแถวและคอลัมน์ทำงานได้อย่างถูกต้อง และเป็นไปตามลักษณะการทำงานที่เรามุ่งหวังไว้

การวางรายการ

ฟีเจอร์ที่มีประสิทธิภาพมากที่สุดอย่างหนึ่งของตารางกริดคือการวางรายการได้โดยไม่ต้องคำนึงถึงลำดับ DOM (แต่เนื่องจากโปรแกรมอ่านหน้าจอจะไปยังส่วนต่างๆ ของ DOM ได้ เราขอแนะนำเป็นอย่างยิ่งว่าคุณควรระมัดระวังวิธีเรียงลำดับองค์ประกอบใหม่ให้เข้าถึงได้ง่าย) หากไม่ได้วางตำแหน่งด้วยตัวเอง ระบบจะวางองค์ประกอบไว้ในตารางกริดตามลำดับ DOM โดยจัดเรียงจากซ้ายไปขวาและบนลงล่าง แต่ละองค์ประกอบจะมีเซลล์ 1 เซลล์ เปลี่ยนลำดับการเติมข้อมูลในตารางได้โดยใช้ grid-auto-flow

เราจะวางองค์ประกอบต่างๆ อย่างไร เราคิดว่าวิธีที่ง่ายที่สุดในการวางรายการในตารางกริดคือการกำหนดคอลัมน์และแถวที่จะครอบคลุม ตารางกริดมีไวยากรณ์ 2 แบบดังนี้ คุณจะกำหนดจุดเริ่มต้นและจุดสิ้นสุดได้ในไวยากรณ์แรก ในวิดีโอที่สอง คุณจะต้องกำหนด จุดเริ่มต้นและระยะเวลา

header {
    grid-column: 1 / 3;
}
nav {
    grid-row: 2 / span 2;
}
ตำแหน่งโฆษณาที่กำหนดเอง

เราต้องการให้ส่วนหัวเริ่มต้นในคอลัมน์แรกและสิ้นสุดก่อนคอลัมน์ที่ 3 การไปยังส่วนต่างๆ ควรเริ่มในแถวที่ 2 และขยายไปทั้งหมด 2 แถว

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

body {
    display: grid;
    grid-template-rows: 150px [nav-start] auto 100px [nav-end];
    grid-template-columns: [header-start] minmax(200px, 3fr) 9fr [header-end];
}
header {
    grid-column: header-start / header-end;
}
nav {
    grid-row: nav-start / nav-end;
}

โค้ดด้านบนจะแสดงเลย์เอาต์เหมือนกับโค้ดก่อนหน้านี้

ยิ่งไปกว่านั้น คือคุณลักษณะของการตั้งชื่อภูมิภาคในตารางกริด

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
    grid-template-areas: "header header"
                        "nav    content"
                        "nav    footer";
}
header {
    grid-area: header;
}
nav {
    grid-area: nav;
}

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

มีอีกไหม

ใช่แล้ว มากเกินกว่าจะกล่าวถึงในบล็อกโพสต์เดียว Rachel Andrew ซึ่งเป็น GDE และเป็นผู้เชี่ยวชาญที่ได้รับเชิญในคณะทำงาน CSS และทำงานร่วมกับพวกเขามาตั้งแต่ต้นเพื่อให้ Grid สามารถออกแบบเว็บได้ง่ายขึ้น เธอถึงขั้นเขียนหนังสือเลย เว็บไซต์ของเธอที่ชื่อ Grid By Example เป็นแหล่งข้อมูลที่มีคุณค่าในการทำความคุ้นเคยกับ Grid หลายคนคิดว่า Grid เป็นก้าวปฏิวัติวงการ ในการออกแบบเว็บ และตอนนี้มีการเปิดใช้ใน Chrome โดยค่าเริ่มต้นแล้ว คุณจึงเริ่มใช้งานได้ทันที