เมื่อใดและอย่างไรที่จะใช้ CSS Multi-Column Layout
เผยแพร่แล้ว: 2022-03-10ความตื่นเต้นเกี่ยวกับ CSS Grid Layout และ Flexbox มักถูกมองข้ามไป ในบทความนี้ ผมจะไปดูที่ Multi-column Layout ซึ่งมักเรียกกันว่า multicol หรือบางครั้งเรียกว่า "CSS Columns" คุณจะพบว่าเหมาะกับงานใดบ้าง และบางสิ่งที่ต้องระวังเมื่อสร้างคอลัมน์
มัลติคอลคืออะไร?
แนวคิดพื้นฐานของ multicol คือคุณสามารถนำเนื้อหาบางส่วนแล้วไหลเป็นหลายคอลัมน์ได้เช่นเดียวกับในหนังสือพิมพ์ คุณทำได้โดยใช้คุณสมบัติหนึ่งในสองคุณสมบัติ คุณสมบัติ column-count
ระบุจำนวนคอลัมน์ที่คุณต้องการให้เนื้อหาเจาะเข้าไป คุณสมบัติ column-width
ระบุความกว้างในอุดมคติ โดยปล่อยให้เบราว์เซอร์หาจำนวนคอลัมน์ที่จะพอดี
ไม่สำคัญว่าองค์ประกอบใดอยู่ในเนื้อหาที่คุณเปลี่ยนเป็นคอนเทนเนอร์แบบมัลติคอล ทุกอย่างยังคงอยู่ในโฟลว์ปกติ แต่แบ่งออกเป็นคอลัมน์ สิ่งนี้ทำให้ multicol ไม่เหมือนกับวิธีการจัดวางแบบอื่นๆ ที่เรามีในเบราว์เซอร์ในปัจจุบัน ตัวอย่างเช่น Flexbox และ Grid นำองค์ประกอบย่อยของคอนเทนเนอร์และรายการเหล่านั้นเข้าร่วมในรูปแบบ flex หรือ grid ด้วย multicol คุณยังคงมีโฟลว์ปกติ ยกเว้นในคอลัมน์
ในตัวอย่างด้านล่าง ฉันใช้ column-width
เพื่อแสดงคอลัมน์อย่างน้อย 14em
Multicol กำหนดคอลัมน์ 14em
ให้มากที่สุดเท่าที่จะพอดี จากนั้นจึงแบ่งพื้นที่ที่เหลือระหว่างคอลัมน์ คอลัมน์จะมีขนาดอย่างน้อย 14em
เว้นแต่เราจะสามารถแสดงได้เพียงคอลัมน์เดียว ซึ่งในกรณีนี้คอลัมน์อาจเล็กกว่า Multicol เป็นครั้งแรกที่เราเห็นพฤติกรรมประเภทนี้ใน CSS คอลัมน์ถูกสร้างขึ้นซึ่งตอบสนองตามค่าเริ่มต้น คุณไม่จำเป็นต้องเพิ่ม Media Queries และเปลี่ยนจำนวนคอลัมน์สำหรับเบรกพอยต์ต่างๆ แต่เราระบุความกว้างที่เหมาะสมที่สุดและเบราว์เซอร์จะจัดการให้
ดู Pen Smashing Multicol: ความกว้างคอลัมน์โดย Rachel Andrew (@rachelandrew) บน CodePen
คอลัมน์จัดแต่งทรงผม
กล่องคอลัมน์ที่สร้างขึ้นเมื่อคุณใช้คุณสมบัติคอลัมน์อย่างใดอย่างหนึ่งไม่สามารถกำหนดเป้าหมายได้ คุณไม่สามารถจัดการกับพวกเขาด้วย JavaScript และคุณไม่สามารถจัดรูปแบบแต่ละกล่องเพื่อให้เป็นสีพื้นหลังหรือปรับช่องว่างภายในและระยะขอบ กล่องคอลัมน์ทั้งหมดจะมีขนาดเท่ากัน สิ่งเดียวที่คุณทำได้คือเพิ่มกฎระหว่างคอลัมน์ โดยใช้คุณสมบัติ column-rule ซึ่งทำหน้าที่เหมือนเส้นขอบ คุณยังสามารถควบคุมช่องว่างระหว่างคอลัมน์ได้โดยใช้คุณสมบัติ column-gap
ซึ่งมีค่าเริ่มต้นเป็น 1em
อย่างไรก็ตาม คุณสามารถเปลี่ยนเป็นหน่วยความยาวที่ถูกต้องได้
ดู Pen Smashing Multicol: การออกแบบคอลัมน์โดย Rachel Andrew (@rachelandrew) บน CodePen
นั่นคือฟังก์ชันพื้นฐานของมัลติคอล คุณสามารถแยกเนื้อหาออกเป็นคอลัมน์ๆ ได้ เนื้อหาจะเติมคอลัมน์ตามลำดับ สร้างคอลัมน์ในทิศทางอินไลน์ คุณสามารถควบคุมช่องว่างระหว่างคอลัมน์และเพิ่มกฎด้วยค่าที่เป็นไปได้เช่นเดียวกับเส้นขอบ จนถึงตอนนี้ดีมาก และทั้งหมดข้างต้นได้รับการสนับสนุนอย่างดีในเบราว์เซอร์และเป็นเวลานาน ทำให้ข้อมูลจำเพาะนี้ปลอดภัยมากที่จะใช้ในแง่ของความเข้ากันได้แบบย้อนหลัง
มีบางสิ่งเพิ่มเติมที่คุณอาจต้องการพิจารณากับคอลัมน์ของคุณ และปัญหาที่อาจเกิดขึ้นบางประการที่ต้องระวังเมื่อใช้คอลัมน์บนเว็บ
คอลัมน์ที่ขยาย
บางครั้งคุณอาจต้องการแบ่งเนื้อหาบางส่วนออกเป็นคอลัมน์ แต่จากนั้นทำให้องค์ประกอบหนึ่งขยายข้ามกล่องคอลัมน์ การใช้คุณสมบัติ column-span
กับการสืบทอดของคอนเทนเนอร์มัลติคอลทำให้สำเร็จ
ในตัวอย่างด้านล่าง ฉันทำให้องค์ประกอบ <blockquote>
ขยายข้ามคอลัมน์ของฉัน โปรดทราบว่าเมื่อคุณทำเช่นนี้ เนื้อหาจะแบ่งออกเป็นชุดกล่องที่อยู่เหนือช่วง จากนั้นเริ่มชุดกล่องคอลัมน์ชุดใหม่ด้านล่าง เนื้อหาไม่ข้ามองค์ประกอบที่ขยาย
ขณะนี้คุณสมบัติ column-span
กำลังถูกนำมาใช้ใน Firefox และอยู่หลังแฟล็กคุณลักษณะ
ดู Pen Smashing Multicol: ช่วงคอลัมน์โดย Rachel Andrew (@rachelandrew) บน CodePen
โปรดทราบว่าในข้อมูลจำเพาะปัจจุบัน ค่าสำหรับ column-span
จะเป็น all
หรือ none
คุณไม่สามารถขยายเฉพาะคอลัมน์บางคอลัมน์ได้ แต่คุณสามารถหาประเภทของเลย์เอาต์ที่คุณอาจเห็นในหนังสือพิมพ์ได้โดยการรวมมัลติคอลกับวิธีเลย์เอาต์อื่นๆ ในตัวอย่างนี้ ฉันมีคอนเทนเนอร์กริดที่มีแทร็กสองคอลัมน์ ทางซ้ายมือคือ 2fr
ทางขวามือ 1fr
. บทความในแทร็กด้านซ้ายฉันได้เปลี่ยนเป็นคอนเทนเนอร์ multicol ที่มีสองแทร็ก แต่ก็มีองค์ประกอบแบบสแปน
ทางด้านขวา เรามีส่วนกันซึ่งเข้าไปในแทร็กคอลัมน์กริดที่สอง ด้วยการลองใช้วิธีการจัดวางรูปแบบต่างๆ ที่เรามี เราสามารถทราบได้ว่าวิธีการจัดวางแบบใดที่เหมาะกับงานที่ทำอยู่ — อย่ากลัวที่จะมิกซ์แอนด์แมทช์!
ดู Pen Smashing Multicol: การผสมวิธีเลย์เอาต์โดย Rachel Andrew (@rachelandrew) บน CodePen
การควบคุมการแบ่งเนื้อหา
หากคุณมีเนื้อหาที่มีหัวเรื่อง คุณอาจต้องการหลีกเลี่ยงสถานการณ์ที่หัวเรื่องกลายเป็นสิ่งสุดท้ายในคอลัมน์ที่มีเนื้อหาอยู่ในคอลัมน์ถัดไป หากคุณมีรูปภาพพร้อมคำอธิบายภาพ สถานการณ์ในอุดมคติก็คือรูปภาพและคำอธิบายภาพจะคงอยู่เป็นหนึ่งเดียว ไม่ถูกแบ่งตามคอลัมน์ เพื่อจัดการกับปัญหาเหล่านี้ CSS มีคุณสมบัติในการควบคุมว่าเนื้อหาแบ่งที่ใด
เมื่อคุณแบ่งเนื้อหาของคุณออกเป็นคอลัมน์ คุณจะทำสิ่งที่เรียกว่าการแตกแฟรกเมนต์ เช่นเดียวกับถ้าคุณแบ่งเนื้อหาของคุณระหว่างหน้า เช่น เมื่อคุณสร้างสไตล์ชีตสำหรับบริบทการพิมพ์ ดังนั้น multicol จึงใกล้เคียงกับ Paged Media มากที่สุด มากกว่าวิธีการจัดวางรูปแบบอื่นๆ บนเว็บ ด้วยเหตุนี้ หลายปีที่ผ่านมาวิธีการควบคุมตัวแบ่งในเนื้อหาจึงเป็นการใช้คุณสมบัติตัวแบ่ง page-break-
ซึ่งเป็นส่วนหนึ่งของ CSS2.1
-
page-break-before
-
page-break-after
-
page-break-inside
เมื่อเร็ว ๆ นี้ข้อมูลจำเพาะ CSS Fragmentation ได้กำหนดคุณสมบัติสำหรับการแตกแฟรกเมนต์ซึ่งออกแบบมาสำหรับบริบทที่มีการแยกส่วน ข้อมูลจำเพาะรวมถึงรายละเอียดสำหรับ Paged Media, multicol และข้อมูลจำเพาะของภูมิภาคที่หยุดชะงัก ภูมิภาคยังแยกส่วนเนื้อหาอย่างต่อเนื่อง ด้วยการทำให้คุณสมบัติเหล่านี้เป็นแบบทั่วไป พวกเขาสามารถนำไปใช้กับบริบทที่แยกส่วนในอนาคตได้ เช่นเดียวกับคุณสมบัติการจัดตำแหน่งจาก Flexbox ถูกย้ายไปยังข้อมูลจำเพาะการจัดตำแหน่งกล่อง เพื่อให้สามารถใช้ในรูปแบบกริดและบล็อกได้

