整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

深入理解 HTML 中的 ARIA Roles: 提高可访问性和用户体验

HTML 中,ARIA 角色(Accessible Rich Internet Applications)是一种用于提高可访问性的技术。ARIA 角色可以帮助屏幕阅读器、键盘用户和其他辅助技术正确地理解和导航网页中的结构和交互元素。

ARIA 角色是一种用于描述网页元素的方式,它可以让辅助技术更好地理解元素的功能和行为。例如,使用 aria-label 属性可以为无视力用户提供元素的描述,使用 aria-labelledby 属性可以将元素与其标签相关联,使用 aria-describedby 属性可以为元素提供描述信息等。

ARIA 角色还可以帮助键盘用户更方便地导航网页,例如,使用 aria-expanded 属性可以控制可折叠的菜单,使用 aria-haspopup 属性可以指示元素包含弹出菜单等。

使用 ARIA 角色不仅可以提高网页的可访问性,还可以让用户体验更好,因为它可以让用户更容易地理解和操作网页中的各种元素。

标题: 实现 HTML 中的 ARIA Roles: 一个简单示例

下面是一个使用 ARIA 角色的简单示例:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Example Page</title>

</head>

<body>

<h1>Example Page</h1>

<p>This is an example page with ARIA roles.</p>

<button aria-label="Open menu">Open menu</button>

<ul role="menu">

<li role="menuitem">Item 1</li>

<li role="menuitem">Item 2</li>

<li role="menuitem">Item 3</li>

</ul>

<p>This is some text that describes the menu.</p>

<button aria-expanded="true">Expand</button>

<ul role="menu" aria-expanded="true">

<li role="menuitem">Subitem 1</li>

<li role="menuitem">Subitem 2</li>

<li role="menuitem">Subitem 3</li>

</ul>

<p>This is some text that describes the submenu.</p>

</body>

</html>

在上述示例中,我们使用了 aria-label 属性来为按钮提供描述,使用 role="menu" 来定义菜单,使用 aria-expanded 属性来控制菜单的展开状态,同时还使用了 role="menuitem" 来定义菜单项。通过这样的方式,我们可以让屏幕阅读器和键盘用户更好地了解和操作网页中的元素。

标题: 实践中的 ARIA Roles: 提高可访问性的关键技巧

实现 HTML 中的 ARIA 角色的关键技巧包括:

1. 正确地使用 ARIA 角色:确保每个元素都有正确的 ARIA 角色,以便辅助技术可以正确地理解元素的功能和行为。

2. 使用描述性 ARIA 属性:使用 aria-label、aria-labelledby 和 aria-describedby 等属性来提供元素的描述,以便于无视力用户。

3. 控制可折叠的元素:使用 aria-expanded 属性来控制可折叠的元素,例如菜单。

4. 指定弹出菜单:使用 aria-haspopup 属性来指定元素包含弹出菜单。

5. 提高键盘导航:使用 ARIA 属性来提高键盘用户的导航体验,例如使用 tabindex 属性来定义元素的焦点顺序。

通过正确地使用 ARIA 角色和属性,我们可以让网页更具可访问性,同时也让用户体验更好。

为一名 7 年多的前端开发者,我从未想过我的工作需要具有可访问性,直到最近才领悟。


是的,我们确实提供了带 alt 标签的图片,并使用 header、footer、main、aside、nav section 标签......就是这些,大多数人止步于此。我们中的一些人仍然使用带 class 的 div 作为这些特定的布局元素。为什么?因为我们不知道。


我们这样做不是任何人的错,除了少数,这个领域的大部分人都是被推到这个坑里谋生的,多数又在坑里一遍又一遍地做着同样的事情,到最后还在想我到底在做什么。


直到有必要改变。


也许这种需要会以启蒙的形式出现,顺便说一句,启蒙很少发生,更有可能是将正确的行业可访问性规范从开发团队的指导方针变为强制性的要求。


后者可能是你我所处的境况。好了,闲聊结束,我们直奔主题。


注意:不适用于高级前端技术人员,我没有详细介绍可访问性,只想制定一个简单的指引,可以在所有项目中遵循,类似于需要注意的事项清单。


如果你发现任何错误,请随时指出,我会尽快纠正。


