建筑设计人员

简要了解 Designcember 的节日日历风格体验的构建过程和所用工具。

在 12 月这个充满节日气氛的月份,许多人都会使用日历来倒计时和庆祝节日,因此我们想重点介绍社区和 Chrome 团队的网络内容。每天,我们都会重点介绍一个与界面开发和设计相关的内容,总共介绍了 31 个重点内容,其中包括 26 个新的演示网站、工具、公告、播客、视频、文章和案例研究。

如需查看完整体验,请访问 designcember.web.app

Designcember 网站。

概览

我们的目标是以尽可能少的字节数提供无障碍、奇趣、现代且自适应的 Web 体验。我们想重点介绍新的自适应 API(例如容器查询),并在以设计为中心且包含大量素材资源的网站中展示一个精美的深色模式示例。为此,我们压缩了文件,提供了多种格式,使用了针对静态网站生成优化的构建工具,发布了新的 Polyfill 等。

从奇思妙想开始

Designcember 日历网站的创意是,在 12 月期间展示我们想要重点介绍的所有作品,同时本身也充当演示网站。我们决定建造一栋自适应公寓楼,它可以变得更高更窄,也可以变得更矮更宽,窗户可以在框架内自行调整位置。每个窗口代表一天(因此,也代表一个内容片段)。 我们与插画家 Alice Lee 合作,将我们的愿景变为现实。

Designcember 页面框架的草图。

Alice 很有启发性,她分享的流程和草图即使在早期概念阶段也令人兴奋不已。在她忙于处理美术工作时,我们则在架构方面下功夫。早期讨论围绕宏观布局、建筑及其窗户展开。随着视口空间越来越大,窗口将如何适应单列、双列或三列布局?它们可以缩小或拉伸多少?建筑物的最大面积是多少?时间范围会发生多大变化?

以下是使用 grid-auto-flow: dense 的自适应原型预览,展示了网格算法如何自动放置窗口。我们很快意识到,虽然宽高比网格在展示艺术作品方面表现出色,但无法让窗口在不均匀的可用空间中放大和缩小,也无法展示容器查询的强大功能。

动画:展示了此线框图如何响应不同的屏幕尺寸。
在 CodePen 上查看此演示。

一旦总体网格相对稳定,并传达了建筑及其窗户的响应方向感,我们就可以专注于单个窗户。网格中有些窗口的拉伸、缩小、挤压、放大和重新组合程度比其他窗口更高。

线框图,显示了窗口在不同断点处的显示方式。

每个窗口都需要处理一定程度的调整大小波动。下图是一个窗口原型,展示了其对湍流的响应能力,显示了每个互动窗口的预期调整幅度。

使用 sprite 表格制作窗口动画

部分窗口带有动画效果,可为用户带来更丰富的互动体验。这些动画是在 Photoshop 中逐帧手绘的。每个帧都会导出,然后使用此精灵图生成器转换为精灵图,最后使用 Squoosh 进行优化。然后,CSS 动画会使用 background-position-xanimation-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 技能,并了解一些关于网络遮罩的知识。我们来看看第 8 天的窗口。

第 8 天的窗口。

若要成为遮罩,内部四叶草类型的形状必须单独分离出来,并填充为白色。白色表示 CSS 会保留哪些内容,而白色以外的所有内容都不会保留。在 Photoshop 中,选择窗口内部,羽化 1 像素(以消除锯齿问题),然后填充白色,并以与窗口框架相同的高度和宽度导出。这样,框架和遮罩就可以直接叠放在一起,从而按预期显示框架内的内容。

Clover 遮罩图片

完成后,窗口的内容可以修改,并且始终显示在自定义框架内。下图显示了窗口的深色模式版本,其中背景渐变效果不同,并且对光线应用了发光 CSS 滤镜。

深色模式下第 8 天的窗口。

遮盖还支持基于响应式容器查询的窗口。在窗口 9 中,有一个角色在窗口变窄之前一直隐藏在面具后面。为了确保用户无法将图片调整到框架之外,Alice 为我们完成了整个角色。角色在窗口内被遮盖,但植物没有,因此我们面临的另一个挑战是将遮盖的元素与未遮盖的图层分层,并确保它们都能很好地一起缩放。

下图显示了未对窗口和角色应用遮罩时的效果。

不含遮罩的窗口 9 的图片。

挤压艺术品

为了保持插图的保真度并确保高清屏幕不会出现模糊的用户体验,Alice 以 3 倍像素比进行创作。我们原本打算使用 imgix 在其服务器上提供优化后的图片和格式,但后来发现,使用 Squoosh 工具进行手动调整可以节省 50% 或更多空间。

