定位和层叠上下文

243 阅读11分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

position属性用来指定一个元素在网页上的位置,一共有5种定位方式,即position属性 主要有五个值。

static (默认值)

布局作用
static是 position属性的默认值。如果省略position 属性,浏览器就认为该元素是static定位。

这时浏览器会按照源码的顺序,决定每个元素的位置,这称为"正常的页面流" ( normal flow)。每个块级元素占据自己的区块(block) ,元素与元素之间不产生重叠,这个位置就是元素的默认位置。

static定位所导致的元素位置,是浏览器自主决定的,所以这时top、bottom、 left、right这四个属性无效;

relative (相对定位)

布局作用
relative表示,相对于默认位置(即static时的位置)进行偏移;

即定位基点是元素的默认位置。

它必须搭配top、bottom、left、 right这 四个属性一起使用,用来指定偏移的方向和距离。

absolute

布局作用
absolute表示,相对于上级元素(一般是父元素)进行偏移,即定位基点是父元素。

定位基点(一般是父元素)不能是static定位,否则定位基点就会变成整个网页的根元素html。

它必须搭配top、bottom、 left、 right这四个属性一起使用,用来指定偏移的方向和距离。

absolute定位的元素会被"正常页面流"忽略即在"正常页面流"中,该元素所占空间为零,周边元素不受影响。

fixed

布局作用
fixed表示,相对于视口(viewport, 浏览器窗口)进行偏移,即定位基点是浏览器窗口这会导致元素的位置不随页面滚动而变化好像固定在网页上一样。

它如果搭配top、bottom、left、 right这四个属性一起使用,表示元素的初始位置是基于视口计算的,否则初始位置就是元素的默认位置

sticky (2017年浏览器才支持的)

布局作用
sticky跟前面四个属性值都不一样,它会产生动态效果,很像relative和fixed的结合: 一些时候是relative定位(定位基点是自身默认位置),另一些时候自动变成fixed定位(定位基点是视口)

因此,它能够形成"动态固定"的效果。比如,网页的搜索工具栏,初始加载时在自己的默认位,置(relative定 位)

页面向下滚动时,工具栏变成固定位置,始终停留在页面头部(fixed定位)

等到页面重新向上滚动回到原位,工具栏也会回到默认位置。

  • sticky生效的前提是,必须搭配top、bottom、 left、 right这四个 属性一起使用, 不能省略,否则等同于relative定位,不产生"动态固定"的效果。原因是这四个属性用来定义"偏移距离", 浏览器把它当作sticky的生效门槛。

  • 它的具体规则是,当页面滚动,父元素开始脱离视口时(即部分不可见),只要与sticky元素的距离达到生效门槛,relative定位自动切换为fixed定位;等到父元素完全脱离视口时(即完全不可见),fixed定 位自动切换回relative定位。

  • 除了已被淘汰的IE以外,其他浏览器目前都支持sticky。但是,Safari浏览器需要加上浏览器前缀-webkit-;

  • position: -webkit-sticky; /* safari浏览器*/ position: sticky; /其他浏览器/

position fixed和sticky的区别

position:sticky粘性定位与position:fixed固定定位;都可以在拖动滚动条的时候,将元素固定于指定位置,但是两者的区别也是非常巨大的;

position:fixed

  • 元素可以被固定于页面指定位置,始终固定于此位置。
  • 定位位置可以通过top、bottom、 left 与right属性设置。
  • 如果属性同时设置,那么top的优先级高于bottom,left的优 先级高于right。
  • top、 bottom、 left 与right无需显式设置,fixed定 位也会生效。
  • 元素的定位参考对象是当前窗口。
  • 元素脱离文档流。

position:sticky

  • 元素可以被固定于页面指定位置,但并不一定始终固定于此位置。
  • 定位位置可以通过top、bottom、 left 与right属性设置,但是此位置是-一个临界值,也就是说元素 只有达到设置的这个临界值才会固定,其他位置并不会固定。
  • 如果属性同时设置,那么top的优先级高于bottom, left的优先级高于right。
  • 必须至少显式设置top、bottom、 left与right其中某- 一个属性值,sticky定位才会生效。
  • 元素的定位参考对象距离其最近的overflow属性值为visible的具有滚动条的祖先元素,如果是以body或者body的父辈元素为考,那么定位参考对象是窗口。
  • 元素不会脱离文档流。
  • 浏览器兼行当前有点差,不过以后肯定会越来越好。Safari目前还需要-webkit-私有前缀。

sticky 应用

堆叠效果

  • 堆叠效果(stacking)指的是页面滚动时,下方的元素覆盖上方的元素

表格的表头锁定

  • 型表格滚动的时候,表头始终固定,也可以用sticky实现

什么叫层叠上下文?

  • 层叠上下文(stacking context),是HTML中-一个三维的概念。在CSS2.1规范中, 每个盒模型的位置是三维的,分别是平面画布上的X轴,Y轴以及表示层叠的Z轴。一般情况下,元素在页面上沿X轴Y轴平铺,我们察觉不到它们在Z轴上的层叠关系。而一旦元素发生堆叠,这时就能发现某个元素可能覆盖了另一个元素或者被另一个元素覆盖。
  • 如果一个元素含有层叠上下文,(也就是说它是层叠上下文元素),我们可以理解为这个元素在Z轴上就“高人--等”,最终表现就是它离屏幕观察者更近。

层叠上下文具象理解

  • 层叠上下文是一个概念,跟「块状格式化上下文(BFC)」 类似。然而,概念这个东西是比较虚比较抽象的
  • 可以把「层叠上下文」理解为当官:网页中有很多很多的元素,我们可以看成是真实世界的芸芸众生。真实世界里,我们大多数人是普通老百姓们,还有一-部分人是做官的官员。OK,这里的“官员”就可以理解为网页中的层叠上下文元素。
  • 换句话说,页面中的元素有了层叠上下文,就好比我们普通老百姓当了官,一旦当了官,相比普通老百姓而言,离皇帝更近了,对不对,就等同于网页中元素级别更高,离我们用户更近了

