探究 position-sticky 失效问题

简介: 探究 position-sticky 失效问题

CSS 的 position 值中,有一个非常有用的值 -- position: sticky,通常会被用于各种吸顶,吸底,吸边的效果中。


如果你对 sticky 还不太熟悉,可以先看看我的这篇文章:使用 position:sticky 实现粘性布局,当然,这篇文章里面有稍微探讨 position: sticky 生效或者说失效的规则,但是不太充分。


最近遇到一些 position-sticky 失效的场景,所以总结了一下。

 

position-sticky 生效的原理



在 W3 官方文档中的定义是:Sticky positioning is similar to relative positioning except the offsets are automatically calculated in reference to the nearest scrollport.


转换成通俗的大白话就是,Sticky 定位类似于相对定位,(当它表现为 fixed 定位的特性时)会根据最近的滚动容器(nearest scrollport)自动计算偏移量。

其中有一个非常重要的概念就是 nearest scrollport,它表示 sticky 元素在即将消失前会相对它最近的 scrollport 去做定位。

 

正常的 DEMO


所以正常而言,类似下面的这种情况,sticky 是可以正常展示的。


<div class="container"> - 可滚动的容器 scrollport    
    <div class="sticky">   - 设置了 sticky 的元素

608782-20201223184412023-354635239.gif


CodePen Demo -- Normal Sticky Demo 


失效的 position: sticky



1、包裹的父容器高度与 sticky 元素一致


有趣的是,如果在 .sticky 元素和你希望 .sticky 生效吸附的滚动元素中间,添加上一层 .parent 的 div 元素,不给 div 添加任何样式,sticky 则失效了。

譬如是这样:


<div class="container">      - 可滚动的容器 scrollport    
    <div class="parent">
         <div class="sticky">   - 设置了 sticky 的元素

608782-20201223184607730-1786843282.gif


CodePen Demo -- invalid Sticky Demo 1


失效原因:此时 .sticky 元素的最近的 scrollport 变成了它的父容器 div,而父容器 div 的高度和 .sticky 元素的高度是一样的,所以表现不出 fixed 的特性。

其实,这里不算失效,我们只需要将包裹 .sticky 元素的父容器的高度设置的大于 .sticky 元素本身,也能看到效果。

譬如,我们可以加上


.parent {
    height: 100vh;
}

此时,sticky 将重新生效,像是这样:

608782-20201223184710351-1417842054.gif


其实,造成这种现象的本质原因是,设置了 position: sticky 的元素吸附的基准元素从 .container 变成了 .parent 。

 

2、包裹的父容器设置了 overflow: hidden


第二种情况,也会导致 position: sticky 的 fixed 定位特性失效。也就是 .sticky 元素的祖先容器存在 overflow: hidden。类似这样

<div class="container">      - 可滚动的容器 scrollport    
    <div class="hidden">      - 设置了 overflow: hidden
         <div class="sticky">   - 设置了 sticky 的元素

608782-20201223184738674-987109470.gif


CodePen Demo -- invalid Sticky Demo 2


在上面这个 DEMO 里面,设置了 sticky 的元素的父元素 hidden 元素,它的高度是远比 stikcy 元素高的,但是滚动的过程中却没有表现出 fixed 的特性。