使用 Squoosh 压缩图片。

插画在压缩方面面临独特的挑战,尤其是 Alice 使用的笔触和透明粗糙边缘风格。我们选择将每个通过 Photoshop 导出的 3 倍 png 图片压缩为较小的 png、webp 和 avif。每种文件类型都有自己的特殊压缩能力,我们压缩了 50 多张图片,才找到一些通用的优化设置。

在需要优化 200 多张图片的情况下,Squoosh CLI 变得至关重要,如果手动完成所有这些操作,则需要花费数天时间。获得通用优化设置后,我们以命令行指令的形式提供这些设置,并批量处理整个文件夹的 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 开发者来说都很熟悉,而作用域限定的类名样式系统可帮助每位开发者了解自己在窗口上的工作不会与其他人发生冲突。

天数(以组件形式)

每天都是一个组件,用于从build time data store 中提取状态。这样,我们就可以在 HTML 到达浏览器之前运行模板逻辑。该逻辑会确定相应日期是否应显示其提示,因为非活动日期没有弹出式窗口。

构建每小时运行一次,当构建服务器超过午夜时,构建时间数据存储区会解锁新的一天。这些可自行更新且自给自足的小型系统可确保网站保持最新状态。

作用域样式和 Open Props

Astro 可将样式限定在其组件模型内,这使得在许多团队成员之间分配工作负载变得更加容易,也让使用 Open Props 变得更加有趣。Open Props normalize.css 样式在自适应(浅色和深色)主题中非常有用,还有助于处理段落和标题等内容。

作为 Astro 的早期采用者,我们在使用 PostCSS 时遇到了一些问题。例如,由于存在太多 build 问题,我们无法更新到最新版 Astro。您可以在此处花费更多时间来优化 build 和开发者工作流程。

灵活的容器

有些窗口会放大和缩小,但会保持宽高比,以保留其艺术效果。我们还使用了一些其他窗口来展示基于组件的架构与容器查询的强大功能。容器查询意味着窗口可以拥有自己的自适应样式信息,并根据自身的大小进行重新调整。有些窗口从窄变宽,因此需要调整其中媒体的大小以及媒体的放置位置。

演示窗口在空间变大时如何变化。

当窗口有更多可用空间时,我们可以调整窗口的大小或子元素以适应空间。事实证明,为了实现自适应窗口,容器查询不仅可以用来展示,而且是必需的,并且可以大幅简化某些布局的编排。

.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 依赖于 ResizeObserverMutationObserver 和 CSS :is() 函数。因此,所有现代浏览器都支持该填充,具体而言,Chrome 和 Edge 从版本 88 开始支持,Firefox 从版本 78 开始支持,Safari 从版本 14 开始支持。使用 Polyfill 可采用以下任一语法:

/* These are all equivalent */
@container (min-width: 200px) {
  /* ... */
}
@container (width >= 200px) {
  /* ... */
}
@container size(width >= 200px) {
  /* ... */
}

深色模式

Designcember 网站的浅色模式版本和深色模式版本并排显示。

对于 Designcember 网站而言,最后也是至关重要的一点是采用美观的深色主题。我们想展示如何利用艺术本身积极参与打造出色的深色模式体验。为此,我们以编程方式调整了每个窗口本身的背景样式,并在创建窗口素材资源时尽可能多地使用了 CSS。大多数背景都是 CSS 渐变,这样可以更轻松地调整其颜色值。然后,我们在这些图层之上添加了艺术效果。

其他彩蛋

个性化元素

我们在该网页中添加了一些个性化元素,让网站更具特色。首先是角色阵容,其灵感来自我们的团队。我们还在非活跃日添加了怀旧风格的光标,并尝试了不同的网站图标样式。

自定义光标样式和 favicon 选项

功能性触控

新增的功能之一是“跳转到今天”功能,该功能在建筑物顶部显示一只小鸟。点击或按 Enter 键后,页面会向下滚动到当月当天的位置,以便您快速查看最新发布的内容。

Designcember 网站还提供了一个特殊的打印样式表,其中包含最适合在 8.5 英寸 x 11 英寸纸张上打印的特定图片,因此您可以自行打印日历,全年都保持节日氛围。

海报尺寸的日历设计打印件。
Una 拿着日历的大幅打印件。

总而言之,我们投入了大量精力,打造出有趣、奇幻的现代网络体验,以庆祝整个 12 月的界面开发。希望您喜欢!

带有注释和视觉注释的日历部分