Chrome中伪元素不适用于overflow:hidden

9
我正在制作一个“灰色主题”,虽然还需要进行一些微调,但我对它感到相当满意。 但我在使用Chrome浏览器时遇到了问题,当悬停在“测试按钮”上时,伪元素不遵循border-radius,导致出现了方形边角的hover效果。其他浏览器似乎没有这个问题。 enter image description here 我希望伪元素能够遵循边框半径。
我的按钮代码如下:

+ function() {
  var to;
  $(".wrap").on('mouseenter', function() {
    var circles = $(this).find(".circle");
    var degree = (2 * Math.PI) / circles.length; //calc delta angle
    var transforms = [];

    // Calculate the position for each circle
    circles.each(function(index) {
        var x = 100 * Math.cos(-0.5 * Math.PI + degree * (-1 * index - 0.5));
        var y = 100 * Math.sin(-0.5 * Math.PI + degree * (-1 * index - 0.5));

      transforms.push('translate(' + x + 'px,' + y + 'px)');
    });

    // Function to moves all the circles
    // We'll pop a circle each time and than call this function recursively
    function moveCircles() {
      var transform = transforms.shift();
      circles.css('transform', transform);

      circles.splice(0, 1);
      if (circles.length) to = setTimeout(moveCircles, 400);
    }

    moveCircles();
  });

  $(".wrap").on('mouseleave', function() {
    var circles = $(this).children().css('transform', '');
    clearTimeout(to);
  });
}();
html, body {
    background:darkgray
}

/*****************Radial Menu (plus bit of button)***********************/

.wrap {
    height:300px;
    width:300px;
    position:relative;
    transform-origin: center center;
    transition:all 0.8s;
}
.circle {
    transition:all 0.8s;
    position:absolute;
    height:5px;
    width:5px;
    text-align: center;
    line-height: 15px;
    top: calc(50% - 2px);
    left: calc(50% - 2px);
    border-radius: 50%;
    overflow:hidden;
}
.parent{
     transition:all 0.8s;
    position:absolute;
    background:gray;
    height:50px;
    width:50px;
    text-align: center;
    line-height: 25px;
    top: calc(50% - 25px);
    left: calc(50% - 25px);
    border-radius: 50%;
    z-index:8;
    box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}
.parent:before,.parent:after{
    content:"";
    position:absolute;
    transition:all 0.8s;
    height:5px;
    width:25px;
    top:22px;
    left:12px;
    background:black; 
    opacity:1;
}
.parent:before{
  top:15px;
    box-shadow: 0 14px 0 black;
}
.parent:hover:before,.parent:hover:after{
    transform:translate(0,20px);
    color:gray;
    opacity:0;
    box-shadow: 0 14px 0 none;
}
.wrap:hover .parent,.wrap:hover .parent:before,.wrap:hover .parent:after{
    background:darkgray;
}
.wrap:hover .parent:before{
    box-shadow:none;
}
.wrap:hover .circle {
    height:50px;
    width:50px;
    line-height: 25px;
    top: calc(50% - 25px);
    left: calc(50% - 25px);
    box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}
.circle img {
    position:absolute;
    height:100%;
    width:100%;
    left:0;
    top:0;
}
.circle:before {
    border-radius:50%;
    transition:all 0.8s;
    content:"";
    position:absolute;
    height:100%;
    width:100%;
    top:0;
    left:0;
    z-index:8;
}
.circle:after,button:after {
    transition:all 0.8s;
    border-radius:50%;
    content:"";
    position:absolute;
    height:200%;
    width:200%;
    top:50%;
    left:200%;
    z-index:8;
    background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
    background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(50%, rgba(255, 255, 255, 0.4)), color-stop(100%, rgba(255, 255, 255, 0)));
    background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
    background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
    background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
    background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffffff', endColorstr='#00ffffff', GradientType=1);
}
.circle:hover:after,button:hover:after {
    left:-200%;
    top:-50%;
}
.circle:hover:before {
      box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}

/********************Button************************/

