问题,而使用过渡+不透明度变化+溢出隐藏
Issue while using transitions + opacity change + overflow hidden
如果您看到我分享的代码示例,您可以看到覆盖在框外。我将问题追溯到transition
属性。
我想删除div外的内容。溢出不工作,因为它应该。(删除transition
工作,但我想保留它,如果可能的话)
感谢您的帮助
Codepen联系
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>
实际上是border-radius
在过渡发生时没有得到尊重。这是因为创建了加速渲染的合成层,可以通过查看以下文章来解释:
- HTML5岩石- Chrome加速渲染
- GPU加速合成在Chrome。
为什么当转换被禁用时不会发生这个问题?
- 当样式改变,但没有一个需要创建合成层的标准被满足(即,没有动画或过渡或3D变换等):
- 没有合成层,所以整个区域似乎在每次变化时都被重新绘制。因为一个完整的重漆发生,没有问题。
在Dev工具中启用"显示绘制矩形"answers"显示合成层边界"后,查看下面的代码片段(全屏模式),观察如下: - 没有创建橙色边框(合成层)的区域。
- 每次通过将焦点设置在
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;
}
<a href='#'>Test</a>
<div class='outer border-radius'>
<div class='inner'>I am a strange root.
</div>
</div>
为什么添加过渡会产生问题?
- 初始渲染没有合成层,因为元素上还没有过渡。查看下面的代码片段,并注意当代码片段运行时,油漆(红色或绿色闪烁区域)发生了,但没有创建合成层(橙色边框区域)。
- 当过渡开始时,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; */
}
<a href='#'>Test</a>
<div class='outer border-radius'>
<div class='inner'>I am a strange root.
</div>
</div>
这说明,当图层合并回来和完全重绘发生时,父层上的border-radius
也得到应用和尊重。然而,在过渡期间,只有合成层的属性被改变,因此该层似乎不知道其他层的属性,因此不尊重父层的边界半径。
我认为这是因为图层渲染的方式。每一层都是一个软件位图,所以它有点相当于有一个圆形图像,然后在它上面放一个div
。这显然不会导致任何内容的剪辑。
这个bug线程中的注释似乎也证实了当不再需要单独的层时,会发生重绘。
如果"gets own layer"要改变,我们想要重新绘制
注意:虽然它们是Chrome特定的,我认为行为应该是类似的在其他也。
解决方案是什么?
解决方案似乎是为父元素(.qs-timer
)创建一个单独的堆叠上下文。创建一个单独的堆叠上下文似乎会导致为父层创建一个单独的合成层,这解决了这个问题。
正如BoltClock在这个回答中提到的,以下任何一个选项都会为父节点创建一个单独的堆栈上下文,并且执行其中一个选项似乎可以解决这个问题。
-
将父
.qs-timer
上的z-index
设置为非auto。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="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>
-
设置
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="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>
-
为元素添加
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="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>
前两种方法比第三种方法更可取,因为第三种方法只适用于支持CSS转换的浏览器。
是的,将opacity: 0.99;
添加到.qs-timer
的问题将会修复。
当不透明度:1或NOT定义:
在这种特殊情况下,没有涉及透明度,因此gfx
可以避免做昂贵的事情。
In case: 0.99:
nsIFrame::HasOpacity()
决定有一个不透明度,所以gfx
包含有价值的东西。(像opacity
和border-radius
一样)
需要更多的帮助,特殊情况下不透明度:0.99,将其视为不透明度:1的图形,这张票并没有提供我们的实际目标的意见,但给出了关于CSS内部发生的事情的想法。
- 如何更改文本框控件的不透明度值
- 在js中访问元素时不透明度和样式未定义,但在css中定义
- Greenstock不透明度动画从0到1再返回
- 如何在html画布上替换ByImage()而不是drawImage()(忽略不透明度)
- 设置1400个Raphael.js对象的不透明度动画会影响动画性能
- 选中复选框时降低父级的不透明度
- 更改alphaMap不透明度不会更新(THRE.JS R76)
- 如何在页面向下滚动时获得图像以获得不透明度
- 在Materialize设计中删除转盘图像的不透明度
- 如何删除javascript中的不透明度
- 如何使用javascript在rgba中获取不透明度参数
- 如何在悬停时更改高图的不透明度
- 更改整个类的不透明度元素
- 具有不透明度和类似模态行为的向导
- 选择选项可更改图像的不透明度
- 使用媒体查询设置背景图像的不透明度
- 无花果标题的不透明度正在神秘地变化
- 将鼠标悬停在图像上,图像的不透明度和图像下方标题的颜色会发生变化..同样,当标题变成两行时,它会破坏格式
- 问题,而使用过渡+不透明度变化+溢出隐藏
- 滚动时导航栏不透明度/rgba变化