探究 position-sticky 失效问题

CSS 的 position 值中,有一个很是有用的值 -- position: sticky,一般会被用于各类吸顶,吸底,吸边的效果中。css

若是你对 sticky 还不太熟悉,能够先看看个人这篇文章:使用 position:sticky 实现粘性布局,固然,这篇文章里面有稍微探讨 position: sticky 生效或者说失效的规则,可是不太充分。html

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

 

position-sticky 生效的原理

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

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

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

 

正常的 DEMO

因此正常而言,相似下面的这种状况,sticky 是能够正常展现的。spa

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

CodePen Demo -- Normal Sticky Demo 3d

失效的 position: sticky

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

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

譬如是这样:code

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

CodePen Demo -- invalid Sticky Demo 1

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

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

譬如,咱们能够加上

.parent {
    height: 100vh;
}

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

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

 

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

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

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

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 的优先级高
  2. 设定为 position: sticky 的元素的任意父节点的 overflow 属性必须是 visible,不然 position:sticky 不会生效;在知足上述状况下,设定了 position: sticky 的元素的父容器的高度必须大于当前元素,不然也会失效。(固然,此时,sticky 吸附的基准元素就会变成父元素)
    • 若是 position: sticky 元素的任意父节点定位设置为 position: overflow,则父容器没法进行滚动,因此 position:sticky 元素也不会有滚动而后固定的状况
  3. 在知足上述状况下,设定了 position: sticky 的元素的父容器的高度必须大于当前元素,不然也会失效。(固然,此时,sticky 吸附的基准元素就会变成父元素)

 

最后

好了,本文到此结束。

更多精彩 CSS 技术文章汇总在个人 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

若是还有什么疑问或者建议,能够多多交流,原创文章,文笔有限,才疏学浅,文中如有不正之处,万望告知。

相关文章
相关标签/搜索