CSS 中 Sticky 定位工作原理解析

Vue.js

CSS 静态定位已经具有非常好的浏览器支持,但是大多数开发人员并未使用它。

其原因有两个:首先,长时间等待好的浏览器支持:浏览器支持花费了很长时间,并且在实现该功能时被忘记了。

第二个原因是大多数开发人员没有完全理解它工作背后的逻辑,这就是我的用武之地。

我想大家都知道CSS的定位,但是还是让我们做一个简短的回顾:

直到3年前,有四个CSS定位:静态相对绝对固定的

静态相对绝对固定之间的主要区别是它们在DOM流中占据的空间。 静态相对定位在文档流中保留其自然空间,而绝对固定的不保留它们的空间被删除,它们具有浮动行为。

接下来我将解释新的 Sticky 定位与其他所有类型的相似之处。

初识 Sticky

我猜各位都曾把玩过 sticky 定位。像我已经用一段时间了,直到最近我意识到自己并不完全了解它。

在初次了解 sticky 定位时,每个人都很快的理解到,元素将会在到达视窗指定位置时粘附。

例子:

.some-component{
    position: sticky;
    top: 0;
}

而问题在于这个代码有时是可以工作的,而有时不可以。当它工作时,元素会粘附,不过在滚动的其他部分中,它又停止粘附了。作为靠 CSS 吃饭的人,这让我根本无法理解并且不能接受这个问题,因此我决定彻底的探索 Sticky 定位

探索 Sticky

在使用时,我很快注意到,当包装一个带有 position: sticky 样式的元素并且它是包装元素中唯一的元素时,定义了 position: sticky 的元素将不会粘附。

<!-- 不起作用!!! -->
<style>
    .sticky{
        position: sticky;
        top: 0;
    }
</style>
<div class="wrapper">
   <div class="sticky">
        SOME CONTENT
   </div>
</div>

当我在包装元素上添加更多内容时,它又正常了。

这是为啥?
因为每当一个元素被赋予 position: sticky 样式时,粘贴元素的容器是唯一可以粘附的区域。该项目没有任何需要浮动的元素,因为它只能漂浮在兄弟节点上,如果它是唯一的孩子节点,它就没有兄弟节点了。

CSS Sticky 定位如何真正起作用的!

CSS Sticky 定位有两个主要部分,粘附条目粘附容器

粘附条目 - 定义了 position: sticky 样式的元素。当视窗位置与定义的位置相匹配时,该元素将会浮动,比如:top: 0px

例子

.some-component{
    position: sticky;
    top: 0px;
}

粘附容器 - 包裹了 粘附条目 的 HTML 元素。这是粘附条目的最大可浮动范围。

当您定义了带有 position sticky 的元素时,您将自动定义其父元素为粘附容器
这一点需要记住,非常重要!容器是粘附条目的范围,粘附条目不能脱离其对应粘附容器的范围。

这就是上述案例没有粘附的原因:粘附元素是粘附容器的唯一子元素。

CSS Sticky 定位的可视案例

Vue.js

粘附条目以及粘附容器

CodePen 示例:

理解 CSS 粘附行为

如我之前所述,CSS Sticky 定位行为与其他 CSS 定位不同,不过从另一方面来说,他们确实有所相似。且听我慢慢道来:

相对定位(或者静态定位) - 粘附的元素位置类似于相对定位和静态定位,因为其保持了 DOM 间的自然间距(停留在流中)。
固定定位 - 当条目粘附的时候,其行为类似 position: fixed,在视窗的相同位置浮动,从流中移除。
绝对定位 - 在粘附区域的尾端,元素停住了并堆叠到其他元素的顶部,就像是绝对定位于 position: relative 容器内一样。

沾到底部?!

在大多数场景下,我们使用 sticky 定位以便粘附元素到顶部,如下所示:

.component{
    position: sticky;
    top: 0;
}

这正是它创建时的情况,而在此之前,它只能用 JavaScript 完成。

不过你也可以将其用于粘附底部的情况。意味着页脚可以被定义为 sticky 定位,并且向下滚动时它将始终表现为粘附在底部。当我们到达粘附容器末端时,元素将不会在其自然定位上。最好用于自然位置在底部的粘附容器。

完整案例:

HTML

<main class="main-container">
  <header class="main-header">HEADER</header>
  <div class="main-content">MAIN CONTENT</div>
  <footer class="main-footer">FOOTER</footer>
</main>

CSS

.main-footer{
     position: sticky;
     bottom: 0;
}

在线 CodePen 示例

在实际需求中,我将其用于粘性汇总表,也可用于粘性页脚导航,使用此方法可以非常优雅的实现。

浏览器支持

  • Sticky 定位被除老版 IE 外的现代主流浏览器支持。
  • 针对Safari 浏览器,需要添加 -webkit 前缀。
position: -webkit-sticky; /* Safari */
position: sticky;

Vue.js

Final Words

以上就是本篇博客的全部内容了,
希望你能享受本文,并从我的经验中学到一些东西。
如果您喜欢这篇文章,我将不胜感激并欢呼炫耀 :-)

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://medium.com/@elad/css-position-st...

译文地址:https://learnku.com/vuejs/t/53034

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!