以下是我们在开发任何前端时需要注意的事项:


  1. HTML 语义 —— 正确使用 HTML 分区元素
  2. 标题 —— 用于显示文档的结构,而非用于大字体的设计
  3. 键盘导航使用“tabindex”和 ARIA —— 确保 tab 可用以及删除多余的 tab 链接
  4. 可访问的图标按钮 —— 至少使用带有适当标签的<button>
  5. 焦点指示器 —— 除非有替代方案,否则不要禁用默认的焦点样式
  6. 尽可能提供视觉标签
  7. 描述性信息图——为屏幕阅读器提供回退文本描述

HTML 语义


有一种叫做 ARIA 地标的东西,它能简单地将网页划分为不同的地标,使屏幕阅读器更容易在网页内部导航。


当前这是不需要主动思考就能实现的,因为我们可能在不知不觉中就这么做了,即“默认情况下,HTML 分区元素定义了 ARIA 地标”。


这意味着正确地使用 HTML 分区元素,像<header>、<main>、<nav>、<footer>、article>、 <nav>等,而不要使用<div class="header">。


请查看ARIA实践,可以更深入地学习。

标题


屏幕阅读器浏览网页的另一种方式是使用标题。


使用标题是展示文档结构的一种方式,如果只是设计上要显示大字体或粗体,则不要使用它。


考虑一个没有 h1 页面的场景,当屏幕阅读器读到这样的页面时,用户是无法获知标题的,而页面的标题通常是用<h1>表示。


在这种情况下,为了提高可访问性,你可以做两件事:


  1. 请设计师做出一些必要的改变,这可能行不通,因为设计已经被客户签署了。
  2. 将<h1>标签添加到页面结构,并隐藏它。


当我们需要在网页上隐藏某些内容时,有以下几个选项:


  1. display: none;
  2. visibility: hidden;
  3. opacity: 0;
  4. clip-path: inset(100%)


选项 1 2 不可行,因为它们使元素从 DOM 中完全删除了,屏幕阅读器也不可用,隐藏属性也不行,这等同于“display: none;”。


参考用下面的样式类来隐藏你的元素:


