为什么“position: relative”会干扰“transform: scale”?

5

给定以下的标记和样式

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>

当鼠标悬停在第一个
元素上时,第二个
元素中的一些字母会被缩放的元素“隐藏”。然而,当在

1
嗯...它并没有真正地干扰。你看到的是一个z-index堆叠问题。你的label具有除静态位置之外的位置,这会隐式地改变渲染方式,使其“置于顶部”其他元素,包括包含的div - Joseph Marikle
1个回答

5
应用变换到一个元素会导致它建立一个新的堆叠上下文。
定位一个元素(例如将其position设置为除static以外的其他值)不一定会导致它建立一个堆叠上下文,特别是当一个相对定位的元素具有z-index:auto(默认值)时,它不会建立一个堆叠上下文。
话虽如此,这两种类型的元素在CSS2.1第9.9节定义的绘制顺序中被分成一组:
  • 在每个堆叠上下文中,以下层按从后往前的顺序绘制:
    1. 形成堆叠上下文的元素的背景和边框。
    2. 具有负堆叠级别的子堆叠上下文(最负面的先绘制)。
    3. 流动的、非内联级、非定位的后代。
    4. 非定位的浮动元素。
    5. 流动的、内联级、非定位的后代,包括内联表格和内联块。
    6. 堆叠级别为0的子堆叠上下文和堆叠级别为0的定位后代。
    7. 具有正堆叠级别的子堆叠上下文(最正面的先绘制)。
当你悬停在第一个div上时,它变成了一个堆叠级别为0的子堆叠上下文,但是这个子堆叠上下文与第二个div中的label一起参与同一个父堆叠上下文,因为第二个div本身没有建立一个堆叠上下文。
由于所有元素都具有相同的堆叠级别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>


1
哇塞!你太棒了,BoltClock!回答得真好。 - Joseph Marikle
1
@Joseph Marikle:啊,你让我害羞了——考虑到你甚至删除了你的+2答案! - BoltClock
这篇文章的研究远不如你的充分。我可能会把它收藏起来,以备查询 W3C 堆叠级别时使用。我发誓那个网站让人无法轻易找到任何东西。 - Joseph Marikle
@Joseph Marikle:有趣的是,我实际上有一些答案(http://stackoverflow.com/search?q=user%3A106224+%22within+each+stacking+context%22),它们都指向同一个列表。而我回答的所有问题都不是彼此的重复。 - BoltClock
谢谢你的出色回答。我从中学到了一些有趣的东西。我只想说,你可能没有在Chrome/Opera中测试过它。实际上,在发布问题之前,我已经尝试设置z-index,但没有成功。如果我也在Firefox甚至是Internet Explorer中进行测试,我可能会发现结果是不同的。 - Andrei V
@BoltClock 我有一个类似的HTML...但问题是 'position: relative' 导致文本模糊...如果我移除 'position relative',文本就变得清晰了...文本模糊消失了... - Fábio Zangirolami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接