CSS 筆記 - 客製自動跳號格式
2 |
這篇筆記技術成分不高,主要是自己備忘用的。如果你已知道(或是完全不想知道)怎麼在網頁用 <ol> <li> 配 CSS 做出如下圖的 1) 2)、3.1、3.2,請略過本文。
寫了十幾年網頁,前陣子才遇到這個需求。條文資料分兩層 <ol> <li>,第一層用 1. 2. 3.,第二層要顯示成 1) 2) 3)。若是 Word 文件我知道怎麼做,在網頁做倒是第一次。
爬了文章,MDN Web Docs 有說明與範例 ,主要原理是利用 counter-reset: counterVarName; 重設計數器,在 <li> 宣告 counter-increment: counterVarName; 自動跳號、content: counter(section) ". "; 指定呈現格式。
-
-
- 案例我在第二層 <ol> 加了 class="sub",然後用 li::marker 將跳號格式設為 content: counter(count) ') '; :Live Demo
-
<!DOCTYPE html>
<html>
<head>
<style>
ol.sub {
padding-left: 20px;
padding-inline-start: 20px;
counter-reset: count;
}
ol.sub li {
counter-increment: count;
}
ol.sub li::marker {
content: counter(count) ') ';
}
</style>
</head>
<body>
<ol>
<li>First</li>
<li>Second</li>
<li>
Third
<ol class="sub">
<li>Sub-First, Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Aliquam mattis mauris et elit luctus,
at condimentum odio rhoncus.</li>
<li>Sub-Second</li>
</ol>
</li>
<li>Forth</li>
<li>Fifth</li>
</ol>
</body>
這個寫法在 Chrome 顯示很完美,可是瑞凡,IE 他X的不支援 ::marker 偽元素啊....
替代寫法是用 libefore 取代 limarker,並用 list-style-type: none 取消內建跳號,但 li 文字如有多行,跟數字會靠左對齊,不符合慣例,肯定要被客戶挑剔: (內心 OS: 大家都別用 IE 了好嗎?放過 IE 也放過自己...)
最後我試著將 li::before 設成 postion: absolute + margin-left: -1.2em,得到可接受的結果: Live Demo
<!DOCTYPE html>
<html>
<head>
<style>
ol.sub {
padding-left: 1.5em;
padding-inline-start: 1.5em;
counter-reset: count;
}
ol.sub li {
counter-increment: count;
list-style-type: none;
}
ol.sub li::before {
content: counter(count) ') ';
position: absolute;
margin-left: -1.2em;
}
</style>
</head>
<body>
<ol>
<li>First</li>
<li>Second</li>
<li>
Third
<ol class="sub">
<li>Sub-First, Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Aliquam mattis mauris et elit luctus,
at condimentum odio rhoncus.</li>
<li>Sub-Second</li>
</ol>
</li>
<li>Forth</li>
<li>Fifth</li>
</ol>
</body>
IE 跟 Chrome 檢視都 OK。
多層跳號還有一個花式用法:content: counters(count, '.') ' ' 配多層 <ol> 可做出 3、3.1、3.1.1 的效果。為了支援 IE,我又得含淚放棄好用的 li::marker,改用 li:before + postion: absolute + margin-left: 負值算位置。但挑戰來了,3 跟 3.1.1 寬度差很多,若預留放得下 3.1.1 寬度,對 3 及 3.1 會留白過多,像以下這樣:
最後我想到的解法是在第二、三層 <ol> 加上 class="l2" / class="l3" (或者不加 class,靠 ol ol、ol ol ol 選擇器自動識別也可以),再指定不同 padding-left 及 margin-left:Live Demo
<!DOCTYPE html>
<html>
<head>
<style>
ol {
padding-left: 1.2m;
padding-inline-start: 1.2em;
counter-reset: count;
}
li {
counter-increment: count;
list-style-type: none;
}
li::before {
content: counters(count, '.') ' ';
display: block;
position: absolute;
margin-left: -1.2em;
}
ol.l2 {
padding-left: 2em;
padding-inline-start: 2em;
}
.l2 li::before {
margin-left: -2em;
}
ol.l3 {
padding-left: 2.8em;
padding-inline-start: 2.8em;
}
.l3 li::before {
margin-left: -2.8em
}
</style>
</head>
<body>
<ol>
<li>First</li>
<li>Second</li>
<li>
Third
<ol class="l2">
<li>Sub-First
<ol class="l3">
<li>Sub-Sub-First Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Aliquam mattis mauris et elit luctus,
at condimentum odio rhoncus.</li>
<li>Sub-Sub-Second</li>
</ol>
</li>
<li>Sub-Second</li>
</ol>
</li>
<li>Forth</li>
<li>Fifth</li>
</ol>
</body>
</html>
逐層設 class 及指定 margin-left、padding-left 的寫法有點笨拙,但看起來還堪用就是了。
大家如果知道其他巧妙解法,歡迎分享給我。
[2020-12-19 更新] 在專頁貼文後,讀者 Kei Cheng 分享了他的 CSS Framework - Kule Lazy 4,從中我偷學到改用 table-row、table-cell 解決 3、3.1、3.1.1 的對齊問題,比原本為各層設定不同 margin-left、padding-left 的寫法簡潔許多: Live Demo
<!DOCTYPE html>
<html>
<head>
<style>
ol {
counter-reset: count;
padding-left: 0;
}
li {
counter-increment: count;
list-style-type: none;
display: table-row;
}
li::before {
content: counters(count, '.') ' ';
display: table-cell;
min-width: 2.5em;
padding-right: 0.25em;
text-align: right;
}
</style>
</head>
<body>
<ol>
<li>First</li>
<li>Second</li>
<li>
Third
<ol>
<li>Sub-First
<ol>
<li>Sub-Sub-First Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Aliquam mattis mauris et elit luctus,
at condimentum odio rhoncus.</li>
<li>Sub-Sub-Second</li>
</ol>
</li>
<li>Sub-Second</li>
</ol>
</li>
<li>Forth</li>
<li>Fifth</li>
</ol>
</body>
最後補充一些花式技巧:
Examples of customizing LI counter format with CSS styles.
Comments
# by null
現在應該可以不用管 IE 了吧?都要廢棄了。
# by Jeffrey
to null, 看情況,如果你網站用戶都來自 Internet,現在已經可以放生 IE 了,但 IE 在企業內網估計還會再戰十年。https://blog.darkthread.net/blog/is-ie-dead/