純CSS實(shí)現(xiàn)markdown標(biāo)題自動(dòng)編號(hào)

# 問題的由來

第一次關(guān)注這個(gè)標(biāo)題編號(hào)的問題應(yīng)該回溯到本科畢業(yè)論文的時(shí)候了,當(dāng)時(shí)還單獨(dú)涉獵過這個(gè)主題,`Word` 有個(gè)很好的特性`級(jí)聯(lián)標(biāo)題`,一次設(shè)置好之后,后續(xù)只要設(shè)置標(biāo)題樣式就能按照設(shè)置的標(biāo)題編號(hào)方式自動(dòng)編號(hào),我們要做的只是將對(duì)應(yīng)的標(biāo)題設(shè)置成對(duì)應(yīng)基本的標(biāo)題樣式就好了,這個(gè)方法讓我愛不釋手,多年來一直沿用。完全解決了中途插入一章,一節(jié)等等導(dǎo)致的章節(jié)編號(hào)都需要人肉調(diào)整的問題,當(dāng)然還有圖片的編號(hào)命名什么的,都是類似的。

直到后面開始用`markdown` 由于各個(gè)編輯器的切換,一直沒有一個(gè)好用的替代方案,所以幾年前我寫了一個(gè)小工具用命令行來做這事`rawbin-/markdown-clear`,這個(gè)工具解決了在`github`寫博客的問題,同時(shí)在解決博客的問題的基礎(chǔ)上解決了在各個(gè)平臺(tái)發(fā)文的問題,因?yàn)榫幪?hào)是用腳本寫上去的,所以用`markdown here`在各個(gè)平臺(tái)發(fā)文也就順理成章的轉(zhuǎn)成html就行了,也解決了這個(gè)階段的問題。

前兩天把拖欠幾個(gè)月的`全面認(rèn)知`的總結(jié)寫了,突然不想用這個(gè)腳本來編號(hào)了,產(chǎn)生一個(gè)想法:能不能不人肉編號(hào),自動(dòng)編上?然后就有了下面的內(nèi)容。

# 先搞起來解決問題

>>> 以下操作案例都是在macOS中產(chǎn)出,其他平臺(tái)可能有些許差別,換湯不換藥。

## 在`typora`中寫`markdown`自動(dòng)編號(hào)

- 打開`typora`【偏好設(shè)置】

- 找到【外觀】=>【主題】=>【打開主題文件夾】

- 將如下代碼加入到打開目錄的`base.user.css` 中

```css

#writer {

? ? counter-reset: h1

}

h1 {

? ? counter-reset: h2

}

h2 {

? ? counter-reset: h3

}

h3 {

? ? counter-reset: h4

}

h4 {

? ? counter-reset: h5

}

h5 {

? ? counter-reset: h6

}

#writer h1:before {

? ? counter-increment: h1;

? ? content: counter(h1) ". "

}

#writer h2:before {

? ? counter-increment: h2;

? ? content: counter(h1) "." counter(h2) ". "

}

#writer h3:before {

? ? counter-increment: h3;

? ? content: counter(h1) "." counter(h2) "." counter(h3) ". "

}

#writer h4:before {

? ? counter-increment: h4;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "

}

#writer h5:before {

? ? counter-increment: h5;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "

}

#writer h6:before{

? ? counter-increment: h6;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "

}

```

### 講道理

- 打開`typora`【偏好設(shè)置】

- 找到【通用】=>【高級(jí) 】=>【開啟調(diào)試模式】=>勾選

- 然后在非源碼模式下=>【右鍵】=>【檢查元素】,就可以看到為什么是`#write`了

- 這個(gè)后面還有用

## 在`github pages` 寫`markdown`博客自動(dòng)編號(hào)

我用的是`jekyllbootstrap.com`的模板,比較簡(jiǎn)單

- 打開任意一篇`rawbin-.github.io`中的文章,然后【右鍵】=>【檢查】

