将动画添加到其他元素时,不会考虑边框半径和溢出 [英] Border radius and overflow aren't respected when animation is added on a different element

查看:96
本文介绍了将动画添加到其他元素时,不会考虑边框半径和溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是我的代码:

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,您可以看到它解决了问题。

<:c $ c> *,*:之前,*:之后{}之后的代码片段代码 box-sizing:border-box;}。btn_exchange a {position:relative;显示:块;向左飘浮;宽度:150px;颜色:#ffffff; font-size:14px;文字修饰:无; text-align:center; font-weight:bold;背景:#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;动画:脉冲1s线性无限;}#box_avatar {position:relative;显示:块;宽度:125px; height:125px;保证金:0汽车; 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;宽度:100%;底部:0;填充:8px 0 10px 0;背景:#4c4747;不透明度: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>

#box_avatar 应用 z-index 也会解决问题。






原因:

渲染和合成很难解释,但是如果没有 z-index z-index:0 被设置为 a.abc




  • a.abc 获取自己的渲染和合成图层,因为它具有动画变换和显式定位属性。

  • 渲染和合成图层的创建过程在这篇文章。可以通过在开发工具中启用显示绘制矩形和显示合成图层边框来查看图层。
  • #box_avatar #bg_gray 也可以获得他们自己的合成图层。 #box_avatar 似乎正在获得一个单独的图层,因为它具有等于或低于 z-index 的先前兄弟。

  • 我无法准确指出为什么 #bg_gray 获得一个单独的图层,但似乎主要是因为 z-index:auto 创建一个单独的堆栈上下文。 (源代码 - W3C规范

  • ul>

    #box_avatar 创建不同的图层时, #bg_gray 它们被放置在另一个之上, #bg_gray 不完全在里面 #box_avatar code>,所以并不尊重 overflow border-radius 。这就像是将两层纸放在另一层纸上。






    解决方案的详细解释: z-index:1 a上分配。

    abc 元素:




    • 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 lower z-index.
    • I am not able to exactly pinpoint why the #bg_gray gets a separate layer but it seems to mostly be because of how z-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 lower z-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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