为什么“位置:相对”干扰“变换:缩放”? [英] Why does "position: relative" interfere with "transform: scale"?

查看:128
本文介绍了为什么“位置:相对”干扰“变换:缩放”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下标记和样式

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节


在每个堆叠环境中,以下图层按照先后顺序绘制:


  1. 背景以及构成堆叠上下文的元素的边界。
  2. 子stac (负数第一)。
  3. 流入式,非内联式,非定位后裔。

  4. 包含行内表格和内联块的流入内联级别非定位后代。

  5. 具有积极堆栈级别的子堆叠上下文(最不积极优先)。
  6. li>


当您将第一个 div 成为堆栈级别为0的子堆叠上下文,但此子堆叠上下文参与第二个 div 中的标签 code>作为第二个 div 本身并不建立堆叠上下文。



由于所有的元素具有相同的堆栈级别0(基于默认 z-index:au这个规范说:


在堆叠环境中具有相同堆栈级别的框被堆叠回来,由于你的第一个 div 发生了,在第二个 div 标签之前,标签<尽管进行了转换,第二个 div 的第二个/ code>被绘制在第一个 div 上。



您可以通过在 div:hover 上指定 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 second div are being "hidden" under the scaled element. When, however, position: relative is set on the label 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 than static) doesn't necessarily cause it to establish a stacking context, in particular a relatively positioned element with z-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:

  1. the background and borders of the element forming the stacking context.
  2. the child stacking contexts with negative stack levels (most negative first).
  3. the in-flow, non-inline-level, non-positioned descendants.
  4. the non-positioned floats.
  5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. 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 the label in the second div as the second div 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 second div and its label, the label of the second div is painted over the first div despite the transform.

You can fix this by specifying z-index: 1 on 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;
}

<div>
  <label>some random text</label>
</div>
<div>
  <label>some random text</label>
</div>

这篇关于为什么“位置:相对”干扰“变换:缩放”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