一尘不染

使用转换时出现问题+不透明度更改+溢出隐藏

css

如果看到我共享的代码示例,则可以看到叠加层超出了框的范围。我将问题追溯到该transition属性。

我想删除div之外的内容。溢出无法正常运行。(正在删除transition作品,但如果可能,我想保留它)

任何帮助表示赞赏

var timer = setInterval(function() {

  document.querySelector(".qs-timer-overlay").style.opacity = (document.querySelector(".qs-timer-overlay").style.opacity * 1) + 0.1;

  if (document.querySelector(".qs-timer-overlay").style.opacity * 1 == 1) {

    clearInterval(timer);

  }

}, 1000);


.qs-main-header .qs-timer {

  padding: 13px 10px;

  min-width: 130px;

  text-align: center;

  display: inline-block;

  background-color: #dd8b3a;

  color: #FFF;

  font-size: 20px;

  border-radius: 50px;

  text-transform: uppercase;

  float: right;

  cursor: pointer;

  position: relative;

  overflow: hidden;

}

.qs-main-header .qs-timer-overlay {

  z-index: 1;

  width: 10%;

  max-width: 100%;

  position: absolute;

  height: 100%;

  top: 0;

  left: 0;

  background-color: #c7543e;

  opacity: 0.0;

  /* border-radius: 50px 50px 0px 50px; */

}

.qs-main-header .qs-timer-content {

  z-index: 2;

  position: relative;

}

.scale-transition {

  -webkit-transition: all 1s;

  transition: all 1s;

}


<div class="qs-main-header">

  <div class="qs-timer scale-transition ng-hide" ng-show="visibility.timer">

    <div class="scale-transition qs-timer-overlay"></div>

    <div class="qs-timer-content ng-binding">0 <span class="ng-binding">Sec(s)</span>

    </div>

  </div>

</div>

阅读 290

收藏
2020-05-16

共1个答案

一尘不染

实际上,border-radius当过渡发生时,它并没有得到尊重。


禁用过渡后,为什么不会出现此问题?

  • 如果样式发生更改,但没有满足创建合成层的所有条件(即,没有动画或过渡或3D变换等),则不满足:
    • 没有合成层,因此每次更改似乎都会重新粉刷整个区域。由于发生了完整的重新绘制,因此没有问题。
  • 在开发人员工具中启用“显示油漆矩形”和“显示复合层边框”后,请查看以下代码段(以全屏模式显示),并注意以下几点:

    • 没有创建带有橙色边框的区域(合成层)。
    • 每次通过将焦点放在a标签之一上来修改样式,整个区域都会重新绘制(红色或绿色闪烁区域)。

    .outer {

    position: relative;

    height: 100px;

    width: 100px;

    margin-top: 50px;

    border: 1px solid red;

    overflow: hidden;

    }

    .border-radius {

    border-radius: 50px;

    }

    .inner {

    width: 50px;

    height: 50px;

    background-color: gray;

    opacity: 0.75;

    }

    a:focus + .outer.border-radius > .inner {

    transform: translateX(50px);

    height: 51px;

    opacity: 0.5;

    }

    Test

    I am a strange root.


为什么添加过渡会带来问题?

  • 初始渲染没有合成层,因为元素上还没有过渡。查看下面的代码段,并注意运行该代码段时如何发生油漆(红色或绿色闪烁区域),但是没有创建合成层(带有橙色边框的区域)。
  • 过渡开始时,当某些属性(如不透明度,变换等)正在过渡时,Chrome会将它们拆分为不同的合成层。请注意,一旦将焦点设置在锚标记之一上,将立即显示两个带有橙色边框的区域。这些是创建的合成层。
  • 为了加速渲染,正在发生图层拆分。如HTML5 Rocks文章所述,不透明度和变换更改是通过更改合成层的属性来应用的,并且不会发生重新绘制。
  • 在过渡结束时,由于合成层不再适用(基于创建层的标准),重新绘制恰好将所有层合并回到单个层中。

    .outer {

    position: relative;

    height: 100px;

    width: 100px;

    margin-top: 50px;

    border: 1px solid red;

    overflow: hidden;

    }

    .border-radius {

    border-radius: 50px;

    }

    .inner {

    width: 50px;

    height: 50px;

    background-color: gray;

    transition: all 1s 5s;

    /transition: height 1s 5s; / uncomment this to see how other properties don’t create a compositing layer */

    opacity: 0.75;

    }

    a:focus + .outer.border-radius > .inner {

    transform: translateX(50px);

    opacity: 0.5;

    /height: 60px; /

    }

    Test

    I am a strange root.

这说明当合并图层并进行完全重绘时,border- radius父级上的也会得到应用和尊重。但是,在过渡期间仅更改了合成层的属性,因此该层似乎不了解其他层的属性,因此不考虑父层的边界半径。

我认为这是因为图层渲染的工作方式。每一层都是一个软件位图,因此它有点像具有圆形图像,然后在其div上放置一个。显然,这不会导致内容的裁剪。

这个bug线程中的注释似乎还确认了当不再需要单独的图层时是否发生了重新绘制。

如果“获取自己的图层”将要更改,我们想重绘

注意: 尽管它们是特定于Chrome的,但我认为其他行为也应相似。


解决办法是什么?

