使用偏好的媒体查询构建用户自适应界面

1. 准备工作

211ff61d01be58e.png

如今,用户在设备上设置了许多偏好设置。他们希望操作系统和应用的外观和风格符合自己的喜好。用户自适应界面是指能够利用这些偏好设置来提升用户体验、让用户感觉更舒适、更像是在使用自己的设备的界面。如果操作得当,用户可能永远不会知道用户体验正在调整或已经调整。

用户偏好设置

设备硬件选择属于偏好设置,操作系统属于选择,应用和操作系统颜色属于偏好设置,应用和操作系统文档语言属于偏好设置。用户的偏好似乎只会越来越多。网页无法访问所有内容,原因显而易见。

以下是 CSS 可以使用的一些用户偏好设置示例:

以下是即将在 CSS 中推出的一些用户偏好设置示例:

媒体查询

CSS 和 Web 通过媒体查询实现自适应和响应式设计,媒体查询是一种声明式条件,如果该条件为 true,则包含一组样式。最常见的是针对设备视口大小的条件:如果大小小于 800 像素,则针对这种情况提供一些更好的样式。

用户自适应

非自适应界面是指在用户访问时不会发生任何变化的界面,本质上是向所有人提供一种体验,无法进行调整。用户自适应界面可以为五个不同的用户提供五种不同的外观和风格。功能相同,但美观度更高,而且用户可以调整界面,因此更易于使用。

前提条件

构建内容

在此 Codelab 中,您将构建一个用户自适应表单,该表单可适应以下情况:

  • 系统颜色方案偏好设置,为表单控件和周围的界面元素提供浅色和深色配色方案
  • 系统动作偏好设置,提供多种类型的动画
  • 小型和大型设备视口,可提供移动设备和桌面设备体验
  • 各种输入类型,例如键盘、屏幕阅读器、触控和鼠标
  • 任何语言和读写模式

de5d580a5b8d3c3d.png

学习内容

在此 Codelab 中,您将了解有助于构建用户自适应表单的现代 Web 功能。您将学习如何进行以下操作:

  • 制作浅色和深色主题
  • 构建动画和无障碍表单
  • 布局自适应表单
  • 使用相对单位和逻辑属性

f142984770700a43.png

此 Codelab 将重点介绍用户自适应界面。对于不相关的概念,我们仅会略作介绍,但是会提供相应代码块供您复制和粘贴。

所需条件

  • Google Chrome 89 及更高版本,或您首选的浏览器

19e9b707348ace4c.png

2. 进行设置

获取代码

您可以在 GitHub 代码库中找到所需的有关此项目的所有内容。首先,您需要获取相关代码,然后在您常用的开发者环境中将其打开。或者,您也可以复刻此 Codepen,并从那里开始。

推荐:使用 Codepen

  1. 打开新的浏览器标签页。
  2. 前往 https://codepen.io/argyleink/pen/abBMeeq。
  3. 如果您没有账号,请创建一个账号来保存工作。
  4. 点击创建分支 (Fork)。

替代方案:在本地工作

如果您想下载代码并在本地运行,则需要安装 Node.js 12 或更高版本,并设置好代码编辑器。

使用 Git

  1. 访问 https://github.com/argyleink/Google-IO-2021-Workshop_User-Adaptive-Interfaces
  2. 将代码库克隆到某个文件夹。
  3. 请注意,默认分支为 beginning。

使用文件

  1. 将下载的 ZIP 文件解压到一个文件夹中。

运行项目

使用在上述任一步骤中建立的项目目录,然后:

  1. 运行 npm install 以安装运行服务器所需的依赖项。
  2. 运行 npm start,在端口 3000 上启动服务器。
  3. 打开新的浏览器标签页。
  4. 前往 http://localhost:3000。

关于 HTML

本课将介绍用于支持用户自适应互动性的 HTML 方面。本次研讨会专门针对 CSS。如果您不熟悉如何构建表单或网站,建议您查看提供的 HTML。在无障碍功能和布局方面,HTML 元素的选择至关重要。

当您准备好开始时,这就是您要将其转换为动态自适应用户体验的骨架。

de5d580a5b8d3c3d.png

3. 自适应互动

Git 分支:beginning

学完本部分后,您的设置表单将适应:

  • 游戏手柄 + 键盘
  • 鼠标 + 触控
  • 屏幕阅读器或类似的辅助技术

HTML 属性

源代码中提供的 HTML 是一个很好的起点,因为已经选择了有助于对表单输入进行分组、排序和标记的语义元素。