-
break-before
-
break-after
-
break-inside
ตัวอย่างเช่น ฉันได้ใช้ break-inside avoid
องค์ประกอบ <figure>
เพื่อป้องกันไม่ให้คำอธิบายภาพหลุดออกจากภาพ เบราว์เซอร์ที่สนับสนุนควรเก็บตัวเลขไว้ด้วยกัน แม้ว่าจะทำให้คอลัมน์ดูไม่สมดุลก็ตาม
ดู Pen Smashing Multicol: break-inside โดย Rachel Andrew (@rachelandrew) บน CodePen
น่าเสียดายที่การรองรับคุณสมบัติเหล่านี้ใน multicol นั้นค่อนข้างหยาบ แม้แต่ในกรณีที่รองรับก็ควรถูกมองว่าเป็นข้อเสนอแนะ เนื่องจากมีความเป็นไปได้ที่จะส่งคำขอจำนวนมากในขณะที่พยายามควบคุมการหยุดทำงาน ซึ่งโดยพื้นฐานแล้วเบราว์เซอร์ไม่สามารถพังได้ทุกที่ ข้อมูลจำเพาะจะกำหนดลำดับความสำคัญในกรณีนี้ อย่างไรก็ตาม อาจมีประโยชน์มากกว่าสำหรับคุณในการควบคุมเฉพาะกรณีที่สำคัญที่สุดเท่านั้น
ปัญหาของคอลัมน์บนเว็บ
เหตุผลหนึ่งที่เราไม่เห็น multicol ใช้มากในเว็บก็คือความจริงที่ว่ามันจะง่ายมากที่จะจบลงด้วยประสบการณ์การอ่านซึ่งทำให้ผู้อ่านเลื่อนในมิติบล็อก นั่นหมายถึงการเลื่อนขึ้นและลงในแนวตั้งสำหรับพวกเราที่ใช้ภาษาอังกฤษหรือโหมดการเขียนแนวตั้งอื่น นี่ไม่ใช่ประสบการณ์การอ่านที่ดี!
หากคุณแก้ไขความสูงของคอนเทนเนอร์ เช่น โดยใช้หน่วยวิวพอร์ต vh
และมีเนื้อหามากเกินไป โอเวอร์โฟลว์จะเกิดขึ้นในทิศทางอินไลน์ ดังนั้นคุณจะได้รับแถบเลื่อนแนวนอนแทน
ดูคอลัมน์ Pen Smashing Multicol: ล้นโดย Rachel Andrew (@rachelandrew) บน CodePen
สิ่งเหล่านี้ไม่เหมาะ และการใช้ multicol บนเว็บเป็นสิ่งที่เราต้องคิดอย่างรอบคอบในแง่ของปริมาณเนื้อหาที่เราอาจตั้งเป้าที่จะไหลเข้าสู่คอลัมน์ของเรา
บล็อกคอลัมน์ล้น
สำหรับข้อกำหนดระดับ 2 เรากำลังพิจารณาวิธีเปิดใช้งานวิธีการที่คอลัมน์ล้นซึ่งปัจจุบันทำให้เกิดแถบเลื่อนแนวนอนแทนที่จะสร้างขึ้นในทิศทางบล็อก ซึ่งหมายความว่าคุณสามารถมีคอนเทนเนอร์แบบหลายคอลัมน์ที่มีความสูงได้ และเมื่อเนื้อหาสร้างคอลัมน์ที่เติมคอนเทนเนอร์นั้นแล้ว จะมีการสร้างคอลัมน์ชุดใหม่ด้านล่าง สิ่งนี้จะดูเหมือนตัวอย่างการขยายของเราด้านบนเล็กน้อย อย่างไรก็ตาม แทนที่จะมีประแจทำให้กล่องคอลัมน์ใหม่เริ่มทำงาน มันจะเป็นการล้นที่เกิดจากคอนเทนเนอร์ที่มีข้อจำกัดในมิติบล็อก
คุณลักษณะนี้จะทำให้ multicol มีประโยชน์มากขึ้นสำหรับเว็บ แม้ว่าเราจะอยู่ห่างไกลออกไปเล็กน้อยในขณะนี้ คุณสามารถจับตาดูปัญหานี้ได้ใน repo ของ CSS Working Group หากคุณมีกรณีการใช้งานเพิ่มเติมสำหรับคุณลักษณะนี้ โปรดโพสต์ไว้ สามารถช่วยได้มากเมื่อออกแบบคุณลักษณะใหม่
Multicol มีประโยชน์สำหรับวันนี้อย่างไร?
ด้วยข้อกำหนดปัจจุบัน เราไม่แนะนำให้แยกเนื้อหาทั้งหมดของคุณออกเป็นคอลัมน์โดยไม่คำนึงถึงปัญหาในการเลื่อน อย่างไรก็ตาม มีบางกรณีที่ multicol เหมาะสมที่สุดบนเว็บ มีกรณีการใช้งานเพียงพอที่จะทำให้คุณควรพิจารณาเมื่อดูรูปแบบการออกแบบ
การยุบ UI หรือองค์ประกอบข้อความขนาดเล็ก
Multicol สามารถเป็นประโยชน์ในทุกที่ที่คุณมีรายการเล็ก ๆ ที่คุณต้องการใช้พื้นที่น้อยลง ตัวอย่างเช่น รายการกล่องกาเครื่องหมายอย่างง่าย หรือรายชื่อ บ่อยครั้งในสถานการณ์เหล่านี้ ผู้เข้าชมไม่ได้อ่านคอลัมน์ใดคอลัมน์หนึ่งแล้วย้อนกลับไปที่ด้านบนสุดของคอลัมน์ถัดไป แต่สแกนเนื้อหาเพื่อหาช่องทำเครื่องหมายที่จะคลิกหรือเลือกรายการ แม้ว่าคุณจะสร้างประสบการณ์แบบเลื่อนขึ้น แต่ก็อาจไม่ใช่ปัญหา
คุณสามารถดูตัวอย่างของ multicol ที่ใช้ในวิธีนี้โดย Sander de Jong บนเว็บไซต์ DonarMuseum