什么叫层叠等级?

  • 层叠等级(stacking level, 叫“层叠级别”"层叠水平”也行)
  • 在同一个层叠上下文中,它描述定义的是该层叠上下文中的层叠上下文元素在Z轴上的上下顺序。
  • 在其他普通元素中,它描述定义的是这些普通元素在Z轴上的上下顺序;

总结

  • 普通元素的层叠等级优先由其所在的层叠上下文决定。
  • 层叠等级的比较只有在当前层叠上下文元素中才有意义。不同层叠上下文中比较层叠等级是没有意义的。

层叠上下文的例建:

  • 根层叠上下文:页面根元素天生具有层叠上下文,称之为“根层叠上下文”。
  • 定位元素与传统层叠上下文: z-index值为数值的定位元素的传统层叠上下文。
  • CSS3中的新属性也可以产生层叠上下文:
  1. z-index值不为auto的flex项(父元素display:flex|linline-flex)
  2. 元素的opacity值不是1
  3. 元素的transform值不是none
  4. 元素mix-blend-mode値不是normal
  5. 元素的filter值不是none
  6. 元素的isolation值是isolate
  7. will-change 指定的属性值为上面任意-个
  8. 元素的-webkit-overflow-scrolling 设为touch

什么叫层叠顺序?

"层叠顺序" (stacking order)表示元素发生层叠时按照特定的顺序规则在Z轴上垂直显示。由此可见,前面所说的“层叠上下文”和“层叠等级”是一种概念,而这里的“层叠顺序”是一种规则。

在不考虑CSS3的情况下,当元素发生层叠时,层叠顺讯遵循下面图中的规则。

同一个堆叠上下文元素在Z轴的排列

布局作用
创建堆叠上下文的元素的背景和边框

堆叠级别(z-index,stack level)为负值的堆叠上下文

常规流非定位的块盒

非定位的浮动盒子

常规流非定位行盒

任何z-index是auto的定位子元素,以及z-index是0的堆叠上下文

堆叠等级为正值的堆叠上下文

层叠准则

  • 谁大谁上:当具有明显的层叠水平标示的时候,如识别的z-index值, 在同一个层叠上下文领或,层叠水平值大的那-一个覆盖小的那-一个。通俗讲就是官大的压死官小的。
  • 后来居上:当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。

层叠上下文的特性

  • 层叠.上下文的层叠水平要比普通元素高
  • 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文。
  • 每个层叠上下文和兄弟元素独立,也就是当进行层叠变化或渲染的时候,只需要考虑后代元素。
  • 每个层叠上下文都是自成体系的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。

层叠上下文形成条件

含义:层叠上下文(stacking context), 它是一 块区域,这块区域由某个元素创建,它规定了该区域中的内容在Z轴上排列的先后顺序。

  • 凡是拥有层叠上下文的元素,将离用户最近,也就是越靠在Z轴前面。默认情况下只有根元素HTML会产生一个层叠上下文,并且元素一旦使用了一些属性也将会产生一个层叠上下文,如我们常用的定位属性。如两个层叠上下文相遇时,总是后一一个层叠前一个,除非使用z- index来改变

文档中的层叠上下文由满足以下任意一个条件的元素形成

  • 文档根元素(<html>)
  • position值为absolute (绝对定位)或relative (相对定位)且z-index值不为auto的元素;
  • position 值为fixed (固定定位)或sticky (粘滞定位)的元素(沾滞定位适配所有移
  • 动设备上的浏览器,但老的桌面浏览器不支持);
  • flex (flexbox)容器的子元素,且z-index值不为auto;
  • grid (grid) 容器的子元素,且z-index值不为auto;
  • opacity属性值小于1的元素

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

  • transform
  • filter
  • perspective
  • clip-path
  • mask / mask-image / mask-border
  • isolation属性值为isolate的元素;
  • webkit-overflow-scrolling
  • will-change 值设定了任一属性而该属性在non-initial 值时会创建层叠上下文的元素;
  • contain属性值为layout、paint 或包含它们其中之一的合成值(比如contain: strict、contain: content) 的元素

固定定位的特殊情况

正常情况下,固定定位是相对于浏览器视窗(viewport) 进行定位的,但是当其祖先元素中存在符合以下任意一个条件的元素时,固定定位元素会相对于该元素进行定位:

  • 1、transform属性值不为none;
  • 2、transform-style: preserve-3d;
  • 3、perspective属性值不为none;
  • 4、will-change属性指定了, 上面3个CSS属性中的任意一个;

层叠对上下文对z-index的影响

含义: z-index属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。该属性设置一个定位元素沿z轴的位置,z轴定义为垂直延伸到显示区的轴。如果为正数,则离用户更近,为负数则表示离用户更远.

  • 层叠上下文(stacking context) 并不只是z-index (必须配合position才能生效)才能创建,还有很多其他元素(如:opacity、 transform等) 也可以创建层叠上下文;

  • 在存在层叠上下文的情况下,z-index的大小决定了层叠水平(stacking level),即谁在谁上 面,这是“谁大谁上”原则;

  • 层叠水平的比较只有在同一级别的DOM节点的层叠上下文中才有意义;

  • 在同一DOM节点,并且层级水平-样的情况下,在HTML文档中写在后面的元素会遮住前面的元素(后者会在前者上面),这是"后来居上"原则;

  • 为什么这个元素会覆盖

  • 为什么设置较高的z-index不起作用