表单通常是业务的关键互动点,因此表单必须能够适应网络可以提供的多种输入类型。例如,表单可能需要支持在移动设备上通过触控方式使用。在本部分中,您需要在布局和样式之前确保自适应输入可用性。

分组输入

HTML 中的 <fieldset> 元素用于将类似的输入和控件分组在一起。在表单中,您有两个组,一个用于音量,一个用于通知。这对于用户体验非常重要,因为用户可以跳过整个部分。

对元素进行排序

元素的顺序符合逻辑。这对用户体验非常重要,可确保游戏手柄、键盘或屏幕阅读器技术的视觉体验顺序相同或相似。

键盘互动

网络用户已经习惯使用 Tab 键在表单中移动,幸运的是,如果您提供预期的 HTML 元素,浏览器会处理此问题。使用 <button>、<input>、<h2> 和 <label> 等元素会自动成为键盘或屏幕阅读器的目标。

9fc2218473eee194.gif

上面的视频演示了如何使用 Tab 键和箭头键在界面中移动并进行更改。不过,蓝色轮廓与输入元素非常紧密,请添加以下样式,让此互动有一些喘息空间。

style.css

input {
  outline-offset: 5px;
}

可尝试的操作

  1. 查看 index.html 中使用的 HTML 元素。
  2. 在浏览器中点击演示页面。
  3. 按 tab 键和 shift+tab 键可在表单中移动元素焦点。
  4. 使用键盘更改滑块和复选框的值。
  5. 连接蓝牙游戏手柄控制器,并在表单中移动元素焦点。

鼠标互动

网络用户已经习惯了使用鼠标与表单互动。请尝试使用鼠标操作表单。滑块和复选框虽然可行,但您还可以做得更好。这些复选框太小,不方便用鼠标点击。

ab51d0c0ee0d6898.gif

看到您获得了两项用户体验功能来连接标签及其输入了吗?

第一个功能是提供可供互动的选项,并且标签比小方块更容易用鼠标定位。

第二个功能是确切知道标签对应的是哪个输入。目前,如果不使用 CSS,很难确定哪个标签对应哪个复选框,除非您提供一些属性。

这种显式连接还可以改善屏幕阅读器的体验,下一部分将对此进行介绍。

无关联:没有连接元素的属性

<input type="checkbox">
<label>...</label>

关联:连接元素的属性

<input type="checkbox" id="voice-notifications" name="voice-notifications">
<label for="voice-notifications">...</label>

提供的 HTML 已为所有输入和标签添加了属性。如果这对您来说是一个新概念,那么值得进一步研究。

可尝试的操作

  1. 将鼠标悬停在标签上,您会看到复选框突出显示。
  2. 使用 Chrome 开发者工具调查标签元素,直观呈现可选中复选框的可点击表面区域。

屏幕阅读器互动

辅助技术可以与此表单互动,并且只需几个 HTML 属性,即可让用户体验更加顺畅。

28c4a14b892c62d0.gif

对于在 Chrome 中使用屏幕阅读器浏览当前表单的用户,屏幕阅读器会在 <picture> 元素处不必要地停顿(并非 Chrome 独有)。使用屏幕阅读器的用户很可能存在视力障碍,因此在图片上停顿并无帮助。您可以使用属性对屏幕阅读器隐藏元素。

index.html

<picture aria-hidden="true">

现在,屏幕阅读器会跳过纯视觉元素。

f269a73db943e48e.gif

滑块元素 input[type="range"] 具有一个特殊的 ARIA 属性:aria-labelledby="media-volume"。这会为屏幕阅读器提供特殊指令,以提升用户体验。

可尝试的操作

  1. 使用操作系统的屏幕阅读器技术在表单中移动焦点。
  2. 下载并尝试在表单上使用一些屏幕阅读器软件。

4. 自适应布局

Git 分支:layouts

学完此部分后,设置页面将:

  • 使用自定义属性和用户相对单位创建间距系统
  • 编写 CSS 网格,实现灵活、自适应的对齐和间距
  • 使用逻辑属性实现国际化自适应布局
  • 编写媒体查询,以便在紧凑型布局和宽敞型布局之间进行调整

f142984770700a43.png

间距

实现良好布局的关键在于限制间距选项。这有助于内容自然地对齐和协调。

自定义属性

本研讨会基于一组七个自定义属性大小。

  • 将以下代码放在 style.css 的顶部:

