当前位置: 首页 > article >正文

详解position: sticky粘性定位

深入了解sticky属性值与粘性定位

  • 1 前言
  • 1 可滚动元素对粘性定位的影响
  • 2 理解粘性定位的计算规则
  • 3 理解粘性定位的堆叠规则
  • 4 其他

1 前言

我们经常可以看到这样的效果,当导航元素在屏幕内的时候,可以跟随屏幕内容一起滚动,当导航元素到上边缘的距离为0的时候,就粘在了上边缘,如同固定定位的效果。

这样的效果实现只需要几行CSS代码:

position: -webkit-sticky;
position: sticky;
top: 0;

当粘性定位元素“粘住”的时候,看起来和效果和固定定位一样,但是它和固定定位并没有任何关系,粘性定位是相对定位的延伸。

粘性定位和相对定位有一些共同点

  • 元素发生偏移的时候,元素的原始位置是保留的
  • 创建了新的绝对定位包含块,也就是粘性定位元素里面如果有绝对定位的子元素,那么这个子元素的left属性、top属性、right属性和bottom属性时的偏移计算是相对于当前粘性定位元素的
  • 支持设置z-index属性值来改变元素的层叠顺序

再说一下粘性定位和相对定位的不同点

  • 偏移计算元素不一样。相对定位偏移计算的容器是父元素,而粘性定位偏移计算的元素是层级最近的可滚动元素overflow属性值不是visible的元素)。如果一个可滚动元素都没有,则相对浏览器视窗进行位置偏移
  • 偏移定位计算规则不一样。粘性定位的计算规则比较复杂,涉及多个粘性定位专有的概念
  • 重叠表现不一样。相对定位元素彼此独立,重叠的时候表现为堆叠;但是粘性定位元素在特定布局下,元素重叠的时候表现为A粘性定位元素推开B粘性定位元素的视觉表现

接下来深入讲解一下上面提到的3点不同之处。

1 可滚动元素对粘性定位的影响

通常的Web页面都是窗体(body)滚动的,而粘性定位偏移计算的元素是层级最近的那个滚动元素。因此如果粘性定位的某个祖先元素的overflow的属性值不是visible,那么窗体滚动的时候就不会有粘性定位的效果,例如:

<div class="hidden">
  <nav class="nav">橘猫吃不胖</nav>
</div>
<div class="block" style="background-color: lightblue;">滚动块1</div>
<div class="block" style="background-color:cornflowerblue;">滚动块2</div>
<div class="block" style="background-color: darkblue;">滚动块3</div>
.hidden {
  width: 200px;
  height: 200px;
  background-color: lemonchiffon;
  overflow: hidden;
}

.nav {
  position: sticky;
  top: 0;
  background-color: orange;
}

.block {
  width: 150px;
  height: 150px;
}

把浏览器窗口高度缩小,此时滚动页面<nav>元素是没有粘性效果的,因为<nav>元素粘性定位的偏移计算是相对于父级<div>元素计算的,粘性效果也只有在<div>元素滚动的时候才能够体现。
在这里插入图片描述
在这里插入图片描述
如果我们将div元素样式调整一下,让div元素成为可滚动元素,如下所示:

<div class="hidden">
  <nav class="nav">橘猫吃不胖</nav>
  <div class="block" style="background-color: lightblue;">滚动块1</div>
  <div class="block" style="background-color:cornflowerblue;">滚动块2</div>
  <div class="block" style="background-color: darkblue;">滚动块3</div>
</div>
.scroll {
  width: 300px;
  height: 300px;
  background-color: lemonchiffon;
  overflow: auto;
}

.nav {
  position: sticky;
  top: 0;
  background-color: orange;
}

.block {
  width: 150px;
  height: 150px;
}

此时滚动div元素,就会发现nav元素没有跟着滚动,有粘性定位的效果。
在这里插入图片描述

2 理解粘性定位的计算规则

粘性定位中有一个“流盒”(flow box)的概念,指的是粘性定位元素最近的可滚动元素的尺寸盒子,如果没有可滚动的元素,则表示浏览器视窗盒子。

粘性定位中还有一个名为“粘性约束矩形”的概念,指的是粘性定位元素的包含块(通常是父元素)在文档流中呈现的矩形区域和流盒的4个边缘在应用黏性定位元素的lefttoprightbottom属性的偏移计算值后的新矩形的交集。

滚动的时候,流盒的位置是不变的,粘性定位元素的包含块跟着滚动,因此粘性约束矩形随着滚动是实时变化的。假设我们的粘性定位元素只设置了top属性值,则粘性定位元素碰到粘性约束矩形的顶部时就开始向下移动,直到它完全被包含在粘性约束矩形中。

上面就是粘性定位计算和渲染的规则,下面通过一个例子来理解上面这段描述。

我们设计一个窗体滚动的页面,包含父子关系的divnav元素,代码如下

<body>
  <div class="container">
    <nav class="nav">橘猫吃不胖</nav>
  </div>
  <div class="block" style="background-color: lightblue;">滚动块1</div>
  <div class="block" style="background-color:cornflowerblue;">滚动块2</div>
</body>
.container {
  height: 100px;
  margin-top: 50px;
  border: 3px solid orange;
}

.nav {
  position: sticky;
  top: 20px;
  background-color: yellow;
}

.block {
  width: 150px;
  height: 150px;
}