เนื้อหาจำนวนน้อยที่รู้จัก
มีบางครั้งที่เราออกแบบเว็บไซต์ที่เรารู้ว่าเนื้อหาบางส่วนมีขนาดค่อนข้างเล็ก และจะพอดีกับหน้าจอส่วนใหญ่โดยไม่ทำให้เกิดการเลื่อนที่ไม่ต้องการ ฉันเคยใช้ multicol ในหน้าการนำเสนอของ Notist เพื่อแนะนำการพูดคุย
Andy Clarke ได้ออกแบบตัวอย่างที่น่ารักสำหรับเว็บไซต์ Equfund

เพื่อหลีกเลี่ยงความเป็นไปได้ที่หน้าจอขนาดเล็กมากจะทำให้เกิดการเลื่อน โปรดจำไว้ว่าคุณสามารถใช้การสืบค้นสื่อเพื่อตรวจสอบความสูงและความกว้าง (หรือในโลกตรรกะ บล็อกและในบรรทัด) หากคุณเปิดใช้งานเฉพาะคอลัมน์ที่จุดพักซึ่งมี min-height
เพียงพอสำหรับเนื้อหา การทำเช่นนี้จะช่วยประหยัดผู้ใช้อุปกรณ์ขนาดเล็กมากที่มีประสบการณ์การเลื่อนที่ไม่ดี
การแสดงเนื้อหาเหมือนก่ออิฐ
อีกที่หนึ่งที่ Layout แบบหลายคอลัมน์ทำงานอย่างสวยงามคือถ้าคุณต้องการสร้างการแสดงเนื้อหาประเภท Masonry Multicol เป็นวิธีการจัดวางรูปแบบเดียวที่จะสร้างเลย์เอาต์ประเภทนี้ด้วยรายการที่มีความสูงไม่เท่ากัน กริดจะเว้นช่องว่างหรือยืดไอเท็มเพื่อสร้างกริดสองมิติที่เข้มงวด
Veerle Pieters มีตัวอย่างที่สวยงามของการใช้ multicol ในลักษณะนี้ในหน้าแรงบันดาลใจของเธอ

