有关如何为电视、手机、桌面设备等设备构建自适应水平滚动视图的基础概览。
在这篇博文中,我想分享一些创建水平滚动的想法 提供极简、响应迅速、易于访问,并可跨各种平台运行, 浏览器和平台(例如电视!)。试用 演示。
<ph type="x-smartling-placeholder">如果你更喜欢视频,可以参阅此博文的 YouTube 版本:
概览
我们将构建一个水平滚动布局,用于托管
媒体或产品。该组件以一个简单的 <ul>
列表开始,但
通过 CSS 实现流畅的滚动体验
并将它们贴靠到网格上。添加了 JavaScript
漫游索引交互,帮助键盘用户跳过 100 多个项的遍历。
此外,我们还使用一个实验性媒体查询 prefers-reduced-data
来
转换为轻量级标题滚动条体验
从可访问的标记入手
媒体滚动条由几个核心组件组成,即一个包含项目的列表。答 列表的形式最为简单,可以在世界各地推广,而且明确 到达此页面的用户可以浏览列表并点击链接 查看某项。这是我们的无障碍基地。
提交包含 <ul>
元素的列表:
<ul class="horizontal-media-scroller">
<li></li>
<li></li>
<li></li>
...
<ul>
使用 <a>
元素使列表项可交互:
<li>
<a href="#">
...
</a>
</li>
使用 <figure>
元素从语义上表示图片及其说明:
<figure>
<picture>
<img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
</picture>
<figcaption>Legends</figcaption>
</figure>
请注意 <img>
中的 alt
和 loading
属性。媒体的替代文本
滚动条是一种用户体验机会,有助于为缩略图提供额外的背景信息,或者
后备文字(如果图片未加载),或为用户提供语音界面
依靠屏幕阅读器等辅助技术。通过 Five golden 了解详情
“合规”替代规则
文本。
loading
属性接受关键字 lazy
作为表示此图片的信号
仅当图片位于视口内时才提取来源。可以是
非常适合大型列表,因为用户只会下载自己希望展示的商品的图片
滚动进入视图。
支持用户的配色方案偏好设置
使用 color-scheme
作为 <meta>
标记,向浏览器表明您的网页
需要同时采用浅色和深色的用户代理样式。这是一种免费的深色模式
或浅色模式:
<meta name="color-scheme" content="dark light">
元标记会提供尽可能早的信号,因此浏览器 如果用户偏好深色主题,可以选择深色的默认画布颜色。 这意味着在网站页面之间的导航不会闪烁白色画布 加载背景。在两次加载间无缝切换深色主题,呈现效果更佳 眼睛。
要了解更多信息,请访问 Thomas Steiner https://web.dev/color-scheme/.
添加内容
基于上述 ul > li > a > figure > picture > img
内容结构,
下一项任务是添加要滚动浏览的图片和标题。我已将演示放入了
静态占位符图片和文本,但您也可以随时通过
喜爱的数据源
使用 CSS 添加样式
现在,CSS 可以获取这一通用内容列表,并将其转换为 体验Netflix、应用商店以及许多其他网站和应用均采用横屏展示 滚动区域,使用类别和选项打包视口。
创建滚动条布局
务必避免截断版式或依赖文本 并用省略号截断。许多电视都有媒体滚动条,就像 但往往采用省略内容。但这种布局却不然! 它还允许媒体内容替换列大小,从而生成 1 个布局 足够灵活,能够处理许多有趣的组合。
该容器允许通过提供默认大小来替换列大小,如下所示: 自定义属性这种网格布局以列大小为主, 仅管理间距和方向:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
margin: 0;
}
然后,<picture>
元素使用该自定义属性来创建基本宽高比:方框:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
& picture {
inline-size: var(--size);
block-size: var(--size);
}
}
只需再添加几个小样式,即可完成媒体滚动条的基本功能:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
& > li {
display: inline-block; /* removes the list-item bullet */
}
& picture {
inline-size: var(--size);
block-size: var(--size);
}
}
设置 overflow
会将 <ul>
设置为允许滚动和键盘导航
其列表中,则每个直接子 <li>
元素的 ::marker
都会移除
方法是获取新的显示类型 inline-block
。
但图片还不具有自适应能力,它们是开箱即刻突显出来的 以及它们所处的环境调整它们的尺寸、大小和边框样式 延迟加载时的背景渐变:
img {
/* smash into whatever box it's in */
inline-size: 100%;
block-size: 100%;
/* don't squish but do cover the space */
object-fit: cover;
/* soften the edges */
border-radius: 1ex;
overflow: hidden;
/* if empty, show a gradient placeholder */
background-image:
linear-gradient(
to bottom,
hsl(0 0% 40%),
hsl(0 0% 20%)
);
}
滚动内边距
与网页内容的对齐方式以及无边框滚动区域 对和谐、最小的组件至关重要。
为了实现与我们的排版一致的全屏滚动布局
和布局行,请使用与 scroll-padding
匹配的 padding
:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
padding-inline: var(--gap);
scroll-padding-inline: var(--gap);
padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}
水平滚动内边距 bug 修复 上面的代码展示了 但该滚动容器存在明显的兼容性问题 (不过,在 Chromium 91 及更高版本中已修复!)。请参阅 此处 但简而言之,填充并不总是会被考虑 滚动视图中的内容
为了诱骗浏览器在滚动条的末尾放置内边距,我将 定位每个列表中的最后一个数字,并附加一个伪元素, 所需的内边距。
.horizontal-media-scroller > li:last-of-type figure {
position: relative;
&::after {
content: "";
position: absolute;
inline-size: var(--gap);
block-size: 100%;
inset-block-start: 0;
inset-inline-end: calc(var(--gap) * -1);
}
}
使用逻辑属性可让媒体滚动条在任何写入模式下运行 和文档方向
贴靠滚动
具有 overflow 的滚动容器可以成为具有一行 CSS 的贴靠视口,然后由子元素指定它们与该视口的对齐方式。
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
padding-inline: var(--gap);
scroll-padding-inline: var(--gap);
padding-block-end: calc(var(--gap) / 2);
scroll-snap-type: inline mandatory;
& figure {
scroll-snap-align: start;
}
}
专注
这个组件的灵感来自于它在电视机上极受欢迎 App Store 等。许多视频游戏平台都非常使用媒体滚动条 用作主主屏幕布局。专注可带来极大的用户体验 而不是仅仅增加一点点想象一下,在 拿出遥控器,就对这种互动进行一些细微的增强:
.horizontal-media-scroller a {
outline-offset: 12px;
&:focus {
outline-offset: 7px;
}
@media (prefers-reduced-motion: no-preference) {
& {
transition: outline-offset .25s ease;
}
}
}
这会使焦点轮廓样式 7px
远离框,从而为其提供一些不错的
空间。如果用户对减少动作没有偏好,则偏移
过渡效果,为焦点事件赋予微妙的运动效果。
漫游索引
在这些长长的列表中,游戏手柄和键盘用户需要特别注意 滚动内容和选项解决此问题的常见模式称为 漫游索引。每次 项容器获得键盘焦点,但只允许 1 个子项持有焦点 。这个每次可聚焦项的体验旨在 无需按 Tab 50+ 到达结尾的次数。
该演示的第一个滚动条中有 300 个项。我们可以做得比 它们将遍历所有位置,直至到达下一部分。
为了打造这种体验,JavaScript 需要观察键盘事件和焦点 事件。我在 Google Cloud 上创建了一个小型开源库 npm 轻松实现。下面展示了如何将其用于 3 个滚动条:
import {rovingIndex} from 'roving-ux';
rovingIndex({
element: someElement
});
此演示在文档中查询滚动条,并为每个滚动条调用
rovingIndex()
函数。向 rovingIndex()
传递元素以获取流动
例如列表容器和目标查询选择器,
焦点目标不是直接的后代。
document.querySelectorAll('.horizontal-media-scroller')
.forEach(scroller =>
rovingIndex({
element: scroller,
target: 'a',
}))
如需详细了解此效果,请参阅开源库 roving-ux。
宽高比
截至撰写本博文时,
aspect-ratio
落后于
标记,但适用于 Chromium 浏览器或机顶盒。由于
媒体滚动条网格布局仅指定方向和间距,但调整尺寸
在该功能检查是否支持宽高比的媒体查询内进行更改。
通过渐进增强的方式让媒体滚动条更加动态化。
@supports (aspect-ratio: 1) {
.horizontal-media-scroller figure > picture {
inline-size: auto; /* for a block-size driven ratio */
aspect-ratio: 1; /* boxes by default */
@nest section:nth-child(2) & {
aspect-ratio: 16/9;
}
@nest section:nth-child(3) & {
/* double the size of the others */
block-size: calc(var(--size) * 2);
aspect-ratio: 4/3;
/* adjust size to fit more items into the viewport */
@media (width <= 480px) {
block-size: calc(var(--size) * 1.5);
}
}
}
}
如果浏览器支持 aspect-ratio
语法,则媒体滚动条图片为
已升级为 aspect-ratio
大小。使用草稿嵌套语法,
更改其宽高比,具体取决于它是第一行、第二行还是第三行。通过
nest 语法还允许设置一些较小的
调整视口大小,并采用其他大小调整逻辑。
有了 CSS,随着更多浏览器引擎支持此功能, 但会呈现更具视觉吸引力的布局
希望减少数据流量
下一种分析法仅适用于
在下列情况下,位于某个标志后面:
Canary 版、
我想和您分享一下如何节省大量网页加载时间,
使用几行 CSS 来降低数据使用效率。prefers-reduced-data
媒体查询来自
级别 5:允许询问设备是否处于
减少数据流量状态(例如流量节省程序模式)。如果是,我可以修改
在本示例中,是隐藏图片。
figure {
@media (prefers-reduced-data: reduce) {
& {
min-inline-size: var(--size);
& > picture {
display: none;
}
}
}
}
内容仍然可导航,但无需消耗大量图片
已下载。以下是添加 prefers-reduced-data
CSS 之前的网站:
(7 个请求,100kb 资源,131 毫秒)
以下是添加 prefers-reduced-data
CSS 后的网站性能:
(71 个请求,1.07 秒内存储 1.2MB 资源)
减少 64 个请求,即视口内大约 60 张图片(已进行的测试) 将页面加载速度提升约 80%,并且 10% 的数据通过网络传输。非常强大的 CSS。
总结
现在你知道我怎么做到的了,你会怎么做?!🙂
让我们一起采用多样化的方法,学习所有在 Web 上构建应用的方法。 创建一个 Codepen 或托管自己的演示,将它发到 Twitter 微博中,然后我会将其添加到 下方的“社区混剪作品”部分。
来源
社区混剪作品
此处尚无任何可显示的内容!