style.css

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

命名方式接近人们在日常交流中描述空间时所用的措辞。您还可以专门使用 rem 单位来设置清晰易读的整体单位大小,以便适应并考虑用户的偏好设置。

页面样式

接下来,您需要设置一些文档样式,移除元素的边距,并将字体设置为美观的 Sans Serif。

  • 将以下内容添加到 style.css 中:

style.css

* {
  box-sizing: border-box;
  margin: 0;
}

html {
  block-size: 100%;
}

body {
  min-block-size: 100%;  
  padding-block-start: var(--space-xs);
  padding-block-end: var(--space-xs);
}

您已经首次使用了间距自定义属性!您的太空之旅就此开始。

排版

此布局的字体是自适应的。system-ui 关键字将使用用户操作系统确定的最佳界面字体。

body {
  font-family: system-ui, sans-serif;
}

h1,h2,h3 { 
  font-weight: 500;
}

small {
  line-height: 1.5;
}

h1、h2 和 h3 的样式是次要的,仅用于样式设计。不过,small 元素需要额外的 line-height,以便在文本换行时使用。否则,它们会挤在一起。

逻辑属性

请注意,body 上的 padding 使用逻辑属性(block-start、block-end)来指定侧边。在此 Codelab 的其余部分,我们将广泛使用逻辑属性。与 rem 单位一样,它们也会适应用户。此布局可以翻译成其他语言,并设置为用户习惯的母语自然书写和文档方向。逻辑属性只需定义一次间距、方向或对齐方式,即可支持此功能。

ce5190e22d97156e.png

网格和 Flexbox 已经与流相关,这意味着为一种语言编写的样式将根据上下文适当应用于其他语言。自适应方向性;内容流相对于文档方向性。

逻辑属性可让您以更少的样式覆盖更多用户。

CSS 网格布局

grid CSS 属性是一种强大的布局工具,具有许多功能,可用于处理复杂任务。您将构建几个简单的网格布局和一个复杂的布局。您还将从外到内、从宏观布局到微观布局进行设计。间距自定义属性将变得至关重要,不仅是内边距或外边距值,还包括列大小、边框半径等。

以下是 Chrome 开发者工具一次性叠加每个 CSS 网格布局的屏幕截图:

84e57c54d0633793.png

  1. 请按照以下步骤操作,将以下每个样式添加到 style.css:

<main>

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
  padding: var(--space-sm);
}

默认情况下,网格会将每个子元素放入各自的行中,因此非常适合堆叠元素。它还具有使用 gap 的额外优势。之前,您使用 * 选择器在所有元素上设置了 margin: 0,现在,由于您使用 gap 来设置间距,因此这一点非常重要。Gap 不仅是管理容器中空间的单一位置,而且与其流相对。

<form>

form {
  max-width: 89vw;
  display: grid;
  gap: var(--space-xl) var(--space-xxl);
  align-items: flex-start;
  grid-template-columns: 
    repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
}

这是设计中最棘手的网格布局,但也是最令人兴奋的自适应方面:

  • max-width 为布局算法提供了一个值,供其在决定可设置多大尺寸时使用。
  • gap 正在使用自定义属性,并传递与 column-gap 不同的 row-gap。
  • align-items 设置为 flex-start,以免拉伸项高度。
  • grid-template-columns 的语法有些复杂,但目标很明确:保持列宽为 35ch,且不小于 10ch,如果有空间,就将内容放入列中,否则放入行中。
  1. 测试调整浏览器大小。请注意,在小视口中,表单会折叠成行,但如果有空间,则会流入新列,无需媒体查询即可自适应。这种不使用媒体查询的自适应样式策略对于组件或以内容为中心的布局特别有用。

<section>

section {
  display: grid;
  gap: var(--space-md);
}

每个部分都应是一个行网格,子元素之间留有中等间距。

header {
  display: grid;
  gap: var(--space-xxs);
}

每个标题都应是一个行网格,子元素之间有极小的间距。

<fieldset>

fieldset {
  padding: 0;
  display: grid;
  gap: 1px;
  border-radius: var(--space-sm);
  overflow: hidden;
}

此布局负责创建类似卡片的外观并将输入内容分组。在下一部分中添加颜色后,overflow: hidden 和 gap: 1px 就会变得清晰。

.fieldset-item

.fieldset-item {
  display: grid;
  grid-template-columns: var(--space-lg) 1fr;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
}

