เมื่อทำงานกับ CSS Grid สิ่งแรกที่ต้องทำคือตั้งค่า display: grid
ในองค์ประกอบที่เราต้องการให้เป็นคอนเทนเนอร์กริด จากนั้นเรากำหนดกริดอย่างชัดเจนโดยใช้การรวมกันของ grid-template-columns
, grid-template-rows
และ grid-template-areas
. และจากนั้น ขั้นตอนต่อไปคือการวางรายการไว้ในตาราง
นี่เป็นแนวทางคลาสสิกที่ควรใช้และฉันยังแนะนำอีกด้วย อย่างไรก็ตาม มีอีกแนวทางหนึ่งในการสร้างกริด โดยไม่มีคำจำกัดความที่ชัดเจน. เราเรียกสิ่งนี้ว่า กริดโดยปริยาย.
สารบัญ
"อย่างชัดเจนโดยปริยาย? นี่มันเกิดอะไรขึ้นกันแน่เนี่ย?”
เงื่อนไขแปลกใช่มั้ย? มานูเอล มาตูโซวิช แล้ว มี คำอธิบายที่ดี ของสิ่งที่เราอาจ "โดยนัย" และ "ชัดเจน" ใน CSS Grid แต่ให้เจาะลึกลงไปในสิ่งที่ specification พูดว่า:
พื้นที่
grid-template-rows
,grid-template-columns
และgrid-template-areas
คุณสมบัติกำหนดจำนวนแทร็กที่แน่นอนที่สร้าง ตารางที่ชัดเจน. เมื่อรายการกริดอยู่ในตำแหน่งนอกขอบเขตเหล่านี้ คอนเทนเนอร์กริดจะสร้างแทร็กกริดโดยนัยโดยการเพิ่มเส้นกริดโดยปริยายลงในกริด เส้นเหล่านี้ร่วมกับรูปแบบกริดที่ชัดเจน ตารางโดยปริยาย.
ดังนั้น ในภาษาอังกฤษธรรมดา เบราว์เซอร์จะสร้างแถวและคอลัมน์พิเศษโดยอัตโนมัติ ในกรณีที่องค์ประกอบใด ๆ เกิดขึ้นนอกกริดที่กำหนด
แล้วการจัดตำแหน่งอัตโนมัติล่ะ
คล้ายกับแนวคิดของกริดโดยปริยาย การจัดตำแหน่งอัตโนมัติ คือความสามารถของเบราว์เซอร์ในการวางรายการภายในกริดโดยอัตโนมัติ เราไม่จำเป็นต้องให้ตำแหน่งของแต่ละรายการเสมอไป
เราจะมาดูกันว่าฟีเจอร์ดังกล่าวสามารถช่วยเราสร้างกริดที่ซับซ้อนและไดนามิกได้อย่างไรโดยใช้โค้ดไม่กี่บรรทัดจากกรณีการใช้งานที่แตกต่างกัน
แถบด้านข้างแบบไดนามิก
ที่นี่ เรามีเลย์เอาต์ที่แตกต่างกันสามแบบ แต่เรามีเพียงการกำหนดค่ากริดเดียวเท่านั้นที่ใช้ได้กับทุกเลย์เอาต์
main {
display: grid;
grid-template-columns: 1fr;
}
มีเพียงคอลัมน์เดียวเท่านั้นที่ใช้พื้นที่ว่างทั้งหมด นี่คือตารางที่ "ชัดเจน" ของเรา ตั้งค่าให้พอดีกับรายการกริดหนึ่งรายการใน main
คอนเทนเนอร์กริด นั่นคือทั้งหมดที่ หนึ่งคอลัมน์และหนึ่งแถว:
แต่ถ้าเราตัดสินใจใส่องค์ประกอบอื่นลงไป ให้พูดว่า an aside
(แถบด้านข้างแบบไดนามิกของเรา) ตามที่กำหนด (และชัดเจน) ในปัจจุบัน ตารางของเราจะต้องปรับโดยอัตโนมัติเพื่อค้นหาสถานที่สำหรับองค์ประกอบนั้น และถ้าเราไม่ดำเนินการใดๆ กับ CSS ของเรา นี่คือสิ่งที่ DevTools บอกเราว่ากำลังเกิดขึ้น
เราสามารถย้าย <aside>
ไปยังคอลัมน์ข้าง <section>
:
aside {
grid-column-start: 2;
}
และนี่คือสิ่งที่ DevTools บอกเราในตอนนี้:
เราวางองค์ประกอบของเราในคอลัมน์ที่สอง แต่... เราไม่มีคอลัมน์ที่สอง แปลกใช่มั้ย? เราไม่เคยประกาศคอลัมน์ที่สองใน <main>
คอนเทนเนอร์กริด แต่เบราว์เซอร์สร้างมาให้เรา! นี่คือส่วนสำคัญจากข้อกำหนดที่เราดู:
เมื่อรายการกริดอยู่ในตำแหน่งนอกขอบเขตเหล่านี้ คอนเทนเนอร์กริดจะสร้างแทร็กกริดโดยนัยโดยการเพิ่มเส้นกริดโดยปริยายลงในกริด
คุณลักษณะอันทรงพลังนี้ช่วยให้เรามีเลย์เอาต์แบบไดนามิก ถ้าเรามีเพียง <section>
องค์ประกอบ ทั้งหมดที่เราได้รับคือหนึ่งคอลัมน์ แต่ถ้าเราเติม an <aside>
องค์ประกอบในการผสม คอลัมน์พิเศษจะถูกสร้างขึ้นเพื่อให้มี
เราสามารถวาง <aside>
ก่อนที่จะ <section>
แทนเช่นนี้:
aside {
grid-column-end: -2;
}
สิ่งนี้จะสร้างคอลัมน์โดยนัยที่จุดเริ่มต้นของกริด ซึ่งแตกต่างจากโค้ดก่อนหน้าที่วางคอลัมน์โดยนัยที่ส่วนท้าย
เราสามารถทำสิ่งเดียวกันได้ง่ายขึ้นโดยใช้ grid-auto-flow
คุณสมบัติเพื่อตั้งค่าแทร็กโดยนัยใด ๆ และทั้งหมดให้ไหลใน column
ทิศทาง:
ตอนนี้ไม่จำเป็นต้องระบุ grid-column-start
ที่จะวาง <aside>
องค์ประกอบทางด้านขวาของ <section>
! อันที่จริง รายการกริดอื่น ๆ ที่เราตัดสินใจที่จะใส่ในเวลาใด ๆ จะไหลไปในทิศทางของคอลัมน์ โดยแต่ละรายการจะวางในแทร็กกริดโดยนัยของมันเอง เหมาะสำหรับสถานการณ์ที่ไม่ทราบจำนวนรายการในตารางล่วงหน้า!
ที่กล่าวว่าเรายังต้องการ grid-column-end
ถ้าเราต้องการวางในคอลัมน์ทางซ้ายของมัน เพราะไม่เช่นนั้น <aside>
จะครอบครองคอลัมน์ที่ชัดเจนซึ่งจะผลักดัน <section>
นอกกริดที่ชัดเจนและบังคับให้ใช้คอลัมน์โดยปริยาย
ฉันรู้ว่าฉันรู้ว่า. มันซับซ้อนเล็กน้อย นี่เป็นอีกตัวอย่างหนึ่งที่เราสามารถใช้เพื่อทำความเข้าใจความแปลกเล็กน้อยนี้ได้ดีขึ้น:
ในตัวอย่างแรก เราไม่ได้ระบุตำแหน่งใดๆ ในกรณีนี้ เบราว์เซอร์จะวาง .ก่อน <aside>
องค์ประกอบในคอลัมน์ที่ชัดเจนเนื่องจากมาก่อนใน DOM ดิ <section>
ในขณะเดียวกัน จะถูกวางไว้โดยอัตโนมัติในคอลัมน์กริดที่เบราว์เซอร์สร้างขึ้นโดยอัตโนมัติ (หรือโดยปริยาย) สำหรับเรา
ในตัวอย่างที่สอง เราตั้งค่า <aside>
องค์ประกอบนอกกริดที่ชัดเจน:
aside {
grid-column-end: -2;
}
ตอนนี้ก็ไม่เป็นไร <aside>
มาก่อนใน HTML โดยมอบหมายใหม่ <aside>
ที่อื่นเราได้ทำ <section>
องค์ประกอบที่พร้อมใช้งานสำหรับคอลัมน์ที่ชัดเจน
ตารางภาพ
มาลองใช้สิ่งที่แตกต่างออกไปกับตารางรูปภาพที่เรามีรูปภาพขนาดใหญ่และรูปขนาดย่อด้านข้าง (หรือด้านล่าง)
เรามีการกำหนดค่ากริดสองแบบ แต่เดาอะไร? ฉันไม่ได้กำหนดกริดใด ๆ เลย! ทั้งหมดที่ฉันทำคือ:
.grid img:first-child {
grid-area: span 3 / span 3;
}
น่าแปลกใจที่เราต้องการโค้ดเพียงบรรทัดเดียวในการดึงข้อมูลแบบนี้ออกมา ดังนั้น มาวิเคราะห์กันว่าเกิดอะไรขึ้น แล้วคุณจะพบว่ามันง่ายกว่าที่คุณคิด ก่อนอื่นเลย, grid-area
เป็นคุณสมบัติชวเลขที่รวมคุณสมบัติต่อไปนี้เป็นการประกาศเดียว:
grid-row-start
grid-row-end
grid-column-start
grid-column-end
รอ! ไม่ใช่
grid-area
คุณสมบัติที่เราใช้ในการกำหนด พื้นที่ที่มีชื่อ แทนที่จะเป็นที่องค์ประกอบเริ่มต้นและสิ้นสุดในตาราง?
ใช่ แต่ก็ยังทำมากกว่า เราสามารถเขียนเพิ่มเติมเกี่ยวกับ grid-area
แต่ในกรณีนี้:
.grid img:first-child {
grid-area: span 3 / span 3;
}
/* ...is equivalent to: */
.grid img:first-child {
grid-row-start: span 3;
grid-column-start: span 3;
grid-row-end: auto;
grid-column-end: auto;
}
เราสามารถเห็นสิ่งเดียวกันเมื่อทำการแคร็กเปิด DevTools เพื่อขยายเวอร์ชันชวเลข:
ซึ่งหมายความว่าองค์ประกอบภาพแรกในตารางต้องขยาย สามคอลัมน์ และ สามแถว. แต่เนื่องจากเราไม่ได้กำหนดคอลัมน์หรือแถวใดๆ เบราว์เซอร์จึงกำหนดให้กับเรา
โดยพื้นฐานแล้วเราได้วางรูปภาพแรกใน HTML เพื่อใช้ตาราง 3⨉3 นั่นหมายความว่ารูปภาพอื่น ๆ จะถูกวางโดยอัตโนมัติในสามคอลัมน์เดียวกันโดยไม่ต้องระบุอะไรใหม่
โดยสรุป เราบอกเบราว์เซอร์ว่ารูปภาพแรกต้องใช้พื้นที่สามคอลัมน์และสามแถวที่เราไม่เคยกำหนดไว้อย่างชัดเจนเมื่อตั้งค่าคอนเทนเนอร์กริด เบราว์เซอร์ตั้งค่าคอลัมน์และแถวเหล่านั้นให้เรา ผลที่ตามมา, รูปภาพที่เหลือในโฟลว์ HTML เข้าที่โดยใช้สามคอลัมน์และแถวเดียวกัน. และเนื่องจากรูปภาพแรกใช้ทั้งสามคอลัมน์ในแถวแรก รูปภาพที่เหลือจะไหลเข้าสู่แถวเพิ่มเติมซึ่งแต่ละรูปประกอบด้วยสามคอลัมน์ โดยที่แต่ละรูปภาพใช้คอลัมน์เดียว
ทั้งหมดนี้จาก CSS บรรทัดเดียว! นั่นคือพลังของกริด "โดยนัย" และการจัดตำแหน่งอัตโนมัติ
สำหรับการกำหนดค่ากริดที่สองในการสาธิตนั้น ทั้งหมดที่ฉันทำคือเปลี่ยนทิศทางการไหลอัตโนมัติโดยใช้ grid-auto-flow: column
แบบเดียวกับที่เราทำก่อนหน้านี้เมื่อวาง an <aside>
องค์ประกอบถัดจาก a <section>
. สิ่งนี้บังคับให้เบราว์เซอร์สร้าง a ที่สี่ คอลัมน์ที่ใช้วางภาพที่เหลือได้ และเนื่องจากเรามีสามแถว รูปภาพที่เหลือจึงอยู่ในคอลัมน์แนวตั้งเดียวกัน
เราจำเป็นต้องเพิ่มคุณสมบัติบางอย่างให้กับรูปภาพเพื่อให้แน่ใจว่าพอดีภายในกริดโดยไม่มีรายการมากเกินไป:
.grid {
display: grid;
grid-gap: 10px;
}
/* for the second grid configuration */
.horizontal {
grid-auto-flow: column;
}
/* The large 3⨉3 image */
.grid img:first-child {
grid-area: span 3 / span 3;
}
/* Help prevent stretched or distorted images */
img {
width: 100%;
height: 100%;
object-fit: cover;
}
และแน่นอน เราสามารถอัปเดตตารางเพื่อพิจารณารูปภาพเพิ่มเติมได้ง่ายๆ ด้วยการปรับค่าเดียว นั่นจะเป็น 3
ในรูปแบบภาพขนาดใหญ่ เรามีสิ่งนี้:
.grid img:first-child {
grid-area: span 3 / span 3;
}
แต่เราสามารถเพิ่มคอลัมน์ที่สี่ได้ง่ายๆ โดยเปลี่ยนเป็น 4
แทน:
.grid img:first-child {
grid-area: span 4 / span 4;
}
ดียิ่งขึ้นไปอีก: มาตั้งค่าให้เป็นคุณสมบัติที่กำหนดเองเพื่อให้การอัปเดตต่างๆ ง่ายยิ่งขึ้น
เค้าโครงแบบไดนามิก
กรณีการใช้งานครั้งแรกที่มีแถบด้านข้างคือรูปแบบไดนามิกแรกของเรา ตอนนี้ เราจะจัดการกับเลย์เอาต์ที่ซับซ้อนมากขึ้น โดยที่จำนวนองค์ประกอบจะกำหนดการกำหนดค่ากริด
ในตัวอย่างนี้ เราสามารถมีองค์ประกอบตั้งแต่หนึ่งถึงสี่องค์ประกอบ โดยที่กริดจะปรับให้พอดีกับจำนวนองค์ประกอบโดยไม่ทิ้งช่องว่างที่น่าอึดอัดใจหรือช่องว่างที่ขาดหายไป
เมื่อเรามีองค์ประกอบเดียว เราจะไม่ทำอะไรเลย องค์ประกอบจะขยายเพื่อเติมแถวและคอลัมน์เดียวที่สร้างโดยอัตโนมัติโดยกริด
บิตเมื่อเราเพิ่มองค์ประกอบที่สอง เราจะสร้างคอลัมน์อื่น (โดยนัย) โดยใช้ grid-column-start: 2
.
เมื่อเราเพิ่มองค์ประกอบที่สาม ควรใช้ความกว้างของสองคอลัมน์ นั่นคือเหตุผลที่เราใช้ grid-column-start: span 2
แต่ถ้าเป็น :last-child
เพราะถ้า (และเมื่อไหร่) เราเพิ่มองค์ประกอบที่สี่เข้าไป สิ่งนั้นควรใช้คอลัมน์เดียว
บวกกับที่เรามี การกำหนดค่าสี่กริด ด้วยเท่านั้น สองประกาศ และความมหัศจรรย์ของกริดโดยปริยาย:
.grid {
display: grid;
}
.grid :nth-child(2) {
grid-column-start: 2;
}
.grid :nth-child(3):last-child {
grid-column-start: span 2;
}
มาลองกันอีกแบบหนึ่ง:
เราไม่ได้ทำอะไรสำหรับกรณีแรกและกรณีที่สองที่เรามีเพียงหนึ่งหรือสององค์ประกอบ เมื่อเราเพิ่มองค์ประกอบที่สาม เราจะบอกเบราว์เซอร์ว่า ตราบใดที่เป็น :last-child
— ควรขยายสองคอลัมน์ เมื่อเราเพิ่มองค์ประกอบที่สี่ เราบอกเบราว์เซอร์ว่าจำเป็นต้องวางองค์ประกอบในคอลัมน์ที่สอง
.grid {
display: grid;
}
.grid :nth-child(3):last-child {
grid-column-start: span 2;
}
.grid :nth-child(4) {
grid-column-start: 2;
}
คุณเริ่มที่จะได้รับเคล็ดลับหรือไม่? เราให้คำแนะนำเฉพาะเบราว์เซอร์ตามจำนวนองค์ประกอบ (โดยใช้ :nth-child
) และบางครั้ง คำสั่งเดียวสามารถเปลี่ยนเค้าโครงได้อย่างสมบูรณ์
ควรสังเกตว่าขนาดจะไม่เท่ากันเมื่อเราทำงานกับเนื้อหาที่แตกต่างกัน:
เนื่องจากเราไม่ได้กำหนดขนาดใดๆ สำหรับรายการของเรา เบราว์เซอร์จะปรับขนาดให้เราโดยอัตโนมัติตามเนื้อหา และเราอาจได้ขนาดที่แตกต่างจากที่เราเพิ่งเห็น เพื่อเอาชนะสิ่งนี้ เราต้อง อย่างชัดเจน ระบุว่าคอลัมน์และแถวทั้งหมดมีขนาดเท่ากัน:
grid-auto-rows: 1fr;
grid-auto-columns: 1fr;
นี่เรายังไม่ได้เล่นกับคุณสมบัติเหล่านั้นเลย! grid-auto-rows
และ grid-auto-columns
กำหนดขนาดของแถวและคอลัมน์โดยนัยตามลำดับในคอนเทนเนอร์กริด หรือเช่น ข้อมูลจำเพาะ อธิบายว่า:
พื้นที่
grid-auto-columns
และgrid-auto-rows
คุณสมบัติระบุขนาดของแทร็กที่ไม่ได้กำหนดขนาดโดยgrid-template-rows
orgrid-template-columns
.
นี่เป็นอีกตัวอย่างหนึ่งที่เราสามารถเพิ่มได้ถึงหกองค์ประกอบ คราวนี้ฉันจะให้คุณผ่ารหัส ไม่ต้องกังวล ตัวเลือกอาจดูซับซ้อน แต่ตรรกะค่อนข้างตรงไปตรงมา
แม้จะมีองค์ประกอบหกประการ แต่เราต้องการการประกาศเพียงสองครั้งเท่านั้น ลองนึกภาพเค้าโครงที่ซับซ้อนและไดนามิกที่เราสามารถทำได้ด้วยโค้ดเพียงไม่กี่บรรทัด!
เป็นอะไรไปเนี่ย
grid-auto-rows
และทำไมต้องใช้สามค่า? เรากำลังกำหนดสามแถวหรือไม่?
ไม่ เราไม่ได้กำหนดสามแถว แต่เรา เป็น กำหนดค่าสามค่าเป็นรูปแบบสำหรับแถวโดยนัยของเรา ตรรกะมีดังนี้:
- ถ้าเรามีแถวเดียว มันจะได้ขนาดด้วยค่าแรก
- ถ้าเรามีสองแถว แถวแรกจะได้ค่าแรก และแถวที่สองจะได้ค่าที่สอง
- ถ้าเรามีสามแถว ค่าทั้งสามจะถูกใช้
- ถ้าเรามีสี่แถว (และส่วนที่น่าสนใจก็มาถึง) เราจะใช้ค่าสามค่าสำหรับสามแถวแรก และเราใช้ค่าแรกซ้ำอีกครั้งสำหรับแถวที่สี่ นั่นเป็นสาเหตุที่เป็นรูปแบบที่เราทำซ้ำเพื่อกำหนดขนาดแถวโดยนัยทั้งหมด
- ถ้าเรามี 100 แถว ก็จะได้ขนาดสามคูณสาม
2fr 2fr 1fr 2fr 2fr 1fr 2fr 2fr 1fr
ฯลฯ
แตกต่าง grid-template-rows
ซึ่งกำหนดจำนวนแถวและขนาด grid-auto-rows
เฉพาะขนาดแถวที่อาจสร้างขึ้นระหว่างทาง
หากเรากลับไปที่ตัวอย่างของเรา ตรรกะคือต้องมีขนาดเท่ากันเมื่อสร้างสองแถว (เราจะใช้ 2fr 2fr
) แต่ถ้าสร้างแถวที่สามขึ้นมา เราจะทำให้มันเล็กลงเล็กน้อย
รูปแบบกริด
สำหรับอันสุดท้ายนี้ เราจะพูดถึงรูปแบบ คุณอาจเคยเห็นรูปแบบคอลัมน์สองคอลัมน์ที่คอลัมน์หนึ่งกว้างกว่าอีกคอลัมน์หนึ่ง และแต่ละแถวจะสลับตำแหน่งของคอลัมน์เหล่านั้น
เลย์เอาต์การจัดเรียงนี้อาจทำได้ยากเช่นกันโดยไม่รู้ว่าเรากำลังจัดการกับเนื้อหามากน้อยเพียงใด แต่พลังการจัดตำแหน่งอัตโนมัติโดยนัยของ CSS Grid ทำให้เป็นเรื่องง่าย
แกะโค้ดดูเลยครับ มันอาจจะดูซับซ้อน แต่ขอแบ่งมันออกเพราะมันค่อนข้างตรงไปตรงมา
สิ่งแรกที่ต้องทำคือการระบุรูปแบบ ถามตัวเองว่า: “รูปแบบควรทำซ้ำหลังจากกี่องค์ประกอบ” ในกรณีนี้คือหลังจากทุกๆ XNUMX องค์ประกอบ ทีนี้มาดูการใช้เพียงสี่องค์ประกอบในตอนนี้:
ตอนนี้ มากำหนดกริดและตั้งค่ารูปแบบทั่วไปโดยใช้ :nth-child
ตัวเลือกสำหรับการสลับระหว่างองค์ประกอบ:
.grid {
display: grid;
grid-auto-columns: 1fr; /* all the columns are equal */
grid-auto-rows: 100px; /* all the rows equal to 100px */
}
.grid :nth-child(4n + 1) { /* ?? */ }
.grid :nth-child(4n + 2) { /* ?? */ }
.grid :nth-child(4n + 3) { /* ?? */ }
.grid :nth-child(4n + 4) { /* ?? */ }
เราบอกว่ารูปแบบของเราซ้ำทุก ๆ สี่องค์ประกอบ ดังนั้นเราจะใช้อย่างมีเหตุผล 4n + x
ที่ไหน x
มีตั้งแต่ 1 ถึง 4 การอธิบายรูปแบบด้วยวิธีนี้จะง่ายกว่าเล็กน้อย:
4(0) + 1 = 1 = 1st element /* we start with n = 0 */
4(0) + 2 = 2 = 2nd element
4(0) + 3 = 3 = 3rd element
4(0) + 4 = 4 = 4th element
4(1) + 1 = 5 = 5th element /* our pattern repeat here at n = 1 */
4(1) + 2 = 6 = 6th element
4(1) + 3 = 7 = 7th element
4(1) + 4 = 8 = 8th element
4(2) + 1 = 9 = 9th element /* our pattern repeat again here at n = 2 */
etc.
สมบูรณ์แบบใช่มั้ย? เรามีสี่องค์ประกอบ และทำซ้ำรูปแบบในองค์ประกอบที่ห้า องค์ประกอบที่เก้า และอื่นๆ
เหล่านั้น :nth-child
ตัวเลือกอาจเป็นเรื่องยุ่งยาก! คริสมีประโยชน์สุดๆ คำอธิบายวิธีการทำงานทั้งหมดรวมทั้ง สูตรสร้างลวดลายต่างๆ.
ตอนนี้เรากำหนดค่าแต่ละองค์ประกอบเพื่อให้:
- องค์ประกอบแรกต้องใช้สองคอลัมน์และเริ่มต้นที่คอลัมน์หนึ่ง (
grid-column: 1/span 2
). - องค์ประกอบที่สองอยู่ในคอลัมน์ที่สาม (
grid-column-start: 3
). - องค์ประกอบที่สามถูกวางไว้ที่คอลัมน์แรก: (
grid-column-start: 1
). - องค์ประกอบที่สี่ใช้เวลาสองคอลัมน์และเริ่มต้นที่คอลัมน์ที่สอง: (
grid-column: 2/span 2
).
นี่คือใน CSS:
.grid {
display: grid;
grid-auto-columns: 1fr; /* all the columns are equal */
grid-auto-rows: 100px; /* all the rows are equal to 100px */
}
.grid :nth-child(4n + 1) { grid-column: 1/span 2; }
.grid :nth-child(4n + 2) { grid-column-start: 3; }
.grid :nth-child(4n + 3) { grid-column-start: 1; }
.grid :nth-child(4n + 4) { grid-column: 2/span 2; }
เราสามารถหยุดที่นี่และทำเสร็จแล้ว… แต่เราทำได้ดีกว่า! โดยเฉพาะอย่างยิ่ง เราสามารถลบการประกาศบางรายการและอาศัยอำนาจการจัดตำแหน่งอัตโนมัติของกริดเพื่อทำหน้าที่แทนเรา นี่เป็นส่วนที่ยากที่สุดในการคร่ำครวญและต้องใช้การฝึกฝนอย่างมากเพื่อให้สามารถระบุสิ่งที่สามารถลบออกได้
สิ่งแรกที่เราทำได้คืออัปเดต grid-column: 1 /span 2
และใช้เท่านั้น grid-column: span 2
เนื่องจากโดยค่าเริ่มต้น เบราว์เซอร์จะวางรายการแรกลงในคอลัมน์แรก นอกจากนี้เรายังสามารถลบสิ่งนี้:
.grid :nth-child(4n + 3) { grid-column-start: 1; }
โดยการวางรายการแรก รายการที่สอง และสี่ ตารางจะวางรายการที่สามในตำแหน่งที่ถูกต้องโดยอัตโนมัติ นั่นหมายความว่าเราเหลือสิ่งนี้:
.grid {
display: grid;
grid-auto-rows: 100px; /* all the rows are equal to 100px */
grid-auto-columns: 1fr; /* all the columns are equal */
}
.grid :nth-child(4n + 1) { grid-column: span 2; }
.grid :nth-child(4n + 2) { grid-column-start: 2; }
.grid :nth-child(4n + 4) { grid-column: 2/span 2; }
แต่เดี๋ยวเราไปเดินเล่นกันดีกว่า! นอกจากนี้เรายังสามารถลบสิ่งนี้:
.grid :nth-child(4n + 2) { grid-column-start: 2; }
ทำไม หากเราวางองค์ประกอบที่สี่ในคอลัมน์ที่สองโดยปล่อยให้คอลัมน์เต็มสองคอลัมน์ เรากำลังบังคับให้กริดสร้างคอลัมน์โดยปริยายที่สาม ทำให้เรามีคอลัมน์ทั้งหมดสามคอลัมน์โดยไม่บอกอย่างชัดเจน องค์ประกอบที่สี่ไม่สามารถเข้าไปในแถวแรกได้เนื่องจากรายการแรกนั้นใช้สองคอลัมน์ด้วย ดังนั้นองค์ประกอบนั้นจึงไหลไปยังแถวถัดไป การกำหนดค่านี้ทำให้เรามีคอลัมน์ว่างในแถวแรกและคอลัมน์ว่างในแถวที่สอง
ฉันคิดว่าคุณรู้ตอนจบของเรื่องแล้ว เบราว์เซอร์จะวางรายการที่สองและสามในตำแหน่งว่างเหล่านั้นโดยอัตโนมัติ ดังนั้นรหัสของเราจึงง่ายยิ่งขึ้น:
.grid {
display: grid;
grid-auto-columns: 1fr; /* all the columns are equal */
grid-auto-rows: 100px; /* all the rows are equal to 100px */
}
.grid :nth-child(4n + 1) { grid-column: span 2; }
.grid :nth-child(4n + 4) { grid-column: 2/span 2; }
ใช้เพียงการประกาศห้าครั้งเพื่อสร้างรูปแบบที่เท่และยืดหยุ่นมาก ส่วนการเพิ่มประสิทธิภาพอาจเป็นเรื่องยาก แต่คุณชินกับมันและได้รับลูกเล่นจากการฝึกฝน
ทำไมไม่ใช้
grid-template-columns
เพื่อกำหนดคอลัมน์ที่ชัดเจนเนื่องจากเราทราบจำนวนคอลัมน์?
เราสามารถทำเช่นนั้นได้! นี่คือรหัสสำหรับมัน:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr); /* all the columns are equal */
grid-auto-rows: 100px; /* all the rows are equal to 100px */
}
.grid :nth-child(4n + 1),
.grid :nth-child(4n + 4) {
grid-column: span 2;
}
อย่างที่คุณเห็น โค้ดนั้นเข้าใจง่ายกว่าแน่นอน เรากำหนดคอลัมน์กริดที่ชัดเจนสามคอลัมน์และเราบอกเบราว์เซอร์ว่าองค์ประกอบที่หนึ่งและสี่จำเป็นต้องใช้สองคอลัมน์ ฉันขอแนะนำวิธีนี้! แต่เป้าหมายของบทความนี้คือการสำรวจแนวคิดและกลเม็ดใหม่ๆ ที่เราได้รับจากอำนาจการจัดตำแหน่งโดยปริยายและอัตโนมัติของ CSS Grid
วิธีการที่ชัดเจนนั้นตรงไปตรงมามากกว่า ในขณะที่กริดโดยปริยายต้องการให้คุณ — ขอโทษที่เล่นสำนวน — เติมช่องว่างที่ CSS ทำงานเพิ่มเติมเบื้องหลัง ในท้ายที่สุด ฉันเชื่อว่าการมีความเข้าใจอย่างถ่องแท้เกี่ยวกับกริดโดยนัยจะช่วยให้คุณเข้าใจอัลกอริทึม CSS Grid ได้ดีขึ้น ท้ายที่สุด เราไม่ได้อยู่ที่นี่เพื่อศึกษาสิ่งที่ชัดเจน เรามาที่นี่เพื่อสำรวจพื้นที่ป่าเถื่อน!
ลองใช้รูปแบบอื่น คราวนี้เร็วขึ้นเล็กน้อย:
รูปแบบของเราจะทำซ้ำทุกๆ XNUMX องค์ประกอบ องค์ประกอบที่สามและสี่แต่ละองค์ประกอบต้องมีสองแถวเต็ม หากเราวางองค์ประกอบที่สามและองค์ประกอบที่สี่ ดูเหมือนว่าเราไม่จำเป็นต้องแตะองค์ประกอบอื่น ดังนั้น ให้ลองทำดังต่อไปนี้:
.grid {
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 100px;
}
.grid :nth-child(6n + 3) {
grid-area: span 2/2; /* grid-row-start: span 2 && grid-column-start: 2 */
}
.grid :nth-child(6n + 4) {
grid-area: span 2/1; /* grid-row-start: span 2 && grid-column-start: 1 */
}
อืม ไม่ดี เราจำเป็นต้องวางองค์ประกอบที่สองในคอลัมน์แรก มิฉะนั้น ตารางจะวางไว้ในคอลัมน์ที่สองโดยอัตโนมัติ
.grid :nth-child(6n + 2) {
grid-column: 1; /* grid-column-start: 1 */
}
ดีกว่าแต่ยังมีงานอีกมาก เราต้องเลื่อนองค์ประกอบที่สามไปที่ด้านบนสุด เป็นการดึงดูดที่จะลองวางไว้ในแถวแรกด้วยวิธีนี้:
.grid :nth-child(6n + 3) {
grid-area: 1/2/span 2;
/* Equivalent to:
grid-row-start: 1;
grid-row-end: span 2;
grid-column-start: 2
*/
}
แต่มันใช้ไม่ได้เพราะมันบังคับ 6n + 3
ให้วางองค์ประกอบไว้ในบริเวณเดียวกันซึ่งทำให้มีการจัดวางที่คลาดเคลื่อน ทางออกที่แท้จริงคือการรักษานิยามเริ่มต้นขององค์ประกอบที่สามและเพิ่ม grid-auto-flow: dense
เพื่อเติมเต็มช่องว่าง จาก MDN:
[] อัลกอริธึมการบรรจุ "หนาแน่น" พยายามเติม ในหลุมก่อนหน้าในตาราง, ถ้าของชิ้นเล็กๆ มาทีหลัง. ซึ่งอาจทำให้รายการดูไม่เป็นระเบียบ เมื่อทำเช่นนั้นจะเป็นการอุดรูที่เหลือโดยรายการที่มีขนาดใหญ่กว่า หากละเว้น จะใช้อัลกอริธึม "กระจัดกระจาย" โดยที่อัลกอริธึมการจัดวางจะเคลื่อนที่ "ไปข้างหน้า" ในตารางเมื่อวางรายการเท่านั้น ห้ามถอยหลังเพื่อเติมหลุม เพื่อให้แน่ใจว่ารายการที่วางอัตโนมัติทั้งหมดจะปรากฏ "ตามลำดับ" แม้ว่าจะปล่อยให้เป็นรูที่อาจถูกเติมด้วยรายการในภายหลัง
ฉันรู้ว่าคุณสมบัตินี้ไม่ง่ายนัก แต่อย่าลืมเมื่อคุณประสบปัญหาเกี่ยวกับตำแหน่ง ก่อนลองกำหนดค่าต่างๆ อย่างเปล่าประโยชน์ ให้เพิ่มเข้าไปเพราะอาจแก้ไขเลย์เอาต์ของคุณได้โดยไม่ต้องใช้ความพยายามเพิ่มเติม
ทำไมไม่เพิ่มคุณสมบัตินี้เป็นค่าเริ่มต้นเสมอ?
ฉันไม่แนะนำเพราะในบางกรณี เราไม่ต้องการพฤติกรรมนั้น สังเกตว่าคำอธิบายของ MDN ที่กล่าวถึงนั้นทำให้รายการไหล “ไม่อยู่ในลำดับ” เพื่ออุดรูที่เหลือโดยรายการที่มีขนาดใหญ่กว่าอย่างไร ลำดับภาพมักจะมีความสำคัญพอๆ กับลำดับต้นทาง โดยเฉพาะอย่างยิ่งเมื่อพูดถึงอินเทอร์เฟซที่เข้าถึงได้ และ grid-auto-flow: dense
บางครั้งอาจทำให้เกิดความไม่ตรงกันระหว่างลำดับภาพและแหล่งที่มา
รหัสสุดท้ายของเราคือ:
.grid {
display: grid;
grid-auto-columns: 1fr;
grid-auto-flow: dense;
grid-auto-rows: 100px;
}
.grid :nth-child(6n + 2) { grid-column: 1; }
.grid :nth-child(6n + 3) { grid-area: span 2/2; }
.grid :nth-child(6n + 4) { grid-row: span 2; }
อีกอัน? ไปกันเถอะ!
สำหรับอันนี้ ฉันจะไม่พูดมาก และจะแสดงภาพประกอบของรหัสที่ฉันใช้ให้คุณดูแทน ลองดูว่าคุณเข้าใจวิธีที่ฉันเข้าถึงรหัสนั้นหรือไม่:
รายการที่เป็นสีดำจะถูกวางไว้ในตารางโดยปริยาย ควรสังเกตว่าเราสามารถจัดวางเลย์เอาต์เดียวกันได้หลายวิธีมากกว่าที่ฉันไปถึงที่นั่น คุณช่วยคิดออกด้วยได้ไหม ใช้แล้วได้อะไร grid-template-columns
? แบ่งปันผลงานของคุณในส่วนความคิดเห็น
ฉันจะปล่อยให้คุณมีรูปแบบสุดท้าย:
ที่ฉันทำ มีทางแก้ สำหรับอันนี้ แต่ถึงคราวที่คุณต้องฝึกฝน นำสิ่งที่เราได้เรียนรู้มาทั้งหมดและลองเขียนโค้ดด้วยตัวเองแล้วเปรียบเทียบกับโซลูชันของฉัน อย่ากังวลหากคุณลงท้ายด้วยบางสิ่งที่ละเอียด สิ่งที่สำคัญที่สุดคือการหาวิธีแก้ปัญหาที่ได้ผล
ต้องการมากขึ้น?
ก่อนจบ ฉันต้องการแบ่งปันคำถามสองสามข้อเกี่ยวกับ CSS Grid เกี่ยวกับ Stack Overflow ซึ่งฉันได้เพิ่มคำตอบที่ใช้เทคนิคมากมายที่เรากล่าวถึงที่นี่ เป็นรายการที่ดีที่แสดงให้เห็นจำนวนกรณีการใช้งานจริงและสถานการณ์จริงที่เกิดขึ้นซึ่งสิ่งเหล่านี้มีประโยชน์:
ตัดขึ้น
CSS Grid มีมาหลายปีแล้ว แต่ก็ยังมีเทคนิคที่ไม่ค่อยมีใครรู้จักและใช้กันมากนักซึ่งไม่ได้กล่าวถึงกันอย่างแพร่หลาย คุณสมบัติกริดโดยปริยายและการจัดตำแหน่งอัตโนมัติเป็นคุณสมบัติสองอย่าง!
และใช่ มันอาจจะท้าทาย! ฉันต้องใช้เวลานานมากในการทำความเข้าใจตรรกะที่อยู่เบื้องหลังกริดโดยปริยาย และฉันยังคงต่อสู้กับการจัดตำแหน่งอัตโนมัติ หากคุณต้องการใช้เวลามากขึ้นในการพิจารณาตารางที่ชัดเจนและโดยปริยาย ต่อไปนี้เป็นคำอธิบายและตัวอย่างเพิ่มเติมสองสามข้อที่ควรค่าแก่การตรวจสอบ:
ในทำนองเดียวกันคุณอาจต้องการอ่านเกี่ยวกับ grid-auto-columns
ใน CSS-Tricks Almanac เนื่องจาก Mojtaba Seyadi มีรายละเอียดที่ยอดเยี่ยมและมีภาพที่เป็นประโยชน์อย่างเหลือเชื่อเพื่อช่วยอธิบายพฤติกรรม
อย่างที่ฉันพูดเมื่อเราเริ่มต้น วิธีการที่เรากล่าวถึงในที่นี้ไม่ได้หมายถึงการแทนที่วิธีทั่วไปที่คุณทราบอยู่แล้วสำหรับการสร้างกริด ฉันแค่สำรวจวิธีการต่างๆ ที่อาจเป็นประโยชน์ในบางกรณี