.sr-only {
    clip: rect(0 0 0 0);
    clip-path: inset(100%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
}

复制代码

键盘导航使用“tabindex”和 ARIA


我们需要了解的是,不是所有的用户都使用鼠标来浏览网页,有些只使用键盘导航,还有一些使用屏幕阅读器。对这些用户来说,从网页的一个部分到另一个部分,可能不像使用鼠标操作的人那么简单。


我们考虑下面的场景:


假设我们有一个博客,在文章的列表页上,一篇文章如下所示:



它有一个缩略图、一个标题、一个描述和一个“阅读更多”的按钮,这是几乎所有博客文章的通用模板。那么,我们是如何链接到详情页呢?


我们将缩略图做成一个链接(link 1),接着是标题(link 2),然后是“阅读更多”按钮(link 3),这 3 个链接都指向同一个页面。


因此,当我们使用屏幕阅读器或键盘浏览页面时,我们必须用 tab 键按 3 次才能跳转到下一篇文章。


这当然得避免,也很简单。对冗余的链接,可以添加以下属性:


  1. tabindex="-1"(它可以防止链接被 tab 选中 —— 对于键盘用户)
  2. aria-hidden="true"(你不需要将它暴露给屏幕阅读器,因为已经有了相同的链接 —— 对于屏幕阅读器)


可访问图标按钮


首先,在设计中有按钮时,应使用<button>元素,不要使用<div>等其他元素,再将样式设置为按钮的样子,我知道我们这样做已经很久了,但是时候改变了。


原因正如 HTML 语义部分所述,原生元素有很多内置的 ARIA 特性。


尽管用<div><button>做出来的按钮对于大多数用户来说,看起来是一模一样的,但对于使用屏幕阅读器的盲人用户来说,它看起来非常不同,屏幕阅读器甚至可能会忽略这是一个按钮。


这里也有一些注意事项:


不设置按钮样式以及设置按钮样式的理想方法


针对于没有任何文本、只有图片的按钮,可遵循以下三个步骤中的任何一个:

  1. 使用隐藏的<span>来指明按钮标签
  2. <button>上使用 aria-label
  3. <button>上使用 aria-labelledby


如果你有兴趣,请查看这篇博文,了解更多关于上述步骤的详情。


焦点指标


你用过以下代码吗?


:focus {
    outline: none;
}

复制代码


当我们在网页上按 tab 键时,看到的轮廓就是焦点指示器,通常我们用上面的代码禁用它,至少我以前是这么做的。


这真是个糟糕的主意,焦点指示器能告诉使用键盘导航的用户们他们当前正在交互的位置,如果我们移除焦点样式,相当于将这些用户置于黑暗中,隐藏焦点指示器就像隐藏鼠标光标。


因此,如果你删除了默认的焦点样式,那一定得添加自定义的焦点样式。


在设置焦点指示器的样式时,我们需要考虑以下几点:

  1. 对比区
  2. 与相邻颜色对比
  3. 不要遮盖焦点元素


在下面的示例中,黑色显示了焦点指示器启用状态(使用键盘 tab 时的样式):


设置焦点指示器样式的不同方法


对比区 —— 颜色发生变化的地方

相邻颜色 —— 与焦点指示器相邻的颜色


聚焦状态和非聚焦状态的颜色对比度最小应为 3:1,焦点指示器和相邻颜色之间也要符合这个规则。


意思是,如果你将一个白色背景页上的绿色按钮,设置的焦点指示器样式为 2px 的黑色边框,那么黑色绿色、以及黑色白色之间的最小对比度应该是 3:1


如果你要覆盖默认的焦点样式,可使用以下代码:


:focus {
    outline: none;
}
 
button:focus {
    /* some exciting button focus styles */
}


button:focus:not(:focus-visible) {
    /* undo all the above focused button styles if the button has focus but the browser wouldn't normally show default focus styles */
}


button:focus-visible {
    /* some even *more* exciting button focus styles */
}



如果你有兴趣,可以查看这篇博文了解详情。

尽可能提供视觉标签


这对于使用语音命令浏览网页的人来说很有用。大家有点难理解吧,我先解释下为什么。首先,想想语音识别软件是如何工作的:


以苹果的 Siri 为例,我们先说一个关键句:“Hey Siri”,然后再说想要执行的命令。

比如:“Hey Siri,现在几点了?”


同理,想象一下用 Siri 浏览网页:


假设有一个按钮叫“发送”,我们可以说:”Hey Siri,点击发送按钮”。这很简单,对吧?

但是如果按钮只有一个图标,而没有“发送”标签,你要如何告诉 Siri 点击哪个按钮呢?


因此,尽可能提供视觉标签,如果不行,那至少让它可通过 tab 使用

描述性信息图


当 SVG 用于图表等信息图或其它类型的数据表示时,通常不会为可访问用户提供任何信息。为了方便他们,最好的方式是提供屏幕阅读器能够读取到信息图文本描述。


下面示例实现这类 SVG 的好方法:


<object
    role="img"
    aria-label="Average something of something"
    aria-describedby="something_desc"
    data="some.svg"
    type="image/svg+xml"
>
 <!-- fallback -->
 <p id="something_desc">90% increase in number of sales in the year 2022 with proper SEO tactics implemented as to no SEO done for the previous year.</p>
</object>


小结


一份可以立刻行动的汇总清单:


  1. 是否正确地使用了所有的 HTML 分区元素,而不仅仅是 div?
  2. 标题是否用于适当的结构,而不是强调大小?
  3. 是否用 tabindex=-1 删除了不需要的链接?
  4. 所有按钮是否都可以访问?他们有合适的名称或标签吗?如果没有,你是否提供了 ARIA 标签或替代方法?
  5. 你改变焦点指示器的样式了吗?如果是,它们是否符合规范?
  6. 按钮、复选框和单选等表单元素,应该是可访问的。
  7. 尽可能提供视觉标签。
  8. 信息图表应该有一个文字说明的回退,如果使用 SVG,则<object>应带有回退描述。
  9. 应使用 tabindex= -1 禁用屏幕外链接,不然用户将被卡住,而不知道发生了什么。


可访问性就像是一片海洋,我只触及了表面。希望通过本文,能够为我们大多数人照亮一个潜在的黑暗区域。


我所写的一切都基于Sara Soueidan的博客和谈话,请访问她的博客了解更多信息。她有许多很酷的话题,非常地深入浅出。


原文链接:Frontend accessibility. Doing it the right way.

了解更多软件开发与相关领域知识,点击访问 InfoQ 官网:https://www.infoq.cn/,获取更多精彩内容!

先,我们先来看自 Nuxt 创建以来的一些统计数据:

Google Analytics

  • 约 1200 万次页面访问;
  • 约 75 万独立访问者;
  • 访问者最多的 5 个国家:美国、中国、英国、日本和俄罗斯。

GitHub

  • 96 次发布;
  • 约 14860 个 star;
  • 约 3900 个问题和 PR(97% 已关闭)。

Twitter

  • 13 万 5 千多个关注者(https://twitter.com/nuxt_js);
  • 900 多个推文。

NPM

  • 约 1200 万次下载;
  • 53 个官方模块(https://www.npmjs.com/org/nuxtjs)。

新版本的主要变化:

支持 Webpack 4

光是这一改进就值得专门写一篇文章进行介绍:

  • Webpack 4 速度非常快;
  • 模式、#0CJS 和合理的默认值;
  • 不再需要 CommonsChunkPlugin;
  • WebAssembly 支持;
  • 引入模块类型以及.mjs 支持。

其他变化:

  • 客户端捆绑包的默认开发工具是默认的 eval,它的速度是最快的。
  • 默认情况下启用模块串联(作用域提升)优化。
  • 删除了实验选项 build.dll。它不太稳定,况且 Webpack 4 已经足够快了。

迁移提示:用户不需要修改项目中的任何一行代码,升级到 Nuxt 2 后,一切都将神奇般地自动帮你迁移完毕。

不再需要 vendors

Nuxt 2 仍然存在 vendors 块,但会自动处理它,而且效率更高。从这个版本开始,不再使用 CommonsChunkPlugin,所以用户不必在项目中显式定义 vendors。Nuxt 会自动将核心软件包(vue、vue-router、babel-runtime 等)添加到指定的 Cache Group 中,这有助 Webpack 以最有效的方式拆分代码。

迁移提示:从 nuxt.config.js 中删除 vendors。如果你的项目中包含了 vendors,可以安全地删除它们。如果你是模块作者,可以保留 this.addVendor() 为旧版本提供支持。下一版本可能会显示弃用警告。

完全控制块拆分

Nuxt 尝试提供开箱即用的最有效的代码拆分功能,不过,现在用户可以通过 build.splitChunks 选项来完全控制代码拆分,并可以选择性地禁用路由的异步块。

重大变更:默认情况下,Nuxt 不再拆分布局块。它们将与主入口点一起加载,就像 Nuxt Core、Plugins、Middleware 和 Store 一样。用户可以通过 build.splitChunks.layouts: true 来启用布局拆分。另外,为了更好地控制 Webpack 块拆分,可以使用 build.optimization.splitChunks 选项。

重大变更:对于生产版本的构建,不再使用文件名作为块名称的一部分(/_nuxt/pages/foo/bar.[hash].js 变成了 [hash.js])。用户可以使用 build.optimization.splitChunks.name:true 强制恢复启用文件名称(如果未指定,在 dev 和 --analyze 模式下仍然会启用文件名称)。

重大变更:为了减少异步请求,Webpack 默认不拆分运行时(manifest)块,并将其移到主块中。用户可以通过 build.optimization.runtimeChunk:true 来启用运行时拆分。

注意:Nuxt 的默认设置是以一些最佳实践为基础,并基于实际项目的基准测试进行了优化。建议用户在每次做出更改后使用 nuxt build --analyze 分析 bundle。

迁移提示:保持默认设置。对你的实际项目进行基准测试,然后根据你的需要精心定制配置选项。

Vue Loader 15 和 mini-css-extract-plugin**

vue-loader(https://vue-loader.vuejs.org/en/)可以将.vue 文件解析为可运行的 JS/CSS 和 HTML。Vue-Loader 15 使用完全不同的新架构进行了重写,可以将主 Webpack 配置中定义的任何规则应用于 *.vue 文件中的语言块。

对于 CSS 提取,使用了一个新的插件 mini-css-extract-plugin,它支持按需加载 CSS 和 SourceMaps(CSS 拆分),并且是基于 Webpack v4 的新功能(模块类型)而构建。

因为这两个插件都是新的,所以预计在最终发布 2.0.0 版本之前,可能会出现一些不一致。这两个插件已经在不同场景中进行了全面测试,它们表现得非常好!

Nuxt 和 ES module

现在用户可以通过 std/esm(https://github.com/standard-things/esm)在 nuxt.config.js 中导入和导出 Middleware 和模块中。std/esm 是一个快速、生产就绪、零依赖的软件包,用于在 Node 6+ 中启用 ES 模块。

CLI 改进

开发者需要优雅的开发经验来开发出色的软件,于是 Nuxt 团队重新设计了很多有关 CLI 的东西。

在使用 nuxt dev 时,即使 CLI 显示 Nuxt 已准备就绪,用户仍然可能感觉到构建延迟。这是因为运行了两次 Webpack。一次是为客户端,一次是为 SSR 捆绑,但第二次运行被隐藏起来。现在构建被并行化,同时开发了 WebpackBar(https://github.com/nuxt/webpackbar),可以查看构建进度,还有其他很多功能。

现在,默认情况下隐藏所有调试消息(可以通过设置环境变量 DEBUG = nuxt:* 来启用),同时为构建器和生成器更智能、更好地显示消息。

用户经常要求 Nuxt 支持测试和 CI(持续集成)环境。Nuxt 2 将自动检测 CI 和测试环境,并切换到 minimalCLI 特殊模式,在该模式下包含较少的打印消息。

移除 Nuxt 1.0 中弃用的特性

  • 移除 context.isServer 和 context.isClient(使用 process.client 和 process.server 代替);
  • 移除 build.extend() 中的 options.dev(使用 options.isDev 代替);
  • 移除了模块中的 tappable hooks(nuxt.plugin())(使用新的钩子系统);
  • 删除了模块的回调(使用异步或返回 Promise)。

实验性的多线程编译器

这个特性将在 Webpack 5 中正式发布,不过用户现在可以通过 options.build.cache: true 来启用 cache-loader 和 Babel 缓存,以及通过 options.build.parallel: true 来启用 thread-loader。

SPA 改进

Nuxt.js 是 Vue.js 开发人员的通用框架,它既可以用于全局环境(与服务器端渲染一起),也可以用于客户端(单页应用程序,SPA)。Nuxt 重新设计了与 SPA 有关的一些重要方面。

SPA 最重要的组件之一是页面加载指示器。Nuxt 团队对其进行了重新设计,如果出现任何问题,就会进入错误状态,并在大约 2 秒后自适应地显示在 DOM 中。如果 SPA 应用程序加载足够快,可以避免不必要的屏幕闪烁。还添加了 aria 标签,帮助屏幕阅读器和搜索引擎正确检测启动画面。

出于 SEO 方面的原因以及支持 HTTP2 推送,SPA 模式使用特殊的 Meta 渲染器将 nuxt.config.js 中定义的所有元标记添加到页眉中。同时还为 SPA 模式添加了 options.render.bundleRenderer.shouldPrefetch 和 options.render.bundleRenderer.shouldPreload。

重大变更:默认情况下禁用 shouldPrefetch。很多用户反应存在不必要的页面块预取,尤其是在中型项目中。此外,为了方便调试,非生产模式下默认禁用所有不必要的资源提示。

create-nuxt-app

create-nuxt-app 是 Nuxt 官方的脚手架工具,用于生成各种模板,如项目启动模板、Express 模板等。有了 create-nuxt-app,用户可以选择与服务器端框架(如 Express、Koa、Adonis 等)集成,或者与 UI 框架(如 Vuetify、Bootstrap、Tailwind 等)集成,或者也可以使用 axios 模块。

现在你可以更快地创建一个 Nuxt 新项目了。

迁移指南

用户可以通过 yarn add nuxt@^2.0.0 或 npm install nuxt@^2.0.0 进行升级。下面是完整的迁移步骤指南:

  • 仔细阅读发布公告;
  • 如果使用的是 VCS,请在新分支上进行代码提交和推送;
  • 停止所有的 Nuxt 进程;
  • 可选:删除所有.nuxt、node_modules、yarn.lock 和 package.lock.json 目录和文件;
  • 确保使用的是最新版本的 Node(建议使用 Node 10.x 和 NPM 5 以上版本);
  • 在 nuxt.config.js、modules 和 serverMiddleware 中使用 import/export 代替 require;
  • 确保没有在 package.json 中显式设置 Webpack 和 Vue 依赖,如果有,请将它们升级到与 Nuxt 匹配的版本;
  • 使用 npm 和 yarn 进行安装;
  • 可选:使用 npm outdated 或 yarn outdated,并小心手动更新所有依赖项;
  • 如果使用了 CDN 部署系统,请确保更新 CI/CD 配置,使用.nuxt/dist/client 代替.nuxt/dist。

参考链接

  • https://medium.com/@nuxt_js/nuxt-js-2-0-webpack-4-esm-modules-create-nuxt-app-and-more-6936ce80d94c
  • https://medium.com/nuxt/nuxt-2-is-coming-oh-yeah-212c1a9e1a67
  • https://github.com/nuxt/nuxt.js/releases/tag/v2.0.0