我们在 最近的新闻通讯中 提到了使用纯 CSS 创建轮播的一种方法,我认为更详细的说明会很有趣,并且可以捕捉我的一些想法。
所以,今天我们要做的是
这里没有 JavaScript,一点都没有!没有 jQuery 插件。没有技巧。只是一些我一直尝试使用的新 CSS 属性以及一些基本的 HTML。
好的,首先,我们需要关注标记。设计包括由图像组成的左侧导航和右侧的大型图像库,我们可以单独滚动浏览每个图像。我们还需要一个包装器来帮助我们整理布局
<div class="wrapper">
<nav class="lil-nav"></nav>
<div class="gallery"></div>
</div>
接下来,我们可以添加图像!对于这个小例子,我查看了我们列出的拥有 您可以免费使用的高质量图像 的网站,并选择了 Unsplash。
在使用 CodePen 资产管理器保存图像后,我开始将 URL 添加到 nav
元素
<nav class="lil-nav">
<a href="#image-1">
<img class="lil-nav__img" src="..." alt="Yosemite" />
</a>
<a href="#image-2">
<img class="lil-nav__img" src="..." alt="Basketball hoop" />
</a>
<!-- more images go here -->
</nav>
请注意,每个链接的 href
都指向一个 ID?这是因为如果我们再次查看演示,我们希望能够点击一个图像,然后我们希望它跳到右侧库中该图像的较大型版本。
所以,现在我们可以开始将这些图像添加到大型库中……
<div class="gallery">
<img class="gallery__img" id="image-1" src="..." alt="Yosemite" />
<img class="gallery__img" id="image-2" src="..." alt="Basketball hoop" />
<!-- more images go here -->
</div>
漂亮。接下来是乐趣部分:为这个东西添加样式。我们可以使用网格布局作为父 .wrapper
并为 img
元素设置一些智能默认值
img {
display: block;
max-width: 100%;
}
.wrapper {
display: grid;
grid-template-columns: 1fr 5fr;
grid-gap: 20px;
}
到目前为止,我们的布局已经排序,链接也已设置好。接下来,让我们处理可能会溢出到包装器外部的溢出,并确保导航和库是可滚动的
.wrapper {
display: grid;
grid-template-columns: 1fr 5fr;
grid-gap: 10px;
overflow: hidden;
height: 100vh;
}
.gallery {
overflow: scroll;
}
.lil-nav {
overflow-y: scroll;
overflow-x: hidden;
}
现在我们可以滚动浏览库中的每个图像,但是如果这是一个生产网站,我们可能希望确保人们可以更轻松地滚动到轮播的前面。 Trent Walton 几年前就写过 这个问题,我认为始终值得牢记。
接下来,让我们关注库中每个图像的轮播捕捉。为此,我们需要使用 scroll-snap-type
和 scroll-snap-align
属性,如下所示
.gallery {
overflow: scroll;
scroll-snap-type: x mandatory;
}
.gallery__img {
scroll-snap-align: start;
margin-bottom: 10px;
}
现在再次尝试滚动浏览右侧的库
如果您想了解有关这些属性的更多信息,我强烈推荐这篇关于 实用 CSS 滚动捕捉 的文章,它深入探讨了这些属性的细节。
我们已经拥有一个非常实用的轮播!从这里,我们要做的就是整理设计,因为库图像没有占据整个屏幕高度。为此,我们可以使用 object-fit
并使用 vh
单位为每个图像提供一个 min-height
,就像这样
.gallery__img {
scroll-snap-align: start;
margin-bottom: 10px;
min-height: 100vh;
object-fit: cover;
}
现在,大型库图像将始终占据整个屏幕大小,并将按比例调整大小以占据宽度和高度。让我们继续,解决小型导航图像的样式
.lil-nav {
overflow-y: scroll;
overflow-x: hidden;
}
.lil-nav a {
height: 200px;
display: flex;
margin-bottom: 10px;
}
.lil-nav__img {
object-fit: cover;
}
最初,我让这个小导航也像轮播一样工作,但感觉真的很奇怪。目前,我只是保留默认的 scroll
行为。在上面的演示中,尝试点击一个图像。请注意,它如何立即跳到轮播中的该图像?如果我们能够稍微动画化这个过渡,那就太好了 - 我们可以做到!
.gallery {
overflow: scroll;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
}
那个 scroll-behavior
CSS 属性对于这一点非常有用,因此现在如果您点击任何导航项,整个东西都会动画化
很漂亮,对吧?我们可以在这里做的另一件小事是在导航项上添加一个过滤器,使它们变为黑白,然后在悬停时动画化它们
.lil-nav__img {
object-fit: cover;
filter: saturate(0);
transition: 0.3s ease all;
}
.lil-nav__img:hover {
transform: scale(1.05);
filter: saturate(1);
}
我确信我们还可以做很多事情,但我认为这已经相当不错了!
我们甚至可以将少量 JavaScript 添加到混合中,以显示哪个图像处于活动状态,但我认为人们只要看看库就能知道。
就这样!我们现在拥有一个对渐进增强非常有利的轮播,这意味着我们不必加载 JavaScript 库或编写比实际需要更多代码。
让轮播响应式……
但让我们更进一步,让它响应式。我们要做的是反转网格的顺序,将我们所有当前的样式移动到仅在大屏幕上激活的媒体查询中。
您可能想要在一个新标签页中打开此演示,并减小/增大浏览器的尺寸以查看更改。
如果您在移动设备上加载此演示,您应该会看到布局如何在两种模式之间切换。这是通过对 .wrapper
元素使用单个媒体查询来实现的。请注意,我们使用的是 Sass
$large: 1200px;
.wrapper {
overflow: hidden;
height: 100vh;
display: grid;
grid-template-rows: 2fr 1fr;
grid-gap: 10px;
@media screen and (min-width: $large) {
grid-template-columns: 1fr 5fr;
grid-template-rows: auto;
}
}
让我们在导航上也添加一个。但是这次,我们需要告诉导航从第二行开始,这样它就会移动到屏幕底部
.lil-nav {
overflow-x: scroll;
overflow-y: hidden;
display: flex;
grid-row-start: 2;
@media screen and (min-width: $large) {
overflow-y: scroll;
overflow-x: hidden;
display: block;
grid-row-start: auto;
}
}
对于库,我们需要为大屏幕切换 scroll-type
并反转 overflow
属性
.gallery {
overflow-x: scroll;
overflow-y: hidden;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
display: flex;
@media screen and (min-width: $large) {
display: block;
overflow-y: scroll;
overflow-x: hidden;
scroll-snap-type: y mandatory;
}
}
这些是我们需要进行的大部分更改,我非常喜欢它!如果我们想让它投入生产,我们会考虑可访问性(例如,我们可能不希望屏幕阅读器读出导航和库中的所有图像)。然后是性能 - 我们可能会考虑延迟加载,以便图像仅在需要时呈现。
无论如何,这是一个好的开始!
哇,我想说这篇文章正是我一直需要学习的,我要非常感谢管理员提供这些免费的知识。
我会尝试在我的网站 mycontentstore.com 上实现它
太棒了,感谢您提供这篇易于理解的文章,我得试试这个轮播!
这正是 Bulma 仍然缺少的……也许你应该和他们合作?
轮播工作正常,我接受这一点。但对于关心用户体验的项目来说,它毫无用处。因为缺少一些基本的轮播事件,例如活动元素说明。在我看来,它需要 JavaScript 才能获得更好的用户体验。
我喜欢它。感谢分享!
@M. Volkan
毫无用处有点过分了。它当然不是毫无用处。可能是不完整的,可能是一个好的起点,但绝不是毫无用处。
@James
啊!你说得对!抱歉。“不完整”比“毫无用处”更合适的词。
哪个更好,这个还是使用 JavaScript 的?
在 Safari 中,动画不起作用。轮播可以工作,但只是简单的跳转。有什么想法吗?
那是因为 Safari 不支持 scroll-behavior: smooth。您可以使用 polyfill 让它工作。
我刚刚放弃了纯 CSS 轮播,转而实现 WAI-ARIA 创作实践。我没有看到如何在不使用 JavaScript 的情况下实现更改 ARIA 属性的方法。顺便说一下,菜单栏也是这样 - 但至少在那里我可以有一个对有视觉障碍的用户仍然有效的无脚本回退。
我真的很喜欢不必为交互式内容运行脚本的想法,但可访问性才是更重要的关注点。您是否看到了解决这一困境的可能性?
我当然同意,本教程对我来说很明确……感谢您抽出时间,Robin。
这很有启发性,也很聪明!感谢您的文章。
太棒了。希望可以正常使用!
非常详细,文章也很棒。干得漂亮,谢谢。
嗨,我在一个项目中测试它。它工作了一段时间,但现在页面在点击时会跳动。你知道如何修复它并保持轮播的纯 CSS 功能吗?
在我的 Firefox Webdev Edition 78.0b8 中没有显示……只显示第一张图像。