我有一个名为div
的img-with-overlay
,它包含一个静态定位图像和一个绝对定位的覆盖。当img-with-overlay
被悬停时,覆盖将从0
不透明转到1
。一个意想不到的副作用是,当覆盖层是不透明的,在Chrome和基于铬的浏览器中,垂直滚动条就消失了。它不会发生在Firefox中。
你问,为什么滚动条在那里?您可以看到有一个container
,它有一个非常特定的width
和height
。如果这些维度被改变,甚至半像素,意外的副作用将不会发生.我使用这个容器来表示我的网页的body
,尽管我已经缩小了它,以便将它插入到一个片段中。虽然大多数屏幕大小不会出现问题,但我仍然希望防止它的过度发生。
$(document).ready(function () {
$('.img-with-overlay').hover(function () {
$('.overlay').css('opacity',1);
}, function () {
$('.overlay').css('opacity',0);
})
});
.container {
width: 600px;
height: 248.5px;
overflow: auto;
overflow-x: hidden;
}
.img-with-overlay {
position: relative;
overflow: hidden;
width: 100%;
}
img {
display: block;
width: 100%;
}
.overlay {
position: absolute;
top: 0;
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="img-with-overlay">
<img src="https://via.placeholder.com/468x200?text=Hover">
<div class="overlay">This is an overlay</div>
</div>
</div>
为什么当覆盖的不透明度发生变化时滚动条会消失/重新出现?
我注意到了一些有趣的事情:
如果将
div
,则不会出现滚动条。如果覆盖不透明度设置为小于1 (例如0.7 ),则滚动条不会在悬停时消失。发布于 2021-10-13 09:46:17
正在发生的事情很简单,但不那么明显。
背景
设置图像width: 100%
时,将自动计算图像高度以保留原始比例。容器比图像小一点,因为它有overflow-y: auto
,所以会出现垂直滚动。但现在,神奇的事情发生了:垂直滚动条减少了容器内部的宽度,因此图像宽度相应地减小,其高度保持比例。但是现在图像比容器小一点,所以不再需要垂直滚动条了。但是,如果滚动条消失,图像将再次展开,开始无限循环,所有东西都会闪烁。为了防止这种竞争情况,浏览器选择始终显示滚动条,但是由于图像适合于容器,因此不需要向下滚动,因此会禁用滚动条。
这就解释了为什么改变大小可以解决这个问题:如果您使容器变窄或高一点,则图像总是适合的,而不需要滚动条;如果使容器变宽或变短,则图像永远不适合,滚动条总是显示出来。
不透明度问题
现在考虑以下几点。你的图像既有display: block
,也有width: 100%
。这两个属性都影响相同的属性(宽度),但在布局工作流中以不同的方式和时间影响。这足以启动一个没有定义行为的竞赛条件,浏览器试图以自己的方式解决这个问题。您可以通过打开检查器并切换img的display
属性来验证它:在开始时,有一个禁用的滚动条,然后当您关闭该属性时,滚动条将被启用,然后当您重命名该属性时,滚动条将完全消失。什么?!我们再次处于初始条件,但结果并不相同?!:OMG:大多数情况下,这种竞赛条件没有影响,但在这种情况下,由于上一节所描述的情况,情况变得很清楚。
现在让我们来谈谈不透明。不透明度小于1的元素必须以特定的顺序呈现(从后到前),并在后面呈现不透明的元素之后。虽然我不知道Chrome和Firefox是如何实现的,但这种行为表明,在Chrome中,呈现顺序会在某种程度上影响布局工作流程。这就解释了为什么opacity=1的行为不同于opacity=0.999。但是,正如前面所解释的那样,这种情况之所以发生,只是因为有一种条件没有明确的行为。
因此,解决方案非常简单:删除导致未定义行为的条件。由于display: block
不影响图像大小,而只影响元素占用的空间,所以要做的事情是显而易见的:删除 img
,只在img
元素上留下。
如果出于某些原因,您不希望删除display: block
,则可以通过在容器上编码overflow-y: scroll
来强制滚动条始终可见(还可以删除溢出属性)。这样,您不会删除导致未定义行为的条件,而是删除滚动条上的争用条件。
https://stackoverflow.com/questions/69393843
复制相似问题