“滑块”,指的是一排盒子,您可以浏览它们。您知道什么是滑块。滑块可能需要很多功能。举个例子,您可能希望滑块能够滑动或滚动。或者,您可能不希望这样,而是希望滑块只响应点击或可点击的按钮来导航到幻灯片。或者您可能两者都想要。或者您可能希望将所有这些与自动播放结合起来。
我要说的是,滑块作为一种 UI 组件,其复杂程度足以进入使用 JavaScript 的领域。 Flickity 就是一个很好的例子。我也想说,仅用 HTML 和 CSS 就能做出外观漂亮且功能完善的滑块。从这种方式开始,可以使 JavaScript 更容易,并且,我敢说,这是一个渐进增强的好例子。
首先考虑语义标记。
一堆盒子可能很简单,就像
<div class="slider">
<div class="slide" id="slide-1"></div>
<div class="slide" id="slide-2"></div>
<div class="slide" id="slide-3"></div>
<div class="slide" id="slide-4"></div>
<div class="slide" id="slide-5"></div>
</div>
使用少量 CSS 代码,我们可以将它们并排放置并让它们滚动。
.slider {
width: 300px;
height: 300px;
display: flex;
overflow-x: auto;
}
.slide {
width: 300px;
flex-shrink: 0;
height: 100%;
}

不妨让它在基于 WebKit 的移动浏览器上平滑滑动。
.slider {
...
-webkit-overflow-scrolling: touch;
}

我们可以做得更好!
让我们让每个幻灯片都通过捕捉点捕捉到位。
自从最初发布以来,这方面有一些变化!我正在更新下面的代码块。
.slider {
...
/* CURRENT way. */
scroll-snap-type: x mandatory;
/* OLD WAY. Probably not worth including at all.
-webkit-scroll-snap-points-x: repeat(300px);
-ms-scroll-snap-points-x: repeat(300px);
scroll-snap-points-x: repeat(300px);
-webkit-scroll-snap-type: mandatory;
-ms-scroll-snap-type: mandatory;
scroll-snap-type: mandatory;
*/
}
.slides > div {
/* CURRENT way. */
scroll-snap-align: start;
}
看看现在有多漂亮

跳转链接
滑块可能有一个小的 UI 用于跳转到特定的幻灯片,所以让我们也以语义的方式来做,使用锚链接跳转到正确的幻灯片
<div class="slide-wrap">
<a href="#slide-1">1</a>
<a href="#slide-2">2</a>
<a href="#slide-3">3</a>
<a href="#slide-4">4</a>
<a href="#slide-5">5</a>
<div class="slider">
<div class="slide" id="slide-1">1</div>
<div class="slide" id="slide-2">2</div>
<div class="slide" id="slide-3">3</div>
<div class="slide" id="slide-4">4</div>
<div class="slide" id="slide-5">5</div>
</div>
</div>
锚链接实际上充当指向相关内容的链接,并且具有语义性和可访问性,因此没有问题(如果我错了,请随时纠正我)。
让我们稍微美化一下……我们得到了一些执行其工作的按钮

在桌面和移动设备上,我们仍然可以确保获得流畅的滑动效果!
.slides {
...
scroll-behavior: smooth;
}
也许我们只在没有漂亮快速滑动的情况下显示按钮?
如果浏览器支持scroll-snap-type
,则它具有漂亮的快速滑动功能。如果我们想隐藏按钮,我们可以这样做
@supports (scroll-snap-type) {
.slider > a {
display: none;
}
}
需要对“活动”幻灯片做一些特殊处理吗?
我们可以为此使用:target
。当单击导航幻灯片的按钮之一时,URL 会更改为该 #hash,此时:target
生效。所以
.slides > div:target {
transform: scale(0.8);
}

