早些时候有看到过一个 纯CSS轮播图 的文章,当时有研究过实现,大概是利用了 hash
(锚标记) 和 scroll-snap
来实现的,但是具体实现已经回忆不起来了。
正好现在分享群组里边暂时没有主题了,就想着可以当成一个常驻的补位小环节,大家一起浏览 CodePen 之类的社区找一个大家都感兴趣的 Demo 来研究。
在分享前还是需要自己重新研究一遍的,不然在讲述的时候出错可太 “甜蜜的” 尴尬了。
首先呢,先实现一个简易的的可控轮播示例
在样例的实现中我将会使用到一下技术栈,希望你可以稍微了解一下
Pug
(HTML预处理器)Stylus
(CSS预处理器)
P.S.
以下笔记内容将逐步实现目标文章示例,会复原目标文章内的元素样式,稍微有点改动但变化不大,因为自己想的样式太丑了。
讲解:
可以点开上方示例中的选项卡查看实现代码,
- 在
html
中书写了 5 个<div
并且声明了对应的ID
; - 并且在后续添加了
<a>
标签来改变URL当中的hash
值来控制卡片的切换; - 在
css
利用scroll-behavior:smooth
这个属性,来达到切换卡片的平滑滚动效果。
但是缺少了切换前进后退按钮,接下来我们就来实现这个功能
讲解:
其实很憨,直接为每一个卡片添加了前进后退按钮的 <a>
标签而已。
稍微有点麻烦的就是 如何让这两个按钮随着卡片的切换而改变,而不被后一个卡片的按钮所覆盖,因为这两个按钮是不会随着卡片切换所移动的,这里就需要脑洞大开了!
正常思路来说,肯定是会尝试修改 前进后退按钮 的父级的定位方式。
确实,会需要修改成 position:relative
,但是这个其实是为了每次切换卡片后变更对应的锚链接的。
原示例是从轮播组件的最外层容器创建了 ::before
和 ::after
两个伪类,给他们设置的切换按钮的样式,并且设置为点击穿透,然后把轮播卡片内的 前进后退按钮 为 透明
底色。
这样所展示的 “按钮” 就不会随卡片所以移动了,而实际的切换按钮会随着卡片所移动,只是不会被浏览者发现。
功能基本实现了,然后我们复原一下原示例的样式。
对照一下原示例,除了自动播放外还差了些什么呢?emmmm…..自动播放!
💥 尾关BOSS 💥 自动轮播
最后来看一下她是如何实现自动播放的,这里的实现方式如果他不讲我直接就蒙圈了,但是确实很赞!👍
- First I slowly offset the scroll snap points to the right, making the scroll area follow along due to being snapped to them.
首先我缓慢地将滚动捕捉点向右偏移,使滚动区域由于捕捉它们而跟随。- After having scrolled the width of a whole slide, I deactivate the snapping. The scroll area is now untied from the scroll snap points.
在滚动整个幻灯片宽度后,我停用了捕捉。 滚动区域现在与滚动捕捉点解除绑定。- Now I let the scroll snap points jump back to their initial positions without them “snap-dragging” the scroll area back with them
现在我让滚动捕捉点跳回到它们的初始位置,而不用它们 “捕捉拖动” 滚动区域- Then I re-engage the snapping which now lets the scroll area snap to a different snap point 🤯
然后我重新启用捕捉,让滚动区域捕捉到不同的捕捉点
看起来有点不易懂,但是其实并不复杂的。
其实就是利用了 scroll-snap
会使滚动容器的捕捉点变更为你设定的元素对齐位置(scroll-snap-align
),然后通过修改 left
属性值使滚动容器向右滚动实现向后滚动的效果,然后通过修改当前元素的对齐位置为 none
, 让滚动容器捕捉到下一个元素的对齐位置,以此来达到自动轮播的效果,那么让我们来实现一下吧!
但是我还没有增加悬停停止自动轮播和一些其他的优化,有兴趣的可以自己实现一下,用到的CSS属性:
完整复现一下原示例吧!
尾声
其实一开始我是不知道他如何实现的视差滚动的,结果在研究自动轮播的时候,突然就通了,所以就加上来了
通过 transform:translate3d()
给中间的元素,增加了 Z轴 属性,使其脱离了平面 “悬浮” 在轮播卡片上,然后在最外层容器的 “轮播器” 设置了 perspective
指定了容器平面与 视窗 的 Z轴 距离。
但是有点问题,只有在自动播放动画执行时才会体现出来,手动控制切换是感觉不出来的,因为手动滚动时无法应用 scroll-snap
。
⚡ 兼容性
什么?你问我兼容性?友尽了啊!
别想了,scroll-snap
属性都是 CR
阶段,也就是候选,具体正式上线还有2个阶段要走,
并且scroll-behavior
(平滑滚动)属性 Safari 是不支持的,
“scroll-behavior” | Can I use
“scroll-snap” | Can I use
所以移动端的兼容有很大问题,毕竟还有一个毒瘤 —— 微信内置浏览器,也是不支持这些属性的,
我在制作的过程中都没有考虑过移动端的适配,直接放弃了,PC端还是可以玩玩的。
自动轮播实现不了,那么视差滚动也就没办法实现了,
闹这么大一圈,其实就是个图个乐子,不过尝一下鲜,学习到别人的脑洞就好了。
文档链接
scroll-behavior - CSS | MDN
perspective - CSS | MDN
scroll-snap-type - CSS | MDN
scroll-snap-align - CSS | MDN
hover - CSS | MDN
:focus-within - CSS | MDN
prefers-reduced-motion - CSS | MDN
CSS-Only Carousel | CSS-Tricks
You can get pretty far in making a slider with just HTML and CSS | CSS-Tricks
大侠,请留步,要不过来了解下CSS Scroll Snap? « 张鑫旭-鑫空间-鑫生活