- 可以拿到兩個(gè)內(nèi)容

? - 容器類為 `.content` ,嚴(yán)格點(diǎn)為`#wrap .content`

? - 樣式文件在`assets/themes/bootstrap3`,可以修改其下的`css/style.css`

- 將如下內(nèi)容改到源代碼的`assets/themes/bootstrap3/css/style.css`中

```css

.content {

? ? counter-reset: h1

}

h1 {

? ? counter-reset: h2

}

h2 {

? ? counter-reset: h3

}

h3 {

? ? counter-reset: h4

}

h4 {

? ? counter-reset: h5

}

h5 {

? ? counter-reset: h6

}

.content h1:before {

? ? counter-increment: h1;

? ? content: counter(h1) ". "

}

.content h2:before {

? ? counter-increment: h2;

? ? content: counter(h1) "." counter(h2) ". "

}

.content h3:before {

? ? counter-increment: h3;

? ? content: counter(h1) "." counter(h2) "." counter(h3) ". "

}

.content h4:before {

? ? counter-increment: h4;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "

}

.content h5:before {

? ? counter-increment: h5;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "

}

.content h6:before{

? ? counter-increment: h6;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "

}

```

## 在其他網(wǎng)頁(yè)編輯中自動(dòng)編碼

比如各個(gè)博客平臺(tái),各個(gè)自媒體平臺(tái)等,像我們常用的寫文檔的語雀都可以的。

這里面涉及到一款瀏覽器插件`markdown here`,可以在頁(yè)面富文本編輯器中將`markdown` 自動(dòng)轉(zhuǎn)換為網(wǎng)頁(yè),這也是我前面說到的這幾年在各個(gè)平臺(tái)發(fā)文的套路,寫好編號(hào)好標(biāo)題`markdown`往編輯器里面一貼,然后一點(diǎn) ,搞定。

### 簡(jiǎn)單嘗試

- `markdown here` 有一個(gè)配置頁(yè)面,可以配置和調(diào)整css,并能預(yù)覽效果

- 簡(jiǎn)單看了下是用`js`把類轉(zhuǎn)成了`style`屬性,并且不支持偽類

### 修改源碼

- 到`adam-p/markdown-here` 看到,已經(jīng)兩年沒動(dòng)代碼了

- 不管三七二十三先 `fork`一把到`rawbin-/markdown-here`,然后把代碼拉下來

- 先把css文件建起來`src/common/auto-number-title`,找容器類可以在`markdown here`的選項(xiàng)頁(yè)面找到`.markdown-here-wrapper`

```css

.markdown-here-wrapper {

? ? counter-reset: h1

}

.markdown-here-wrapper h1 {

? ? counter-reset: h2

}

.markdown-here-wrapper h2 {

? ? counter-reset: h3

}

.markdown-here-wrapper h3 {

? ? counter-reset: h4

}

.markdown-here-wrapper h4 {

? ? counter-reset: h5

}

.markdown-here-wrapper h5 {

? ? counter-reset: h6

}

.markdown-here-wrapper h1:before {

? ? counter-increment: h1;

? ? content: counter(h1) ". "

}

.markdown-here-wrapper h2:before {

? ? counter-increment: h2;

? ? content: counter(h1) "." counter(h2) ". "

}

.markdown-here-wrapper h3:before {

? ? counter-increment: h3;

? ? content: counter(h1) "." counter(h2) "." counter(h3) ". "

}

.markdown-here-wrapper h4:before {

? ? counter-increment: h4;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "

}

.markdown-here-wrapper h5:before {

? ? counter-increment: h5;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "

}

.markdown-here-wrapper h6:before{

? ? counter-increment: h6;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "

}

```

- 然后修改一下注入配置,允許加載這個(gè)樣式文件,并引入這個(gè)樣式問題

- 剩下的有錯(cuò)改錯(cuò)就好了