有一种方法可以使用 复选框技巧 构建此幻灯片,并仍然使用:checked
对“活动幻灯片”进行操作,但您可能会认为这种方法的语义性和可访问性稍差。
到目前为止,我们已经完成了这些。
查看 Chris Coyier 的 CodePen 上的
简单滑块 (@chriscoyier)
在 CodePen 上。
事情开始变得有点复杂。
使用:target
是一种巧妙的技巧,但它在以下情况下不起作用:例如,页面加载时没有哈希值。或者如果用户自行滚动或轻扫而不使用按钮。我认为仅用 HTML 和 CSS 无法解决这个问题,也不认为这是 HTML 和 CSS 的完全失败。这只是 JavaScript 的用途之一。
JavaScript 可以确定活动幻灯片是什么。JavaScript 可以设置活动幻灯片。可能值得研究一下 Intersection Observer API。
还有哪些限制?
我们已经充分利用了 HTML 和 CSS 在此处的功能。
- 想要能够用鼠标轻扫?这不是鼠标行为,因此您需要使用 DOM 事件来完成所有操作。任何类型的奇特交互行为(例如物理)都需要 JavaScript。尽管有一个 奇怪的技巧 可以将垂直滚动翻转为水平滚动。
- 想知道何时更改了幻灯片?就像回调函数?这属于 JavaScript 的领域。
- 需要自动播放?您可以使用复选框、
:checked
和控制@keyframes
动画的animation-play-state
来做一些基本的事情,但效果会有限且不流畅。 - 想要让它在一个方向上无限滚动,并在需要时重复?这将需要克隆并在 DOM 中移动内容。或者可能滥用
<marquee>
。
我将把这些留给您。我的观点只是,在您需要 JavaScript 之前,您可以做很多事情。从这样一个强大的基础开始可能是最好的方法,无论您在其之上做什么,它都能提供一个良好的回退方案。
这是一篇很棒的文章!遗憾的是,我三年前就需要它了。滑块是移动设计的重要组成部分,或者至少对我来说是这样。我喜欢尽可能地减少我的网站/应用程序的大小。
另一个可以在纯 CSS 中实现的有趣效果
以微型马赛克的形式显示所有幻灯片。
例如: http://xem.github.io/talks/boxmodel/index.html#slide0
(点击底部的按钮)
优秀的示例
仅供参考,不幸的是,CSS 滚动捕捉点在 Chrome 中尚不受支持,
https://bugs.chromium.org/p/chromium/issues/detail?id=497851
看,现在你让我觉得自己很无知了,Chris!我不知道那么多CSS属性存在!:p
不错的简单实现!
有一件事困扰着我……如果你去掉了
.slides > div
上的过渡效果,当我们使用按钮时,幻灯片的定位就会出错。我就是不明白为什么……看看这里,唯一改动的是注释掉了过渡行(:42)。
在我看来,初始定位是正常的。我唯一能想到的是,你期望它自动设置为填充整个div,这就是过渡的作用——以平滑的方式使幻灯片增长以填充div。相反,它跳跃了,因为不再涉及缓动效果了。
那是一篇很棒的文章!它证明了CSS在当今有多强大和被低估。看到开发人员在遇到问题时直接转向JavaScript,我感到很痛苦。我希望有更多文章介绍如何采用CSS方法而不是JavaScript方法。
我觉得我是这个星球上为数不多的几个不喜欢JavaScript的网站开发人员之一。它似乎总是以某种形式减慢网页速度。也许我发现这一点如此令人痛苦的原因是我的游戏开发背景,在游戏开发中,性能是一切。
我并不是在“抨击”JavaScript,而只是指出它不应该一直被使用。尤其是在现在,当使用大量JavaScript时,移动网页确实显得慢了很多。我建议始终尝试先在CSS中找到解决方案,然后在绝对需要时再回退到JavaScript。
我认为问题在于在生产环境中,你正在寻找最快的解决方案。使用JavaScript库来解决问题比找到CSS的变通方法容易得多。这并不是说这是正确的方法或应该采用的方式,但在我的工作中,我们的首要任务是生产。
我是一名来自伊朗(洛雷斯坦省)的网页设计师。这篇文章对我来说非常棒
谢谢您
我称之为轮播。滑块是你在轨道内拖动的控件,用于设置数值。
嘿,感谢这篇文章!
不过我有一个简单的问题:我访问了caniuse.com,查看了“scroll-behavior”或“scroll-snap”等属性的支持情况,发现Chrome还没有支持。
然而我正在使用Chrome,并且可以在你发布的Codepen中看到预期的结果。这意味着当你的浏览器缺乏兼容性时,Codepen会自己完成工作吗?谢谢
可惜scroll-snap-points已弃用(顺便问一下,有人知道为什么吗?)并且在Chrome中不起作用。
优秀的文章。我的意思是,我确信在很多情况下,使用这种“有限的”基于CSS的滑块是关键。谢谢Chris。
你好,Chris,
仅仅因为你询问
我相信这种方法与许多开发人员用于选项卡面板的结构相匹配,但在我看来,这完全错误,因为这种导航机制首先与内容相关,正如尼尔森的这篇旧文章中所解释的那样。
换句话说,跳转链接旨在用于需要长时间滚动才能发现的内容。在我看来,我们采用(并维护)这种结构的唯一原因是它易于设置样式。
无论如何,“跳转链接”应该分组在一个列表中(它们应该位于列表项内)。
#个人意见
除了捕捉点、滚动平滑、触摸支持和:target之外,我7年前就开始制作仅使用HTML和CSS的幻灯片了。因此,除了触摸支持(在触摸屏成为个人电脑使用的一部分之前不需要)和一些不错但对于功能而言并非绝对必要的选项之外,这种方法具有极强的向后兼容性。即使IE6在这种非JS幻灯片轮播中也能表现得相当好。
很棒的文章。非常感谢。从中学习了很多。
我构建了一个仅使用radio和CSS的选项,但它需要一些额外的标记,为第一个和最后一个幻灯片的导航创建重复的标签以形成完整的循环。如果适当的标记至关重要,则它可以作为非循环滑块正常运行。