盤(pán)點(diǎn)CSS文本兩端對(duì)齊的N種方式
介紹一個(gè)你可能見(jiàn)過(guò)的文本兩端布局(也可以叫文本均等分布),如下:
說(shuō)難不難,說(shuō)簡(jiǎn)單也不簡(jiǎn)單。這里盤(pán)點(diǎn)了多種實(shí)現(xiàn)該布局的方式,看看你都知道哪些吧~
一、加空格
很多人從直覺(jué)上會(huì)加空格,從視覺(jué)上達(dá)到文本兩端對(duì)齊的效果,也是比較符合直覺(jué)的,例如像這樣。
<ul class="demo">
<li>技 術(shù) 部</li>
<li>體驗(yàn)設(shè)計(jì)部</li>
<li>行 政 部</li>
</ul>
但是直接加空格沒(méi)啥效果,因?yàn)槟J(rèn)情況下空格會(huì)合并。
如果不想合并,可以用white-space來(lái)改變這種行為。
li{
white-space: pre;
}
這樣,無(wú)論敲多少個(gè)空格,都會(huì)原封不動(dòng)保留下來(lái)。
這樣就得到了一種“近似”的兩端對(duì)齊效果。
除了用white-space改變以外,還可以用 來(lái)輸入“實(shí)體”空格。
<ul>
<li>技 術(shù) 部</li>
<li>體驗(yàn)設(shè)計(jì)部</li>
<li>行 政 部</li>
</ul>
也能得到類(lèi)似的效果。
二、加標(biāo)簽
上面的實(shí)現(xiàn)其實(shí)只是“近似”的,并不能完美對(duì)齊,如下:
很明顯還是差了點(diǎn)。
不過(guò)可以換一種思路,因?yàn)榭崭癫⒉荒芎芎玫拿枋鲆粋€(gè)中文字符的寬度,無(wú)論多少個(gè)空格,總是有點(diǎn)差距的,所以這里可以手動(dòng)加一個(gè)空標(biāo)簽。
<ul>
<li>技<span></span>術(shù)<span></span>部</li>
<li>體驗(yàn)設(shè)計(jì)部</li>
<li>行<span></span>政<span></span>部</li>
</ul>
然后,我們給這些標(biāo)簽設(shè)置一個(gè)字符的寬度就好了。
li span{
width: 1em;
}
這樣就能完美對(duì)齊了。
前面這兩種方式其實(shí)都不大推薦,局限性太大,需要手動(dòng)去補(bǔ)全剩余空間,如果字?jǐn)?shù)不一樣,又得手動(dòng)重新計(jì)算了。
下面介紹幾個(gè)實(shí)際更推薦的方式。
三、justify-content: space-between
很多同學(xué)可能都會(huì)想到這種方式,畢竟現(xiàn)在flex布局實(shí)在太普遍了,不過(guò)這只適合具體的元素,不適合純文本,所以需要改造一下,將所有文本拆分成單獨(dú)的標(biāo)簽,類(lèi)似這樣。
<ul>
<li><span>技</span><span>術(shù)</span><span>部</span></li>
<li><span>體</span><span>驗(yàn)</span><span>設(shè)</span><span>計(jì)</span><span>部</span></li>
<li><span>行</span><span>政</span><span>部</span></li>
</ul>
這么多標(biāo)簽,手寫(xiě)太麻煩了,可以在 JS自動(dòng)生成。
txt.split('').map(el => `<span>${el}</span>`).join('')
然后直接利用flex布局的兩端對(duì)齊就可以了。
li{
display: flex;
justify-content: space-between;
}
效果如下:
而且這種適應(yīng)性更好,改變外層寬度,也能做到兩端對(duì)齊。
四、flex:1
利用flex布局,還可以用另一種方式來(lái)實(shí)現(xiàn)。
我們可以在每個(gè)字符中間都添加一個(gè)空標(biāo)簽,然后讓這些空標(biāo)簽自動(dòng)分配剩余空間,這樣不就實(shí)現(xiàn)文本兩端對(duì)齊了嗎?
<ul>
<li>技<span></span>術(shù)<span></span>部</li>
<li>體<span></span>驗(yàn)<span></span>設(shè)<span></span>計(jì)<span></span>部</li>
<li>行<span></span>政<span></span>部</li>
</ul>
同樣可以用JS來(lái)生成,相比上一種方式更容易。
txt.split('').join('<span></span>')
然后設(shè)置flex:1。
li{
display: flex;
}
li span{
flex: 1;
}
效果如下:
這兩種方式適應(yīng)性更好,基本可以在實(shí)際生產(chǎn)使用了,不過(guò)需要對(duì)HTML進(jìn)行改造,稍微麻煩點(diǎn),而且看著不夠干凈,畢竟都是空標(biāo)簽,沒(méi)有實(shí)際價(jià)值。
下面再介紹兩個(gè)不需要改變HTML的方式。
五、text-align: justify
文本對(duì)齊方式中天然就有一個(gè)兩端對(duì)齊的方式,叫做justify,但是這種方式不包括最后一行。
由于不支持最后一行,所以對(duì)于單行文本,這種對(duì)齊方式自然也就失效了。
既然不支持單行文本,我們可以手動(dòng)讓“單行”變成“多行”,具體做法其實(shí)也很簡(jiǎn)單,用一個(gè)偽元素,強(qiáng)制換行就可以了,具體實(shí)現(xiàn)如下:
li::after{
content: '';
display: inline-block;
width: 100%;
}
這樣在設(shè)置text-align: justify時(shí),原本的第一行就不再是最后一行了,自然也就生效了。
li{
text-align: justify;
}
效果如下:
不過(guò)由于換行的關(guān)系,導(dǎo)致整體高度要比以前高出一部分,所以這種方式需要手動(dòng)限制一個(gè)高度。
li{
text-align: justify;
height: 24px;
line-height: 24px;
}
這樣就完美實(shí)現(xiàn)了。
另外,在 MDN文檔上還看到這樣一個(gè)屬性值justify-all,可以滿足我們的需求。
不過(guò)現(xiàn)在還沒(méi)有任何瀏覽器支持。
六、text-align-last: justify
CSS中還有一個(gè)專(zhuān)門(mén)適用于最后一行文本的對(duì)齊方式,叫做text-align-last,剛好可以滿足這個(gè)場(chǎng)景。所以我們可以在HTML不做任何修改的情況下,設(shè)置最后一行文本兩端對(duì)齊就可以了。
li{
text-align-last: justify;
}
效果如下:
這應(yīng)該是最完美的方式了,不過(guò)兼容性稍微差點(diǎn),又是Safari脫了后腿。
七、SVG 中的lengthAdjust
除了以上CSS的各種方式外,SVG中也可以實(shí)現(xiàn)類(lèi)似這樣的文本兩端對(duì)齊,需要用到lengthAdjust屬性。
這個(gè)屬性有兩個(gè)值,一個(gè)是spacing,表示剩余空間自動(dòng)填充,另一個(gè)是spacingAndGlyphs,表示會(huì)讓字符自動(dòng)壓縮或拉伸來(lái)適配整個(gè)文本長(zhǎng)度(textLength)。
<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<g font-face="sans-serif">
<text x="0" y="20" textLength="300" lengthAdjust="spacing">
Stretched using spacing only.
</text>
<text x="0" y="50" textLength="300" lengthAdjust="spacingAndGlyphs">
Stretched using spacing and glyphs.
</text>
<text x="0" y="80" textLength="100" lengthAdjust="spacing">
Shrunk using spacing only.
</text>
<text x="0" y="110" textLength="100" lengthAdjust="spacingAndGlyphs">
Shrunk using spacing and glyphs.
</text>
</g>
</svg>
效果如下:
我們也可以用這種對(duì)齊方式來(lái)實(shí)現(xiàn)我們想要的效果。
八、總結(jié)和說(shuō)明
以上共介紹了7種方式來(lái)實(shí)現(xiàn)文本兩端對(duì)齊,完整 demo 可以查看以下鏈接。
- CSS text justify (juejin.cn)[1]
除此之外,你還知道哪些方式呢?歡迎留言討論,下面總結(jié)一下。
- 加空格的方式比較符合直覺(jué),但是只能達(dá)到近似的對(duì)齊效果。
- 加標(biāo)簽可以實(shí)現(xiàn)精準(zhǔn)對(duì)齊,但是是純手動(dòng),而且和文字字?jǐn)?shù)也有關(guān)系。
- flex布局的兩端對(duì)齊需要給每個(gè)文字套上一個(gè)標(biāo)簽。
- 也可以在每個(gè)文字之間加上一個(gè)空標(biāo)簽,設(shè)置自動(dòng)填充。
- text-align: justify可以實(shí)現(xiàn)文本兩端對(duì)齊,但是不包括最后一行。
- 借助偽元素?fù)Q行,可以手動(dòng)將原本的最后一行變成非最后一行。
- text-align-last: justify可以最完美的實(shí)現(xiàn)這個(gè)效果,不過(guò)兼容性欠佳。
- SVG中的lengthAdjust也能實(shí)現(xiàn)類(lèi)似的對(duì)齊效果。
資訊一下,如果面試(5年內(nèi))出這樣一道題,你們覺(jué)得難嗎?
[1]CSS text justify (juejin.cn): https://code.juejin.cn/pen/7399192945481482290