เผยแพร่: 30 เมษายน 2024, อัปเดตล่าสุด: 13 กุมภาพันธ์ 2026
ทีม Chrome ต้องการเห็นการติดตั้งใช้งานเลย์เอาต์ประเภทเมสันรีบน เว็บ อย่างไรก็ตาม เราคิดว่าการนำไปใช้เป็นส่วนหนึ่งของข้อกำหนด CSS Grid ตามที่เสนอในโพสต์ล่าสุดของ WebKit จะเป็นการตัดสินใจที่ผิดพลาด นอกจากนี้ เรายังรู้สึกว่าโพสต์ของ WebKit โต้แย้งกับเวอร์ชัน ของเลย์เอาต์แบบก้อนอิฐที่ไม่มีใครเสนอ
ดังนั้น โพสต์นี้จึงมีจุดมุ่งหมายเพื่ออธิบายว่าเหตุใดเราที่ Chrome จึงกังวลเกี่ยวกับการ ใช้เลย์เอาต์แบบเมสันรีเป็นส่วนหนึ่งของข้อกำหนดเลย์เอาต์ตารางกริด CSS และชี้แจง ว่าข้อเสนอทางเลือกนี้ช่วยให้ทำอะไรได้บ้าง โดยสรุป
- ทีม Chrome กระตือรือร้นที่จะปลดบล็อกเลย์เอาต์แบบก้อนอิฐเป็นอย่างมาก เราทราบดีว่านักพัฒนาซอฟต์แวร์ต้องการฟีเจอร์นี้
- การเพิ่มการจัดวางแบบก่ออิฐลงในข้อกำหนดของกริดเป็นปัญหาด้วยเหตุผลอื่นๆ นอกเหนือจากว่าคุณคิดว่าการจัดวางแบบก่ออิฐเป็นกริดหรือไม่
- การกำหนดเมสันนรี นอกข้อกำหนดของกริดไม่ได้ป้องกันขนาดแทร็กหลายขนาดสำหรับ เมสันนรี หรือการใช้พร็อพเพอร์ตี้ เช่น การจัดแนวหรือช่องว่าง หรือฟีเจอร์อื่นๆ ที่ใช้ในเลย์เอาต์กริด
ควรใช้การจัดวางแบบก้อนอิฐเป็นส่วนหนึ่งของตารางกริดไหม
ทีม Chrome เชื่อว่าเลย์เอาต์แบบเมสันควรเป็นวิธีการ
เลย์เอาต์แยกกัน
ซึ่งกำหนดโดยใช้ display: masonry (หรือคีย์เวิร์ดอื่นหากมีการตัดสินใจใช้ชื่อที่ดีกว่า) ในส่วนท้ายของโพสต์นี้ คุณจะเห็นตัวอย่างลักษณะของโค้ด
เราคิดว่าการกำหนดเลย์เอาต์แบบเมสันนารีภายนอกเลย์เอาต์กริดจะดีกว่าด้วยเหตุผล 2 ประการที่เกี่ยวข้อง ได้แก่ ปัญหาด้านประสิทธิภาพของเลย์เอาต์ที่อาจเกิดขึ้น และข้อเท็จจริงที่ว่าทั้งเลย์เอาต์แบบเมสันนารีและกริดมีฟีเจอร์ที่เหมาะกับเลย์เอาต์วิธีหนึ่ง แต่ไม่เหมาะกับอีกวิธีหนึ่ง
ประสิทธิภาพ
กริดและเมสันรีจะตรงกันข้ามในแง่ของวิธีที่เบราว์เซอร์จัดการกับการปรับขนาดและ การจัดวาง เมื่อวางเลย์เอาต์กริด ระบบจะวางรายการทั้งหมดก่อนเลย์เอาต์ และ เบราว์เซอร์จะทราบอย่างแน่นอนว่ามีอะไรอยู่ในแต่ละแทร็ก ซึ่งช่วยให้การกำหนดขนาดโดยเนื้อแท้ที่ซับซ้อน ซึ่งมีประโยชน์อย่างยิ่งในตารางกริด เมื่อใช้เลย์เอาต์แบบเมสันรี ระบบจะวางรายการตามที่จัดวางไว้ และเบราว์เซอร์จะไม่ทราบว่ามีรายการกี่รายการในแต่ละแทร็ก ปัญหานี้ไม่ได้เกิดกับแทร็กที่มีขนาดโดยเนื้อแท้ทั้งหมดหรือแทร็กที่มีขนาดคงที่ทั้งหมด แต่จะเกิดขึ้นหากคุณ ใช้แทร็กที่มีขนาดคงที่และแทร็กที่มีขนาดโดยเนื้อแท้ร่วมกัน เบราว์เซอร์ต้อง ทำขั้นตอนก่อนการจัดวางโดยการจัดวางทุกรายการในทุกวิถีทางที่เป็นไปได้เพื่อรับ การวัดผล ซึ่งในกริดขนาดใหญ่จะทำให้เกิดปัญหาด้านประสิทธิภาพการจัดวาง
ดังนั้น หากคุณมีเลย์เอาต์แบบก้อนอิฐที่มีคำจำกัดความของแทร็กเป็น
grid-template-columns: 200px auto 200px ซึ่งเป็นสิ่งที่พบบ่อยมากในตาราง คุณจะ
เริ่มพบปัญหา ปัญหาเหล่านี้จะเพิ่มขึ้นแบบทวีคูณเมื่อคุณเพิ่ม
ตารางย่อย
แม้ว่าจะมีข้อโต้แย้งว่าคนส่วนใหญ่จะไม่เจอปัญหานี้ แต่เราทราบอยู่แล้วว่าผู้ใช้มีตารางขนาดใหญ่มาก เราไม่ต้องการเปิดตัวฟีเจอร์ที่มีข้อจำกัดในการใช้งานเมื่อมีแนวทางอื่น
เราจะจัดการกับสิ่งที่ไม่สมเหตุสมผลในแต่ละวิธีการจัดเลย์เอาต์อย่างไร
เมื่อ Flexbox และ Grid กลายเป็นส่วนหนึ่งของ CSS นักพัฒนาซอฟต์แวร์มักรู้สึกว่าองค์ประกอบเหล่านี้ทำงานในลักษณะที่ไม่สอดคล้องกัน ความไม่สอดคล้องที่ผู้ใช้พบเกิดจากสมมติฐานที่ยึดถือมานานเกี่ยวกับวิธีการทำงานของเลย์เอาต์โดยอิงตามเลย์เอาต์ของบล็อก เมื่อเวลาผ่านไป นักพัฒนาแอปเริ่มเข้าใจบริบทการจัดรูปแบบ เมื่อเราเปลี่ยนไปใช้บริบทการจัดรูปแบบกริดหรือ Flex บางสิ่งจะทำงานแตกต่างออกไป เช่น คุณทราบว่าเมื่ออยู่ใน Flexbox จะมีวิธีการจัดแนวบางอย่างที่ไม่พร้อมใช้งาน เนื่องจาก Flexbox เป็นแบบ 1 มิติ
การรวมเลย์เอาต์แบบก้อนอิฐเข้ากับกริดจะทําให้ลิงก์ที่ชัดเจนระหว่างบริบทการจัดรูปแบบและความพร้อมใช้งานของสิ่งต่างๆ เช่น พร็อพเพอร์ตี้การจัดแนว ซึ่งกําหนดไว้ในข้อกําหนด Box Alignment ต่อบริบทการจัดรูปแบบขาดหายไป
หากเราตัดสินใจที่จะจัดการกับปัญหาด้านประสิทธิภาพที่ระบุไว้ก่อนหน้านี้โดยการทำให้ คำจำกัดความของแทร็กแบบผสมทั้งแบบแท้จริงและแบบคงที่ผิดกฎหมายใน Masonry คุณจะต้อง จำไว้ว่ารูปแบบทั่วไปมากสำหรับการจัดวางแบบกริดใช้ไม่ได้กับ Masonry
นอกจากนี้ยังมีรูปแบบที่สมเหตุสมผลในงานก่อสร้าง เช่น
grid-template-columns: repeat(auto-fill, max-content) เนื่องจากคุณไม่มีข้อจำกัดข้าม แต่ต้องยังคงไม่ถูกต้องในกริด ต่อไปนี้คือ
รายการพร็อพเพอร์ตี้ที่เราคาดว่าจะทํางาน
แตกต่างกัน
หรือมีค่าที่ถูกต้องแตกต่างกัน
grid-template-areas: ในเลย์เอาต์แบบก้อนอิฐ คุณจะระบุได้เฉพาะแถวเริ่มต้นใน ทิศทางที่ไม่ใช่เลย์เอาต์แบบก้อนอิฐgrid-template: ตัวย่อจะต้องครอบคลุมความแตกต่างทั้งหมด- ติดตามค่าการกำหนดขนาดสำหรับ
grid-template-columnsและgrid-template-rowsเนื่องจากค่าทางกฎหมายแตกต่างกัน grid-auto-flowไม่มีผลกับเลย์เอาต์แบบก้อนอิฐ และmasonry-auto-flowไม่มีผลกับเลย์เอาต์แบบตารางกริด การผสานรวมจะทำให้เกิดปัญหาเกี่ยวกับรายการที่ไม่ถูกต้องเนื่องจากวิธีการจัดวางที่คุณใช้- กริดมีพร็อพเพอร์ตี้ตำแหน่ง 4 รายการ (
grid-column-startและอื่นๆ) ส่วนเมสันรีมีเพียง 2 รายการ - Grid ใช้คุณสมบัติทั้ง 6 รายการของ
justify-*และalign-*ได้ แต่ Masonry ใช้เฉพาะชุดย่อย เช่น Flexbox
นอกจากนี้ ยังต้องระบุสิ่งที่เกิดขึ้นในกรณีข้อผิดพลาดใหม่ทั้งหมดที่เกิดจากนักพัฒนาแอปที่ใช้ค่าที่ไม่ถูกต้องใน grid-with-masonry หรือ grid-without-masonry เช่น คุณใช้ grid-template-columns: masonry หรือ grid-template-rows: masonry ได้ แต่จะใช้ทั้ง 2 อย่างพร้อมกันไม่ได้ จะเกิดอะไรขึ้นหากคุณใช้ทั้งสองอย่างพร้อมกัน
คุณต้องระบุรายละเอียดเหล่านี้เพื่อให้เบราว์เซอร์ทั้งหมด
ทํางานเหมือนกัน
ซึ่งทั้งหมดนี้จะมีความซับซ้อนในมุมมองของข้อกำหนด ทั้งในปัจจุบันและ
อนาคต เราจะต้องตรวจสอบว่าทุกอย่างคำนึงถึงเลย์เอาต์แบบก้อนอิฐ และ
เลย์เอาต์แบบก้อนอิฐใช้งานได้หรือไม่ นอกจากนี้ยังสร้างความสับสนในมุมมองของนักพัฒนาแอปด้วย ทำไมคุณจึงควรทราบว่าแม้จะใช้display: grid แต่บางอย่างก็ใช้งานไม่ได้เนื่องจากใช้เลย์เอาต์แบบก้อนอิฐ
ข้อเสนอทางเลือก
ดังที่ได้กล่าวไปแล้ว ทีม Chrome ต้องการกำหนดเลย์เอาต์แบบก้อนอิฐนอกข้อกำหนดของกริด แต่ไม่ได้หมายความว่าคุณจะถูกจำกัดให้ใช้เฉพาะวิธีการจัดเลย์เอาต์ที่เรียบง่ายมาก ซึ่งมีขนาดคอลัมน์เหมือนกัน การสาธิตทั้งหมดในโพสต์ของ WebKit จะยังคงเป็นไปได้
เลย์เอาต์การก่ออิฐแบบคลาสสิก
เมื่อพูดถึงเลย์เอาต์แบบอิฐ คนส่วนใหญ่มักจะนึกถึงเลย์เอาต์ที่มีหลายคอลัมน์ขนาดเท่ากัน ซึ่งจะกำหนดโดยใช้ CSS ต่อไปนี้ ซึ่งต้องใช้โค้ดน้อยกว่าเวอร์ชันที่มาพร้อมกับกริดที่เทียบเท่ากัน 1 บรรทัด
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
gap: 1rem;
}

