将动画添加到其他元素时,不会考虑边框半径和溢出 [英] Border radius and overflow aren't respected when animation is added on a different element
问题描述
这是我的代码:
p>
*,*:before,*:after {box-sizing:border-box; -moz-box-sizing:border-box; -webkit-box-sizing:border-box;}。btn_exchange a {position:relative;文字修饰:无;显示:块;宽度:150px;向左飘浮;颜色:#ffffff; font-size:14px;背景:#0ea2d3; box-shadow:0 3px 0 0 rgba(7,154,190,0.75); text-align:center; font-weight:bold;} @ keyframes pulse {0%{transform:scale(1); } 50%{transform:scale(1.05); } 100%{transform:scale(1); }} @ - webkit-keyframes pulse {0%{transform:scale(1); } 50%{transform:scale(1.05); } 100%{transform:scale(1); }} a.abc {z-index:0; -webkit-animation:脉冲1s线性0s无限交替;动画:脉冲1s线性无限;}#box_avatar {position:relative;保证金:0汽车; -webkit-border-radius:62.5px; -moz-border-radius:62.5px; -ms-border-radius:62.5px; -o-border-radius:62.5px; border-radius:62.5px;宽度:125px; height:125px; border:2px solid #ccc;显示:块; overflow:hidden;}#img_avatar {width:125px; height:125px;光标:指针; border-radius:62.5px;}#bg_gray {background:#4c4747;宽度:100%;位置:绝对;底部:0;填充:8px 0 10px 0;不透明度:0.8;}#bg_gray img {display:block; width:20px; margin:0 auto;}
< div class = btn_exchange fl bad> < a class =button abchref =#>按钮< / a>< / div>< div id =box_avatar> < img id =img_avatarsrc =http://i.imgur.com/O29DJOZ.jpgalt =avatar/> < div id =bg_gray> < img src =http://i.imgur.com/m5qIRID.pngalt =btn_camera/> < / div>< / div>< div class =btn_exchange fl good> < a class =button abchref =#>按钮< / a>< / div>
p>
当我使用 .bad
div(删除 .good
div),那么包含相机图标的灰色背景并不位于圆形图像内。
如果我在CSS中删除动画 transform
,那么按钮将不再脉动,但灰色背景将变为里面的圆形图像。
任何人都知道它是什么以及如何解决它? 这个问题非常类似于我以前回答过。带有相机图标的灰色框不包含在圆圈内(未由圆圈裁剪)是因为创建图层的方式以及浏览器执行的加速渲染。您可以在我之前链接的答案中找到关于它的更多信息。
解决方案:
解决你的问题的办法是通过设置一个更高的 z-index
值给脉冲按钮。在下面的代码片段中,我将它设置为1,您可以看到它解决了问题。
< div class = btn_exchange fl bad> < a class =button abchref =#>按钮< / a>< / div>< div id =box_avatar> < img id =img_avatarsrc =http://i.imgur.com/O29DJOZ.jpgalt =avatar/> < div id =bg_gray> < img src =http://i.imgur.com/m5qIRID.pngalt =btn_camera/> < / div>< / div>< div class =btn_exchange fl good> < a class =button abchref =#>按钮< / a>< / div>
p>
对 #box_avatar
应用 z-index
也会解决问题。
原因: 渲染和合成很难解释,但是如果没有 为 解决方案的详细解释:
z-index
或 z-index:0
被设置为 a.abc
:
a.abc
获取自己的渲染和合成图层,因为它具有动画变换和显式定位属性。
#bg_gray
也可以获得他们自己的合成图层。 #box_avatar
似乎正在获得一个单独的图层,因为它具有等于或低于 z-index
的先前兄弟。
#bg_gray
获得一个单独的图层,但似乎主要是因为 z-index:auto
创建一个单独的堆栈上下文。 (源代码 - W3C规范)
#box_avatar
创建不同的图层时, #bg_gray
它们被放置在另一个之上, #bg_gray
不完全在里面 #box_avatar
code>,所以并不尊重 overflow
和 border-radius
。这就像是将两层纸放在另一层纸上。
z-index:1
在 a上分配。
-
a.abc
获取它自己的渲染和合成层,因为它有一个动画变换。
- 容器
a.abc
也获取它的图层,因为它具有
- 既不是
#box_avatar
也不是#bg_gray
获取单独的合成图层,因为它们不符合为获得合成图层而定义的任何标准。
- 既不是
当 z-index:0
分配在 a.abc
和 z-index:1
#box_avatar :
-
a.abc
获取自己的渲染和合成图层,因为它有一个动画变换 -
a.abc
的容器也获取它的图层,因为它有一个具有合成图层的子 -
#box_avatar
获得自己的渲染和合成图层,因为它有一个同胞(a.abc
元素的容器),它有一个合成图层z-index
。 -
#bg_gray
成为#box_avatar
元素的图层,并且没有单独的图层。
在上面的情况下,因为 #box_avatar
和 #bg_gray
没有单独的图层,所以它们被绘在一起,所以 #bg_gray
知道在哪里被裁剪。
I got a weird behavior when working with transform
in CSS3.
Here is my code:
*, *:before, *:after {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.btn_exchange a {
position: relative;
text-decoration: none;
display: block;
width: 150px;
float: left;
color: #ffffff;
font-size: 14px;
background: #0ea2d3;
box-shadow: 0 3px 0 0 rgba(7, 154, 190, 0.75);
text-align: center;
font-weight: bold;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
@-webkit-keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
a.abc {
z-index: 0;
-webkit-animation: pulse 1s linear 0s infinite alternate;
animation: pulse 1s linear infinite;
}
#box_avatar {
position: relative;
margin: 0 auto;
-webkit-border-radius: 62.5px;
-moz-border-radius: 62.5px;
-ms-border-radius: 62.5px;
-o-border-radius: 62.5px;
border-radius: 62.5px;
width: 125px;
height: 125px;
border: 2px solid #ccc;
display: block;
overflow: hidden;
}
#img_avatar {
width: 125px;
height: 125px;
cursor: pointer;
border-radius: 62.5px;
}
#bg_gray {
background: #4c4747;
width: 100%;
position: absolute;
bottom: 0;
padding: 8px 0 10px 0;
opacity: 0.8;
}
#bg_gray img {
display: block;
width: 20px;
margin: 0 auto;
}
<div class="btn_exchange fl bad">
<a class="button abc" href="#">Button</a>
</div>
<div id="box_avatar">
<img id="img_avatar" src="http://i.imgur.com/O29DJOZ.jpg" alt="avatar" />
<div id="bg_gray">
<img src="http://i.imgur.com/m5qIRID.png" alt="btn_camera" />
</div>
</div>
<div class="btn_exchange fl good">
<a class="button abc" href="#">Button</a>
</div>
The problem happens when I use the .bad
div (remove .good
div) then the gray background which contains the camera-icon does not lay inside the circle image.
If I remove the animation transform
in CSS, the button won't pulse anymore but the gray background will be inside circle image.
Anyone know what it is and how to solve it?
This problem is quite similar to the one that I had answered earlier. The reason why the gray box with the camera icon is not contained within the circle (not cropped by the circle) is because of how layers are created and accelerated rendering is performed by browsers. You can find more information about it in the answer that I had linked earlier.
Solution:
The solution to your problem would be to move the pulsing buttons to a layer higher by setting a higher z-index
value to it. In the below snippet, I have set it to 1 and you can see that it solves the problem.
*, *:before, *:after {
box-sizing: border-box;
}
.btn_exchange a {
position: relative;
display: block;
float: left;
width: 150px;
color: #ffffff;
font-size: 14px;
text-decoration: none;
text-align: center;
font-weight: bold;
background: #0ea2d3;
box-shadow: 0 3px 0 0 rgba(7, 154, 190, 0.75);
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
a.abc {
z-index: 1;
animation: pulse 1s linear infinite;
}
#box_avatar {
position: relative;
display: block;
width: 125px;
height: 125px;
margin: 0 auto;
border-radius: 62.5px;
border: 2px solid #ccc;
overflow: hidden;
}
#img_avatar {
width: 125px;
height: 125px;
border-radius: 62.5px;
cursor: pointer;
}
#bg_gray {
position: absolute;
width: 100%;
bottom: 0;
padding: 8px 0 10px 0;
background: #4c4747;
opacity: 0.8;
}
#bg_gray img {
display: block;
width: 20px;
margin: 0 auto;
}
<div class="btn_exchange fl bad">
<a class="button abc" href="#">Button</a>
</div>
<div id="box_avatar">
<img id="img_avatar" src="http://i.imgur.com/O29DJOZ.jpg" alt="avatar" />
<div id="bg_gray">
<img src="http://i.imgur.com/m5qIRID.png" alt="btn_camera" />
</div>
</div>
<div class="btn_exchange fl good">
<a class="button abc" href="#">Button</a>
</div>
Applying a z-index
for the #box_avatar
would also solve the issue.
Reason:
Rendering and compositing are tricky to explain but the following is what happens when no z-index
or z-index: 0
is set to the a.abc
:
- The
a.abc
gets its own rendering and compositing layer because it has an animated transform and explicit positioning properties. - The rendering and compositing layer creation process is explained in this article. The layers can be seen by enabling the "Show Paint Rects" and "Show composited layer borders" in Dev tools.
- The
#box_avatar
and#bg_gray
also get their own compositing layer. The#box_avatar
seems to be getting a separate layer because it has a previous sibling with equal or lowerz-index
. - I am not able to exactly pinpoint why the
#bg_gray
gets a separate layer but it seems to mostly be because of howz-index: auto
creates a separate stacking context. (Source - W3C Spec)
When distinct layers are created for #box_avatar
, #bg_gray
and they are placed one on top of the other, the #bg_gray
isn't exactly inside the #box_avatar
and so doesn't respect the overflow
and border-radius
. It is kind of like placing two layers of paper one on top of the other.
Detailed Explanation of Solution:
When z-index: 1
is assigned on a.abc
element:
- The
a.abc
gets its own rendering and compositing layer because it has an animated transform. - The container of
a.abc
also gets its layer because it has a child which has a compositing layer. - Neither
#box_avatar
nor#bg_gray
get a separate compositing layer because they don't meet any of the criteria defined to get a compositing layer.
When z-index: 0
is assigned on a.abc
and z-index: 1
is assigned on #box_avatar
:
- The
a.abc
gets its own rendering and compositing layer because it has an animated transform - The container of
a.abc
also gets its layer because it has a child which has a compositing layer - The
#box_avatar
gets its own rendering and compositing layer because it has a sibling (a.abc
element's container) which has a compositing layer with lowerz-index
. - The
#bg_gray
becomes a part of the#box_avatar
element's layer and gets no separate layer.
In both the above cases, because the #box_avatar
and #bg_gray
don't get separate layers, they are kind of painted together and so the #bg_gray
knows where to get cropped.
这篇关于将动画添加到其他元素时,不会考虑边框半径和溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!