我遇到了一個小問題,我有一個 span 在 header 中,而我想要在 span 的前面產生一個換行。鄭重宣告,在 span 前面插入一個 <br>
標籤當然沒問題(而事實上,你還可以顯示/隱藏這個標籤,這非常有用)。但是…不得不用 HTML 去做一個佈局相關的事情始終感覺有點奇怪。
因此,讓我們來深入探索一下,在這個探索中,我們會多次說到“然而…”。
1 2 3 4 5 6 7 8 9 10 11 |
<h1 class="one"> Break right after this <!-- <br> could go here, but can we do it with CSS? --> <span> and before this </span> </h1> |
塊級元素能做到
不同於 <span>
,我們可以使用一個 <div>
,而之所以用 div 可以是因為它是一個塊級元素。
但是我們有使用 span 的理由,因為設計上要求我們用 span。在換行之後的文字應該是一個行內/行內塊元素,因為我們可能想給它一個背景或者 padding 或者其他什麼。
你可以通過偽元素插入換行
這很容易:
1 2 3 |
h1 span::before { content: "\A"; } |
然而… <span>
是一個行內元素。換行不會產生任何效果!就像真正的回車換行一樣不產生。
我們可以通過樣式讓空白符生效,來強制讓換行有效…
1 2 3 4 |
h1.two span::before { content: "\A"; white-space: pre; } |
這樣實際有效果了。然而… 由於 padding 和背景存在,它把左 padding 的部分留在了上一行:
我們可以使用 box-decoration-break: clone;
來修復這個“左邊緣環繞”的問題,然而… 它會導致上一行產生更大的黑塊:(此處不明白的同學可以看這個例子——譯者注)
box-decoration-break 對於處理一些問題來說好極了,但不包括這個問題。
如果我們將 span 變成 inline-block,那麼換行將會發生在那個塊裡面,這也不是我們想要的效果:
將偽元素設定成塊級元素,讓 span 保持行內元素,這樣也不行:
你可能會有點奇怪,為何不直接將實際的文字寫在偽元素裡
這是 Aaron Bushnell 想出的辦法。這個技巧是讓 span 成為塊級元素,然後把文字通過偽元素插入進去,以偽元素作為行內元素新增樣式。
1 2 3 4 5 6 7 8 |
h1 span { display: block; } h1 span::before { content: attr(data-text); background: black; padding: 1px 8px; } |
這樣可以!然而…
我一直是偽元素技巧的簇擁,但是這麼用有點危險,因為你可能破壞了可訪問性。我認為一些讀屏軟體會讀偽元素,但不是所有的都會,也不是所有的都打算支援。更何況這種方式下你不能拷貝和貼上所有的文字,儘管這些文字完整地出現在 HTML 文件裡。
利用 table 佈局
我最喜歡的方式是由 Thierry Koblentz 提出的。只需要給 span 設定 display:table;
就行了。當然這不是真正的表格資料,但沒關係。通過 CSS 將元素強制用 table 佈局以利用 table 佈局獨特的佈局屬性,它唯一的問題僅僅是——不語義化。
1 2 3 |
h1 span { display: table; } |
線上例子
包括使用 <br>
的那個例子,那樣做也是好的。