上面这段代码实际效果如下所示,nav这个粘性定位元素的top偏移是20px,并且最近可滚动尺寸盒子是浏览器视窗盒子,那么流盒矩形就是浏览器滚动窗口矩形向下偏移20px的地方,也就是蓝色线往下的区域。粘性定位元素nav的包含块是其父元素container(设置了橘黄色边框),粘性约束矩形就是流盒矩形和包含块的重叠区域,也就是蓝色线下方和橘黄色方框区域重叠的矩形区域。
在这里插入图片描述
在初始状态下,由于container元素设置了margin-top: 50px;,所以nav粘性定位元素的顶部到可以完全触碰到粘性约束矩形顶部(粘性约束矩形是要一起往上滚动的)有33px(流盒到粘性约束矩形顶部30px+粘性约束矩形的边框3px),这时滚动浏览器页面不会有粘性效果,如下图所示:
在这里插入图片描述
页面接着向上滚,nav元素的顶部距离粘性约束矩形的顶部越来越小,直到距离为0,这时nav元素开始下移,把自己约束在粘性约束矩形的范围里面,此时的粘性约束矩形为nav元素的顶部到下方的橘黄色边框。
在这里插入图片描述
在这里插入图片描述
页面继续滚动,直到nav元素的底部和粘性约束矩形范围的底部重合,页面再继续向上滚动时,粘性约束矩形会继续变小,由于粘性定位元素不能超过粘性约束矩形的范围,所以粘性效果失效了,nav元素会跟着一起滚走。
在这里插入图片描述
在这里插入图片描述
了解了粘性定位的计算规则,那么我们就明白了,如果粘性定位元素的父元素的高度和粘性定位元素的高度相同,那么垂直滚动的时候,粘性定位的效果是不会出现的,因为这时粘性定位元素没有了实现粘性效果的空间。

3 理解粘性定位的堆叠规则

黏性定位元素的偏移由容器决定,如果多个黏性定位元素在同一容器中,则这几个黏性定位元素会产生元素重叠的情况;

如果黏性定位元素分布在不同的容器中,同时这些容器在布局上是上下紧密相连的,则视觉上会表现为新的黏性定位元素挤开原来的黏性定位元素,形成依次占位的效果。

例如,同一个容器中,包含了多个粘性定位元素,代码如下:

<body>
  <div class="container">A</div>
  <div class="block" style="background-color: lightblue;">滚动块1</div>
  <div class="container">B</div>
  <div class="block" style="background-color:cornflowerblue;">滚动块2</div>
  <div class="container">C</div>
  <div class="block" style="background-color: darkblue;">滚动块3</div>
</body>
.container {
  position: sticky;
  top: 0;
  background-color: yellow;
}

.block {
  width: 100%;
  height: 150px;
}

上面这个示例中,在同一个容器body中包含了许多个粘性定位元素container,在滚动浏览器页面的时候,可以看到出现了元素重叠的现象。
在这里插入图片描述
在这里插入图片描述
再比如说粘性定位元素分布在不同的容器中,例如下面这段代码:

<body>
  <div>
    <div class="container">A</div>
    <div class="block" style="background-color: lightblue;">滚动块1</div>
  </div>
  <div>
    <div class="container">B</div>
    <div class="block" style="background-color:cornflowerblue;">滚动块2</div>
  </div>
  <div>
    <div class="container">C</div>
    <div class="block" style="background-color: darkblue;">滚动块3</div>
  </div>
</body>
.container {
  position: sticky;
  top: 0;
  background-color: yellow;
}

.block {
  width: 100%;
  height: 150px;
}

上面这个示例中,粘性定位元素分布在了不同的元素中,滚动浏览器页面,可以看到下面的元素把上面的元素推开了。
在这里插入图片描述
这是因为当粘性定位元素分布在不同的容器时,就会有多个不同的粘性约束矩形,这些粘性约束矩形排列整齐,所以视觉表现出来就是上一个粘性定位元素被滚走。当粘性定位元素共用一个容器的时候,也就共用一个粘性约束矩形,这时滚动元素会一个一个重叠起来。

4 其他

Safari浏览器中,粘性定位元素需要添加-webkit-私有前缀。


http://www.kler.cn/a/511723.html

相关文章:

  • EasyControl:首个登陆AWS Marketplace的中国MDM先锋
  • mongodb详解二:基础操作
  • 利用rsync备份全网服务器数据
  • 芯片详细讲解,从而区分CPU、MPU、DSP、GPU、FPGA、MCU、SOC、ECU
  • 解决 WSL 2 中 Ubuntu 22.04 安装 Docker 后无法启动的问题
  • redis性能优化参考——筑梦之路
  • 性能优化之动态加载
  • Android APK的打包流程_android apk打包流程
  • iOS UIScrollView的一个特性
  • (k8s)k8s部署mysql与redis(无坑版)
  • opengrok_windows_环境搭建
  • 云原生周刊:K8s 生产环境架构设计及成本分析
  • pthread_exit函数
  • HTML之拜年/跨年APP(改进版)
  • 基于Java+SpringBoot+Vue的前后端分离的家具网站
  • 大数据学习(36)- Hive和YARN
  • Auto-go 环境配置
  • 华为升腾算子开发(一) helloword
  • 使用vscode在本地和远程服务器端运行和调试Python程序的方法总结
  • 游戏画面总是卡顿 原因及解决方法
  • 第 3 章 核心处理层(中)
  • Elixir语言的文件操作
  • 【初阶数据结构】探索数据的多米诺链:单链表
  • 跳石头,,
  • 【机器学习】嘿马机器学习(科学计算库)第11篇:Pandas,学习目标【附代码文档】
  • TensorFlow深度学习实战——情感分析模型