为什么“位置:相对”干扰“变换:缩放”? [英] Why does "position: relative" interfere with "transform: scale"?
问题描述
给定以下标记和样式
div {width:300px; height:50px;边框:1px纯黑色;显示:inline-block;过渡:全部.1s缓和;背景颜色:白色; padding:0px 5px;} div:hover {transform:scale(1.2);} label {/ * position:relative; * /}
< div> < label>一些随机文本< / label>< / div>< div> < label>一些随机文字< / label>< / div>
b
$ b
将第二个 div
的某些字母悬停在第一个 div
时,会被缩放元素下的隐藏 。但是,当在标签
元素上设置 position:relative
时,文本将呈现在缩放元素上:
div {width:300px; height:50px;边框:1px纯黑色;显示:inline-block;过渡:全部.1s缓和;背景颜色:白色; padding:0px 5px;} div:hover {transform:scale(1.2);} label {position:relative;}
< div> < label>一些随机文本< / label>< / div>< div> < label>一些随机文字< / label>< / div>
b
$ b我试图理解这背后的原因。由于这些接口在浏览器中保持一致,我认为它是在规格中定义的。如果是这样,基本原理是什么?如果不能触及相对位置,我该如何关闭它?解析方案
将元素应用于元素导致它建立一个新的堆栈上下文。
定位一个元素(即将 static
)并不一定会导致它建立一个堆栈上下文,特别是一个相对定位的元素,其中 z-index:auto
(缺省值)不会建立堆栈上下文。
就是说,这两种元素按照 CSS2.1的第9.9节:
在每个堆叠环境中,以下图层按照先后顺序绘制:
- 背景以及构成堆叠上下文的元素的边界。
- 子stac (负数第一)。
- 流入式,非内联式,非定位后裔。
- 包含行内表格和内联块的流入内联级别非定位后代。
- 具有积极堆栈级别的子堆叠上下文(最不积极优先)。
li>
当您将第一个 div
成为堆栈级别为0的子堆叠上下文,但此子堆叠上下文参与第二个 div 中的
标签
code>作为第二个 div
本身并不建立堆叠上下文。
由于所有的元素具有相同的堆栈级别0(基于默认 z-index:au这个规范说:
在堆叠环境中具有相同堆栈级别的框被堆叠回来,由于你的第一个
div
发生了,在第二个div
和它标签
之前,标签<尽管进行了转换,第二个
div
的第二个/ code>被绘制在第一个div
上。
您可以通过在
div:hover $ c $>上指定
z-index:1
div {width:300px; height:50px;边框:1px纯黑色;显示:inline-block;过渡:全部.1s缓和;背景颜色:白色; padding:0px 5px;} div:hover {transform:scale(1.2); z-index:1;} label {position:relative;}
< DIV> < label>一些随机文本< / label>< / div>< div> < label>一些随机文本< / label>< / div>
Given the following markup and style
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>
when hovering over the first
div
some letter from the seconddiv
are being "hidden" under the scaled element. When, however,position: relative
is set on thelabel
element, the text gets rendered over the scaled element: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>
I'm trying to understand the reasoning behind this. Since this seams consistent across browsers, I'm thinking that it is defined in the specs. If so, what's the rationale? And how do I "turn it off", if can't touch the relative positioning?
解决方案Applying a transform to an element causes it to establish a new stacking context.
Positioning an element (i.e. setting its
position
to something other thanstatic
) doesn't necessarily cause it to establish a stacking context, in particular a relatively positioned element withz-index: auto
(the default) does not establish a stacking context.That being said, both types of elements are grouped together in the painting order defined in 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).
When you hover the first
div
, it becomes a child stacking context with stack level 0, but this child stacking context participates in the same parent stacking context as thelabel
in the seconddiv
as the seconddiv
itself doesn't establish a stacking context.As all of your elements have the same stack level of 0 (based on the default
z-index: auto
), the spec says:Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
Since your first
div
occurs before the seconddiv
and itslabel
, thelabel
of the seconddiv
is painted over the firstdiv
despite the transform.You can fix this by specifying
z-index: 1
ondiv: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; }
<div> <label>some random text</label> </div> <div> <label>some random text</label> </div>
这篇关于为什么“位置:相对”干扰“变换:缩放”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!