此布局负责将图标和复选框及其关联的标签和控件居中。网格模板的第一列 var(--space-lg) 创建了一个比图标更宽的列,以便子元素有空间居中。

此布局展示了自定义属性中已经做出了多少设计决策。内边距、间距和列的大小都使用您已定义的值,在系统内保持和谐。

<picture>

.fieldset-item > picture {
  block-size: var(--space-xl);
  inline-size: var(--space-xl);
  clip-path: circle(50%);
  display: inline-grid;
  place-content: center;
}

此布局负责设置、图标圆圈的大小、创建圆形以及将图片居中放置在圆圈内。

<picture> 和 [checkbox] 对齐

.fieldset-item > :is(picture, input[type="checkbox"]) {
  place-self: center;
}

此布局使用 :is 伪选择器,仅将图片和复选框元素居中。

  1. 将选择器 picture > svg 替换为 .fieldset-item svg,如下所示:

.fieldset-item <svg>

.fieldset-item svg {
  block-size: var(--space-md);
}

这会将 SVG 图标大小设置为尺寸系统中的值。

.sm-stack

.sm-stack {
  display: grid;
  gap: var(--space-xs);
}

此实用程序类适用于复选框标签元素,用于为复选框的辅助文本留出空间。

input[type="checkbox"]

input[type="checkbox"] {
  inline-size: var(--space-sm);
  block-size: var(--space-sm);
}

这些样式使用间距集中的值来增加复选框的大小。

可尝试的操作

  1. 打开 Chrome 开发者工具,然后在元素面板中找到 HTML 上的网格标记。点击这些按钮即可开启调试工具。
  2. 打开 Chrome 开发者工具,然后将鼠标悬停在样式窗格中的间隙上。
  3. 打开 Chrome 开发者工具,前往样式窗格,然后从样式切换到布局。通过切换其设置并开启布局来探索此区域。

媒体查询

以下 CSS 会根据视口尺寸和方向调整样式,以便根据视口上下文调整间距或排列方式,从而达到最佳效果。

<main>

@media (min-width: 540px) {
  main {
    padding: var(--space-lg);
  }
}

@media (min-width: 800px) {
  main {
    padding: var(--space-xl);
  }
}

这两个媒体查询会在视口空间增加时为 main 提供更多内边距。这意味着,它一开始是紧凑的,内边距较小,但随着可用空间增加,它会变得越来越宽敞。

<form>

form {
  --repeat: auto-fit;
  grid-template-columns: 
    repeat(var(--repeat), minmax(min(10ch, 100%), 35ch));
}

@media (orientation: landscape) and (min-width: 640px) {
  form {
    --repeat: 2;
  }
}

该表单已经通过 auto-fit 响应视口大小,但在移动设备上进行测试时,将设备转为横向并不会使两个表单组并排显示。使用 orientation 媒体查询和视口宽度检查来适应这种横屏模式。现在,如果设备处于横屏模式且宽度至少为 640 像素,则通过将 --repeat 自定义属性切换为数字(而非 auto-fit 关键字)来强制显示两列。

.fieldset-item

@media (min-width: 540px) {
  .fieldset-item {
    grid-template-columns: var(--space-xxl) 1fr;
    gap: var(--space-xs);
    padding: var(--space-md) var(--space-xl) var(--space-md) 0;
  }
}

此媒体查询是当有更多视口空间可用时的另一种间距扩展。网格模板通过在模板中使用较大的自定义属性 (var(--space-xxl)) 来扩展第一列。内边距也会增加到更大的自定义属性中。

可尝试的操作

  1. 展开和收缩浏览器,观察空间如何调整。
  2. 在移动设备上预览
  3. 在移动设备上横向预览

5. 自适应颜色

Git 分支:colors

完成本部分后,您的设置表单将:

  • 适应深色和浅色偏好
  • 具有源自品牌十六进制颜色的配色方案
  • 使用无障碍颜色

19e9b707348ace4c.png

HSL

在下一部分中,您将使用 HSL 创建一个颜色系统,以帮助您制作浅色和深色主题。它基于 CSS 中的核心概念:calc()。

HSL 代表色调、饱和度和亮度。色调是一个角度,就像钟表上的一个点,而饱和度和亮度则是百分比。calc() 能够对百分比和角度进行数学运算。您可以在 CSS 中对这些百分比执行亮度和饱和度计算。将颜色通道计算与自定义属性相结合,您就可以获得一种现代、动态的配色方案,其中变体是根据基础颜色计算得出的,从而避免在代码中管理大量颜色。

