溢出:隐藏不适用于 Chrome 中的伪元素

Posted

技术标签:

【中文标题】溢出:隐藏不适用于 Chrome 中的伪元素【英文标题】:Overflow: hidden not applying to a pseudo element in Chrome 【发布时间】:2015-04-16 20:43:05 【问题描述】:

我正在生成一个“灰色主题”——尽管仍有一些调整需要做,但我对此相当满意。

Gray Theme

但我似乎在这里偶然发现了一个问题,即 Chrome 中的按钮(其他浏览器似乎还可以),其中悬停效果似乎会产生不需要的结果。

如果我将鼠标悬停在菜单上,然后继续悬停“测试按钮”,则伪元素不符合边框半径,在hover 上给出方角。

我会寻找符合边界半径的伪元素。

我的按钮代码是:

+ 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>

有没有办法阻止按钮的伪元素出现在实际元素边框半径的前面(效果是生成一个'shine')?


复制说明

在 chrome 中运行 sn-p 悬停径向菜单 现在悬停按钮 在动画结束时查看按钮伪按钮的“方角”。

我现在得到的:

我想要得到什么

我在最新版本的 chrome 中遇到了这个问题(似乎)。


注意事项

在径向菜单上完美地使用了相同的效果,所以我不确定为什么它会出现在按钮实例上?

有没有办法确保在生产中不会发生这种情况,这样这个“方角”就不会出现(似乎只在最新的 chrome 中出现)?


更新

另一位用户报告了这一点;

右键单击按钮,左键单击检查元素并在开发工具打开之前悬停=>错误(“悬停”效果也有错误)

将重现此问题。

而另一个用户根本无法重现此问题(在 V.24 上)

【问题讨论】:

这似乎是随机发生的 @BoltClock:你能建议解决这个问题吗? 不,对不起,我什么都没得到。 @BoltClock:我想是时候与 chrome 开发人员交谈了,然后 :(。我能问一下您是如何复制的吗?正如我所说,或者其他方式?建议在聊天中与其他人交谈他们可以用不同的方式复制吗? issue reported / ticket opened here 【参考方案1】:

也许我们都应该阅读更多关于 css will-change 属性的信息,您可以找到一篇有用的文章 here。这是一项实验性技术,目前被 Chrome、Firefox 和 Opera 支持。

will-change CSS 属性为作者提供了一种提示方式 浏览器关于元素预期的变化类型,所以 浏览器可以提前设置适当的优化 在元素实际改变之前。这类优化 可以通过潜在地提高页面的响应能力 在实际需要之前提前完成昂贵的工作。

它通过在过渡发生之前准备图层来帮助您的浏览器使用 GPU 渲染元素过渡。在这种情况下它会有所帮助,我们只需要小心设置这个属性。我们不应该将will-change 设置为页面上的每个元素,而应该在即将发生转换的时刻针对特定元素。这就是为什么我们应该像这样在父元素上使用:hover 状态:

.will_change:hover *,
.will_change:hover *:before,
.will_change:hover *:after 
    will-change: transform, opacity;

.will-change是父元素的类,具体可以看updated CodePen here。

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

它不会像上面boltclock 写的那样随机发生,而是仅在浏览器同时呈现其他转换时发生。只有在悬停在上面的菜单之后(虽然那个动画还没有完成),我们才开始在按钮上新建一个。在您的示例中,如果您从下方或侧面悬停按钮,则不会看到任何故障。 我的猜测是:使用will-change 会强制进行图形加速,这样可以节省CPU 出错率。 -webkit-transform: translateZ(0px) 的类似技巧有助于在 Chrome 上呈现文本。

【讨论】:

这很有趣。它似乎修复了该错误,但帧速率低于没有该属性。 是的,认为它会强制图形加速...也许 CSS 可以更准确,但我找不到更好的方法来实现它。

以上是关于溢出:隐藏不适用于 Chrome 中的伪元素的主要内容,如果未能解决你的问题,请参考以下文章

IE10:“可见性:可见”在“可见性:隐藏”元素的伪元素之前

如何在Firefox中垂直居中变换旋转中的伪元素

如何在 Chrome 的检查器中添加/插入之前或之后的伪元素?

溢出:隐藏;不适用于带有 IFRAME 的 Chrome?

隐藏溢出不适用于图像

用于在另一个元素内插入图标的伪元素选择器