-Webkit-Box 在 Safari 中出現的兼容性問題(bug?)
本文轉載自微信公眾號「志語自樂」,作者linxz。轉載本文請聯系志語自樂公眾號。
問題來源背景
這個是當時在『iCSS前端CSS交流討論』群中看到的,當時轉為朋友的提問是這樣的:
看這個圖,主要是有兩點:多行截斷和 tag 環繞。多行截斷那就是用 -webkit-box 那種方式,tag 環繞呢那就是早期圖文環繞的方式,用 float 就好了。
理想是豐滿的,現實是骨感的。未經他人之苦,一切都是那么輕松。當我提到說使用 float 就可以實現后,群里有朋友反饋說在 Safari 和移動端會有問題。
事實上我的確也沒在意過,于是事后嘗試了一下,的確如此。
摸索前進
這是一個比較奇怪的現象,首先就我個人而言的確是沒有見到過這樣的情況,之前都沒有這樣類似的需求。
初次嘗試
在沒有查閱任何資料之前,直接做了一個最簡單的 demo 看效果。
- <div class="text-overflow">
- <span class="tag">new</span>
- 很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容
- </div>
一個很簡單的 HTML 結構和一份很簡單的 CSS 樣式。
- .text-overflow {
- width: 200px;
- overflow: hidden;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- font-size: 13px;
- line-height: 1.425;
- background-color: pink;
- }
- .tag {
- float: right;
- padding: 0 2px;
- color: #fff;
- background-color: #f32600;
- border-radius: 2px;
- }
最終的效果就是前面所看到的,在 Chrome 中很完美地得到期望結果,但是 Safari 中發現 tag 不見了,并且有一條空白存在。
按照常規想法,一般這種內容突然不見的,如果不是被截斷了就是被覆蓋了,或者渲染有問題。嘗試性在 .tag 中增加了 position: relative; 看看效果,發現 tag 出現了,并且是獨占一行。
設想
tag 獨占一行,說明至少有類似 block 塊級元素的特性存在,而 float 之后本身就是會將元素轉為塊級。想到這里,突然想到,-webkit-box 這個是早期版本的 flex 布局,那會不會就跟 display: flex; 這個一樣,當有了 flex 容器之后,flex 元素就不再是 BFC、IFC 之類的,而是 FFC 呢?
如果真是這樣的話,那么是不是就可以多嵌套一層,由最外層控制文本多行截斷,最里層控制 tag 的浮動效果呢?于是改變一下 HTML 結構。
- <div class="box">
- <div class="text-overflow">
- <span class="tag">new</span>
- 很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容很多文本內容
- </div>
- </div>
在原有的基礎上,增加一層,CSS 部分也改變一下,其實只要把選擇符 .text-overflow 換成 .box 就可以了。
- .box {
- width: 200px;
- overflow: hidden;
- display: -webkit-box;
- -webkit-line-clamp: 3;
- -webkit-box-orient: vertical;
- }
- .tag {
- float: right;
- padding: 0 2px;
- color: #fff;
- background-color: #f32600;
- border-radius: 2px;
- }
那么最終的結果就是這樣。也就是說的確是 -webkit-box 的影響,而且應該就是 FFC 的關系。至于瀏覽器中差異可能就是兼容性問題了。
查資料
既然 -webkit-box 是早期 flex 布局的一個版本,那么必定還有其他一些屬性,比如以下幾個:
- box-pack;
- box-align;
- box-orient;
那么就按照這個思路,我們可以看看 flex 相關的資料文檔。
在之前的 flex 教程文檔(https://www.yuque.com/linxz/flex)有關 display: flex; 有過介紹,前面也提到了 FFC,那么具體的我們也可以從 w3c 文檔中看到:
A flex container establishes a new flex formatting context for its contents. This is the same as establishing a block formatting context, except that flex layout is used instead of block layout. For example, floats do not intrude into the flex container, and the flex container’s margins do not collapse with the margins of its contents. Flex containers form a containing block for their contents exactly like block containers do. [CSS21] The overflow property applies to flex containers.
以上內容來自:https://www.w3.org/TR/css-flexbox-1/#flex-formatting-context
其中 A flex container establishes a new flex formatting context for its contents. 和 floats do not intrude into the flex container,至少說明了在 flex 布局中,浮動是有“可能”是無效的。
我的結論
針對這個問題的處理方式,我的結論,是的,僅僅只是代表我個人的一個結論就是:多套一層,由外層控制元素多行截斷,最里層去實現浮動環繞的效果,避開因為 flex 容器而導致子元素浮動失效的情況。