为什么 "position: relative" 会干扰 "transform: scale"?
Why does "position: relative" interfere with "transform: scale"?
给定以下标记和样式
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
中的某些字母正在 "hidden" 缩放元素下方。但是,当在 label
元素上设置 position: relative
时,文本将呈现在缩放元素上:
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>
我正在尝试理解这背后的原因。由于这种接缝跨浏览器是一致的,我认为它是在规范中定义的。如果是这样,理由是什么?还有我怎么"turn it off",如果摸不到相对定位呢?
对元素应用转换会导致它建立新的堆叠上下文。
定位元素(即将其 position
设置为 static
以外的其他内容)不一定会导致它建立堆叠上下文,特别是相对定位的元素 z-index: auto
(默认值)不建立堆叠上下文。
话虽如此,两种类型的元素都按照 section 9.9 of CSS2.1 中定义的绘制顺序组合在一起:
Within each stacking context, the following layers are painted in back-to-front order:
- the background and borders of the element forming the stacking context.
- the child stacking contexts with negative stack levels (most negative first).
- the in-flow, non-inline-level, non-positioned descendants.
- the non-positioned floats.
- the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
- the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
- the child stacking contexts with positive stack levels (least positive first).
当您悬停第一个 div
时,它成为堆栈级别为 0 的子堆栈上下文,但此子堆栈上下文与第二个 label
中的子堆栈上下文参与相同的父堆栈上下文 div
因为第二个 div
本身不建立堆栈上下文。
由于您的所有元素都具有相同的堆栈级别 0(基于默认值 z-index: auto
),规范说:
Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
由于您的第一个 div
发生在第二个 div
和 its label
之前,因此第二个 label
div
被绘制在第一个 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>
给定以下标记和样式
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
中的某些字母正在 "hidden" 缩放元素下方。但是,当在 label
元素上设置 position: relative
时,文本将呈现在缩放元素上:
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>
我正在尝试理解这背后的原因。由于这种接缝跨浏览器是一致的,我认为它是在规范中定义的。如果是这样,理由是什么?还有我怎么"turn it off",如果摸不到相对定位呢?
对元素应用转换会导致它建立新的堆叠上下文。
定位元素(即将其 position
设置为 static
以外的其他内容)不一定会导致它建立堆叠上下文,特别是相对定位的元素 z-index: auto
(默认值)不建立堆叠上下文。
话虽如此,两种类型的元素都按照 section 9.9 of CSS2.1 中定义的绘制顺序组合在一起:
Within each stacking context, the following layers are painted in back-to-front order:
- the background and borders of the element forming the stacking context.
- the child stacking contexts with negative stack levels (most negative first).
- the in-flow, non-inline-level, non-positioned descendants.
- the non-positioned floats.
- the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
- the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
- the child stacking contexts with positive stack levels (least positive first).
当您悬停第一个 div
时,它成为堆栈级别为 0 的子堆栈上下文,但此子堆栈上下文与第二个 label
中的子堆栈上下文参与相同的父堆栈上下文 div
因为第二个 div
本身不建立堆栈上下文。
由于您的所有元素都具有相同的堆栈级别 0(基于默认值 z-index: auto
),规范说:
Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
由于您的第一个 div
发生在第二个 div
和 its label
之前,因此第二个 label
div
被绘制在第一个 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>