简要介绍如何打造类似于网页版 Instagram 快拍的体验。
在这篇博文中,我想分享一下您关于为 Web 构建自适应网页、支持键盘导航且可跨浏览器运行的“故事”组件的想法。
如果您更希望通过实操演示来了解如何自行构建此短片故事组件,请查看“短片故事组件”Codelab。
如果你更喜欢视频,可以参考本博文的 YouTube 版本:
概览
故事用户体验的两个热门例子是 Snapchat 故事和 Instagram 故事(更不用说舰队)。 一般来说,在用户体验方面,短片故事通常是一种仅适用于移动设备且以点按为中心的模式,用于浏览多项订阅。例如,在 Instagram 上,用户打开朋友的故事并浏览其中的照片。通常,他们一次会处理很多朋友。用户只需点按设备的右侧,即可跳至该朋友的下一个故事。通过向右滑动,用户可以跳到另一个好友。“故事”组件与轮播界面非常相似,但支持浏览多维数组(而不是单维数组)。就像每个轮播界面中都有轮播界面一样。🤯
![使用卡片直观呈现的多维数组。从左到右是一叠紫色边框卡片,每张卡片内部是 1 个多张青色边框。以列表形式列出。](https://web.developers.google.cn/static/articles/building/a-stories-component/image/visualized-multi-dimensio-bca9c1e40444a.png?authuser=5&hl=ro)
第二个故事“堆叠”轮播界面
👍? 以列表形式列出,也称为:多维数组
选择合适的工具
总的来说,我发现这个组件的构建非常简单,要归功于几个关键的网络平台功能。让我们来介绍一下!
CSS 网格
事实证明,我们的布局对于 CSS 网格来说并不高,因为它配备了一些强大的内容整理方法。
好友布局
我们的主要 .stories
组件封装容器是移动设备优先的水平滚动视图:
.stories {
inline-size: 100vw;
block-size: 100vh;
display: grid;
grid: 1fr / auto-flow 100%;
gap: 1ch;
overflow-x: auto;
scroll-snap-type: x mandatory;
overscroll-behavior: contain;
touch-action: pan-x;
}
/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
max-inline-size: 480px;
max-block-size: 848px;
}
我们来细分该 grid
布局:
- 在移动设备上,我们会使用
100vh
和100vw
明确填充视口,并在桌面设备上限制视口大小 /
用于分隔行模板和列模板- “
auto-flow
”翻译成grid-auto-flow: column
- 自动流模板为
100%
,在本例中为滚动窗口宽度
在手机上,可以将行大小视为视口高度,每列代表视口宽度。继续以 Snapchat 快拍和 Instagram 快拍为例,每一列都对应一个好友的故事。我们希望“好友故事”在视口之外继续呈现,以便留出某个地方可供滚动浏览。网格将根据所需的列数为每个好友故事安排 HTML 布局,从而为我们创建一个动态且响应式滚动容器。网格使我们能够集中处理整体效果
堆叠
对于每个好友,我们都需要他们的故事处于分页状态。为了准备动画和其他有趣的模式,我选择了堆栈。我说的堆叠,我的意思是看着三明治,而不是从侧面看
借助 CSS 网格,我们可以定义一个单单元格网格(即方形),其中的行和列共用一个别名 ([story]
),然后每个子项都会被分配到该带别名的单单元格空间:
.user {
display: grid;
grid: [story] 1fr / [story] 1fr;
scroll-snap-align: start;
scroll-snap-stop: always;
}
.story {
grid-area: story;
background-size: cover;
…
}
这样一来,我们的 HTML 就可以控制堆叠顺序,并让所有元素都保持流畅。请注意,我们无需对 absolute
定位或 z-index
执行任何操作,也不需要使用 height: 100%
或 width: 100%
进行正确装箱。父网格已经定义了故事图片视口的大小,因此无需告知任何故事组件填充它!
CSS 滚动贴靠点
CSS 滚动贴靠点规范可让您轻松在滚动时将元素锁定到视口中。在这些 CSS 属性出现之前,您必须使用 JavaScript,至少可以说相当棘手。请查看 Sarah Drasner 的介绍 CSS Scroll Snap Points,详细了解使用方法。
scroll-snap-points
样式的水平滚动。
如果没有它,用户就可以照常自由滚动。这样,浏览器就会轻轻地基于每个项目。
.stories { display: grid; grid: 1fr / auto-flow 100%; gap: 1ch; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior: contain; touch-action: pan-x; }带滚动回弹的父级定义了贴靠行为。
.user { display: grid; grid: [story] 1fr / [story] 1fr; scroll-snap-align: start; scroll-snap-stop: always; }子项选择成为快照目标。
我选择“滚动 Snap Points ”是出于以下几个原因:
- 免费无障碍。滚动贴靠点规范指出,默认情况下,按向左箭头和向右箭头键应在贴靠点之间移动。
- 规范不断增加。滚动 Snap Points 规范一直在不断推出新功能和改进,这意味着我的“短片故事”组件以后可能会越来越好。
- 实施的难易程度。滚动贴靠点实际上是为以触摸为中心的水平分页用例构建的。
- 平台样式的自由惯性。每个平台都将按照自己的样式进行滚动和静止,这与标准化的惯性相反,后者具有不可思议的滚动和静止样式。
跨浏览器兼容性
我们在 Opera、Firefox、Safari 和 Chrome 以及 Android 和 iOS 上进行了测试。下面简要概述了我们发现在功能和支持方面存在差异的 Web 功能。
尽管有些 CSS 并不适用,因此一些平台目前错失了用户体验优化机会。我很喜欢不需要管理这些功能,并且确信它们最终将覆盖其他浏览器和平台。
scroll-snap-stop
轮播界面是促使我们制定 CSS 滚动贴靠点规范的主要用户体验用例之一。与故事不同,轮播界面并不总是需要在用户与图片互动后停下来。最好或鼓励快速循环浏览轮播界面。另一方面,故事最好逐个浏览,而这正是 scroll-snap-stop
提供的功能。
.user {
scroll-snap-align: start;
scroll-snap-stop: always;
}
在撰写本文时,scroll-snap-stop
仅适用于基于 Chromium 的浏览器。如需了解最新动态,请查看浏览器兼容性。不过,这并不是阻碍因素。这仅仅意味着,在不受支持的浏览器上,用户可能会意外跳过好友。因此,用户必须更加小心谨慎,或者我们需要编写 JavaScript 来确保跳过的好友不会被标记为已查看。
如果您感兴趣,请参阅规范,了解详情。
overscroll-behavior
您是否曾在滚动模态窗口时突然开始滚动模态窗口后面的内容?overscroll-behavior
可让开发者捕获该滚动,使其永不离开。它适合各种场合。“我的故事”组件使用该组件来防止其他滑动和滚动手势离开该组件。
.stories {
overflow-x: auto;
overscroll-behavior: contain;
}
Safari 和 Opera 是两款不支持此功能的浏览器,您完全可以这样做。这些用户将获得与往常一样的滚动体验,可能永远不会注意到此增强功能。我个人就是我的忠实粉丝,喜欢在我实现的几乎所有滚动回弹功能中都添加这项功能。这是一项无害的附加功能,只能改善用户体验。
scrollIntoView({behavior: 'smooth'})
当用户点按或点击浏览完朋友的故事集的末尾时,就可以移动到滚动贴靠点集中的下一个朋友了。借助 JavaScript,我们能够引用下一个好友,并请求将其滚动到视野范围内。此 API 对基本功能的支持非常好,每个浏览器都会滚动到视野范围内。但并非每个浏览器都能做到 'smooth'
。这只是表示该元素滚动到视图中,而不是贴靠。
element.scrollIntoView({
behavior: 'smooth'
})
Safari 是唯一此处不支持 behavior: 'smooth'
的浏览器。如需了解最新动态,请查看浏览器兼容性。
实践操作
现在你已经知道我是怎么做的,你知道该怎么做呢?!让我们了解一下各种方法,并了解在 Web 上构建网站的所有方法。创建一个 Glitch,将您的版本发推给我,然后我就会将其添加到下面的社区混剪部分。
社区混剪作品
- @geoffrich_(使用 Svelte):演示和代码
- @GauteMeekOlsen(使用 Vue):演示 + 代码
- @AnaestheticsApp 与 Lit:演示和代码