ใช้การกำหนดขนาดแทร็กประเภทกริดสำหรับความกว้างของคอลัมน์ที่แตกต่างกัน
นอกเหนือจากปัญหาที่กล่าวถึงก่อนหน้านี้เกี่ยวกับการกำหนดขนาดแทร็กแบบผสมทั้งแบบเนื้อหาและแบบคงที่ คุณสามารถใช้การกำหนดขนาดแทร็กทั้งหมดที่คุณชื่นชอบจากกริดได้ เช่น ตัวอย่างจากบล็อกโพสต์ของ WebKit รูปแบบของคอลัมน์แคบและกว้างที่ซ้ำกัน
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
gap: 1rem;
}

การกำหนดขนาดแทร็กเพิ่มเติมสำหรับเลย์เอาต์แบบก้อนอิฐ
นอกจากนี้ยังมีตัวเลือกการกำหนดขนาดแทร็กเพิ่มเติมที่เราไม่อนุญาตในกริดเนื่องจาก ข้อเท็จจริงที่ว่ากริดเป็นวิธีการจัดเลย์เอาต์แบบ 2 มิติ ซึ่งจะมีประโยชน์ในเลย์เอาต์แบบก้อนอิฐ แต่จะสร้างความสับสนหากใช้ไม่ได้ในเลย์เอาต์แบบกริด
การเติมแทร็กขนาด max-content โดยอัตโนมัติ
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, max-content);
gap: 1rem;
}
การเติมแทร็กที่มีขนาด auto โดยอัตโนมัติ ซึ่งจะสร้างแทร็กที่มีขนาดเท่ากัน
ปรับขนาดอัตโนมัติให้รองรับแทร็กที่ใหญ่ที่สุด
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, auto);
gap: 1rem;
}

