解决 border-radius 元素在应用了 transform 的子元素 时overflow:hidden 失效的问题

  受大家启迪,于是最近深入研究了一下Css3中的一些属性。之中也是碰到了个不为我知的问题,在这里特此总结并与大家分享。

  问题重现:在父元素上应用了 border-radius 的圆角属性、加上  overflow:hidden属性 、并且子元素填充整个父元素。于是看到的效果是:子元素超出父元素圆角的部分被隐藏掉,形成一个圆角头像容器的结构。代码如下:

  

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        html,body{
            width: 100%;
            height: 100%;
        }

        #father {
            width: 200px;
            height: 200px;
            overflow: hidden;
            border-radius: 50%;
            background-color: #ccc;
        }
        #child {
            background-color: red;
            width: 100%;
            height: 100%;
            -webkit-transition:all 0.5s ease;
            transition:all 0.5s ease;
        }
    </style>

</head>
<body>

<div id="father">
    <div id="child"></div>
</div>



</body>
</html>
View Code

 

  效果如下:

 

  想着使用translate3d实现对半圆的动画效果,于是乎问题就显现了。

  问题描述:对  #child 应用一个 transform 变化,使用  translate3d 对其进行横向偏移。会发现  #child 溢出了 #father 的圆角范围。 overfow:hidden 失效。

  代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        html,body{
            width: 100%;
            height: 100%;
        }

        #father {
            width: 200px;
            height: 200px;
            overflow: hidden;
            border-radius: 50%;
            background-color: #ccc;
        }
        #child {
            background-color: red;
            width: 100%;
            height: 100%;
            -webkit-transition:all 0.5s ease;
            transition:all 0.5s ease;
        }

        /*使用 translate3d 让子元素沿x正轴偏移100px*/
        #child.add-translate {
            -webkit-transform:translate3d(100px,0,0);
            transform:translate3d(100px,0,0);
        }
    </style>

</head>
<body>

<div id="father">
    <div id="child" class="add-translate"></div>
</div>



</body>
</html>
使用 translate3d 让子元素沿x正轴偏移100px

 

  显示如下:

 

  

  解决方案:

    1:使用webkit-mask-image 覆盖圆角溢出部分。(文章后面会提供关于webkit-mask-image的相关介绍)

    -webkit-mask-image 可以使用图片、Gradient 渐变或者 SVG mask 作为元素的 mask 遮罩。在 WebKit 的兼容性还算可以。

(图片来源于  CSS遮罩 – w3cplus )

 

     回到刚才的问题。在这里使用一个纯黑色的 1px png 图像。应用 mask 遮罩解决该问题。在#father 上应用  add-mask-image类名后,#child触发  transform 动画后就不会出现溢出的问题了。代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        html,body{
            width: 100%;
            height: 100%;
        }

        #father {
            width: 200px;
            height: 200px;
            overflow: hidden;
            border-radius: 50%;
            background-color: #ccc;
        }
        #child {
            background-color: red;
            width: 100%;
            height: 100%;
            -webkit-transition:all 0.5s ease;
            transition:all 0.5s ease;
        }

        /*使用 translate3d 让子元素沿x正轴偏移100px*/
        #child.add-translate {
            -webkit-transform:translate3d(100px,0,0);
            transform:translate3d(100px,0,0);
        }

        /*使用 -webkit-mask-image 遮罩*/
        #father.add-mask-image{
           -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
    }
    </style>

</head>
<body>

<div id="father" class="add-mask-image">
    <div id="child" class="add-translate"></div>
</div>



</body>
</html> 
使用 -webkit-mask-image 遮罩

 

     效果如下:

 

     该问题在Stackoverflow的讨论:

     webkit-overflow-issue-on-border-radius-and-transform

     how-to-make-css3-rounded-corners-hide-overflow-in-chrome-opera

 

     有关-webkit-mask-image的简单介绍:

     http://ued.ctrip.com/webkitcss/prop/mask-image.html

  

    2:父元素加上 transform 属性。

      子元素在使用了 transform 属性后致使它改变了原有的默认维度,而这时的父元素无任何改变,仍为2d维度(css默认都为2d维度)。因此导致了子元素使用translate3d属 性后出现溢出的情况。接下来只要在原有的父元素样式中加上 transform 属性将父元素改变维度即可。(可以使用translate3d 或 rotate 解决)

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        html,body{
            width: 100%;
            height: 100%;
        }

        #father {
            width: 200px;
            height: 200px;
            overflow: hidden;
            border-radius: 50%;
            background-color: #ccc;
            transform:translate3d(0,0,0);/*父元素使用transform:translate3d 属性*/
            -webkit-transform:translate3d(0,0,0);
        }
        #child {
            background-color: red;
            width: 100%;
            height: 100%;
            -webkit-transition:all 0.5s ease;
            transition:all 0.5s ease;
        }

        /*使用 translate3d 让子元素沿x正轴偏移100px*/
        #child.add-translate {
            -webkit-transform:translate3d(100px,0,0);
            transform:translate3d(100px,0,0);
        }
    </style>

</head>
<body>

<div id="father">
    <div id="child" class="add-translate"></div>
</div>



</body>
</html>
父元素增加 transform:translate3d 属性

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        html,body{
            width: 100%;
            height: 100%;
        }

        #father {
            width: 200px;
            height: 200px;
            overflow: hidden;
            border-radius: 50%;
            background-color: #ccc;
            -webkit-transform:rotate(0deg);/*父元素使用transform:rotate 属性*/
            transform: rotate(0deg);
        }
        #child {
            background-color: red;
            width: 100%;
            height: 100%;
            -webkit-transition:all 0.5s ease;
            transition:all 0.5s ease;
        }

        /*使用 translate3d 让子元素沿x正轴偏移100px*/
        #child.add-translate {
            -webkit-transform:translate3d(100px,0,0);
            transform:translate3d(100px,0,0);
        }
    </style>

</head>
<body>

<div id="father">
    <div id="child" class="add-translate"></div>
</div>



</body>
</html>
父元素增加 transform:rotote 属性

 

 

     效果:同解决方案一中实现的效果如出一辙,在这里就不贴图了,有兴趣的朋友可以亲自证明一下。

 

     transform的介绍:

     CSS3 transform 详解

 

 

三:补充内容(待注意)

  1:关于感谢:  

    a:首先非常感谢大家对 Lying 的启迪。如有需要,留下你们的评论,随时提供服务。

    b:感谢前文作者。Lying 在借鉴的原文章上增加了一些自个的见解。有时间咋们见个面呗

  2:关于文章内容:

    a:没有对浏览器做兼容测试。(搬砖中写的一篇文章)

    b:Stackoverflow 上许多友人都说这是 google 的一个bug,因此在这里不能保证解决方案的第二条阐述的正确与否。但这条肯定是可以解决问题的      (chrome中亲测有效)

    c:相信还会有其它的解决方案。(简单的看了 Stackoverflow 提供的一些方案,因此在这里没有列出,大家也可以查看文中提供的链接了解了解)

  3:关于对Css 3 见解:

    a:Css 3 的确是很值得学习的,今后 Lying 也会同大家一起一直保持着学习的积极性和善于分享的心。

posted @ 2016-03-31 10:56  Lying二小  阅读(4395)  评论(2编辑  收藏  举报