ทางเลือกกริดและเฟล็กบ็อกซ์
คุณสมบัติ column-
- ยังสามารถใช้เป็นทางเลือกสำหรับเลย์เอาต์ Grid และ Flex หากคุณระบุคุณสมบัติอย่างใดอย่างหนึ่งบนคอนเทนเนอร์ ให้เปลี่ยนคอนเทนเนอร์นั้นเป็นเลย์เอาต์ Flex หรือ Grid โดยใช้ display: flex
หรือ display: grid
พฤติกรรมของคอลัมน์ใดๆ จะถูกลบออก ตัวอย่างเช่น หากคุณมีเลย์เอาต์การ์ดที่ใช้ Grid Layout และเลย์เอาต์นั้นสามารถอ่านได้หากรันในคอลัมน์แทนที่จะเป็นข้ามเพจ คุณสามารถใช้ multicol เป็นทางเลือกง่ายๆ เบราว์เซอร์ที่ไม่รองรับ Grid จะได้รับการแสดงผลแบบ multicol ส่วนเบราว์เซอร์ที่รองรับ Grid จะได้รับ Grid Layout
อย่าลืมมัลติคอล!
บ่อยครั้งที่ฉันตอบคำถาม Grid และ Flexbox โดยที่คำตอบคือไม่ใช้ Grid หรือ Flexbox แต่ให้มองที่ Multicol แทน คุณอาจจะไม่ได้ใช้มันในทุกเว็บไซต์ แต่เมื่อคุณเจอกรณีการใช้งาน มันจะมีประโยชน์มาก ที่ MDN มีแหล่งข้อมูลที่เป็นประโยชน์สำหรับ multicol และคุณสมบัติการกระจายตัวที่เกี่ยวข้อง
หากคุณเคยใช้ multicol ในโปรเจ็กต์ คุณอาจจะจดบันทึกในความคิดเห็น เพื่อแบ่งปันวิธีอื่นๆ ที่เราสามารถใช้คุณลักษณะนี้ได้