WAI-ARIA是一个可访问的富Internet应用程序套件,它定义了一种使残障人士更容易访问Web内容和Web应用程序的方法。它特别有助于使用AJAX,HTML,JavaScript和相关技术开发的动态内容和高级用户界面控件。
我想在创建帖子时单击 Facebook 的照片/视频按钮。该元素是: 我想在创建帖子时单击 Facebook 的照片/视频按钮 。该元素是: <div aria-label="Photo/video" aria-pressed="false" class="..." role="button" tabindex="0"> <div><div><div class="..."><div class="..."><div class="..."> <img class="..." alt="" src="https://static.xx.fbcdn.net/rsrc.php/v3/y7/r/Ivw7nhRtXyo.png?_nc_eui2=AeHY6dd2udiKCsGGc3_l3Lj2PL4YoeGsw5I8vhih4azDks5jrq6FoGG-iYDYkCJ4e3z08U_itrGNYjc5wzxwesxH" style="height: 24px; width: 24px;"> </div><div class="..." role="none" data-visualcompletion="ignore" style="inset: 0px;"></div></div></div></div><div><div></div></div></div></div> 根据页面互动 | Puppeteer,我认为正确的代码是: await page.locator('::-p-aria([name="Photo/video"][role="button"])').click(); 但它没有点击。将 name 更改为 label 没有帮助。你知道如何让它发挥作用吗? 在 Puppeteer 中,与基于 ARIA 属性的元素交互时,如 aria-label,正确的做法是结合使用 page.click() 和适当的选择器,而不是 ::-p-aria 伪元素方法 以下是如何使用 aria-label 单击“照片/视频”按钮: 正确做法: 您可以通过 aria-label 属性定位元素,确保您定位到具有 role="button": 的按钮 await page.click('[aria-label="Photo/video"][role="button"]'); 此选择器将以 aria-label="Photo/video" 和 role="button" 为目标 div,这是您要查找的元素。 如果您尝试单击的元素位于 iframe 内,或者涉及动态元素,您可能需要使用 waitForSelector 或 waitForFunction 等待该元素变得可用,以确保该元素已准备好可供单击: await page.waitForSelector('[aria-label="Photo/video"][role="button"]'); await page.click('[aria-label="Photo/video"][role="button"]'); 让我知道这是否有帮助。
我有一个像这样实现的表,并使用适当的类使其看起来像一个表: ... 我有一个像这样实现的表,并使用适当的类使其看起来像一个表: <div> <div> <div id="e3"> <div role="table"> <div role="rowgroup"> <div role="row"> <div colspan="1" role="cell"> <div> <div><span>First Name</span></div> </div> </div> <div colspan="1" role="cell"> <div> <div><span>Last Name</span></div> </div> </div> <div colspan="1" role="cell"> <div> <div><span>Full Name</span></div> </div> </div> </div> </div> <div role="rowgroup"> <div> <div> <div> <div aria-label="grid" aria-readonly="true" role="grid" tabindex="0"> <div role="rowgroup"> <div> <div role="row" data-row-id="e3-0"> <div role="cell"> <div> <div> <div>John</div> </div> </div> </div> <div role="cell"> <div> <div> <div>Higgins</div> </div> </div> </div> <div role="cell"> <div> <div> <div>John Higgins</div> </div> </div> </div> </div> </div> <div> <div role="row" data-row-id="e3-1"> <div role="cell"> <div> <div> <div>John</div> </div> </div> </div> <div role="cell"> <div> <div> <div>Lennon</div> </div> </div> </div> <div role="cell"> <div> <div> <div>Sean Lennon</div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> 我想在手机上完全自定义语音阅读器。例如,我不希望它读取“第 3 列,共 3 列”,我希望它显示为“第三列,共三列”。 如果您有效地呈现表格数据,如果您可以使用<table>会更好,但无论如何它不会改变我的答案。 您无法更改“第 3 栏(共 3 栏)”等公告。这是一般信息,可准确告诉您在表格中导航时所处的位置。 这些信息由用户控制,如果他/她觉得它没有用,他/她可能会决定隐藏它,但你,作为开发人员或文档编写者,你无法决定什么是好或坏,有用或无用为用户提供的信息。 屏幕阅读器用户通常希望提供此信息,并且绝对有必要始终准确地知道您所在的位置,特别是当表格很大和/或具有 col/rowspan 等复杂内容时。 如果没有此类信息,作为屏幕阅读器用户,您可能会快速而轻松地迷失方向。 如果公布的列号和/或行号是错误的,这可能意味着您的标记不正确,或者您的结构太复杂。如果可能的话,你应该尝试简化它。 如果您认为谈论列和行根本没有意义,可能是您实际上没有数据表,在这种情况下,最好删除所有 ARIA 角色,告诉屏幕阅读器它是数据表。 无论如何,你不应该试图让一切都按照你喜欢的方式说出来,你也不应该害怕情况并非如此。每个用户都有他/她的偏好,即使不计算用户配置,每个屏幕阅读器提供的此类信息也略有不同。 像往常一样,了解最有效和/或最清晰的数据呈现方式的最佳方法是与真实的屏幕阅读器用户进行真正的用户体验测试。
“[aria-hidden="true"] 元素包含可聚焦的后代”;解决这个问题的最佳方法?
我有一个简单的手风琴: 打开手风琴 这是 我有一个简单的手风琴: <div> <button aria-expanded='false' aria-controls='content'> Open accordion </button> <div id='content' aria-hidden='true'> This the accordion's hidden content. </div> </div> 我使用 Javascript 打开/关闭手风琴并设置 aria-* 标签。 一切正常,但是当我在内容中添加链接时: <div> <button aria-expanded='false' aria-controls='content'> Open accordion </button> <div id='content' aria-hidden='true'> This is the accordion's hidden content. <a href='https://www.google.com'>Go to Google</a> </div> </div> 灯塔给了我这个: [aria-hidden="true"] elements contain focusable descendents 在我看来,将 tabindex='-1' 添加到 a 标签可以解决问题: <a tabindex='-1' href='https://www.google.com'>Go to Google</a> 但是,这使得元素“不可选项”,这不利于可访问性。 我可以使用 JavaScript 手动查询手风琴内容中的所有 a 标签,但我什至不确定这是否真的解决了“问题”还是一个肮脏的解决方法?还有更好的选择吗? 为什么会收到此警告? 此警告表明,尽管您使用了 aria-hidden="true",但如果子项可以接收焦点,大多数屏幕阅读器都会忽略父项上的 aria-hidden="true"(考虑到开发人员错误、JavaScript 未正确加载等)。 如何解决? 我假设您正在使用上滑动画或类似的东西,这就是为什么您不简单地在内容上使用display: none。 如果您没有使用动画,那么只需 display: none 应用 aria-hidden="true" 时的内容即可(@Adam 在他的回答中向您展示了执行此操作的完美方法)。 更好的是,您可以直接在 div 上使用 display: none,因为这会隐藏屏幕阅读器看不到的所有内容,因此您不需要在那里使用 WAI-ARIA! 我正在使用动画/过渡,因此不能隐藏所有内容。 如果您使用动画、不透明度更改等,这会阻止您简单地隐藏整个内容,那么您可以做的就是隐藏内容中的可聚焦内容<div>。 当您应用 aria-hidden="true" 时,我们可以使用 CSS 来执行此操作,然后在更改或删除 aria-hidden="true" 时取消隐藏可聚焦元素。 为了避免再次取消隐藏元素时出现“布局卡顿”,我建议使用 visibility: hidden 而不是 display: none,因为这样会为隐藏项目分配空间,并且仍然对屏幕阅读器等隐藏它们。 #content[aria-hidden=true] a[href], #content[aria-hidden=true] area[href], #content[aria-hidden=true] input:not([disabled]), #content[aria-hidden=true] select:not([disabled]), #content[aria-hidden=true] textarea:not([disabled]), #content[aria-hidden=true] button:not([disabled]), #content[aria-hidden=true] [tabindex]:not([disabled]), #content[aria-hidden=true] [contenteditable=true]:not([disabled]){ visibility: hidden; } 快速演示 了解我的意思的最简单方法是通过快速演示,按“切换 aria-hidden on”按钮,它将隐藏 #content <div> 中的所有可聚焦元素。 var btn = document.querySelector('#toggle-aria'); var contentDiv = document.querySelector('#content'); btn.addEventListener('click', function(){ var self = this; if(contentDiv.getAttribute('aria-hidden') == "false"){ self.innerHTML = "Toggle aria-hidden off"; contentDiv.setAttribute('aria-hidden', "true"); }else{ self.innerHTML = "Toggle aria-hidden on"; contentDiv.setAttribute('aria-hidden', "false"); } }); #content{ padding: 20px; border: 1px solid #333; } #content[aria-hidden=true] a[href], #content[aria-hidden=true] area[href], #content[aria-hidden=true] input:not([disabled]), #content[aria-hidden=true] select:not([disabled]), #content[aria-hidden=true] textarea:not([disabled]), #content[aria-hidden=true] button:not([disabled]), #content[aria-hidden=true] [tabindex]:not([disabled]), #content[aria-hidden=true] [contenteditable=true]:not([disabled]){ visibility: hidden; } <br/><br/><button id="toggle-aria">Toggle aria-hidden on</button> <p>When aria-hidden is set to true on the below div all focusable elements should disappear.</p> <hr/> <div id="content" aria-hidden="false"> <a href="https://google.com">To Google</a><br/><br/> <label>An input <input /> </label><br/><br/> <label>A Select <select> <option>option 1</option> <option>option 2</option> <option>option 3</option> </select> </label><br/><br/> <label>A textarea <textarea></textarea> </label><br/><br/> <button>A button</button><br/><br/> <div tabindex="0">A fake button with tabindex</div><br/><br/> <div contenteditable="true">A div that is cotnent editable</div><br/><br/> <p>Only the labels and this paragraph should be the only things left showing when you toggle the aria-hidden to true</p> </div> <br/><br/> <button>I am a button purely so you can see there is nothing focusable within the #content div if you "Tab"</button> 重要提示: 当您按下“打开手风琴”按钮时,您应该删除 aria-hidden 之前任何动画等。这是因为屏幕阅读器用户随后会尝试按 Tab(或通过屏幕阅读器快捷方式导航)进入内容。如果您删除aria-hidden="true"太晚,他们可能会跳过所有内容! 简单的解决方案,使用 CSS display:none 属性来删除元素的焦点: #content[aria-hidden=true] { display:none; } 这不仅有用,而且非常必要,因为我们不希望屏幕阅读器宣布不可见的事情。 我刚刚将 tabindex="-1" 更改为 tabindex="1" 然后就可以正常使用了 <div class="modal fade" id="userModal" tabindex="1" role="dialog" aria-labelledby="userModalLabel" aria-hidden="false" aria-busy="true" > </div
当一个地标元素内部也有一个标题时,它应该有一个 aria 标签吗?
屏幕阅读器用户有多个选项来访问页面上的内容。 例如,所有标题的列表,还有地标的列表。 使用 aria-label,您可以标记一个地标。 考虑
如何在 Voiceover 中只读取一次链接内容? (仅限火狐浏览器)
为什么 Firefox Voiceover 会读取该文本两次?又如何让它读一次呢? (保留列表标记) 此文本重复于 为什么 Firefox Voiceover 会读取该文本两次?又如何让它读一次呢? (保留列表标记) <ul> <li> <a href="/something">This text is duplicated in Voiceover</a> <span class="">Some description</span> </li> </ul> https://jsbin.com/duseqi/edit?html,输出 当链接嵌套在列表中时,VoiceOver 在 Chrome 和 Firefox 中重复链接文本两次。它在 Safari 中不会执行此操作。我不认为这是你的标记的问题,这是 VO 如何与浏览器配合使用的问题。 我在 Chrome 中发现了一些其他奇怪的行为,比如当内容位于带有“main”的 div 内部时,不宣布标题的结构(例如,阅读“我的惊人标题”而不是“二级标题,我的惊人标题”) “ ARIA 具有里程碑意义,在 Safari 中也能正常工作。 这种情况发生在什么类型的设备上(MacBook、iPad、iPhone 等)? 我认为这可以处理您如何浏览文本,和/或它是否是块级链接。 在 Mac 上的 VoiceOver 中,如果您使用 Tab 键导航,则会重复块级链接文本。 根据现已删除的这篇文章,“该行为取决于屏幕阅读器、浏览器和导航模式的组合。” 虽然您的示例不包含此内容,但如果您也存在 aria-label 属性,VO 可以重复文本。 在您的实际标记中,锚标记内是否还有其他元素? 如果是这样,也许切换这些块级元素的结构可以帮助避免重复。 希望这有帮助。
我们可以使用 aria 更改地标元素或任何 html5 元素的原生语义吗
我们可以使用 aria 更改地标元素或 html5 的任何元素的本机语义吗?这样做在语义上是否正确且符合要求? 假设我想使用对话框元素作为
在这个问题中,我们将考虑 2 个示例,但请注意,这个问题是关于任意加载占位符的。 以下是加载占位符的 Bootstrap 5 示例: 在这个问题中,我们将考虑 2 个示例,但请注意,这个问题是关于 任意 加载占位符。 这是加载占位符的 Bootstrap 5 示例: <div class="card" aria-hidden="true"> <img src="..." class="card-img-top" alt="..."> <div class="card-body"> <h5 class="card-title placeholder-glow"> <span class="placeholder col-6"></span> </h5> <p class="card-text placeholder-glow"> <span class="placeholder col-7"></span> <span class="placeholder col-4"></span> <span class="placeholder col-4"></span> <span class="placeholder col-6"></span> <span class="placeholder col-8"></span> </p> <a href="#" tabindex="-1" class="btn btn-primary disabled placeholder col-6"></a> </div> </div> 但是仅仅aria-hidden="true"就足够了吗? 屏幕阅读器等如何理解加载过程? 尝试添加aria-label: <div class="card" aria-hidden="true" aria-label="Loading in progress. Please wait."> <!-- --> </div> 2024 年 9 月,HTML 验证器对此提出投诉: 可能滥用“aria-label”。 (如果您不同意此警告,请提交问题报告或发送电子邮件至 [email protected]。) 如果删除aria-hidden="true",则相同。 再举一个例子我想考虑一下。 <article> <div class="skeleton"> <div aria-hidden="true"></div> <div aria-hidden="true"></div> <div aria-hidden="true"></div> <span>Loading</span> </div> <div aria-busy="true"> <h3><a href="[…]">Glossier Roof Party</a></h3> <img src="[…]" […] alt="[…]"> <p> Gastropub sartorial venmo hashtag […] </p> </div> </article> 未准备好显示的内容已被aria-busy="true"隐藏。但是,在加载过程中从 DOM 中unmount这部分并不难。为此,将留下下面的代码: <div class="skeleton"> <div aria-hidden="true"></div> <div aria-hidden="true"></div> <div aria-hidden="true"></div> <span>Loading</span> </div> Loading跨度在视觉上是隐藏的,因此屏幕阅读器可以加载。但它如何理解整个 <div class="skeleton"> 是加载占位符? 使用 aria-hidden=true 可以完全隐藏屏幕阅读器的内容。因此,同时放置 aria 标签是完全没有用的,而且是矛盾的。 一般来说,将 aria-hidden=true 放在大代码块上并不是一个好习惯: 一旦内容准备好,您很容易忘记将它们全部删除,特别是如果您像在其中一个片段中那样随机地将 aria-hidden=true 放在任何地方 如果内容在 aria 隐藏内容中包含任何可聚焦元素(链接、表单元素等),那么您会遇到更大的问题:可以使用选项卡访问该元素,但不能使用文档导航访问该元素,并且可能无法读取该元素当对焦时。这是另外一件需要注意的事情,您一定不要忘记在删除 aria-hidden=true 的同时删除 tabindex=-1 属性 aria-hidden 应谨慎使用,仅在非常精确的情况下使用,当然不适用于大块代码。 事实上,对于当前正在加载的内容,更安全的是: 仅在内容准备好时才将内容放入 DOM,而不是在此之前 使用 CSS display:none 或 Visibility:hidden 隐藏当前正在加载的内容,这保证了无论使用何种方式读取页面,它都完全不可见、不可读和不可操作 现在关于如何告诉用户正在加载某些内容的第二个问题,当然,如果您将加载横幅放在 aria-hidden=true 下,则完全没有用。 您可以使用 aria-live=polite 将此类加载消息放置在实时区域中,这样每次内容更改时都会宣布该消息。 许多资源提供了此类加载横幅的示例。 注意:aria-live 用于加载消息,例如“正在加载,请稍候”,而不是用于当前正在加载的内容本身。
ARIA 中 `menuitemradio` 和 `radio` 角色有什么区别?
在MDN上搜索radio角色时刚刚了解到menitemradio 然而,似乎没有解释它们的区别。 我可以确认它们实际上是相同的,但是:
检查了 W3C 的可访问富互联网应用程序 (WAI-ARIA) 规范的角色定义以及状态和属性的定义,但似乎没有定义任何角色或状态...
如果一组按钮(或标签)将输入值设置为每个不同的值,那么它们应该具有什么角色和咏叹调? 在这种情况下,用户也可以插入/编辑输入
假设我正在尝试使用复选框列表构建多选输入: 我已将复选框放在带有 标签的 内 有一个输入可以让用户Fi... 假设我正在尝试使用复选框列表构建多选输入: 我已将复选框放在带有 <fieldset> 标签的 <legend> 内 有一个输入可以让用户过滤复选框,以便轻松选择他们想要的 当选择(选中)复选框时,将向用户显示结果按钮。单击此按钮还会取消选中该复选框(取消选择)。同样,这主要是为了用户体验,因为这有助于用户查看他们已经选择的项目。 过滤器和复选框放置在 <details> 和 <summary> 内部,使其具有传统的选择框外观。 这是工作演示: ("use strict"); // Focus on the filter input when the options are expanded/opened document.querySelectorAll(".options-details").forEach(function (details) { details.addEventListener("toggle", function () { if (details.hasAttribute("open")) { details.querySelector(".filter-input").focus(); } }); }); // Filter options document.querySelectorAll(".filter-input").forEach(function (input) { input.addEventListener("input", function () { const options = input.closest("fieldset").querySelectorAll(".btn-check"); options.forEach(function (option) { option.classList.remove("d-none"); const value = option.value.toLowerCase(); if (value !== "" && !value.includes(input.value.toLowerCase().trim())) { option.classList.add("d-none"); } }); }); }); // Add option button when an option is checked document.querySelectorAll(".btn-check").forEach(function (input) { input.addEventListener("input", function () { if (input.checked === true) { const optionButtonItem = document.createElement("li"); optionButtonItem.innerHTML = `<button class="option-button btn btn-primary" type="button" id="${input.getAttribute("id")}-remove" aria-describedby="option-remove">${input.getAttribute("value")}</button>`; input.closest("fieldset").querySelector(".option-buttons-list").appendChild(optionButtonItem); // Add event listener to remove option and button and uncheck option const optionButton = document.getElementById(`${input.getAttribute("id")}-remove`); optionButton.addEventListener("click", function () { document.getElementById(optionButton.getAttribute("id").slice(0, -7)).checked = false; optionButton.closest("li").remove(); }); } else { document .getElementById(`${input.getAttribute("id")}-remove`) .closest("li") .remove(); } }); }); :root { --bs-font-size-base: 1rem; --bs-font-size-sm: 0.875rem; --bs-font-size-lg: 1.125rem; } .option-button::after { content: "\00D7"; margin-left: 12px; } .options-container { min-height: 36px; max-height: 300px; } .btn-check.d-none + .btn-secondary { display: none; } .btn-check:checked + .btn-secondary { background-color: var(--bs-primary) !important; color: var(--bs-primary-foreground) !important; } .btn-check:focus-visible + .btn-secondary { background-color: var(--bs-primary-100) !important; box-shadow: none !important; } .btn-check:checked:focus-visible + .btn-secondary { background-color: var(--bs-primary-active-bg) !important; } <link href="https://cdnjs.cloudflare.com/ajax/libs/Halfmoon/2.0.1/css/halfmoon.min.css" rel="stylesheet"/> <body class="min-vh-100 d-flex align-items-center justify-content-center"> <div class="specific-w-600 mw-100 p-5"> <fieldset> <legend class="form-label">Select the languages you want*</legend> <p class="text-body-secondary mb-4"> Let's get started with the survey. First, please choose all of the languages that you know. </p> <span id="option-remove" class="visually-hidden">remove</span> <ul id="options-selected" class="option-buttons-list list-unstyled d-flex flex-wrap gap-1 m-0" ></ul> <details class="options-details border rounded mt-2 overflow-hidden"> <summary class="px-3 py-2"> Choose one or more options </summary> <div class="border-top"> <div class="p-3 border-bottom"> <span id="filter-label" class="visually-hidden">Filter languages</span> <input type="text" class="filter-input form-control" placeholder="Filter languages" aria-autocomplete="list" aria-labelledby="filter-label options-selected" /> </div> <div class="options-container d-flex flex-column overflow-y-auto" > <input type="checkbox" class="btn-check" id="checkbox-1" value="Python" autocomplete="off" /> <label class="btn btn-secondary text-start px-3 py-2 lh-sm border-0 rounded-0" for="checkbox-1" > Python </label> <input type="checkbox" class="btn-check" id="checkbox-2" value="JavaScript" autocomplete="off" /> <label class="btn btn-secondary text-start px-3 py-2 lh-sm border-0 rounded-0" for="checkbox-2" > JavaScript </label> <input type="checkbox" class="btn-check" id="checkbox-3" value="C++" autocomplete="off" /> <label class="btn btn-secondary text-start px-3 py-2 lh-sm border-0 rounded-0" for="checkbox-3" > C++ </label> </div> </div> </details> </fieldset> </div> </body> JavaScript 执行以下操作: 打开选项后,过滤器输入自动聚焦。 在过滤器输入中键入内容,复选框将使用其值进行过滤。 选中复选框后,会添加结果按钮。当然,单击此按钮将取消选中该复选框。 我的问题是:我当前的设置有多方便?在过滤器输入、结果按钮等上使用正确的 WAI-ARIA 标签方面。此外,可以在此处使用 <details> 和 <summary> 标签来执行我想要执行的操作吗? 我想说这已经是一个非常复杂的实现了。 但是谁能说是否可以使用 <details> 元素呢?就标准而言,没问题。最好现在就与辅助技术的用户一起测试它。 我从aria-autocomplete注意到这一段: 如果某个元素的 aria-autocomplete 设置为 list […],作者 必须 确保满足以下两个条件: 该元素具有为 aria-controls 指定的值,该值引用包含建议值集合的元素。 该元素具有 aria-haspopup 值,该值与包含建议值集合的元素的角色相匹配。 然后,来自aria-haspopup: […] 作者必须确保充当弹出内容容器的元素的角色是menu、listbox、tree, 网格或dialog […] 反过来,listbox只能将option作为可访问子项,而不是checkbox。 所以你需要重新制定清单。请参阅我对第二个问题的回答,了解有关可访问选项列表(键盘可访问性、跳过链接)的更多详细信息。 <input aria-controls="language-list" aria-haspopup="list" /> </div> <ul id="language-list" role="listbox" aria-multiselectable="true"> <li role="option" aria-selected="false" tabindex="0">Python</li> … 这样做的好处是,屏幕阅读器可以宣布项目的数量,帮助用户决定是否过滤。 我刚刚使用 NVDA 测试了问题中的示例,我注意到这些细节: 带有删除按钮的列表缺少标签,以明确列出的语言是什么: <ul … aria-label="Selected languages"></ul> × 是一个视觉指示器,最好对辅助技术隐藏起来。通过CSS添加的content仍然是内容。该按钮的含义如下: Python 时间按钮删除 <button aria-label="Python. Remove">Python</button> 添加到搜索输入名称中的选定选项也包括“时间”,但这可以通过上述建议解决。 将选定的选项添加到输入的名称是多余的,因为选择列表在之前和之后都可用。完善的 combobox 模式也无法做到这一点。 焦点在折叠的详细信息摘要元素上不可见。 代码中的小细节: 您可以考虑使用 document.createElement() 元素,而不是使用 <template>,这会使生成的 DOM 结构难以阅读 autocomplete 在 <input type="checkbox"> 上没有用: 它可用于以文本或数值作为输入的 <input> 元素 [...]
假设我在 中有一个复选框列表。我希望用户能够过滤这个列表(考虑到这个列表相当大),也就是说,你在这个输入中键入一些内容,并且只...... 假设我在 <fieldset> 中有一个复选框列表。我希望用户能够过滤这个列表(考虑到这个列表相当大),也就是说,您在此输入中键入一些内容,并且只有与此输入匹配的复选框才会可见。此输入和/或复选框需要哪些 WAI-ARIA 标签? 或者不需要一些好的标签? 您可以使用 JavaScript 轻松操纵元素的可见性及其 ARIA 设置。输入字段需要 ARIA 属性,被过滤器隐藏的元素需要添加 aria-hidden 属性。 function filterCheckboxes() { const filter = document.getElementById('filter-input').value.toLowerCase() const checkboxes = document.querySelectorAll('#checkbox-list .checkbox-item') checkboxes.forEach(checkbox => { const label = checkbox.querySelector('label').textContent.toLowerCase() if (label.includes(filter)) { checkbox.style.display = 'block' checkbox.removeAttribute('aria-hidden') } else { checkbox.style.display = 'none' checkbox.setAttribute('aria-hidden', 'true') } }) } document.getElementById('filter-input').addEventListener('input', filterCheckboxes) .checkbox-item { display: block; margin-bottom: 5px; } <label for="filter-input">Filter:</label> <input type="text" id="filter-input" aria-controls="checkbox-list" aria-describedby="filter-description"> <fieldset id="checkbox-list"> <legend>Select your favorite fruits</legend> <div class="checkbox-item"> <input type="checkbox" id="apple" name="fruit" value="apple"> <label for="apple">Apple</label> </div> <div class="checkbox-item"> <input type="checkbox" id="banana" name="fruit" value="banana"> <label for="banana">Banana</label> </div> <div class="checkbox-item"> <input type="checkbox" id="orange" name="fruit" value="orange"> <label for="orange">Orange</label> </div> <div class="checkbox-item"> <input type="checkbox" id="grape" name="fruit" value="grape"> <label for="grape">Grape</label> </div> <div class="checkbox-item"> <input type="checkbox" id="peach" name="fruit" value="peach"> <label for="peach">Peach</label> </div> </fieldset>
我有以下代码,我想更改 aria-descriptedby 属性以匹配该 div 中包含的 中的文本。我需要通过 .slick 来识别每个 div...
标记表单一部分的最佳做法是什么? 创建 似乎不是“好”方法。 我有一个很大的表格,有不同的部分,所有东西我... 标记表单一部分的最佳做法是什么? 创建一个<div tabindex="0">似乎不是“好”方法。 我有一个包含不同部分的大表单,所有内容都在一个站点上(没有向导或其他东西)。 我猜使用屏幕阅读器的用户只是使用 TAB 在不同的输入之间导航,一旦他们到达表单的不同区域,我想解释一下它的含义。 有点像标记一个 div,一旦他们到达该 div 中的输入 -> 读取一些内容。 只是一个简化的例子: <form> <!-- some inputs about the company --> <h2>Company</h2> <div> <label for="company-name-input">Company Name</label> <input type="text" id="company-name-input"> </div> <div> <label for="company-address-input">Company Address</label> <input type="text" id="company-address-input"> </div> <h2>Contact Partners</h2> <!-- here are inputs about important person you can contact --> <!-- how do I notify users about this fact, when they just tab thought the form I read it's no good to add a tabindex="0" to the headline --> <div> <!-- person one --> <label for="person-email-1">E-Mail</label> <!-- I could make a aria-label="Here is the email of your first person" but in case someone tabs here from below they might miss that.. and always have a "Person nr X before each input might be strange as well --> <input type="email" id="person-email-1"> <!-- all the other persons --> <button>Add Partner</button> </div> </form> 当用户将输入集中在某个区域而不在每个输入中重复该信息时,让用户意识到他们正在为联系人编辑字段的最佳实践是什么? <fieldset>元素用于对表单中的相关数据进行分组。 <legend> 元素定义 <fieldset> 元素的标题。 <form> <!-- some inputs about the company --> <fieldset> <legend>Company</legend> <div> <label for="company-name-input">Company Name</label> <input type="text" id="company-name-input"> </div> <div> <label for="company-address-input">Company Address</label> <input type="text" id="company-address-input"> </div> </fieldset> <fieldset> <legend>Contact Partners</legend> <!-- here are inputs about important person you can contact --> <!-- how do I notify users about this fact, when they just tab thought the form I read it's no good to add a tabindex="0" to the headline --> <div> <!-- person one --> <label for="person-email-1">E-Mail</label> <!-- I could make a aria-label="Here is the email of your first person" but in case someone tabs here from below they might miss that.. and always have a "Person nr X before each input might be strange as well --> <input type="email" id="person-email-1"> <!-- all the other persons --> <button>Add Partner</button> </div> </fieldset> </form>
如何使用 aria-* 属性使屏幕阅读器可以访问 SVG 图像?
我一直在使用 Inkscape 和 Draw.io 创建图表并将其导出到 SVG 文件。我想让 SVG 文件中的文本在网页上可供选择,或者,如果做不到这一点,至少可以访问
我对自动完成有相当标准的使用,它与固定选项示例相同。当我运行 NVDA 并按 Tab 键进入它时,它不会读出已选择的标签(在上面的情况下为“低俗小说...
我有一个非常简单的文件来测试文本转语音的可访问性: 我有一个非常简单的文件来测试文本转语音的可访问性: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Lorem ipsum</h1> <form method="POST" action=""> <input id="check1" type="checkbox" value="1" aria-labelledby="check1-label" /> <label id="check1-label" for="check1">This is an input label</label> <button type="submit">Submit</button> </form> </body> </html> 我正在使用 read-aloud Chrome / Firefox 扩展程序,因为它似乎是这方面最流行的扩展程序之一。它只是忽略了形式。 我有什么遗漏的吗? 关于屏幕阅读器和 TTS 扩展 此类浏览器扩展程序根本不能代表因障碍(盲人、视力不佳、有障碍等)而需要屏幕阅读或 TTS 的用户。 所有这些用户都使用可以在其设备上的任何位置读取屏幕的软件,而不仅仅是在浏览器中。 无论作者怎么说,这些扩展的功能对于具有真正可访问性需求的用户来说还远远不够完整。 它们更适合偶尔需要 TTS 但并不总是需要它的用户。例如,将文本快速转换为有声读物,供不想阅读的傻瓜或儿童使用。 请注意,不过,有一些更高级的专用应用程序可以制作有声读物或将几段文本转换为语音。 对于您作为开发人员/设计人员来说,如果您的目标是测试网站的可访问性,那么基本上意味着您没有使用具有可访问性需求的真实用户每天真正使用的正确工具进行测试。 换句话说,你没有达到目标,你的测试无效,你在浪费时间。 您应该使用用户在现实生活中使用的真实软件来测试可访问性,以便真正体验它的含义。没有 36 种方法,您应该在计算机中运行屏幕阅读器。 例如,Windows 上的 NVDA、Mac/iPhone/iPad 上的 VoiceOver、Android 上的 Talkback。所有这些都是免费的,VoiceOver 和 Talkback 通常甚至无需安装任何东西即可使用。 关于您的代码 Jaws、NVDA、VoiceOver 和 Talkback 等真正的屏幕阅读器或多或少遵循可访问性和 ARIA 标准。他们所有人在阅读您所呈现的页面时都不会有任何重大问题。我没有看到任何重大错误。 不过,存在无用的冗余。 由于您的 <input> 已经正确链接到您的 <label>,因此您不需要另外将其与 aria-labelledby 链接。您应该删除 aria-labelledby。 这是完全多余的,它可能是导致您的浏览器扩展无法读取它的原因。 但是,TTS 浏览器扩展可以或多或少地遵循标准,或者根本不遵循标准,并且不期望或不需要这样做,因此很难说您观察到的行为是错误还是有意为之,也很难说您应该做什么准确地修复它(如果可以修复)。 根据可访问性标准,这绝对是错误的,但由于此类浏览器扩展主要不是针对残障用户,因此可能有不同的意图。
我目前专注于为应用程序制作的侧边栏的可访问性。它的行为类似于“滑出”,这意味着即使侧边栏不可见,内容仍然位于 dom 内。至
我的客户想要一个结构如下的数据表: 这个想法是表头将粘在整个表上,而帐户标题将粘在表的正下方
我的代码中有 标记,该标记附加了工具提示,并且工具提示应该由 aria-描述的读取。 Mac 上的画外音只是忽略它,只宣布链接。 协会...