อนุญาตให้เนื้อหาครอบคลุมคอลัมน์ และวางรายการในเลย์เอาต์แบบเมสันรี
ไม่มีเหตุผลที่จะไม่ให้เนื้อหาครอบคลุมคอลัมน์ในข้อกำหนด Masonry แยกต่างหาก
ซึ่งอาจใช้พร็อพเพอร์ตี้ masonry-track ซึ่งเป็นรูปแบบย่อของ
masonry-track-start และ masonry-track-end เนื่องจากคุณมีมิติข้อมูลเพียงมิติเดียวที่จะ
ครอบคลุมสิ่งต่างๆ เมื่ออยู่ในเลย์เอาต์แบบเมสันรี
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, auto);
}
.span-2 {
masonry-track: span 2; /* spans two columns */
}
.placed {
masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

การใช้แทร็กเมสันรีในเมสันรีหรือกริดย่อย
ซึ่งอาจรองรับได้ด้วยข้อกำหนดแบบเมสันรีแยกต่างหาก โดยมีข้อแม้ว่าไม่อนุญาตให้ใช้แทร็กที่มีขนาดคงที่และขนาดโดยเนื้อแท้ผสมกัน คุณจะต้องกำหนดลักษณะที่แน่นอนของ สิ่งนั้น เราไม่เห็นเหตุผลว่าทำไมจึงจะใช้ไม่ได้
บทสรุป
เราอยากให้มีข้อกำหนดที่สามารถจัดส่งได้ โดยทำงานร่วมกันได้ อย่างไรก็ตาม เราต้องการทำในลักษณะที่ใช้งานได้ดีทั้งในปัจจุบันและอนาคต รวมถึงเป็นสิ่งที่นักพัฒนาแอปสามารถเชื่อถือได้ วิธีเดียวที่จะจัดการกับปัญหาด้านประสิทธิภาพที่ระบุไว้คือการทำให้ปัญหาที่ 2 ซึ่งก็คือการมีส่วนต่างๆ ของกริดที่ผิดกฎหมายในเลย์เอาต์แบบเมสันรีแย่ลง เราไม่คิดว่านั่นเป็นวิธีแก้ปัญหาที่ดี โดยเฉพาะอย่างยิ่งเมื่อคุณสามารถมีฟีเจอร์ตารางทั้งหมดที่ต้องการ ในขณะที่ยังคงแยกสิ่งต่างๆ ที่แตกต่างกันไว้อย่างชัดเจน
หากมีความคิดเห็น โปรดเข้าร่วมการสนทนาในปัญหา 9041
ขอขอบคุณ Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick และ Chris Harrelson ที่ตรวจสอบโพสต์นี้และพูดคุยจนได้ข้อมูลมาเขียนโพสต์