5300e908c0c33d7.png

自定义属性

在本部分中,您将构建一组自定义属性,以便在其余样式中使用。与您之前在 :root 标记中创建的间距集类似,您将添加颜色。

假设应用的品牌颜色为 #0af。您的第一个任务是将此十六进制颜色码转换为 HSL 颜色值:hsl(200 100% 50%)。此转换会显示 HSL 格式的品牌颜色通道,您可以使用 calc() 计算各种辅助品牌颜色。

本部分中的以下每个代码块都应添加到同一个 :root 选择器中。

品牌频道

:root {
  --hue: 200;
  --saturation: 100%;
  --lightness: 50%;
}

三个 HSL 通道已被提取并放入各自的自定义属性中。

  1. 按原样使用所有这三个属性,并重新创建品牌颜色。

品牌

:root {
  --brand: hsl(
    var(--hue) 
    calc(var(--saturation) / 2)
    var(--lightness) 
  );
}

由于您的配色方案默认为深色,因此最好降低颜色饱和度,以便在深色表面上使用(否则可能会造成视觉不适或难以辨认)。如需降低品牌颜色的饱和度,您可以使用原有的色相和亮度,但通过除法运算将饱和度减半:calc(var(--saturation) / 2)。现在,您的品牌颜色已正确应用到主题中,但已降低饱和度以供使用。

文本

:root {
  --text1: hsl(var(--hue) 15% 85%);
  --text2: hsl(var(--hue) 15% 65%);
}

对于深色主题中的阅读文本,您可以使用品牌色调作为基础,但要从中构建接近白色的颜色。许多用户会认为文字是白色的,但实际上是浅蓝色。保持色调一致是打造和谐设计的有效方式。--text1 包含 85% 的白色,--text2 包含 65% 的白色,两者的饱和度都非常低。

  1. 将代码添加到项目后,打开 Chrome 开发者工具,尝试更改这些通道值。感受 HSL 及其通道如何相互作用。也许您喜欢饱和度更高或更低的画面。

Surface

:root {
  --surface1: hsl(var(--hue) 10% 10%);
  --surface2: hsl(var(--hue) 10% 15%);
  --surface3: hsl(var(--hue) 5% 20%);
  --surface4: hsl(var(--hue) 5% 25%);
}

文本颜色非常浅,因为在深色模式下,表面颜色会很深。如果文字颜色使用较高的亮度值(85% 及以上),则界面将使用较低的值(30% 及以下)。在表面和文本之间保持合理的亮度范围,有助于确保用户能够轻松阅读。

  1. 请注意,颜色从最深的灰色开始,亮度为 10%,饱和度为 10%,然后随着亮度增加而降低饱和度。每个新表面都比前一个表面轻 5%。在较亮的表面上,饱和度也会略微降低。尝试将所有表面的饱和度都设为 10%。您是更喜欢还是更不喜欢?

浅色主题

在指定深色主题的一组文本和表面颜色后,现在可以通过更新 prefers-color-scheme 媒体查询中的颜色自定义属性来适应浅色主题偏好。

您将使用相同的技术,使表面和文本颜色之间的亮度值保持较大差异,从而使颜色保持良好的对比度。

品牌

@media (prefers-color-scheme: light) {
  :root {
    --brand: hsl(
      var(--hue) 
      var(--saturation)
      var(--lightness) 
    );
  }
}

首先是品牌颜色。它需要恢复饱和度,才能发挥全部威力。

文本

@media (prefers-color-scheme: light) {
  :root {
    --text1: hsl(
      var(--hue) 
      var(--saturation)
      10% 
    );

    --text2: hsl(
      var(--hue) 
      calc(var(--saturation) / 2)
      30%
    );
  }
}

与深色主题使用非常浅的蓝色文本颜色类似,浅色主题使用非常深的蓝色文本颜色。看到 HSL 颜色的亮度值为 10% 和 30% 时,您应该意识到这些颜色是深色。

Surface

@media (prefers-color-scheme: light) {
  :root {
    --surface1: hsl(var(--hue) 20% 90%);
    --surface2: hsl(var(--hue) 10% 99%);
    --surface3: hsl(var(--hue) 10% 96%);
    --surface4: hsl(var(--hue) 10% 85%);
  }
}

这些表面颜色最先打破了模式。到目前为止,原本看起来相当合理且线性的过程现在被打破了。好消息是,您可以直接在代码中尝试 HSL 浅色主题颜色组合,并调整亮度和饱和度,从而打造出既不太冷也不太蓝的浅色配色方案。