### 最終產(chǎn)出和應(yīng)用

- 克隆`rawbin-/markdown-here`

- 打開Chrome 設(shè)置三個(gè)點(diǎn)=>【更多工具】=>【擴(kuò)展程序】

- 打開【開發(fā)者模式】

- 選擇【加載已解壓的擴(kuò)展程序】=>選擇克隆代碼下的`src`目錄即可安裝并加載插件

- 將插件固定在插件欄方便使用

- `auto-number-title.scss`內(nèi)容如下

```scss

.markdown-here-wrapper {

? ? counter-reset: h1;

? ? h1 {

? ? ? ? counter-reset: h2;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h1;

? ? ? ? ? ? content: counter(h1) ". ";

? ? ? ? }

? ? }

? ? h2 {

? ? ? ? counter-reset: h3;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h2;

? ? ? ? ? ? content: counter(h1) "." counter(h2) ". "

? ? ? ? }

? ? }

? ? h3 {

? ? ? ? counter-reset: h4;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h3;

? ? ? ? ? ? content: counter(h1) "." counter(h2) "." counter(h3) ". "

? ? ? ? }

? ? }

? ? h4 {

? ? ? ? counter-reset: h5;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h4;

? ? ? ? ? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "

? ? ? ? }

? ? }

? ? h5 {

? ? ? ? counter-reset: h6;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h5;

? ? ? ? ? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "

? ? ? ? }

? ? }

? ? h6:before{

? ? ? ? counter-increment: h6;

? ? ? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "

? ? }

}

```

# 再來簡(jiǎn)單講一下道理

## CSS 自動(dòng)編號(hào)

- 不是一個(gè)新特性,或者說是一個(gè)老特性了,出現(xiàn)在`CSS 2.1`中,搜索`site:w3.org css automatic numbering` 可以找到,當(dāng)然截止今天后來的版本(`CSS 3`, `CSS 2.2`)都有這個(gè)特性,從`caniuse`上可以看到,`IE8`及以上兼容,很棒吧

- 簡(jiǎn)單說明

? - `counter-reset` 重置

? - `counter-increment` ++

? - `counter()` 取值

? - 配合`before`和`after`來做

? - 還有更多的玩法,參見 `CSS The Defiiniitiive Guide 4th` ,這里有翻譯`gdut-yy/CSS-The-Definitive-Guide-4th-zh`

## Chrome插件或擴(kuò)展開發(fā)

- 這個(gè) 我也沒實(shí)際搞過,原來看了看書

- 可參考的資料

? - 官方文檔

? - `sxei/chrome-plugin-demo` 或者搜索`Chrome插件 全攻略`

? - 《Chrome擴(kuò)展及應(yīng)用開發(fā)》,這個(gè)就是我原來看的那本老書

# 還是有些問題沒解決

- 上面的操作方式必須要`h1`到`h6`依次排開,不然會(huì)很好看

- 如果標(biāo)題本身就編號(hào)了的,就有點(diǎn)糟糕了

- 這倆問題在我`github`的博客里面都能看到,解決辦法可以是運(yùn)行下``

## 順便探索下`CSS`其他可變的內(nèi)容

### CSS變量或者說自定義屬性

- 這個(gè)IE不兼容,其他瀏覽器高版本兼容

```

:root{

--var-test:xxx

}

.body{

--var-test:ooo;

prop-test:var(--var-test)

}

```

### attr()

- 這個(gè)`caniuse`也有些說不清楚,主體兼容也是從`IE8`開始的,需要自己總結(jié)

- 強(qiáng)大的地方是可以讀取屬性值,賦給另外的屬性,也就是可以來個(gè)屬性聯(lián)動(dòng)

## 看起來純CSS的解決方案就到此告一段落了

- 如果能有腳本參與,就自由了

- `attr()` 配合偽類來做展示,是一個(gè)JS和CSS通信的一個(gè)比較好的方式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容