简要了解 Designcember 的节假日日历式体验所使用的流程和工具。
考虑到 12 月份以及大家用来倒计时和庆祝的众多日历的精神,我们希望重点介绍一下来自社区和 Chrome 团队的网络内容。每天,我们都会重点介绍一个与界面开发和设计相关的内容,共计 31 个亮点,其中包括 26 个新的演示网站、工具、公告、播客、视频、文章和案例研究。
访问 designcember.com 查看完整体验。
概览
我们的目标是以尽可能少的字节提供一种易于理解、异想天开、现代且响应迅速的 Web 体验。我们希望重点介绍容器查询等新的自适应 API,并在一个注重设计且包含大量资源的网站中添加一个精美的深色模式示例。为了实现这一目标,我们压缩了文件,提供了多种格式,使用了针对静态网站生成进行优化的构建工具,推出了新的 polyfill 等等。
从奇思妙想开始
Designcember 日历网站的设计理念是,展示我们希望在 12 月份重点展示的所有作品,同时充当演示网站本身。我们决定建造一个反应灵敏的公寓楼,它可以不断变高,变窄,也可以变短和变宽,并能够重新排列在框架内的窗户。每个窗口代表一天(因而代表一项内容)。 我们与插画师 Alice Lee 携手合作,将我们的愿景变为了现实。
Alice 激发了灵感,分享了他们创作的过程和草图,即使在早期构思阶段,这些过程和草图也令人激动。她一边创作美术作品,一边我们的建筑设计也在不断进步。早期讨论的内容主要围绕宏观布局、建筑物及其窗户。随着视口空间的增加,窗口会如何适应 1、2 或 3 列?它们可以收缩或拉伸多远?建筑的最大尺寸是多少?窗户的变化幅度如何?
下面是使用 grid-auto-flow: dense
的自适应原型的预览,展示了网格算法如何自动放置窗口。我们很快意识到,虽然宽高比网格在展示艺术作品时效果非常好,但它们并不能让窗口放大和缩小到不均匀的可用空间以及展示容器查询的强大功能。
一旦一般网格相对稳定,并传达出建筑物及其窗户的响应速度的方向感,我们就可以专注于单个窗户。与网格中的其他窗口相比,一些窗户被拉伸、缩小、挤压、增大和重组。
每个窗口都需要处理一定量的大小调整湍流。下面是一个窗口的原型,展示了它对湍流的响应情况,显示了每个交互式窗口的预期调整幅度。
使用精灵表的窗口动画
有些窗口包含动画,可增加额外的互动体验。这些动画是在 Photoshop 中逐帧手绘的。每个帧都会导出,利用此雪碧图生成器转换成雪碧图,然后使用 Squoosh 进行优化。然后,CSS 动画会使用 background-position-x
和 animation-timing-function
,如以下示例所示。
.una
background: url("/day1/una_sprite.webp") 0% 0%;
background-size: 400% auto;
}
.day:is(:hover, :focus-within) .una {
animation: una-wave .5s steps(1) alternate infinite;
}
@keyframes una-wave {
0% { background-position-x: 0%; }
25% { background-position-x: 300%; }
50% { background-position-x: 200%; }
75% { background-position-x: 100%; }
}
有些动画(如第六天的小猪储蓄罐)是基于步的 CSS 动画。
我们使用 steps()
利用类似的技术实现了这种效果,不同之处在于关键帧是 CSS 转换位置,而不是背景位置。
CSS 遮罩
有些窗户的形状各不相同。我们使用遮罩和 aspect-ratio
制作可伸缩、形状独特的自适应窗口。
要创建诸如窗口 8 的此类蒙版,需要掌握一些经典的 Photoshop 技能,并掌握一些有关蒙版在网络上的工作原理的知识。我们来看看第八天的时间范围。
如要成为蒙版,必须将内部的四叶草类型的形状隔离为自己的形状,并填充白色。白色会告知 CSS 保留哪些内容,白色以外的所有内容不会保留。在 Photoshop 中,选中窗口内部,羽化 1px(以消除混叠问题),然后填充白色,并以与窗口框架相同的高度和宽度导出。这样,框架和蒙版就可以直接相互叠加,从而按预期显示框架中的内部内容。
完成后,窗口的内容会被修改,并始终显示在自定义框架内。下图显示了深色模式版本的窗口,其中包含不同的背景渐变和对光线应用的发光 CSS 滤镜。
遮盖还支持基于容器查询的自适应窗口。在窗口 9 中,一个角色隐藏在面具后面,直到窗口变窄为止。为了确保用户无法将图片调整到画面外,Alice 帮我们填完了整个角色。角色在窗口内被遮盖,但植物却没有。因此我们要处理的另一个挑战是将已遮盖的元素与未遮盖的图层叠加,并确保它们可以很好地相互缩放。
下图显示了窗口和字符上不应用蒙版后的效果。
热切艺术
为了保持插图的保真度,并确保高清屏幕不会出现模糊的用户体验,Alice 使用了 3 倍的像素比。他们计划使用 Imgix,并在其服务器上提供经过优化的图片和格式,但我们发现,使用 Squoosh 工具进行手动调整可为我们节省 50% 或更多的费用。
插图在压缩方面存在独特的挑战,尤其是 Alice 使用的笔触和透明粗糙边缘样式。我们选择对每张 3 倍的 Photoshop 导出的 png 图片进行 Squoosh 处理,将其拆分为更小的 png、webp 和 avif 图片。每种文件类型都有其特殊的压缩功能,并且需要压缩 50 多张图片才能找到一些常见的优化设置。
Squoosh CLI 至关重要,因为有 200 多张图片需要优化,而手动执行所有这些操作可能需要几天时间。在确定通用优化设置后,我们以命令行说明的形式提供这些设置,并将整个 PNG 图片文件夹批量处理为对应的 WebP 和 AVIF 压缩文件。
以下是使用的 AVIF CLI squoosh 命令示例:
npx @squoosh/cli --quant '{"enabled":true,"zx":0,"maxNumColors":256,"dither":1}' --avif '{"cqLevel":19,"cqAlphaLevel":17,"subsample":1,"tileColsLog2":0,"tileRowsLog2":0,"speed":6,"chromaDeltaQ":false,"sharpness":5,"denoiseLevel":0,"tune":0}' image-1.png image-2.png image-3.png
将经过优化的海报图片签入代码库后,我们就可以开始从 HTML 加载它们:
<picture>
<source srcset="/day1/inner-frame.avif" type="image/avif">
<source srcset="/day1/inner-frame.webp" type="image/webp">
<img alt="" decoding="async" role="presentation" src="/day1/inner-frame.png">
</picture>
编写图片源代码时需要重复,因此我们构建了一个 Astro 组件,用一行代码嵌入图片。
<Pic filename="day1/inner-frame" role="presentation" />
屏幕阅读器和键盘用户
Designcember 的大部分作品是通过美术和互动窗口实现的。对我们而言,确保键盘用户可以使用网站并窥视窗口,并且屏幕阅读器用户能够获得很好的讲述体验,这一点对我们来说非常重要。
例如,在嵌入图片时,我们使用 role="presentation"
将图片标记为供屏幕阅读器演示。我们认为,如果用户体验介于 5 到 12 条之间,没有条理的 alt
说明,那么用户体验会很糟糕。因此,我们将这些图像标记为演示,并提供整体窗口讲述。然后,在屏幕阅读器的窗口中浏览网页会带来一种很好的叙事感觉,我们希望这会有助于网站要分享的奇思妙想和乐趣。
以下视频展示了键盘体验的演示。按 Tab、Enter、空格键和 Esc 键均用于在弹出式窗口和窗口之间来回编排焦点。
屏幕阅读器体验具有特殊的 ARIA 属性,可以使内容更加清晰。例如,这几天的链接只显示“1”或“2”,但添加一些 ARIA 后,系统会分别读出这些链接:“第 1 天”和“第 2 天”。此外,所有图片都会汇总到一个标签中,因此每个窗口都有一个说明。
Astro,静态优先,由组件驱动的网站生成器
Astro 让团队成员可以轻松地在网站上开展协作。组件模型对 Angular 和 React 开发者都很熟悉,而作用域类名称样式系统让每位开发者都知道他们在窗口上的工作不会与其他任何人发生冲突。
作为组成部分的天数
每天是一个组件,用于从构建时数据存储区中提取状态。这样,我们可以在 HTML 到达浏览器之前运行模板逻辑。逻辑将确定是否应显示该日期的提示,因为处于非活动状态的日期不会弹出。
构建每小时运行一次,当构建服务器过了午夜时,构建时数据存储区会解锁新的一天。这些自我更新和自给自足的小型系统可确保网站保持最新状态。
作用域样式和开放属性
Astro 作用域是在其组件模型中编写的样式,有助于更轻松地在多个团队成员之间分配工作负载,并让 Open Props 的使用变得有趣。Open Props normalize.css 样式在与自适应(浅色和深色)主题搭配使用时非常实用,还有助于整理段落和标题等内容。
作为 Astro 的尝鲜者,我们在使用 PostCSS 时遇到了一些问题。例如,由于构建问题过多,我们无法更新到最新的 Astro 版本。可以投入更多时间来优化构建和开发者工作流程。
灵活容器
有些窗口放大和缩小,同时保持宽高比以保留它们的艺术作品。我们还使用其他一些窗口来展示使用容器查询时基于组件的架构的强大功能。容器查询意味着窗口可以拥有各自的自适应样式信息,并根据自己的大小重新调整。有些窗口从窄变宽,需要调整其中媒体的大小以及媒体的位置。
当窗口可用空间变多时,我们可以调整窗口大小或子元素的大小来适应窗口大小。事实证明,为了实现自适应窗口,容器查询不仅要展示起来很有趣,而且需要它们,并且能够大大简化某些布局的编排。
.day {
container: inline-size;
}
.day > .pane {
min-block-size: 250px;
@container (min-width: 220px) {
min-block-size: 300px;
}
@container (min-width: 260px) {
min-block-size: 310px;
}
@container (min-width: 360px) {
min-block-size: 450px;
}
}
此方法与保持宽高比不同。通过这种广告系列,您可以掌握更多控制权和更多机会。以特定尺寸时,许多子项会四处移动以适应新的布局。
容器查询还让我们能够支持街区方向(垂直)包含。因此,随着窗口的长度变长,我们可以相应地调整其样式,使其适合对象。这可在我们单独使用的基于高度的查询以及基于宽度的查询的基础上进行查看:
.person {
place-self: flex-end;
margin-block: 25% 50%;
margin-inline-start: -15%;
z-index: var(--layer-1);
@container (max-height: 350px) and (max-width: 425px) {
place-self: center flex-end;
inline-size: 50%;
inset-block-end: -15%;
margin-block-start: -2%;
margin-block-end: -25%;
z-index: var(--layer-2);
}
}
我们还使用容器查询来显示和隐藏细节,因为这幅艺术作品在尺寸较小时就会显得越来越拥挤,而尺寸越宽,广告就越空。窗口 9 就是一个很好的例子,说明了这一点:
跨浏览器支持
为了打造出色的现代跨浏览器体验,尤其是对于容器查询等实验性 API,我们需要出色的 polyfill。我们向我们的团队发出了邀请,Surma 率先构建了新的容器查询 polyfill。polyfill 依赖于 ResizeObserver、MutationObserver 和 CSS :is() 函数。因此,所有现代浏览器都支持 polyfill,尤其是 Chrome 和 Edge(版本 88)、Firefox(版本 78)和 Safari(版本 14)。使用 polyfill 允许使用以下任何语法:
/* These are all equivalent */
@container (min-width: 200px) {
/* ... */
}
@container (width >= 200px) {
/* ... */
}
@container size(width >= 200px) {
/* ... */
}
深色模式
Designcember 网站的最后一个元素是美观的深色主题。我们想要展示如何利用艺术本身积极参与打造出色的深色模式体验。为此,我们以编程方式调整了每个窗口本身的背景样式,并在创建窗口图片时尽可能多地使用了 CSS。大多数背景都是 CSS 渐变色,因此可以更轻松地调整其颜色值。然后,我们将这幅画放在它们上面。
其他复活节彩蛋
个人点评
我们为页面添加了一些个性化元素,让网站更具个性。第一种是从我们的团队中汲取灵感的角色。我们还在非活动日期提供复古样式的光标,并调整网站图标样式。
功能触摸
其中一项额外的功能性设置是“跳转到今天”功能,建筑物顶部有一个小鸟。在这只小鸟上点击或按 Enter 键,可以在页面上跳转到当月的当天日期,从而可以快速了解最新发布。
Designcember.com 还提供了一个特殊的打印样式表,基本上我们在其中提供的特定图片在 8.5 x 11 英寸的纸张上效果最佳,因此您可以自行打印日历,让一年一整年都过节。
总之,在 12 月份整月,我们付出了大量的工作来打造趣味十足、异想天开的现代 Web 体验,庆祝界面开发。希望您会喜欢!