【问题标题】:Why does "position: relative" interfere with "transform: scale"?为什么“位置:相对”会干扰“变换:比例”?
【发布时间】:2016-02-17 23:48:42
【问题描述】:

给定以下标记和样式

div {
  width: 300px;
  height: 50px;
  border: 1px solid black;
  display: inline-block;
  transition: all .1s ease-in-out;
  background-color: white;
  padding: 0px 5px;
}
div:hover {
  transform: scale(1.2);
}
label {
  /*position: relative;*/
}
<div>
  <label>some random text</label>
</div>
<div>
  <label>some random text</label>
</div>

当悬停在第一个 div 上时,来自第二个 div 的一些字母被“隐藏”在缩放元素下。但是,当 position: relative 设置在 label 元素上时,文本会在缩放的元素上呈现:

div {
  width: 300px;
  height: 50px;
  border: 1px solid black;
  display: inline-block;
  transition: all .1s ease-in-out;
  background-color: white;
  padding: 0px 5px;
}
div:hover {
  transform: scale(1.2);
}
label {
  position: relative;
}
<div>
  <label>some random text</label>
</div>
<div>
  <label>some random text</label>
</div>

我试图了解这背后的原因。由于这在浏览器之间是一致的,我认为它是在规范中定义的。如果是这样,理由是什么?如果无法触摸相对定位,我该如何“关闭它”?

【问题讨论】:

  • 呃……这并不是真正的干扰。您看到的是 z-index 堆叠问题。你的labels 有一个静态以外的位置,它隐式地将渲染更改为其他元素的“顶部”,包括包含divs

标签: html css css-position css-transforms


【解决方案1】:

对元素应用变换会导致它建立新的堆叠上下文。

定位元素(即将其position 设置为static 以外的其他值)不一定会导致它建立堆叠上下文,特别是具有z-index: auto(默认值)的相对定位元素不会建立堆叠上下文。

话虽如此,两种类型的元素都按照section 9.9 of CSS2.1中定义的绘制顺序组合在一起:

在每个堆叠上下文中,以下图层按从后到前的顺序绘制:

  1. 构成堆叠上下文的元素的背景和边框。
  2. 具有负堆栈级别(最负优先)的子堆栈上下文。
  3. 流入、非内联级别、非定位的后代。
  4. 未定位的浮动。
  5. 流入、内联级、非定位后代,包括内联表和内联块。
  6. 堆栈级别为 0 的子堆栈上下文和堆栈级别 0 的定位后代。
  7. 具有正堆栈级别的子堆栈上下文(最不正的优先)。

当您悬停第一个div 时,它会成为堆栈级别为0 的子堆栈上下文,但此子堆栈上下文与第二个div 中的label 和第二个@ 参与相同的父堆栈上下文987654329@ 本身不建立堆栈上下文。

由于您的所有元素都具有相同的堆栈级别 0(基于默认的 z-index: auto),因此规范说:

在堆叠上下文中具有相同堆叠级别的框根据文档树顺序从后到前堆叠。

由于您的第一个 div 出现在第二个 div label 之前,因此第二个 divlabel 被绘制在第一个 div 上,尽管进行了转换.

您可以通过在 div:hover 上指定 z-index: 1 来解决此问题:

div {
  width: 300px;
  height: 50px;
  border: 1px solid black;
  display: inline-block;
  transition: all .1s ease-in-out;
  background-color: white;
  padding: 0px 5px;
}
div:hover {
  transform: scale(1.2);
  z-index: 1;
}
label {
  position: relative;
}
<div>
  <label>some random text</label>
</div>
<div>
  <label>some random text</label>
</div>

【讨论】:

  • 哇哦!你去吧,BoltClock!很好的答案。
  • @Joseph Marikle:哦,你让我脸红了——考虑到你甚至删除了你的 +2 答案!
  • 它的研究不如你的那么好。当我需要在 W3C 上找到堆叠级别时,我可能会将此添加为书签。我发誓那个网站让我很难找到任何东西。
  • @Joseph Marikle:有趣的是,我实际上有一个handful of answers,它们都指向同一个列表。而且我回答的所有问题都不是彼此重复的。
  • 感谢您的出色回答。我从中学到了一些有趣的东西。我只想说你可能没有在 Chrome/Opera 中测试过它。我实际上已经尝试在发布问题之前设置z-index,但没有运气。如果我也在 Firefox 甚至 Internet Explorer 中测试它,我会看到结果是不同的。
猜你喜欢
  • 1970-01-01
  • 2023-04-01
  • 2013-01-07
  • 2014-07-18
  • 1970-01-01
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多