CSS定位和层叠上下文

220 阅读3分钟

定位

position的五个属性

1、static 默认值,待在文档流中也就是可以理解为正常的文档流。

2、relative 相对定位,相对于自己的位置定位,升起来,但是不脱离文档流。

3、absolute 绝对定位,定位基准是祖先里的非static的元素。是相对于祖先元素中最近的一个定位元素定位的,并不是只相对于relative定位的(一般在写代码时我们都是让他和relative成对出现)。

4、fixed 固定定位,定位基准是视口(viewport),也就是相对于视口的定位。但是如果它的父元素加上transform:scale(x)那么它就不是相对于视口的定位了,所以尽量不要把fixed写在有transform:scale(x)的父级元素上。手机上也尽量不要用。

5、sticky粘滞定位。如果在浏览器页面上能看到sticky属性的元素,它按照文档流排列,一旦滑动浏览器的页面,当要把元素划过时,它就会粘在也页面的最上方,也就是始终保持在浏览器的头部,像导航条一样,但是不影响滑动(现在大部分浏览器还不支持)。

关于position的一些经验

1、如果写了absolute,一般都要补一个relative。

2、如果写了absolute或fixed,一定要写top和left(有些浏览器不写会出错)。

3、善用left:100%,left:50%,加负margin、bottom:100%。

absolute使用left:100%,会基于它的relative或根元素html的大小。

4、一般来说一个东西的关闭按钮(对话框等)都是用绝对定位absolute来写的。

z-index和position(定位)的关系

1、z-index只对有定位属性的元素有效,一般情况下是数只能越大就在最上面,所以如果想改变他们的上下关系直接改动z-index的值。

2、默认情况下z-index:auto。

层叠上下文

我们可以通过代码验证在没有position之前的时候的堆叠顺序。如图所示: 可以得出结论:background < boder < div < float < span

加上position(除static)之后,就全部盖上了。说明定位属性是最高的。

z-index说明

1、z-index 正值越大,越在上面,负值越小越在下面。

这句话不完全正确,假设一个两个子元素,他们分别设置了定位(非static),并分别设置了z-index:1和z-index:-1;

  • 倘若父元素的z-index为默认auto的情况下,那么设置z-index:1的元素肯定比设置-1的元素要高,这是符合z-index基本顺序的,并且设置z-index:-1的元素会脱离父元素的层叠上下文,也就是会比父元素的background还要低。

  • 但是如果父元素都设置了z-index,那情况就发生了变化,子元素之间的index无法比较,因为取决于父元素的z-index值。

就好比同样是保姆,即使一个是高级职称的保姆,一个是中级职称的保姆,不比较主人家的情况当然是高级的更高。但是假设低级的主人是皇帝,高级的主人是地主,那么情况自然无法对比,因为主人(父元素的z-index)不同。

当父元素设置z-index为其他时,就有了一个新的层叠上下文作用域。(原本的是基准点为html的层叠上下文,改变成了基于父元素的层叠上下文)。

我们再来看,当父元素设置了z-index后,子元素设置为z-index:-1的会怎样? 可以推导出,在父元素的z-index为默认(或者没有)时,子元素会脱离父元素的层叠上下文,变成基于html的层叠上下文。而当父元素设置了z-index为其他时,子元素依然逃不出父元素的层叠上下文。

那么最终我们得出一张图:

2、那我来考考你:z-index:5 和z-index:9999哪个大?

什么情况下会出现层叠上下文

满足以下 12 个条件中任意一个的元素会创建一个层叠上下文(来自MDN)

文档根元素(<html>);

position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;

position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);

flex (flexbox) 容器的子元素,且 z-index 值不为 auto;

grid (grid) 容器的子元素,且 z-index 值不为 auto;

opacity 属性值小于 1 的元素

mix-blend-mode 属性值不为 normal 的元素;

以下任意属性值不为 none 的元素:

transform

filter

perspective

clip-path

mask / mask-image / mask-border

isolation 属性值为 isolate 的元素;

-webkit-overflow-scrolling 属性值为 touch 的元素;

will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素

contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素。

(需要特别记忆的已经加粗)