聊聊 CSS 中文字的換行問題

正常情況下,在固定寬度的盒子中的中文會自動換行。但是,當遇到非常長的英文單詞或者很長的 URL 時,文本可能就不會自動換行,而會溢出所在容器。幸運的是,CSS 爲我們提供了一些和文本換行相關的屬性;

  1. overflow-wrap

overflow-wrap 用來說明當一個不能被分開的字符串太長而不能填充其包裹盒時,爲防止其溢出,瀏覽器是否允許這樣的單詞中斷換行。其屬性值有以下三種:

overflow-wrap: normal;
overflow-wrap: anywhere;
overflow-wrap: break-word;

(1)normal

屬性值爲 normal 將使瀏覽器使用系統的默認換行行爲。因此,對於英語和其他相關書寫系統,換行符將出現在空格和連字符處。

從圖中可以看出,段落中有一個很長的單詞溢出了容器,這是系統的默認換行行爲。

(2)anywhere

使用值 anywhere 將在字符串之間的任意點來進行中斷,僅當在其行上顯示單詞會導致溢出時,瀏覽器纔會中斷該單詞。如果單詞放在其行上時仍然溢出,它將在發生溢出的點處中斷該單詞。

可以看到,使用 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 的元素,由於在任何地方都可能發生中斷,因此 min-content 最終成爲單個字符的寬度。

注意,這種行爲只有爲文本所在容器的寬度設置爲min-content時纔會發揮作用,如果寬度設置爲固定的值,那麼anywherebreak-word 的表現是一致的。

另外需要注意,目前有些瀏覽器不支持該屬性:

(3)break-word

break-word 屬性表示如果行內沒有多餘的地方容納該單詞到結尾,則那些正常的不能被分割的單詞會被強制分割換行。

可以看到,文本在長單詞的某個地方自動換行了。如果文本所在容器設置了固定的寬度,就會在長單詞溢出的地方換行。

(4)瀏覽器兼容性

overflow-wrap 屬性就是原來的word-wrapword-wrap最初是一個沒有前綴的 Microsoft 擴展。它不是 CSS 標準的一部分,儘管大多數瀏覽器都使用 word-wrap 這個名稱來實現它。根據 CSS3 規範草案,瀏覽器應將word-wrap視爲overflow-wrap屬性的遺留名稱別名,以確保兼容性。

  1. word-break

word-break 屬性用於指定怎樣在單詞內進行斷行。我們可以使用該屬性在內容發生溢出的確切位置拆分單詞並將其換行到下一行。下面是 word-break的屬性值:

word-break: normal;
word-break: break-all;
word-break: keep-all;
word-break: break-word;

需要注意,break-word 屬性值已經被棄用,但是由於遺留原因,瀏覽器仍然支持它。指定該屬性與同時使用word-break: normaloverflow-wrap: anywhere  的效果是一樣的。

下面就來看看前三個屬性:

(1)normal

word-break 屬性的值設置爲 normal 將應用默認的斷行規則:

可以看到,設置爲 normal 時,和不設置word-break時的效果是一樣的,這就是瀏覽器默認的斷行行爲。

(2)break-all

當屬性值爲 break-all 時,對於 non-CJK (CJK 指中文 / 日文 / 韓文) 的文本,可在任意字符間斷行。

可以看到,長單詞在溢出的位置將剩餘的文本進行了換行。使用 break-all 將在英語和其他相關語言系統中發生溢出的確切位置在兩個字符之間斷開一個單詞。但是,它不會對中文、日文和韓文文本應用相同的行爲。因爲 CJK 書寫系統有自己的應用斷點規則。

(3)keep-all

如果使用值 keep-all,即使內容溢出,瀏覽器也不會將分詞應用於 CJK 文本。應用 keep-all 值的效果與非 CJK 書寫系統的正常效果相同。簡單來說就是,像英語這種 CJK 文本不會斷行,像中文這種 Non-CJK 文本表現同 normal

(4)瀏覽器兼容性

  1. 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 時,可以防止文本自動換行

可以看到,這裏文本並沒有換行,這時文本會在同一行上繼續,直到遇到 <br> 標籤爲止。

(2)pre

當我們將white-space的值設置爲pre時,文本之間的空白會被瀏覽器保留。其行爲方式類似 HTML 中的 <pre> 標籤。

<!-- 這個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>

樣式設置如下:

{
  white-space: pre;
}

pre {
  /* <pre> 會設置 font-family: monospace, 這裏將其重置 */
  font-family: inherit;
}

顯示效果如下:

(3)瀏覽器兼容性

  1. line-break

line-break屬性可以用來處理如何斷開帶有標點符號的中文、日文或韓文文本的行。簡而言之,該屬性可以用來處理過長的標點符號。

(1)anywhere

可以使用 line-break: anywhere 來使長標點符號進行換行:

可以看到,overflow-wrap: break-wordline-break:anywhere 能夠保持內容被包含在容器內,但是 word-break: break-all 在有長標點符號時就會發生溢出。

(2)瀏覽器兼容性

  1. hyphens

hyphens 屬性告知瀏覽器在換行時如何使用連字符連接單詞。可以完全阻止使用連字符,也可以控制瀏覽器什麼時候使用,或者讓瀏覽器決定什麼時候使用。其斷字規則由語言決定,因此需要告訴瀏覽器使用哪種語言。這是通過在 HTML 中指定lang屬性來完成的:

<p lang="en">This is just a bit of arbitrary text to show hyphenation in action.</p>

(1)auto

hyphens 設置爲 auto 時,瀏覽器可以自由地在適當的斷字點自動斷詞:

{
  -webkit-hyphens: auto; / * 用於 Safari */
  hyphens: auto;
}

顯示效果如下:

(2)瀏覽器兼容性

  1. 總結

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/moEHt5kecIgD31a5Sa8szw