มาดูวิธีจัดรูปแบบรายการที่มีประโยชน์และสร้างสรรค์กัน
อะไรที่คุณนึกถึงเมื่อพูดถึงรายการ ตัวอย่างที่เห็นได้ชัดที่สุดคือรายการช็อปปิ้ง ซึ่งเป็นรายการที่เรียบง่ายที่สุด เป็นการรวบรวมรายการต่างๆ โดยไม่เรียงตามลำดับใดๆ แต่เราใช้ลิสต์ในลักษณะต่างๆ มากมายบนเว็บ คอลเล็กชันคอนเสิร์ตที่กำลังจะจัดขึ้นที่สถานที่แห่งหนึ่ง มีแนวโน้มสูงมากที่จะเป็นลิสต์ กระบวนการจองแบบหลายขั้นตอน อาจเป็นรายการ แกลเลอรีรูปภาพ แม้แต่รายการนั้นอาจถือเป็นรายการรูปภาพที่มีคำบรรยายภาพ
บทความนี้จะอธิบายรายการ HTML ประเภทต่างๆ ที่มีให้ใช้งานบนเว็บและกรณีการใช้งาน รวมถึงแอตทริบิวต์บางอย่างที่คุณอาจไม่คุ้นเคย นอกจากนี้ เราจะดูวิธีจัดรูปแบบด้วย CSS ที่มีประโยชน์และสร้างสรรค์
กรณีที่ควรใช้ลิสต์
คุณควรใช้องค์ประกอบรายการ HTML เมื่อต้องจัดกลุ่มรายการตามความหมาย เทคโนโลยีความช่วยเหลือพิเศษ (เช่น โปรแกรมอ่านหน้าจอ) จะแจ้งให้ผู้ใช้ทราบว่ามีรายการและจำนวนรายการ ลองนึกถึงตารางกริดของผลิตภัณฑ์ในเว็บไซต์ช็อปปิ้ง ข้อมูลนี้มีประโยชน์มาก ดังนั้น การใช้องค์ประกอบรายการจึงอาจเป็นตัวเลือกที่ดี
แสดงรายการประเภท
ในส่วนของมาร์กอัป เรามีองค์ประกอบรายการ 3 รายการให้เลือก ได้แก่
- รายการที่ไม่เรียงลำดับ
- รายการตามลำดับ
- รายการคำอธิบาย
การเลือกรูปแบบใดขึ้นอยู่กับกรณีการใช้งาน
รายการที่ไม่เรียงลําดับ (ul)
องค์ประกอบรายการที่ไม่มีลําดับ (<ul>
) มีประโยชน์มากที่สุดเมื่อรายการในรายการไม่ตรงกับลําดับใดๆ โดยค่าเริ่มต้น รายการนี้จะแสดงเป็นลิสต์หัวข้อ ตัวอย่างเช่น รายการช็อปปิ้งที่ลำดับไม่สำคัญ
ตัวอย่างที่พบบ่อยกว่าในเว็บคือเมนูการนำทาง เมื่อสร้างเมนู คุณควรตัด ul
ไว้ในองค์ประกอบ nav
และระบุเมนูด้วยป้ายกำกับเพื่อช่วยเทคโนโลยีความช่วยเหลือพิเศษ นอกจากนี้ เราควรระบุหน้าปัจจุบันในเมนูด้วย ซึ่งทําได้โดยใช้แอตทริบิวต์ aria-current
ดังนี้
<nav aria-label="Main">
<ul>
<li>
<a href="/page-1" aria-current="page">Menu item 1</a>
</li>
<li>
<a href="/page-2">Menu item 2</a>
</li>
<li>
<a href="/page-2">Menu item 2</a>
</li>
…
</ul>
</nav>
บทความเกี่ยวกับโครงสร้างเมนูนี้จะแสดงคําแนะนําหลายประการเพื่อให้มั่นใจว่าทุกคนจะเข้าถึงเมนูการนําทางได้
รายการตามลําดับ (ol)
องค์ประกอบรายการแบบจัดลำดับ (<ol>
) เป็นตัวเลือกที่ดีที่สุดเมื่อลําดับของรายการมีความสําคัญ เช่น กระบวนการแบบหลายขั้นตอน โดยค่าเริ่มต้น รายการในลิสต์จะมีเลขกำกับ ตัวอย่างเช่น ชุดวิธีการที่ต้องทำตามขั้นตอนต่างๆ ตามลำดับ
ทั้งองค์ประกอบ <ol>
และ <ul>
ต้องมีองค์ประกอบ <li>
เป็นองค์ประกอบย่อยโดยตรงเท่านั้น
รายการคำอธิบาย (dl)
รายการคำอธิบายประกอบด้วยคำศัพท์ (องค์ประกอบ <dt>
) และคำอธิบาย (<dd>
) คำศัพท์แต่ละคำอาจมีคำอธิบายมากกว่า 1 รายการ กรณีการใช้งานที่เป็นไปได้อาจรวมถึงอภิธานศัพท์ หรืออาจเป็นเมนูร้านอาหาร รายการคำอธิบายจะไม่แสดงพร้อมกับเครื่องหมายใดๆ โดยค่าเริ่มต้น แม้ว่าเบราว์เซอร์มักจะเยื้ององค์ประกอบ <dd>
ใน HTML อนุญาตให้จัดกลุ่มคำที่มีคำอธิบายประกอบโดยใช้ <div>
ซึ่งอาจมีประโยชน์สำหรับการจัดสไตล์ดังที่เราจะได้เห็นในภายหลัง
<!-- This is valid -->
<dl>
<dt>Term 1</dt>
<dd>This is the first description of the first term in the list</dd>
<dd>This is the second description of the first term in the list</dd>
<dt>Term 2</dt>
<dd>This is the description of the second term in the list</dd>
</dl>
<!-- This is also valid -->
<dl>
<div>
<dt>Term 1</dt>
<dd>This is the first description of the first term in the list</dd>
<dd>This is the second description of the first term in the list</dd>
</div>
<div>
<dt>Term 2</dt>
<dd>This is the description of the second term in the list</dd>
</div>
</dl>
การจัดรูปแบบรายการอย่างง่าย
การใช้รายการที่ง่ายที่สุดอย่างหนึ่งคือภายในบล็อกข้อความเนื้อหา บ่อยครั้งที่รายการง่ายๆ เหล่านี้ไม่จำเป็นต้องมีการจัดรูปแบบที่ซับซ้อน แต่เราอาจต้องการปรับแต่งเครื่องหมายของรายการแบบมีลําดับหรือไม่มีลําดับในบางระดับ เช่น ใช้สีของแบรนด์ หรือใช้รูปภาพที่กําหนดเองสำหรับสัญลักษณ์หัวข้อ เราทําสิ่งต่างๆ ได้มากมายด้วย list-style
และองค์ประกอบจำลอง ::marker
::marker
นอกจากการกำหนดสไตล์พื้นฐานให้กับเครื่องหมายรายการแล้ว เรายังสร้างหัวข้อย่อยแบบวนซ้ำได้ด้วย ในที่นี้เราใช้ URL รูปภาพ 3 รายการที่แตกต่างกันสำหรับค่า content
ขององค์ประกอบจำลอง ::marker
ซึ่งช่วยเพิ่มความรู้สึกว่าเขียนด้วยมือสำหรับตัวอย่างรายการช็อปปิ้ง (แทนที่จะใช้รูปภาพเดียวสำหรับทั้งหมด)
::marker {
content: url("/marker-1.svg") ' ';
}
li:nth-child(3n)::marker {
content: url("/marker-2.svg") ' ';
}
li:nth-child(3n - 1)::marker {
content: url("/marker-3.svg") ' ';
}
ตัวนับที่กำหนดเอง
สำหรับรายการที่เรียงลําดับบางรายการ เราอาจต้องการใช้ค่าตัวนับ แต่เพิ่มค่าอื่นต่อท้าย เราสามารถใช้ตัวนับ list-item
เป็นค่าสําหรับพร็อพเพอร์ตี้ content
ของเครื่องหมายและต่อท้ายเนื้อหาอื่นๆ ดังนี้
::marker {
content: counter(list-item) '🐈 ';
}
ตัวนับจะเพิ่มขึ้น 1 รายการโดยอัตโนมัติ แต่เราสามารถอนุญาตให้ตัวนับเพิ่มขึ้นเป็นค่าอื่นได้หากต้องการ โดยการตั้งค่าพร็อพเพอร์ตี้ counter-increment
ในรายการ ตัวอย่างเช่น การดำเนินการนี้จะเพิ่มตัวนับขึ้น 3 ครั้งทุกครั้ง
li {
counter-increment: list-item 3;
}
เรายังเจาะลึกเรื่องตัวนับได้อีกมาก บทความรายการ มาร์กเกอร์ และตัวนับ CSS จะอธิบายความเป็นไปได้บางอย่างอย่างละเอียด
ข้อจํากัดของการจัดรูปแบบ ::marker
บางครั้งเราอาจต้องการควบคุมตำแหน่งและรูปแบบของเครื่องหมายมากขึ้น ตัวอย่างเช่น คุณจะจัดตําแหน่งเครื่องหมายโดยใช้ Flexbox หรือตารางไม่ได้ ซึ่งบางครั้งอาจเป็นข้อเสียหากคุณต้องการการจัดแนวอื่นๆ ::marker
แสดงคุณสมบัติ CSS จํานวนจํากัดสําหรับการจัดรูปแบบ หากการออกแบบต้องใช้สิ่งอื่นนอกเหนือจากการจัดสไตล์พื้นฐาน เราอาจใช้องค์ประกอบจำลองอื่นจะดีกว่า
จัดรูปแบบรายการที่ไม่ได้มีลักษณะเป็นรายการ
บางครั้งเราอาจต้องการจัดรูปแบบรายการในลักษณะที่แตกต่างจากการจัดรูปแบบเริ่มต้นโดยสิ้นเชิง กรณีนี้มักเกิดขึ้นกับเมนูการนำทาง เช่น ปกติเราต้องการนําเครื่องหมายทั้งหมดออก และอาจแสดงรายการในแนวนอนโดยใช้ Flexbox แนวทางปฏิบัติทั่วไปคือตั้งค่าพร็อพเพอร์ตี้ list-style
เป็น none
ซึ่งหมายความว่าคุณจะเข้าถึงองค์ประกอบเสมือนเครื่องหมายใน DOM ไม่ได้อีกต่อไป
เครื่องหมายที่กำหนดเองด้วย ::before
การจัดสไตล์องค์ประกอบจำลอง ::before
เป็นวิธีทั่วไปในการสร้างเครื่องหมายรายการที่กำหนดเองก่อนที่จะมี ::marker
แต่ถึงตอนนี้ก็ยังช่วยให้เราจัดรูปแบบรายการที่ซับซ้อนได้ยืดหยุ่นมากขึ้นเมื่อต้องการ
เช่นเดียวกับ ::marker
เราเพิ่มสไตล์หัวข้อที่กำหนดเองได้โดยใช้แอตทริบิวต์ content
ซึ่งแตกต่างจากการใช้ ::marker
เนื่องจากเราต้องจัดตำแหน่งด้วยตนเอง เนื่องจากไม่ได้รับสิทธิประโยชน์อัตโนมัติที่ list-style-position
มอบให้ แต่เราจัดตำแหน่งได้ง่ายด้วย Flexbox และ Flexbox ยังเปิดโอกาสในการจัดตำแหน่งได้มากขึ้นด้วย เช่น เราอาจสลับตำแหน่งเครื่องหมายดังนี้
หากจัดรูปแบบรายการเรียงลําดับโดยใช้องค์ประกอบ ::before
เราอาจต้องการใช้ตัวนับเพื่อเพิ่มเครื่องหมายตัวเลขด้วย
li::before {
counter-increment: list-item;
content: counter(list-item);
}
การใช้ ::before
แทน ::marker
จะช่วยให้เราเข้าถึงพร็อพเพอร์ตี้ CSS ได้อย่างเต็มรูปแบบเพื่อการจัดสไตล์ที่กำหนดเอง รวมถึงอนุญาตภาพเคลื่อนไหวและทรานซิชัน ซึ่ง ::marker
รองรับเพียงบางส่วน
แอตทริบิวต์รายการ
องค์ประกอบรายการเรียงลําดับยอมรับแอตทริบิวต์ที่ไม่บังคับบางรายการ ซึ่งจะเป็นประโยชน์ใน Use Case ที่หลากหลาย
รายการที่กลับหัว
หากเรามีรายการอัลบั้มยอดนิยม 10 อันดับของปีที่ผ่านมา เราอาจนับถอยหลังจาก 10 ไป 1 เราอาจใช้ตัวนับที่กําหนดเองสําหรับการนับดังกล่าว และเพิ่มค่าตัวนับในเชิงลบ หรือจะใช้แอตทริบิวต์ reversed
ใน HTML ก็ได้ เราขอโต้แย้งว่าโดยทั่วไปแล้วการใช้แอตทริบิวต์ reversed
แทนการเพิ่มตัวนับใน CSS แบบลบนั้นเหมาะสมตามหลักความหมาย เว้นแต่ตัวนับจะใช้เพื่อแสดงผลเท่านั้น หาก CSS โหลดไม่สำเร็จ คุณยังคงเห็นตัวเลขนับถอยหลังอย่างถูกต้องใน HTML นอกจากนี้ เรายังต้องพิจารณาว่าโปรแกรมอ่านหน้าจอจะตีความรายการนี้อย่างไร
ลองดูตัวอย่างนี้ของอัลบั้ม 10 อันดับแรกจากปี 2021 หากตัวนับเพิ่มขึ้นด้วย CSS เพียงอย่างเดียว ผู้เข้าถึงหน้าเว็บโดยใช้โปรแกรมอ่านหน้าจออาจสรุปว่าตัวเลขนับขึ้น ดังนั้นตัวเลข 10 นั้นจึงหมายถึงตัวเลข 1
คุณจะเห็นในเดโมว่าการใช้แอตทริบิวต์ reversed
ช่วยให้เครื่องหมายมีค่าที่ถูกต้องอยู่แล้วโดยไม่ต้องทำอะไรเพิ่มเติม แต่หากเราสร้างเครื่องหมายรายการที่กำหนดเองโดยใช้องค์ประกอบจำลอง ::before
เราจะต้องปรับตัวนับ เราเพียงแค่ต้องสั่งให้ตัวนับรายการในลิสต์เพิ่มขึ้นในเชิงลบ
li::before {
counter-increment: list-item -1;
content: counter(list-item);
}
ซึ่งจะเพียงพอใน Firefox แต่เครื่องหมายใน Chrome และ Safari จะนับถอยหลังจาก 0 เป็น -10 เราแก้ไขได้โดยการเพิ่มแอตทริบิวต์ start
ลงในรายการ
แยกรายการ
แอตทริบิวต์ start
ช่วยให้เราระบุค่าตัวเลขที่รายการควรเริ่มต้น ประโยชน์อย่างหนึ่งของวิธีนี้คือในกรณีที่คุณต้องการแยกรายการออกเป็นกลุ่ม
มาต่อยอดจากตัวอย่างอัลบั้มยอดนิยม 10 อันดับกัน เราอาจต้องการนับถอยหลังอัลบั้มยอดนิยม 20 อันดับ แต่แบ่งเป็นกลุ่มๆ ละ 10 อันดับ ระหว่างกลุ่ม 2 กลุ่มนี้มีเนื้อหาหน้าเว็บอื่นๆ
เราจะต้องสร้างรายการแยกกัน 2 รายการใน HTML แต่เราจะตรวจสอบได้อย่างไรว่าตัวนับจะถูกต้อง ขณะนี้มาร์กอัปของเรากำหนดให้ทั้ง 2 รายการนับถอยหลังจาก 10 ไป 1 ซึ่งไม่ใช่สิ่งที่เราต้องการ แต่เราสามารถระบุค่าแอตทริบิวต์ start
ใน HTML ได้ หากเราเพิ่มค่า start
เป็น 20 ลงในรายการแรก เครื่องหมายจะอัปเดตโดยอัตโนมัติอีกครั้ง
<ol reversed start="20">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
เลย์เอาต์รายการแบบหลายคอลัมน์
บางครั้งเลย์เอาต์หลายคอลัมน์อาจเหมาะกับรายการของเรามากกว่า ดังที่คุณเห็นจากเดโมก่อนหน้านี้ การตั้งค่าความกว้างของคอลัมน์ช่วยให้มั่นใจได้ว่ารายการจะปรับเปลี่ยนตามอุปกรณ์โดยอัตโนมัติ โดยวางตัวเองใน 2 คอลัมน์ขึ้นไปก็ต่อเมื่อมีพื้นที่เพียงพอเท่านั้น นอกจากนี้ เรายังกำหนดระยะห่างระหว่างคอลัมน์ และเพิ่มcolumn-rule ที่มีสไตล์ (โดยใช้อักษรย่อคล้ายกับพร็อพเพอร์ตี้ border
) เพื่อเพิ่มความน่าสนใจได้ด้วย
ol {
columns: 25rem;
column-gap: 7rem;
column-rule: 4px dotted turquoise;
}
บางครั้งการใช้คอลัมน์อาจทำให้รายการในลิสต์ขาดตอนและไม่สวยงาม ซึ่งไม่ใช่ผลลัพธ์ที่เราต้องการเสมอไป
เราป้องกันช่วงพักที่ไม่ต้องการเหล่านี้ได้โดยใช้ break-inside: avoid
ในรายการ
li {
break-inside: avoid;
}
พร็อพเพอร์ตี้ที่กำหนดเอง
พร็อพเพอร์ตี้ที่กำหนดเองของ CSS เปิดโอกาสมากมายในการจัดรูปแบบรายการ หากทราบดัชนีของรายการในลิสต์ เราจะใช้ดัชนีดังกล่าวเพื่อคํานวณค่าพร็อพเพอร์ตี้ได้ ขออภัย ปัจจุบันยังไม่มีวิธีระบุดัชนีขององค์ประกอบ (ในลักษณะที่ใช้งานได้) ใน CSS เพียงอย่างเดียว ตัวนับอนุญาตให้เราใช้ค่าในพร็อพเพอร์ตี้ content
เท่านั้น และไม่อนุญาตให้ใช้การคํานวณ
แต่เราสามารถตั้งค่าดัชนีขององค์ประกอบภายในแอตทริบิวต์ style
ใน HTML ซึ่งจะทำให้การคำนวณเป็นไปได้จริงมากขึ้น โดยเฉพาะหากเราใช้ภาษาเทมเพลต ตัวอย่างนี้แสดงวิธีตั้งค่าโดยใช้ Nunjucks
<ol style="--length: items|length">
</ol>
Splitting.js เป็นไลบรารีที่ทํางานคล้ายกันฝั่งไคลเอ็นต์
การใช้ค่าพร็อพเพอร์ตี้ที่กำหนดเองช่วยให้เราแสดงความคืบหน้าผ่านรายการได้หลายวิธี วิธีหนึ่งอาจเป็นแถบความคืบหน้าสำหรับรายการขั้นตอน ในตัวอย่างนี้ เราใช้องค์ประกอบจำลองที่มีไล่ระดับสีเชิงเส้นเพื่อสร้างแถบสำหรับแต่ละรายการซึ่งแสดงระยะทางที่ผู้ใช้ดูรายการ
li::before {
--stop: calc(100% / var(--length) * var(--i));
--color1: deeppink;
--color2: pink;
content: '';
background: linear-gradient(to right, var(--color1) var(--stop), var(--color2) 0);
}
นอกจากนี้ เรายังปรับสีได้ขณะที่รายการดำเนินไปโดยใช้ฟังก์ชันสี hsl()
เราคำนวณค่า hue
ได้โดยใช้พร็อพเพอร์ตี้ที่กำหนดเอง
การจัดรูปแบบรายการคำอธิบาย
ดังที่ได้กล่าวไปก่อนหน้านี้ เราสามารถเลือกใช้ div
ใน dl
เพื่อตัดคำศัพท์และคำจำกัดความของคำนั้นๆ ออกเพื่อให้มีตัวเลือกการจัดรูปแบบมากขึ้น เช่น เราอาจต้องการแสดงรายการเป็นตารางกริด การตั้งค่า display: grid
ในรายการโดยไม่มี Wrapper div
รอบแต่ละกลุ่มหมายความว่าระบบจะวางคำศัพท์และคำอธิบายไว้ในเซลล์ตารางกริดที่แตกต่างกัน บางครั้งวิธีนี้มีประโยชน์ เช่น ในตัวอย่างต่อไปนี้ที่แสดงเมนูพายพร้อมคำอธิบาย
เรากําหนดตารางกริดในรายการเองได้ และตรวจสอบว่าคําศัพท์และคําอธิบายจะจัดแนวในคอลัมน์เสมอ โดยความกว้างของคอลัมน์จะกําหนดโดยคําที่ยาวที่สุด
ในทางกลับกัน หากต้องการจัดกลุ่มคำที่มีคำอธิบายเป็นการ์ดแยกกัน การใช้ Wrapper <div>
จะมีประโยชน์มาก
แหล่งข้อมูล
- ลิสต์ ข้อมูลเบื้องต้นเกี่ยวกับลิสต์และ ::marker
- เครื่องหมายที่กำหนดเองโดยใช้ ::marker
- รายการ CSS ที่มีตัวนับ