为什么“位置:相对”会干扰“变换:比例”?

And*_*i V 6 html css css-position css-transforms

给定以下标记和样式

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;*/
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <label>some random text</label>
</div>
<div>
  <label>some random text</label>
</div>
Run Code Online (Sandbox Code Playgroud)

当将鼠标悬停在第一个元素上时,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;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <label>some random text</label>
</div>
<div>
  <label>some random text</label>
</div>
Run Code Online (Sandbox Code Playgroud)

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

Bol*_*ock 5

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

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

也就是说,两种类型的元素都按照CSS2.1 第 9.9 节中定义的绘制顺序分组在一起:

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

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

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

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

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

由于第一个div发生在第二个及其之前div因此 label尽管进行了变换,label第二个的div仍会绘制在第一个上。div

您可以通过指定z-index: 1on来修复此问题div:hover

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;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <label>some random text</label>
</div>
<div>
  <label>some random text</label>
</div>
Run Code Online (Sandbox Code Playgroud)