纯 CSS“返回顶部”特效
原文地址: 《Pure CSS Smooth-Scroll "Back to Top"》
我从事前端开发 13 年有余,一直致力于研究现代 CSS 解决方案,这是我该系列文章的第 4 篇
"Back to top"链接现在可能不经常使用,但有两个现代 CSS 技术很好地展示了它的特点。
position: sticky
scroll-behavior: smooth
2011 年在Web Designer Wall利用jQuery
实现 "back to top" 效果
它的想法是为用户提供一个 "跳转链接",让用户可以滚动回到网站的顶部,在以前的博客上经常使用。
下面我们就来学习一下如何实现。
关于 position: sticky
这个新的 position
属性值在caniuse上描述如下:
保持元素的
position
为 "fixed"或 "relative",这取决于它在视窗中的显示方式,
在元素滚动时表现为fixed
caniuse data
的另一个重要注意事项是,你需要提供它的前缀以获得最好的支持, 我们在Back to top
时不是十分优雅的实现position: fixed
的效果
关于 scroll-behavior: smooth
这是一个非常新的属性,并且支持相对较低。这个确切的定义要求滚动行为,特别是在选择锚点链接时,滚动行为会有一个平滑的动画外观,而不是默认的、更突兀的即时跳转。
使用它提供了“渐进式增强”,这意味着对于那些浏览器支持它的人来说,它将是一个更好的体验,但对于不支持它的浏览器来说,它也可以工作。
令人惊讶的是,Safari
在支持这一点上落后了,但其他主要的浏览器都支持。
基本 html 结构
html 内容:
我们把链接(#top)放在article
之后,但在main
内。它不是具体的article
的一部分,我们也希望它在焦点顺序中排在最后。
我们还可以在<header>
中添加id="top"
,并使用该锚点作为回顶部链接的href
值。如果你只想滚动到<main>
的顶部,当然你也可以将这个id
放在顶部其他位置
添加 smooth-scrolling
第一步很简单,添加下面的 css:
原来的解决方案没有考虑到prefers-reduced-motion
的问题。
之前,我有一篇CSS-Tricks
的文章,是用jQuery
和vanilla JS
完成的。这篇文章已经有一段时间了,感谢那个团队在有新解决方法的时候不断地更新这样的文章👍
我发现了一些奇怪的地方,比如当你访问一个在 URL 中包含锚点的页面时,它仍然会执行平滑滚动,这对你的场景可能并不可取。
添加锚点"Back to Top"
在实现之前,让我们先给这个链接做一些基本的样式。为了好玩,我用了一个emoji
,但你可以换成 SVG 图标。
上面的样式只实现了一个非常基本的圆形按钮。在完整的Codepen
中,我添加了额外的更棒样式和 :hover
和 :focus
样式,但这些并不是必要的。
接下来,你可能会想知道为什么我们要为这个锚点外添加一层。原因是我们需要用它来为链接创建一个 "scroll track"。以使链接可以存在于其中。
position: sticky
会根据element
在dom
中的位置呈现position
属性,然后会根据元素top
的值,展示在窗口中,然而,我们把链接放在文档的最后,所以如果没有一些帮助,它基本上不会被选中。
我们将使用 外层元素.back-to-top-wrapper
和 position: absolute
属性来改变link
位置 ,值得庆幸的是,浏览器使用此视觉调整后的位置(也就是进入视口时)来计算何时“粘贴”链接。
外层元素.back-to-top-wrapper
样式
pointer-events: none;
这个个定义可能对你来说也很陌生,这本质上是让交互事件,比如点击等交互事件在元素中失效,这样就会阻止一些默认事件发生,比如a
标签跳转。
有了这些,我们现在可以看到链接在最初的视口内容下面的内容上有一点重叠。让我们在<main>
中添加一些样式来防止这种重叠,并添加position:relative
, 这对于外层的元素absolute
属性是必须的。
.back-to-top-link
核心link
样式
在浏览器支持sticky
属性时会出现最理想的效果,否则position: fixed;
生效,"Back to Top" 会一直存在窗口中
注意,我们还用pointer-events: all;
还原了指针事件,这样,与链接的交互实际上是可以工作的。
codepen:
https://codepen.io/5t3ph/pen/OJyyqWR
已知问题
在有简短内容场景中,会有一些问题,你可能会想利用overflow: hidden
属性来解决,但不幸的是,这使得position: sticky
无法完全工作☹️,所以在真实的开发中你应该区分出这种情况,或者在模板中注入文章之前执行一个计算来确定文章是否满足长度要求。
版权声明: 本文为 InfoQ 作者【寇云】的原创文章。
原文链接:【http://xie.infoq.cn/article/b783fe190452941103c0c6dc3】。文章转载请联系作者。
评论