รายการ CSS เครื่องหมายและตัวนับ
เผยแพร่แล้ว: 2022-03-10 รายการใน CSS มีคุณสมบัติเฉพาะซึ่งทำให้เรามีรูปแบบรายการมาตรฐานที่เราคาดหวัง รายการที่ไม่เรียงลำดับจะได้รับสัญลักษณ์แสดงหัวข้อย่อยของประเภท disc
และรายการที่เรียงลำดับจะมีหมายเลข ความสนใจของฉันในการสำรวจรายการโดยละเอียดนั้นมาจากงานที่ฉันทำเพื่อจัดทำเอกสาร ::marker
pseudo-element สำหรับ MDN องค์ประกอบหลอกนี้จัดส่งใน Firefox 68 และ เผยแพร่ในวันนี้ ด้วยองค์ประกอบหลอก ::marker
ที่มีให้เรา เราสามารถเริ่มทำสิ่งที่น่าสนใจด้วยรายการ และในบทความนี้ ผมจะอธิบายเพิ่มเติม
ถอดรหัสรายการ
คุณอาจไม่ได้คิดอะไรมากเกี่ยวกับรายการ แม้ว่าเราจะใช้บ่อยในมาร์กอัปของเราก็ตาม หลายสิ่งหลายอย่างสามารถทำเครื่องหมายได้ค่อนข้างมีเหตุผลเป็นรายการ แม้ว่าคำสั่งทีละขั้นตอนหรือองค์ประกอบที่จัดลำดับอาจอธิบายได้ตามธรรมชาติโดยรายการเรียงลำดับ <ol>
หลายสิ่งในการออกแบบสามารถอธิบายได้โดยใช้รายการที่ไม่เรียงลำดับ <ul>
การใช้งานองค์ประกอบทั่วไป เช่น การทำเครื่องหมายการนำทาง เนื่องจากเป็นรายการปลายทางบนไซต์ สำหรับการสำรวจของเรา เรามาเริ่มด้วยการค้นหาว่ารายการนั้นอยู่ใน CSS อะไร
เช่นเดียวกับหลาย ๆ สิ่งใน CSS รายการมีค่าเริ่มต้นบางอย่างที่ใช้กับพวกเขา ค่าเหล่านี้ทำให้ดูเหมือนรายการ ค่าพิเศษเหล่านี้เริ่มต้นด้วยข้อมูลที่รายการมีคุณสมบัติการ display
ที่มีค่า list-item
สิ่งนี้จะสร้างกล่องระดับบล็อกพร้อมกล่องเครื่องหมายเพิ่มเติม กล่องเครื่องหมายเป็นที่ที่เพิ่มรายการสัญลักษณ์แสดงหัวข้อย่อยหรือตัวเลข
รายการถูกกำหนดไว้ตั้งแต่ต้นใน CSS และคำจำกัดความของรายการส่วนใหญ่ที่เราใช้ในปัจจุบันมาจาก CSS2 ข้อกำหนด CSS2 อธิบายรายการดังต่อไปนี้:
“องค์ประกอบที่มีการdisplay: list-item
สร้างกล่องบล็อกหลักสำหรับเนื้อหาขององค์ประกอบ และขึ้นอยู่กับค่าของlist-style-type
และlist-style-image
อาจเป็นกล่องเครื่องหมายเพื่อบ่งชี้ว่าองค์ประกอบนั้น รายการ”
กล่องบล็อกหลัก คือกล่องหลักขององค์ประกอบและประกอบด้วยลูกทั้งหมด เนื่องจากรายการสามารถมีมาร์กอัปอื่นๆ กล่องเครื่องหมายถูกวางไว้ตามกล่องหลักนี้ ข้อมูลจำเพาะระบุรายละเอียดว่าสีพื้นหลังใดๆ จะอยู่ด้านหลังกล่องหลักนี้เท่านั้น ไม่ใช่เครื่องหมาย นอกจากนี้ ยังสามารถตั้งค่าเครื่องหมายให้เป็นหนึ่งในช่วงของค่าที่กำหนดไว้ล่วงหน้าได้:
-
disc
-
circle
-
square
-
decimal
-
decimal-leading-zero
-
lower-roman
-
upper-roman
-
lower-greek
-
lower-latin
-
upper-latin
-
armenian
-
georgian
-
lower-alpha
-
upper-alpha
-
none
-
inherit
ข้อกำหนดการแสดงผลระดับ 3 กำหนด display: list-item
พร้อมกับค่าที่เป็นไปได้อื่นๆ สำหรับคุณสมบัติการ display
มันอ้างอิงกลับไปที่ CSS 2.1 - เช่นเดียวกับคุณสมบัติและค่า CSS จำนวนมากที่มาจาก CSS2 - แต่อธิบายคำหลัก list-item
ว่า "ทำให้องค์ประกอบสร้าง ::marker
pseudo-element"
ข้อมูลจำเพาะระดับ 3 ยังแนะนำความสามารถในการสร้างรายการแบบอินไลน์ด้วยการ display: inline list-item
เบราว์เซอร์นี้ยังไม่ได้ใช้งาน
การสร้างกล่องเครื่องหมายบนรายการที่ไม่ใช่รายการ
เช่นเดียวกับค่าอื่น ๆ ของ display
การกำหนดให้องค์ประกอบ HTML ใด ๆ เป็นประเภทการแสดง list-item
(หากคุณต้องการสร้าง ::marker
องค์ประกอบหลอกบนรายการ) การทำเช่นนี้จะไม่ทำให้องค์ประกอบ กลาย เป็นรายการตามความหมาย แต่จะแสดงเป็นรายการแทนด้วยสายตาเท่านั้น ดังนั้นจึงสามารถมี ::marker
ได้ เมื่อเราพูดถึง ::marker
pseudo-element ด้านล่าง คุณจะค้นพบบางกรณีที่การ display: list-item
อาจมีประโยชน์
CSS แสดงรายการข้อกำหนดระดับ 3: ::marker
And Counters
ข้อกำหนดการ display
จะขยายและชี้แจงคำจำกัดความของรายการที่เราพบใน CSS2 อย่างไรก็ตาม ยังมีข้อกำหนดที่กำหนดลักษณะการทำงานของรายการโดยละเอียด: ข้อกำหนดรายการ CSS ระดับ 3 เนื่องจากพฤติกรรมพื้นฐานของรายการที่กำหนดไว้ใน display
สิ่งนี้ ข้อกำหนดระบุรายละเอียดกล่องเครื่องหมายที่สร้างขึ้นเมื่อมีบางอย่าง display: list-item
พร้อมกับตัวนับที่ใช้โดยค่าเริ่มต้นเมื่อใดก็ตามที่คุณสร้างรายการสั่งซื้อ มีฟังก์ชันที่อาจมีประโยชน์บางอย่างที่เข้าถึงได้ผ่านคุณลักษณะเหล่านี้
The ::marker
Pseudo-Element
::marker
pseudo-element ให้คุณกำหนดเป้าหมายตัวทำเครื่องหมายรายการ — แยกจากเนื้อหาของรายการ สิ่งนี้ไม่สามารถทำได้ใน CSS เวอร์ชันก่อนหน้า ดังนั้น หากคุณเปลี่ยนสีหรือขนาดฟอนต์ของ ul
หรือ li
สิ่งนี้จะเปลี่ยนสีและขนาดฟอนต์ของมาร์กเกอร์ด้วย ในการทำบางสิ่งที่ดูเรียบง่ายเหมือนกับการมีสัญลักษณ์แสดงหัวข้อย่อยของรายการสีที่แตกต่างจากข้อความ จะต้องตัดเนื้อหาของรายการในช่วงเวลาหนึ่ง (หรือใช้รูปภาพสำหรับเครื่องหมาย)
ul { color: #00b7a8; } ul span { color #333; }
ด้วยองค์ประกอบหลอก ::marker
สิ่งที่ง่ายที่สุดที่คุณอาจต้องการลองคือการมีสัญลักษณ์แสดงหัวข้อย่อยเป็นสีข้อความที่แตกต่างกัน ซึ่งหมายความว่าคุณสามารถใช้แทนโค้ดในตัวอย่างด้านบน:
ul { color: #333; } ul ::marker { color: #00b7a8; }
คุณอาจต้องการใช้ขนาดและ font-family
ที่แตกต่างกันสำหรับการกำหนดหมายเลขในรายการที่สั่งซื้อ
ol ::marker { font-size: 200%; color: #00b7a8; font-family: "Comic Sans MS", cursive, sans-serif; }
คุณสามารถดูสิ่งเหล่านี้ได้ในเบราว์เซอร์ที่รองรับโดยใช้ตัวอย่าง CodePen ของฉัน:
คุณสามารถใช้ ::marker
pseudo-element กับรายการที่ไม่ใช่รายการ ในโค้ดด้านล่าง ฉันได้ตั้งค่าหัวเรื่องให้ display: list-item
ซึ่งจะทำให้เป็นสัญลักษณ์แสดงหัวข้อย่อยและด้วยเหตุนี้กล่อง ::marker
เพื่อกำหนดเป้าหมาย
ฉันได้เปลี่ยนสัญลักษณ์แสดงหัวข้อย่อยเพื่อใช้อีโมจิ:
h1 { display: list-item; } h1::marker { content: ""; }
ในตัวอย่างข้างต้น ฉันได้ใช้เนื้อหาที่สร้างขึ้นในกฎสำหรับเครื่องหมาย คุณสมบัติ CSS บางส่วนเท่านั้นที่สามารถใช้ได้บน ::marker
ซึ่งรวมถึงคุณสมบัติแบบอักษรและสี อย่างไรก็ตาม ยังรวมถึงคุณสมบัติ content
สำหรับการรวมเนื้อหาที่สร้างขึ้น
การเพิ่ม content
เป็นคุณสมบัติที่อนุญาตสำหรับ ::marker
เป็นเรื่องล่าสุด อย่างไรก็ตาม เนื้อหานี้รวมอยู่ในการใช้งาน Firefox การรวมหมายความว่าคุณสามารถทำสิ่งต่าง ๆ เช่นรวมสตริงข้อความใน ::marker
นอกจากนี้ยังเพิ่มความเป็นไปได้เพิ่มเติมสำหรับการจัดรูปแบบของเครื่องหมายเมื่อคุณรวมการใช้ตัวนับกับ ::marker
การสนับสนุนเบราว์เซอร์และการย้อนกลับ
สำหรับเบราว์เซอร์ที่ไม่สนับสนุน ::marker
pseudo-element ทางเลือกคือตัวทำเครื่องหมายปกติที่จะถูกแสดงต่อไป ขออภัย ขณะนี้เราไม่สามารถใช้การสืบค้นข้อมูลคุณลักษณะเพื่อตรวจหาการสนับสนุนสำหรับตัวเลือก เช่น องค์ประกอบเทียมนี้ได้ในขณะนี้ แม้ว่าจะมีปัญหาเกิดขึ้นเกี่ยวกับการเพิ่มสิ่งนี้ในข้อกำหนด ซึ่งหมายความว่าคุณไม่สามารถ Fork Code ของคุณเพื่อทำสิ่งหนึ่งเมื่อคุณได้รับการสนับสนุนและทำอย่างอื่นหากคุณทำไม่ได้ ในกรณีส่วนใหญ่ การถอยกลับไปที่เครื่องหมายปกติจะเป็นวิธีแก้ปัญหาที่สมเหตุสมผล
เคาน์เตอร์
รายการที่สั่งซื้อมีการกำหนดหมายเลขรายการ — สิ่งที่ทำได้โดยใช้ตัวนับ CSS ดังนั้นข้อกำหนดรายการ CSS จึงอธิบายตัวนับเหล่านี้ด้วย เราสามารถเข้าถึงและสร้างตัวนับได้เอง ซึ่งเมื่อรวมกับ ::marker
pseudo-element จะทำให้เรามีฟังก์ชันที่มีประโยชน์บางอย่าง ตัวนับเหล่านี้ยังสามารถใช้ในเนื้อหาที่สร้างปกติ (ไม่ใช่ ::marker
)
หากฉันมีรายการขั้นตอนที่เป็นตัวเลข (และฉันต้องการเขียน "ขั้นตอนที่ 1", "ขั้นตอนที่ 2" เป็นต้น) ฉันสามารถทำได้โดยใช้เนื้อหาที่สร้างขึ้นในเครื่องหมายของฉันและต่อท้ายตัวนับ list-item
นี่แสดงถึงตัวนับในตัว:
::marker { content: "Step " counter(list-item) ": "; }
เคาน์เตอร์ซ้อน
หากคุณมีรายการที่ซ้อนกัน วิธีทั่วไปในการกำหนดหมายเลขคือให้รายการระดับบนสุดเป็นจำนวนเต็ม (1) จากนั้นรายการย่อยเป็น (1.1, 1.2) และรายการย่อย (1.1.1, 1.1.2) และอื่นๆ คุณสามารถทำสิ่งนี้ได้โดยใช้ฟังก์ชันเพิ่มเติมของตัวนับ
เมื่อคุณซ้อนรายการ HTML คุณจะลงเอยด้วยตัวนับหลายตัวที่มีชื่อเดียวกัน — ซ้อนอยู่ภายในกันและกัน สามารถเข้าถึงรังของตัวนับได้โดยใช้ฟังก์ชัน counters()
ในโค้ดด้านล่าง ฉันกำลังใช้ counters()
เพื่อจัดรูปแบบตัวทำเครื่องหมายรายการตามที่อธิบายไว้ข้างต้น อาร์กิวเมนต์แรกสำหรับ counters()
คือชื่อของตัวนับที่จะใช้ ฉันกำลังใช้ตัวนับ list-item
ในตัว อาร์กิวเมนต์ที่สองคือสตริง — นี่คือสิ่งที่จะต่อกันระหว่างตัวนับเอาต์พุต (ฉันใช้ a .
) สุดท้าย ฉันเพิ่ม a :
นอกฟังก์ชันตัวนับ แต่อยู่ภายในค่าของ content
เพื่อที่ผลลัพธ์ตัวนับของฉันจะถูกแยกออกจากเนื้อหาด้วยเครื่องหมายทวิภาค
::marker { content: counters(list-item,'.') ':'; color: #00b7a8; font-weight: bold; }
สิ่งนี้ให้ผลลัพธ์เหมือนในภาพ หากคุณกำลังใช้เบราว์เซอร์ที่รองรับ ::marker
และตัวนับ คุณจะเห็นว่ามันทำงานในตัวอย่าง CodePen ลองเปลี่ยนสตริงจากไฟล์ .
อย่างอื่นเพื่อดูว่าผลลัพธ์นั้นเปลี่ยนแปลงไปอย่างไร
ความแตกต่างระหว่างตัว counter()
และ counters()
คืออะไร
ฟังก์ชันตัว counter()
ที่เราใช้ในตัวอย่างแรกเพื่อเขียนขั้นตอนของเรานั้นใช้ตัวนับในสุดเท่านั้น ดังนั้น ในสถานการณ์ที่คุณมีชุดของรายการที่ซ้อนกัน คุณจะเขียนตัวนับที่เกี่ยวข้องกับระดับที่คุณอยู่ในขณะนี้
ฟังก์ชัน counters()
จะเขียนทั้งสาขานั้นโดยพื้นฐานแล้ว และเปิดโอกาสให้คุณเชื่อมสตริงระหว่างตัวนับในสาขา ดังนั้นหากคุณมีรายการที่มีตัวนับ 2
(ซึ่งเป็นส่วนหนึ่งของรายการที่ซ้อนอยู่ภายในรายการที่มีตัวนับ 4
) สาขาจะมี:
-
4
-
2
คุณสามารถส่งออกสิ่งนี้เป็น 4.2
ในตัวทำเครื่องหมายโดยใช้:
::marker { content: counters(list-item,'.'); }
เคาน์เตอร์ในองค์ประกอบอื่นๆ
ตัวนับสามารถใช้กับสิ่งต่าง ๆ ที่ไม่ใช่รายการ — ไม่ว่าจะเพื่อส่งออกเครื่องหมาย — ในกรณีนี้องค์ประกอบจะต้องมี display: list-item
— หรือเพื่อส่งออกเนื้อหาที่สร้างขึ้นตามปกติ ตัวนับถูกนำมาใช้อย่างแพร่หลายในการผลิตหนังสือ เพื่อให้สามารถนับจำนวนบทและตัวเลขอื่นๆ ได้ ไม่มีเหตุผลใดที่จะไม่ใช้วิธีเดียวกันนี้ในเว็บ โดยเฉพาะสำหรับบทความที่ยาวกว่า
คุณสมบัติ CSS ที่กำหนดไว้ในข้อกำหนดรายการ CSS ซึ่งจัดการกับตัวนับเหล่านี้คือ:
-
counter-set
-
counter-reset
-
counter-increment
เพื่อดูว่าสิ่งเหล่านี้ทำงานอย่างไรนอกรายการ เราสามารถดูตัวอย่างการใช้ตัวนับเพื่อกำหนดหมายเลขหัวเรื่องในเอกสาร
สิ่งแรกที่ฉันต้องทำคือสร้างตัวนับสำหรับส่วนหัวขององค์ประกอบร่างกาย - พร้อมใช้งาน ฉันใช้คุณสมบัติ counter-reset
เพื่อทำสิ่งนี้ คุณสมบัติ counter-reset
counter-set
มีความคล้ายคลึงกันมาก คุณสมบัติ counter-reset
จะสร้างตัวนับใหม่หากไม่มีตัวนับของชื่อที่ระบุ แต่จะสร้างตัวนับที่ซ้อนกันตามที่อธิบายไว้ข้างต้นหากมีตัวนับของชื่อนั้นอยู่ คุณสมบัติ counter-set
จะสร้างตัวนับใหม่ก็ต่อเมื่อไม่มีตัวนับของชื่อนั้น สำหรับสิ่งนี้ ใช้คุณสมบัติอย่างใดอย่างหนึ่งก็ใช้ได้ดี อย่างไรก็ตาม counter-set
ไม่มีการสนับสนุนเบราว์เซอร์ที่ดีเท่ากับ counter-reset
ดังนั้นฉันจึงใช้เส้นทางที่ใช้งานได้จริง:
body { counter-reset: heading-counter; }
ตอนนี้ฉันมีตัวนับแล้ว ฉันสามารถใช้คุณสมบัติ counter-increment
บนตัวเลือกสำหรับส่วนหัวได้ สิ่งนี้ควรเพิ่มตัวนับทุกครั้งที่ตัวเลือกตรงกัน
h2 { counter-increment: heading-counter; }
หากต้องการดูค่า ฉันต้องส่งออกไปยังเอกสาร ฉันสามารถทำได้โดยใช้เนื้อหาที่สร้างแล้วเพิ่ม before
ส่วนหัวตามที่แสดงในตัวอย่าง CodePen ต่อไปนี้:
h2::before { content: counter(heading-counter) ": "; color: #00b7a8; font-weight: bold; }
อีกทางหนึ่ง ฉันสามารถทำให้องค์ประกอบ h2
เป็น list-item
แล้วใช้ ::marker
ดังที่แสดงด้านล่าง ตามรายละเอียดแล้ว การใช้องค์ประกอบ ::marker
มีการรองรับเบราว์เซอร์ที่จำกัด ใน Firefox คุณควรเห็นตัวนับที่ใช้เป็นเครื่องหมายสำหรับส่วนหัว ในขณะที่เบราว์เซอร์อื่นๆ จะแสดงสัญลักษณ์แสดงหัวข้อย่อยเริ่มต้น
h2 { display: list-item; } h2::marker { content: counter(heading-counter) ": "; color: #00b7a8; font-weight: bold; }
เคาน์เตอร์บนองค์ประกอบแบบฟอร์ม
นอกจากนี้ยังมีการโต้ตอบเล็กน้อยที่คุณสามารถทำได้โดยใช้ CSS Counters ซึ่งเป็นสิ่งที่คุณอาจคิดว่าจำเป็นต้องใช้ JavaScript
ฉันมีแบบฟอร์มที่มีช่องที่ต้องกรอกหลายช่อง สถานะที่ต้องการสามารถเลือกได้ใน CSS ด้วย :required
pseudo-class และข้อเท็จจริงที่ว่าฟิลด์ที่ยังไม่เสร็จสมบูรณ์สามารถตรวจพบได้โดยใช้คลาส :invalid
pseudo ซึ่งหมายความว่าเราสามารถตรวจสอบช่องที่ทั้งจำเป็นและไม่ถูกต้อง และเพิ่มตัวนับได้ จากนั้นส่งออกว่าเป็นเนื้อหาที่สร้างขึ้น
ความจริงแล้วสิ่งนี้มีประโยชน์เพียงใดเป็นที่ถกเถียงกัน เนื่องจากเราไม่สามารถทำอะไรกับคุณค่านั้นได้นอกจากติดมันในเนื้อหาที่สร้างขึ้น นอกจากนี้ยังมีข้อกังวลเกี่ยวกับเนื้อหาที่สร้างขึ้นซึ่งไม่สามารถเข้าถึงได้สำหรับโปรแกรมอ่านหน้าจอบางตัว ดังนั้นการใช้งานใดๆ ที่มากกว่าการตกแต่งจะต้องทำให้แน่ใจถึงวิธีอื่นๆ ในการเข้าถึงข้อมูลนั้น อ่าน "การสนับสนุนการเข้าถึงสำหรับเนื้อหาที่สร้าง CSS" และข้อมูลล่าสุด "ความเข้ากันได้ของตัวอ่านหน้าจอคุณสมบัติเนื้อหา CSS" สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการเข้าถึงและเนื้อหาที่สร้างขึ้น
อย่างไรก็ตาม มันแสดงให้เห็นว่าตัวนับสามารถบรรลุสิ่งที่มีประโยชน์มากกว่าเพียงแค่การนับรายการ อาจเป็นไปได้ว่าวันหนึ่งความรู้จะมีประโยชน์ในการแก้ปัญหาบางอย่างที่คุณกำลังดำเนินการอยู่
หาข้อมูลเพิ่มเติม
บทความนี้จบลงค่อนข้างไกลจากรายการสไตล์ แม้ว่าจะพบทุกสิ่งที่ฉันอธิบายไว้ในข้อกำหนดรายการ CSS คุณสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับสิ่งต่างๆ ที่อธิบายไว้ในลิงก์ด้านล่าง หากคุณพบการใช้งานที่น่าสนใจสำหรับ CSS Counters หรือสามารถคิดเกี่ยวกับสิ่งที่คุณสามารถใช้ ::marker
ให้เพิ่มหมายเหตุในความคิดเห็น
-
::marker
-
counter-set
-
counter-reset
-
counter-increment
- “การใช้ CSS Counters,” MDN web docs
- “การนับด้วย CSS Counters และ CSS Grid,” CSS-Tricks