为何宽高100%的绝对定位伪元素在父元素设border-radius时仍露父元素?
问题描述
伪元素在设计中应用广泛,比如用::before给按钮添加次级背景(用于hover动画),但存在一个问题:即便将伪元素宽高设为100%,父元素的部分背景仍会从边缘透出。
具体场景:两个按钮的::before伪元素均设置为绿色背景、宽高100%,左侧按钮背景为白色,右侧按钮背景与伪元素同色。仔细观察左侧按钮边缘,能看到白色的父元素背景。这个问题仅在设置border-radius时出现,不同浏览器、不同元素下均存在,推测是抗锯齿渲染导致的。
代码示例:
* { box-sizing: border-box; } body { background: black; } button { position: relative; padding: 10px; margin: 0; border: none; background-color: white; z-index: 0; overflow: hidden; border-radius: 50px; border: 0; } button::before { content: ''; position: absolute; top: 0; left: 0; height: 100%; width: 100%; background-color: green; z-index: -1; } button:nth-child(2) { background-color: green; }
<div> <button>button</button> <button>button</button> </div>
解决方法
以下几种方案均可解决抗锯齿导致的漏边问题:
轻微放大伪元素:将伪元素宽高设为略大于父元素,同时调整位置居中,完全覆盖父元素的抗锯齿边缘:
button::before { content: ''; position: absolute; top: -1%; left: -1%; height: 102%; width: 102%; background-color: green; z-index: -1; }用transform缩放伪元素:通过
transform: scale()让伪元素略微放大,基于中心缩放无需调整定位,同样能覆盖边缘:button::before { content: ''; position: absolute; top: 0; left: 0; height: 100%; width: 100%; background-color: green; z-index: -1; transform: scale(1.05); transform-origin: center; }用clip-path替代border-radius:放弃父元素的
border-radius,改用clip-path给父元素和伪元素统一设置圆角,避免抗锯齿层叠问题:button { position: relative; padding: 10px; margin: 0; border: none; background-color: white; z-index: 0; overflow: hidden; border: 0; clip-path: circle(50% at center); /* 效果对应50px border-radius,可按需调整 */ } button::before { content: ''; position: absolute; top: 0; left: 0; height: 100%; width: 100%; background-color: green; z-index: -1; clip-path: inherit; }
内容的提问来源于stack exchange,提问作者Afik Habaz
相关产品推荐
相关产品推荐

