背景
前兩天在做需求的時(shí)候弄息,發(fā)現(xiàn)了 Safari 瀏覽器(包括 iOS 平臺(tái)各瀏覽器)下有一個(gè)渲染的 Bug嘲叔,其他則沒(méi)問(wèn)題因妇。
復(fù)現(xiàn)示例如下:
<div class="box">
<img src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*lEtuTZi2GvIAAAAAAAAAAABkARQnAQ" alt="picture" />
</div>
.box {
width: 270px;
height: 169px;
margin: 0 auto;
overflow: hidden;
border-radius: 30px;
border: 4px solid #000;
}
.box img {
width: 100%;
height: 100%;
transform: translateZ(10px);
}
CodeSandbox Demo
其實(shí)就是簡(jiǎn)單地在 .box
中添加了 overflow: hidden; border-radius: 30px;
做一個(gè)圓角處理橘忱。上圖為預(yù)期表現(xiàn)党瓮。
但是在 Apple 的 WebKit 平臺(tái)(不包含 Chrome 的 Blink 平臺(tái))斋否,就出現(xiàn)問(wèn)題了 ??
是 overflow: hidden 處理無(wú)效魄健?還是 border-radius 的問(wèn)題妄荔?
原因
解決方法很多,我們先深究下原因迄薄。
前面琅关,我們給 <img>
添加了 transform: translateZ(10px)
,于是該元素產(chǎn)生了 Composite Layer(合成層)讥蔽。
.box img {
width: 100%;
height: 100%;
transform: translateZ(10px);
}
而 Webkit 內(nèi)核中涣易,border-radius
對(duì)含有 Composite Layer 的元素的裁剪是存在 Bug 的,該問(wèn)題可以追溯到 2011 年冶伞,很早就有人提出問(wèn)題了都毒。
Bug 68196: border-radius clipping of composited layers doesn't work
發(fā)現(xiàn)該 Bug 在 2022 年 9 月 7 日已被標(biāo)記為「RESOLVED FIXED」,在 2022 年 10 月 19 日發(fā)布的 Safari Technology Preview 156 中已修復(fù)碰缔。好家伙账劲,這問(wèn)題整整十多年才解決。
隔壁 Blink 內(nèi)核(基于 Webkit 的一個(gè)分支)則在 2017 年 1 月 24 日修復(fù)金抡。
解決方法
我們只要在 border-radius
的元素上添加一個(gè)可創(chuàng)建 Stacking Context(層疊上下文)的 CSS 屬性即可瀑焦。比如 transform: scale(1)
、transform: translateZ(1px)
梗肝、isolation: isolate
榛瓮、position: relative; z-index: 0
等等。
- 從語(yǔ)義角度考慮巫击,個(gè)人更偏向使用 isolation禀晓,它表示該元素是否必須創(chuàng)建一個(gè)新的層疊上下文精续。
- 從兼容性角度考慮,相比 isolation粹懒,transform 或 position + z-index 會(huì)更好一些重付。
.box {
width: 270px;
height: 169px;
margin: 0 auto;
overflow: hidden;
border-radius: 30px;
border: 4px solid #000;
isolation: isolate; /* 新增 */
}
.box img {
width: 100%;
height: 100%;
transform: translateZ(10px);
}