原因在于,设置了 overflow: hidden 的元素,它不再代用滚动的特性,当 sticky元素吸附于.hidden元素的顶部时,它随着 .hidden` 元素本身在 container 移动。所以,所有的 sticky 元素都会被滚动出 container 的滚动区域。

当然,这里有一点比较奇怪的是,.sticky 元素相对 .hidden 元素进行 fixed 定位,而不是相对 .container 元素进行 fixed 定位,表面设置了 overflow: hidden 的元素,它也是一个 scrollport。

其实,不止是 overflow: hidden ,设定为 position: sticky 元素的任意父节点的 overflow 属性必须是 visible,否则 position:sticky 不会生效。

 

总结一下



看完上面几个 DEMO,可以好好总结一下 position:sticky 的生效规则,明白了生效规则就会知道为什么有的时候设定的 sticky 会失效:

  1. 须指定 top, right, bottom 或 left 四个阈值其中之一(且达到设定的阈值),才可使粘性定位生效。否则其行为与相对定位相同;
  • 并且 top 和 bottom 同时设置时,top 生效的优先级高,left 和 right 同时设置时,left 的优先级高
  1. 设定为 position: sticky 的元素的任意父节点的 overflow 属性必须是 visible,否则 position:sticky 不会生效;在满足上述情况下,设定了 position: sticky 的元素的父容器的高度必须大于当前元素,否则也会失效。(当然,此时,sticky 吸附的基准元素就会变成父元素)
  • 如果 position: sticky 元素的任意父节点定位设置为 position: overflow,则父容器无法进行滚动,所以 position:sticky 元素也不会有滚动然后固定的情况
  1. 在满足上述情况下,设定了 position: sticky 的元素的父容器的高度必须大于当前元素,否则也会失效。(当然,此时,sticky 吸附的基准元素就会变成父元素
目录
相关文章
|
JavaScript
原生js中offsetTop, offsetLeft与offsetParent的详细讲解
原生js中offsetTop, offsetLeft与offsetParent的详细讲解
|
JavaScript 前端开发 API
007 Umi 使用 TypeScript 提升开发者体验
007 Umi 使用 TypeScript 提升开发者体验
1381 0
007 Umi 使用 TypeScript 提升开发者体验
npm如何切换淘宝源镜像
npm如何切换淘宝源镜像
4315 0
|
前端开发 容器
彻底理解粘性定位 - position: sticky
彻底理解粘性定位 - position: sticky
|
存储 API
vue3中如何动态自定义创建组件并挂载
vue3中如何动态自定义创建组件并挂载
1094 90
|
监控 前端开发 JavaScript
JS Navigator.sendBeacon 可靠的、异步地向服务器发送数据
Navigator.sendBeacon 是一个用于发送少量数据到服务器的 API,尤其适用于在页面即将卸载时发送数据,如日志记录、用户行为分析等。 与传统的 AJAX 请求不同,sendBeacon 方法的设计目标是确保数据在页面卸载(例如用户关闭标签页或导航到新页面)时能够可靠地发送。 Navigator.sendBeacon 方法可用于通过 HTTP POST 将少量数据异步传输到 Web 服务器。 它主要用于将统计数据发送到 Web 服务器,同时避免了用传统技术(如:XMLHttpRequest)发送分析数据的一些问题。
505 1
|
JSON JavaScript 前端开发
vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户
vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户
|
IDE Java 编译器
lombok编译遇到“找不到符号的问题”
【9月更文挑战第18天】当使用 Lombok 遇到 “找不到符号” 的问题时,可能是由于 Lombok 未正确安装、编译器不支持、IDE 配置不当或项目构建工具配置错误。解决方法包括确认 Lombok 安装、编译器支持,配置 IDE 和检查构建工具配置。通过这些步骤通常可解决问题,若问题仍存在,建议检查项目配置和依赖,或查看日志获取更多信息。
5450 2
|
存储 消息中间件 运维
架构升级的救星!流量回放自动化测试的必备指南
大家好,我是小米,一名29岁的技术宅。今天分享一个物联网领域的实用技能——流量回放自动化测试。系统重构后,测试工作量巨大,本文介绍如何通过日志收集和数据回放进行自动化测试,包括离线、实时和并行回放模式,帮助快速定位Bug,提升测试效率和系统稳定性。欢迎关注我的微信公众号“软件求生”,获取更多技术干货!
462 3
|
Web App开发 移动开发 JavaScript
【Vue版】实现拖拽、排序效果(注意,这个方法在chrome谷歌浏览器上面不适用,dragend会情不自禁触发drag事件先执行,有点像浏览器的一个bug)
【Vue版】实现拖拽、排序效果(注意,这个方法在chrome谷歌浏览器上面不适用,dragend会情不自禁触发drag事件先执行,有点像浏览器的一个bug)