button {
    margin:5px;
    position:relative;
    background:gray;
    outline:0;
    border:0;
    padding:10px;
    border-radius:10px;
    box-shadow: inset 2px 2px 10px transparent, inset 0 0 15px transparent, 0 0 15px black;
    background:rgba(0, 0, 0, 0.2);
    transition:all 0.4s;
    overflow:hidden;
}
button:active {
    box-shadow: inset 2px 2px 8px black, inset 0 0 10px black, 0 0 18px black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<hr/>
hover near the menu to open
<div class="wrap">
  <div class="parent"></div>
    <div class="circle">
        <img src="http://placekitten.com/g/300/300" />
    </div>
    <div class="circle">
        <img src="http://placekitten.com/g/200/300" />
    </div>
    <div class="circle">
        <img src="http://cdn.flaticon.com/png/256/56729.png" />
    </div>
     <div class="circle">
        <img src="http://cdn.flaticon.com/png/256/54976.png" />
    </div>
    <div class="circle">Just Text</div>
    <div class="circle">
        <img src="http://cdn.flaticon.com/png/256/56582.png" />
    </div>
</div>
<hr/>
then hover button
<button>Test Button</button>

有没有办法防止按钮伪类出现在实际元素的边框半径之前(这会产生“闪光”效果)?
重现说明:
- 在 Chrome 中运行片段 - 悬停在径向菜单上 - 现在悬停在按钮上 - 在动画完成时查看按钮伪类的“方形角”。
我目前得到的是:
我想得到的是:
我似乎在最新版本的 Chrome 中遇到了这个问题。
需要注意的一点是,这种效果在径向菜单中完美地使用,所以我不确定为什么它会在按钮实例上发生?
有没有办法确保这在生产中不会发生,以便这个“方形角”不会出现(似乎只在最新的 Chrome 中出现问题)?
更新:
- 另一个用户报告说; - 右键单击按钮,左键单击检查元素,在开发工具打开之前悬停 =>bug(“悬停离开”效果也有 bug) - 另一个用户根本无法重现此问题(在 V.24 上)。

似乎这种情况是随机发生的 - BoltClock
@BoltClock:你能否提供任何解决这个问题的方法吗? - jbutler483
抱歉,对不起,我什么也没有。 - BoltClock
3
在这里报告了问题/开了一张工单(点击链接查看详情)。 - jbutler483
这里有一个类似的项目 - https://dev59.com/343da4cB1Zd3GeqP1IQU#31698580 - Harry
显示剩余5条评论
1个回答

1
也许我们应该多了解一下CSS will-change属性,你可以在这里找到一篇有用的文章。这是一项实验性技术,目前得到Chrome、Firefox和Opera的支持。

will-change CSS属性为作者提供了一种方式,以暗示浏览器元素即将发生哪些变化,从而使浏览器在元素实际变化之前提前设置适当的优化。这些类型的优化可以通过提前执行潜在的昂贵工作来增加页面的响应能力,而不是等到实际需要时再执行。

它可以帮助您的浏览器在过渡发生之前通过准备图层来渲染元素过渡效果。在这种情况下,使用此属性时需要谨慎。我们不应该将will-change设置为页面上的每个元素,而应该在过渡即将发生的时候针对特定元素进行设置。因此,我们应该像这样在父元素上使用:hover状态:
.will_change:hover *,
.will_change:hover *:before,
.will_change:hover *:after {
    will-change: transform, opacity;
}

.will-change是父元素的类,您可以在此处更新的CodePen中查看详细信息。

如果我们想要分析这在Chrome中发生的时间和原因,那么我可以告诉你我注意到了什么:

  • 它并不像boltclock所写的那样随机发生,而只有在浏览器同时呈现其他转换时才会发生。只有在悬停在上面的菜单(当该动画尚未完成)并且我们在按钮上启动了新动画之后才会发生。在您的示例中,如果您从下方或侧面悬停在按钮上,则不会出现任何故障。
  • 我的猜测是:使用will-change强制进行图形加速,并为制造错误节省CPU。使用-webkit-transform: translateZ(0px)的类似技巧有助于在Chrome上呈现文本。

这很有趣。它似乎修复了错误,但帧速率比没有该属性时要低。 - web-tiki
是的,我认为它会强制使用图形加速...也许CSS可能更准确,但我找不到更好的实现方式。 - skobaljic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接