深入研究 CSS 文本換行
今天來研究一下 CSS 中的文本換行。正常情況下,在固定寬度的盒子中的中文會自動換行。但是,當遇到非常長的英文單詞或者很長的URL時,文本可能就不會自動換行,而會溢出所在容器。幸運的是,CSS 為我們提供了一些和文本換行相關(guān)的屬性;
- overflow-wrap
- word-break
- white-space
- line-break
- hyphens
1. overflow-wrap
overflow-wrap 用來說明當一個不能被分開的字符串太長而不能填充其包裹盒時,為防止其溢出,瀏覽器是否允許這樣的單詞中斷換行。其屬性值有以下三種:
overflow-wrap: normal;
overflow-wrap: anywhere;
overflow-wrap: break-word;
(1)normal
屬性值為 normal 將使瀏覽器使用系統(tǒng)的默認換行行為。因此,對于英語和其他相關(guān)書寫系統(tǒng),換行符將出現(xiàn)在空格和連字符處。
從圖中可以看出,段落中有一個很長的單詞溢出了容器,這是系統(tǒng)的默認換行行為。
(2)anywhere
使用值 anywhere 將在字符串之間的任意點來進行中斷,僅當在其行上顯示單詞會導致溢出時,瀏覽器才會中斷該單詞。如果單詞放在其行上時仍然溢出,它將在發(fā)生溢出的點處中斷該單詞。
可以看到,使用 overflow-wrap:anywhere 將溢出的單詞分解成文本塊,這樣就可以將其放入容器中。這里文本所在的容器寬度是固定的。
該屬性會影響其所在元素的 min-content 屬性大小計算。當width設置為min-content時很容易看出來:
.break-word {
width: min-content;
overflow-wrap: break-word;
}
.anywhere {
width: min-content;
overflow-wrap: anywhere;
}
效果如下:
可以看到,帶有overflow-wrap:break-word 的元素計算出的 min-content 就像單詞沒有被破壞一樣,因此它的寬度變成了最長單詞的寬度。而帶有 overflow-wrap:anywhere 的元素,由于在任何地方都可能發(fā)生中斷,因此 min-content 最終成為單個字符的寬度。
注意,這種行為只有為文本所在容器的寬度設置為min-content時才會發(fā)揮作用,如果寬度設置為固定的值,那么anywhere 和 break-word 的表現(xiàn)是一致的。
另外需要注意,目前有些瀏覽器不支持該屬性:
(3)break-word
break-word 屬性表示如果行內(nèi)沒有多余的地方容納該單詞到結(jié)尾,則那些正常的不能被分割的單詞會被強制分割換行。
可以看到,文本在長單詞的某個地方自動換行了。如果文本所在容器設置了固定的寬度,就會在長單詞溢出的地方換行。
(4)瀏覽器兼容性
overflow-wrap 屬性就是原來的word-wrap。word-wrap最初是一個沒有前綴的Microsoft擴展。它不是CSS標準的一部分,盡管大多數(shù)瀏覽器都使用word-wrap這個名稱來實現(xiàn)它。根據(jù)CSS3規(guī)范草案,瀏覽器應將word-wrap視為overflow-wrap屬性的遺留名稱別名,以確保兼容性。
2. word-break
word-break 屬性用于指定怎樣在單詞內(nèi)進行斷行。我們可以使用該屬性在內(nèi)容發(fā)生溢出的確切位置拆分單詞并將其換行到下一行。下面是 word-break的屬性值:
word-break: normal;
word-break: break-all;
word-break: keep-all;
word-break: break-word;
需要注意,break-word 屬性值已經(jīng)被棄用,但是由于遺留原因,瀏覽器仍然支持它。指定該屬性與同時使用word-break: normal 和 overflow-wrap: anywhere 的效果是一樣的。
下面就來看看前三個屬性:
(1)normal
將 word-break 屬性的值設置為 normal 將應用默認的斷行規(guī)則:
可以看到,設置為 normal 時,和不設置word-break時的效果是一樣的,這就是瀏覽器默認的斷行行為。
(2)break-all
當屬性值為 break-all 時,對于 non-CJK (CJK 指中文/日文/韓文) 的文本,可在任意字符間斷行。
可以看到,長單詞在溢出的位置將剩余的文本進行了換行。使用 break-all 將在英語和其他相關(guān)語言系統(tǒng)中發(fā)生溢出的確切位置在兩個字符之間斷開一個單詞。但是,它不會對中文、日文和韓文文本應用相同的行為。因為 CJK 書寫系統(tǒng)有自己的應用斷點規(guī)則。
(3)keep-all
如果使用值 keep-all,即使內(nèi)容溢出,瀏覽器也不會將分詞應用于 CJK 文本。應用 keep-all 值的效果與非 CJK 書寫系統(tǒng)的正常效果相同。簡單來說就是,像英語這種 CJK 文本不會斷行,像中文這種 Non-CJK 文本表現(xiàn)同 normal。
(4)瀏覽器兼容性
3. white-space
white-space 屬性是用來設置如何處理元素中的空白。其屬性值如下:
white-space: normal;
white-space: nowrap;
white-space: pre;
white-space: pre-wrap;
white-space: pre-line
下面來看看這些屬性值都有哪些作用。
(1)nowrap
當我們將white-space的值設置為 nowrap 時,可以防止文本自動換行:
可以看到,這里文本并沒有換行,這時文本會在同一行上繼續(xù),直到遇到
標簽為止。
(2)pre
當我們將white-space的值設置為pre時,文本之間的空白會被瀏覽器保留。其行為方式類似 HTML 中的
標簽。
<!-- 這個HTML的格式會導致額外的空白 -->
<p>
What's worse, ignorance or apathy?
I don't know and I don't care.
</p>
<p>What's worse, ignorance or apathy?
I don't know and I don't care.</p>
<pre>What's worse, ignorance or apathy?
I don't know and I don't care.</pre>
樣式設置如下:
p {
white-space: pre;
}
pre {
/* <pre> 會設置 font-family: monospace, 這里將其重置 */
font-family: inherit;
}
顯示效果如下:
(3)瀏覽器兼容性
4. line-break
line-break屬性可以用來處理如何斷開帶有標點符號的中文、日文或韓文文本的行。簡而言之,該屬性可以用來處理過長的標點符號。
(1)anywhere
可以使用 line-break: anywhere 來使長標點符號進行換行:
可以看到,overflow-wrap: break-word 和 line-break:anywhere 能夠保持內(nèi)容被包含在容器內(nèi),但是 word-break: break-all 在有長標點符號時就會發(fā)生溢出。
(2)瀏覽器兼容性
5.hyphens
hyphens 屬性告知瀏覽器在換行時如何使用連字符連接單詞。可以完全阻止使用連字符,也可以控制瀏覽器什么時候使用,或者讓瀏覽器決定什么時候使用。其斷字規(guī)則由語言決定,因此需要告訴瀏覽器使用哪種語言。這是通過在 HTML 中指定lang屬性來完成的:
<p lang="en">This is just a bit of arbitrary text to show hyphenation in action.</p>
(1)auto
當 hyphens 設置為 auto 時,瀏覽器可以自由地在適當?shù)臄嘧贮c自動斷詞:
p {
-webkit-hyphens: auto; / * 用于 Safari */
hyphens: auto;
}
顯示效果如下:
(2)瀏覽器兼容性
6. 總結(jié)
- 當文本所在容器的寬度固定時,可以使用 overflow-wrap: break-word; 和 overflow-wrap: anywhere; 來實現(xiàn)文本的自動換行;如果容器寬度為 min-content,就只能使用 overflow-wrap: break-word; 實現(xiàn)文本換行;overflow-wrap: break-word;也可以用于長標點符號的換行。
- word-break: break-all; 可以用于文本換行,但是該屬性不能使長標點符號換行;
- white-space: nowrap; 可以用于防止文本自動換行;
- line-break: anywhere 可以用于將長標點符號進行換行;
- hyphens: auto; 可以用于使用連字符連接單詞。
參考:
https://codersblock.com/blog/deep-dive-into-text-wrapping-and-word-breaking/
https://blog.logrocket.com/guide-word-wrap-overflow-wrap-word-break-css/