使用颜色系统

现在,颜色已定义,是时候使用它们了。您有一个醒目的品牌强调色、两种文本颜色和四种表面颜色。

  • 对于以下代码部分,请找到匹配的选择器,并将颜色 CSS 添加到现有代码块中。

<body>

body {
  background: var(--surface1);
  color: var(--text1);
}

页面主色是您创建的第一组表面颜色和文本颜色,这也使默认对比度达到最大。现在可以开始测试浅色和深色切换功能了!

<fieldset>

fieldset {
  border: 1px solid var(--surface4);
  background: var(--surface4);
}

这是设计中的卡片状元素。1 像素的边框和 1 像素的间隙颜色相同,代表每个 .fieldset-item 后面的表面。这能营造出和谐的视觉效果,且易于维护。

.fieldset-item

.fieldset-item {
  background: var(--surface3);
}

每个表单输入都位于各自的表面上。希望您能看出这些元素是如何组合在一起的,以及不同明度的变化是如何层层叠加的。

.fieldset-item > picture

.fieldset-item > picture {
  background: var(--surface4);
}

这是一种风格选择,旨在展示图标周围的圆形。在下一部分中添加互动后,原因就会显而易见。

.fieldset-item svg

.fieldset-item svg {
  fill: var(--text2);
}

表单中的图标已设置为使用替代文本 --text2。在设计中,填充图标的颜色略浅于文字,可避免图标显得过于厚重。

.fieldset-item:focus-within svg

.fieldset-item:focus-within svg {
  fill: var(--brand);
}

当用户与输入容器元素内的某个输入元素互动时,此选择器会匹配该输入容器元素,并定位到 SVG,以使用品牌强调色突出显示该 SVG。这会提供良好的表单用户体验反馈,其中与输入内容互动会突出显示其相关图标。

<small>

small {
  color: var(--text2);
}

文字很小。与标题和段落(主要内容)相比,它应该稍微柔和一些。

深色表单控件

:root {
  color-scheme: dark light;
}

最后,我们还要告诉浏览器,此页面同时支持深色主题和浅色主题。浏览器会为我们提供深色表单控件。

6. 自适应动画

Git 分支:animations

学完此部分后,设置页面将:

  • 适应用户的动作偏好
  • 响应用户互动

b23792cdf4cc20d2.gif

减少动画效果与无动画效果

在操作系统中找到的动画用户偏好设置未提供“无动画”值。该选项用于减少动画效果。对于偏好减少动画的用户,淡入淡出动画、颜色过渡等效果仍然是理想的选择。

在此设置页面中,屏幕上没有太多移动。这种运动更像是一种缩放效果,就像元素正在向用户移动一样。调整 CSS 代码以适应减少动画效果非常简单,只需减少缩放过渡即可。

互动样式

<fieldset>

fieldset {
  transition: box-shadow .3s ease;
}

fieldset:focus-within {
  box-shadow: 0 5px 20px -10px hsl(0 0% 0% / 50%);
}

当用户与其中一个 <fieldset> 卡片式元素的输入内容互动时,系统会添加提升效果。界面将一个元素向前推进,帮助用户聚焦于向其呈现的上下文表单组。

.fieldset-item

.fieldset-item {
  transition: background .2s ease;
}

.fieldset-item:focus-within {
  background: var(--surface2);
}

当用户与输入内容互动时,特定项图层的背景会变为醒目的表面颜色,这是另一项辅助界面功能,有助于吸引用户的注意力并表明输入内容正在接收中。在大多数情况下,无需减少颜色过渡。

.fieldset-item > picture

@media (prefers-reduced-motion: no-preference) {
  .fieldset-item > picture {
    clip-path: circle(40%);
    transition: clip-path .3s ease;
  }

  .fieldset-item:focus-within picture {
    clip-path: circle(50%);
  }
}

以下是一个 clip-path 动画,仅在用户对减少动画效果没有偏好设置时使用。第一个选择器和样式会将圆形剪裁路径缩小 10%,并设置一些过渡参数。第二个选择器和样式会等待用户与输入框互动,然后放大图标的圆圈。如果一切正常,则会显示一个细微但整洁的效果。

7. 恭喜

Git 分支:complete

恭喜,您已成功构建用户自适应界面!

现在,您已掌握了所需的关键步骤,知道如何制作可适应各种用户场景和设置的界面。