ข้อเสนอทางเลือกสำหรับการก่ออิฐ CSS

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

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

  • ทีม Chrome ต้องการเลิกบล็อกช่างก่อสร้าง เรารู้ดีว่านักพัฒนาซอฟต์แวร์ต้องการ
  • การเพิ่มการก่ออิฐในข้อกำหนดของตารางกริดอาจเป็นปัญหาเนื่องด้วยเหตุผลอื่นที่ทำให้คุณคิดว่าอิฐก่อเป็นตารางกริดหรือไม่
  • การกำหนดการก่ออิฐนอกข้อกำหนดของตารางกริดไม่ได้ป้องกันแทร็กขนาดต่างๆ สำหรับการก่ออิฐ หรือการใช้คุณสมบัติอย่างเช่นการปรับแนวหรือช่องว่าง หรือฟีเจอร์อื่นๆ ที่ใช้ในเลย์เอาต์แบบตารางกริด

การก่อสร้างควรเป็นส่วนหนึ่งของตารางกริดหรือไม่

ทีม Chrome เชื่อว่าการก่ออิฐควรเป็นวิธีการจัดวางที่แยกต่างหาก ซึ่งระบุโดยใช้ display: masonry (หรือคีย์เวิร์ดอื่นควรเลือกใช้ชื่อที่ดีกว่า) จากนั้นในโพสต์นี้ คุณจะเห็นตัวอย่างลักษณะของโค้ด

มีเหตุผลที่เกี่ยวข้อง 2 ประการที่ทำให้เรารู้สึกว่าการก่ออิฐถือเป็นรูปแบบที่ดีกว่าเมื่ออยู่นอกเลย์เอาต์แบบตารางกริด ได้แก่ ความเป็นไปได้ของปัญหาด้านประสิทธิภาพเลย์เอาต์ และข้อเท็จจริงที่ว่าทั้งการก่ออิฐและแนวตารางกริดมีฟีเจอร์ที่เหมาะสมในการจัดวางวิธีเดียว แต่ไม่ใช่อีกวิธี

การแสดง

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

ดังนั้น หากคุณมีเลย์เอาต์แบบก่ออิฐที่มีคำจำกัดความแทร็กเป็น grid-template-columns: 200px auto 200px ซึ่งเป็นสิ่งที่พบได้บ่อยในตารางกริดทำให้คุณเริ่มพบปัญหา โจทย์เหล่านี้จะกลายเป็นเลขชี้กำลังเมื่อคุณเพิ่มตารางกริดย่อย

มีข้อโต้แย้งที่คนส่วนใหญ่มักไม่เจอกับปัญหานี้ อย่างไรก็ตาม เราทราบอยู่แล้วว่าผู้คนมีตารางกริดขนาดใหญ่ เราไม่ต้องการส่งมอบผลิตภัณฑ์ที่จำกัดการใช้งาน เมื่อมีทางเลือกอื่น

เราทำอะไรกับสิ่งที่ไม่สมเหตุสมผลในวิธีการจัดวางแต่ละแบบ

เมื่อ Flexbox และ Grid กลายเป็นส่วนหนึ่งของ CSS นักพัฒนาซอฟต์แวร์มักจะรู้สึกว่าตนมีพฤติกรรมที่ไม่สอดคล้องกัน ความไม่สอดคล้องกันที่พบนั้นเกิดขึ้นจากสมมติฐานที่มีมายาวนานเกี่ยวกับวิธีการทำงานของเลย์เอาต์โดยอิงตามเลย์เอาต์แบบบล็อก เมื่อเวลาผ่านไป นักพัฒนาซอฟต์แวร์จะเริ่มเข้าใจบริบทการจัดรูปแบบ เมื่อเราเปลี่ยนไปใช้บริบทการจัดรูปแบบตารางกริดหรือการจัดรูปแบบแบบยืดหยุ่น บางอย่างจะทำงานต่างออกไป เช่น คุณทราบว่าเมื่ออยู่ใน Flexbox จะใช้วิธีจัดตำแหน่งบางวิธีไม่ได้ เนื่องจาก Flexbox เป็นแบบมิติเดียว

การรวมกลุ่มงานก่ออิฐเป็นตารางกริดจะแบ่งลิงก์ที่ชัดเจนระหว่างบริบทการจัดรูปแบบและความพร้อมใช้งานของสิ่งต่างๆ เช่น คุณสมบัติการจัดตำแหน่ง ซึ่งระบุไว้ในข้อกำหนดการปรับแนว Box ตามบริบทการจัดรูปแบบ

หากเราตัดสินใจที่จะจัดการกับปัญหาด้านประสิทธิภาพที่ได้กล่าวไว้ก่อนหน้านี้ โดยทำให้การกำหนดแทร็กทั้งแทร็กเดิมและแทร็กคงที่เป็นเรื่องผิดกฎหมายในการก่อสร้าง คุณจะต้องจำไว้ว่ารูปแบบทั่วไปสำหรับการออกแบบแบบตารางกริดไม่สามารถใช้กับงานก่ออิฐ

นอกจากนี้ยังมีรูปแบบที่เหมาะสำหรับงานก่ออิฐด้วย เช่น 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 แบบ
  • ตารางกริดใช้พร็อพเพอร์ตี้ justify-* และ align-* ทั้ง 6 รายการได้ แต่ Masonry จะใช้เพียงชุดย่อยอย่าง Flexbox เท่านั้น

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

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

ข้อเสนอทางเลือก

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

รูปแบบการก่ออิฐแบบคลาสสิก

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

.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-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 ที่เข้ามาตรวจสอบโพสต์นี้และการพูดคุยที่เป็นประโยชน์ต่อเรา