解决方案似乎是为parent(.qs- timer)元素创建一个单独的堆栈上下文。创建一个单独的堆栈上下文似乎会为父级创建一个单独的合成层,从而解决了这个问题。

所提到的,以下任何一个选项都将为父级创建一个单独的堆栈上下文,而执行其中一个似乎可以解决此问题。

  • z-index父项上的设置为.qs-timerauto以外的任何值。

    var timer = setInterval(function() {
    

    document.querySelector(“.qs-timer-overlay”).style.opacity = (document.querySelector(“.qs-timer-overlay”).style.opacity * 1) + 0.1;

    if (document.querySelector(“.qs-timer-overlay”).style.opacity * 1 == 1) {

    clearInterval(timer);
    

    }

    }, 1000);

    .qs-main-header .qs-timer {
    

    padding: 13px 10px;

    min-width: 130px;

    text-align: center;

    display: inline-block;

    background-color: #dd8b3a;

    color: #FFF;

    font-size: 20px;

    border-radius: 50px;

    text-transform: uppercase;

    float: right;

    cursor: pointer;

    position: relative;

    overflow: hidden;

    z-index: 1; / creates a separate stacking context /

    }

    .qs-main-header .qs-timer-overlay {

    z-index: 1;

    width: 10%;

    max-width: 100%;

    position: absolute;

    height: 100%;

    top: 0;

    left: 0;

    background-color: #c7543e;

    opacity: 0.0;

    / border-radius: 50px 50px 0px 50px; /

    }

    .qs-main-header .qs-timer-content {

    z-index: 2;

    position: relative;

    }

    .scale-transition {

    -webkit-transition: all 1s;

    transition: all 1s;

    }

    <div class="qs-main-header">
    
    <div class="scale-transition qs-timer-overlay"></div>
    
    <div class="qs-timer-content ng-binding">0 <span class="ng-binding">Sec(s)</span>
    
    </div>
    
  • 设置opacity为小于1的值。我在下面的代码段中使用了0.99,因为它不会引起任何视觉差异。

    var timer = setInterval(function() {
    

    document.querySelector(“.qs-timer-overlay”).style.opacity = (document.querySelector(“.qs-timer-overlay”).style.opacity * 1) + 0.1;

    if (document.querySelector(“.qs-timer-overlay”).style.opacity * 1 == 1) {

    clearInterval(timer);
    

    }

    }, 1000);

    .qs-main-header .qs-timer {
    

    padding: 13px 10px;

    min-width: 130px;

    text-align: center;

    display: inline-block;

    background-color: #dd8b3a;

    color: #FFF;

    font-size: 20px;

    border-radius: 50px;

    text-transform: uppercase;

    float: right;

    cursor: pointer;

    position: relative;

    overflow: hidden;

    opacity: 0.99; / creates a separate stacking context /

    }

    .qs-main-header .qs-timer-overlay {

    z-index: 1;

    width: 10%;

    max-width: 100%;

    position: absolute;

    height: 100%;

    top: 0;

    left: 0;

    background-color: #c7543e;

    opacity: 0.0;

    / border-radius: 50px 50px 0px 50px; /

    }

    .qs-main-header .qs-timer-content {

    z-index: 2;

    position: relative;

    }

    .scale-transition {

    -webkit-transition: all 1s;

    transition: all 1s;

    }

    <div class="qs-main-header">
    
    <div class="scale-transition qs-timer-overlay"></div>
    
    <div class="qs-timer-content ng-binding">0 <span class="ng-binding">Sec(s)</span>
    
    </div>
    
  • transform元素添加一个。我translateZ(0px)在以下代码段中使用过,因为这也不会产生任何视觉差异。

    var timer = setInterval(function() {
    

    document.querySelector(“.qs-timer-overlay”).style.opacity = (document.querySelector(“.qs-timer-overlay”).style.opacity * 1) + 0.1;

    if (document.querySelector(“.qs-timer-overlay”).style.opacity * 1 == 1) {

    clearInterval(timer);
    

    }

    }, 1000);

    .qs-main-header .qs-timer {
    

    padding: 13px 10px;

    min-width: 130px;

    text-align: center;

    display: inline-block;

    background-color: #dd8b3a;

    color: #FFF;

    font-size: 20px;

    border-radius: 50px;

    text-transform: uppercase;

    float: right;

    cursor: pointer;

    position: relative;

    overflow: hidden;

    transform: translateZ(0px) / creates a separate stacking context /

    }

    .qs-main-header .qs-timer-overlay {

    z-index: 1;

    width: 10%;

    max-width: 100%;

    position: absolute;

    height: 100%;

    top: 0;

    left: 0;

    background-color: #c7543e;

    opacity: 0.0;

    / border-radius: 50px 50px 0px 50px; /

    }

    .qs-main-header .qs-timer-content {

    z-index: 2;

    position: relative;

    }

    .scale-transition {

    -webkit-transition: all 1s;

    transition: all 1s;

    }

    <div class="qs-main-header">
    
    <div class="scale-transition qs-timer-overlay"></div>
    
    <div class="qs-timer-content ng-binding">0 <span class="ng-binding">Sec(s)</span>
    
    </div>
    
  • 前三种方法比第三种更可取,因为第三种方法仅在支持CSS转换的浏览器上起作用。

    2020-05-16