可访问的仅 CSS 选项卡视图 [英] Accessible CSS-only tab view

查看:32
本文介绍了可访问的仅 CSS 选项卡视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发的网站需要 (a) 不使用 JavaScript 和 (b) 可通过键盘访问.

我使用标签目标技巧来构建标签视图(https://css-tricks.com/functional-css-tabs-revisited/),但我注意到它依赖于被点击的标签.我不知道如何让它与键盘一起工作.这可能吗?

.tabs {背景色:#eee;最小高度:400px;}.tabs__list {边框底部:1px纯黑色;显示:弹性;弹性方向:行;列表样式:无;边距:0;填充:0;位置:相对;}.tabs__tab {填充:0.5rem;}.tabs__content {显示:无;左:0;填充:0.5rem;位置:绝对;顶部:100%;}.tabs__input {显示:无;}.tabs__输入+标签{光标:指针;}.tabs__input:focus,.tabs__input:悬停{红色;}.tabs__input:checked+label {红色;}.tabs__input:checked~.tabs__content {显示:块;}

<ul class="tabs__list"><li class="tabs__tab"><input class="tabs__input" type="radio" id="tab-0" name="tab-group" 选中><label for="tab-0" class="tabs__label" tabindex="0" role="button">Tab 0</label><div class="tabs__content">标签 0 内容

<li class="tabs__tab"><input class="tabs__input" type="radio" id="tab-1" name="tab-group"><label for="tab-1" class="tabs__label" tabindex="0" role="button">Tab 1</label><div class="tabs__content">表1内容

解决方案

接受的答案不是一个可访问的解决方案.

我在这里做了一些更正和一些观察.如果您将来偶然发现这个问题,请不要在生产中使用已接受的答案.使用键盘是一种糟糕的体验.

下面的答案修复了一些 CSS 问题,使其更易于访问.

但是我建议您重新考虑无 JavaScript 要求.

我可以理解有一个很好的回退(我在下面给出的修复示例就是这样),但是您无法制作一组完全可访问的仅 CSS 选项卡.

首先,您应该使用 WAI-ARIA 来补充您的 HTML,以使屏幕阅读器更加清晰.请参阅标签W3C 上的示例 以了解您应该使用哪些 WAI-ARIA 角色.这在没有 JavaScript 的情况下是不可能的,因为状态需要更改(例如,aria-hidden 应该更改).

其次,您应该能够使用某些快捷键.例如,按 home 键以返回到第一个选项卡,您只能通过一些 JS 帮助来完成此操作.

话虽如此,我用公认的答案解决了一些问题,至少可以为您提供一个良好的起点,因为您的无 JavaScript 后备".

问题 1 - 标签上的 tabindex.

通过添加它,您将创建一个无法通过键盘激活的可聚焦元素(除非您使用 JavaScript,否则您不能在标签上按 spaceEnter 来更改选择).

为了解决这个问题,我简单地从标签中删除了 tabindex.

问题 2 - 通过键盘导航时没有焦点指示器.

在示例中,选项卡仅在您关注单选按钮(隐藏)时才起作用.但是,此时没有焦点指示器,因为样式将样式应用到复选框聚焦时而不是其标签.

为了解决这个问题,我使用以下内容调整了 CSS

/*当复选框获得焦点时,我们向标签添加一个焦点指示符.*/.tabs__input:焦点+标签{轮廓:2px 实心 #333;}

问题 3 - 对 :hover:focus 状态使用相同的状态.

这是另一个需要摒弃的坏习惯,总是有不同的方式来显示悬停和焦点状态.一些屏幕阅读器和屏幕放大镜用户会使用鼠标来检查他们是否聚焦了正确的项目并在页面上定位自己.如果没有单独的悬停状态,则很难检查您是否悬停在聚焦的项目上.

/*在悬停时使用不同的颜色背景,你不应该对悬停和焦点状态使用相同的样式*/.tabs__label:hover{背景颜色:#ccc;}

示例

在示例中,我在顶部添加了一个超链接,以便您在使用键盘时可以看到焦点指示器的位置.

当您的焦点指示器位于两个选项卡之一上时,您可以按箭头键更改选项卡(这是预期的行为),焦点指示器将相应调整以明确选择了哪个选项卡.

.tabs {背景色:#eee;最小高度:400px;}.tabs__list {边框底部:1px纯黑色;显示:弹性;弹性方向:行;列表样式:无;边距:0;填充:0;位置:相对;}.tabs__tab {填充:0.5rem;}.tabs__content {显示:无;左:0;填充:0.5rem;位置:绝对;顶部:100%;}.tabs__input {位置:固定;顶部:-100px;}.tabs__输入+标签{光标:指针;}.tabs__label:hover{背景颜色:#ccc;}.tabs__input:焦点+标签{轮廓:2px 实心 #333;}.tabs__input:checked+label {红色;}.tabs__input:checked~.tabs__content {显示:块;}

<a href="#">一个链接,这样你就可以看到你的焦点指示器在哪里</a><div class="tabs"><ul class="tabs__list"><li class="tabs__tab"><input class="tabs__input" type="radio" id="tab-0" name="tab-group" 选中><label for="tab-0" class="tabs__label" role="button">Tab 0</label><div class="tabs__content">标签 0 内容

<li class="tabs__tab"><input class="tabs__input" type="radio" id="tab-1" name="tab-group"><label for="tab-1" class="tabs__label" role="button">Tab 1</label><div class="tabs__content">表1内容

I'm working on a site that needs to (a) work without JavaScript and (b) be keyboard-accessible.

I have used the label target trick to build a tab view (https://css-tricks.com/functional-css-tabs-revisited/), but I've noticed that it relies on the label being clicked. I can't figure out how to make it work with the keyboard. Is this possible?

.tabs {
  background-color: #eee;
  min-height: 400px;
}

.tabs__list {
  border-bottom: 1px solid black;
  display: flex;
  flex-direction: row;
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.tabs__tab {
  padding: 0.5rem;
}

.tabs__content {
  display: none;
  left: 0;
  padding: 0.5rem;
  position: absolute;
  top: 100%;
}

.tabs__input {
  display: none;
}

.tabs__input+label {
  cursor: pointer;
}

.tabs__input:focus,
.tabs__input:hover {
  color: red;
}

.tabs__input:checked+label {
  color: red;
}

.tabs__input:checked~.tabs__content {
  display: block;
}

<div class="tabs">
  <ul class="tabs__list">
    <li class="tabs__tab">
      <input class="tabs__input" type="radio" id="tab-0" name="tab-group" checked>
      <label for="tab-0" class="tabs__label" tabindex="0" role="button">Tab 0</label>
      <div class="tabs__content">
        Tab 0 content
      </div>
    </li>
    <li class="tabs__tab">
      <input class="tabs__input" type="radio" id="tab-1" name="tab-group">
      <label for="tab-1" class="tabs__label" tabindex="0" role="button">Tab 1</label>
      <div class="tabs__content">
        Tab 1 content
      </div>
    </li>
  </ul>
</div>

解决方案

Accepted answer is not an accessible solution.

I have made some corrections and some observations here. Do not use the accepted answer in production if you stumble across this question in the future. It is an awful experience with a keyboard.

The answer below fixes some of the CSS issues to make it more accessible.

However I would recommend you reconsider the no JavaScript requirement.

I can understand having a good fall-back (which the example I give below with the fixes is) but there is no way you can make a fully accessible set of CSS only tabs.

Firstly you should use WAI-ARIA to complement your HTML to make things even more clear for screen readers. See the tabs examples on W3C to see what WAI-ARIA roles you should be using. This is NOT possible without JavaScript as states need to change (aria-hidden for example should change).

Secondly, you should be able to use certain shortcut keys. Press the home key for example in order to return to the first tab, something you can only do with a little JS help.

With that being said here are a few things I fixed with the accepted answer to at least give you a good starting point as your 'no JavaScript fallback'.

Problem 1 - tabindex on the label.

By adding this you are creating a focusable element that cannot be activated via keyboard (you cannot press space or Enter on the label to change selection, unless you use JavaScript).

In order to fix this I simply removed the tabindex from the labels.

Problem 2 - no focus indicators when navigating via keyboard.

In the example the tabs only work when you are focused on the radio buttons (which are hidden). However at this point there is no focus indicator as the styling is applying styling to the checkbox when it is focused and not to its label.

In order to fix this I adjusted the CSS with the following

/*make it so when the checkbox is focused we add a focus indicator to the label.*/
.tabs__input:focus + label {
  outline: 2px solid #333;
}

Problem 3 - using the same state for :hover and :focus states.

This is another bad practice that needs to go away, always have a different way of showing hover and focus states. Some screen reader and screen magnifier users will use their mouse to check they have the correct item focused and orientate themselves on a page. Without a separate hover state it is difficult to check you are hovered over a focused item.

/*use a different colour background on hover, you should not use the same styling for hover and focus states*/
.tabs__label:hover{
   background-color: #ccc;
}

Example

In the example I have added a hyperlink at the top so you can see where your focus indicator is when using a keyboard.

When your focus indicator is on one of the two tabs you can press the arrow keys to change tab (which is expected behaviour) and the focus indicator will adjust accordingly to make it clear which tab was selected.

.tabs {
  background-color: #eee;
  min-height: 400px;
}

.tabs__list {
  border-bottom: 1px solid black;
  display: flex;
  flex-direction: row;
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.tabs__tab {
  padding: 0.5rem;
}

.tabs__content {
  display: none;
  left: 0;
  padding: 0.5rem;
  position: absolute;
  top: 100%;
}

.tabs__input {
  position: fixed;
  top:-100px;
}

.tabs__input+label {
  cursor: pointer;
}


.tabs__label:hover{
   background-color: #ccc;
}

.tabs__input:focus + label {
  outline: 2px solid #333;
}

.tabs__input:checked+label {
  color: red;
}

.tabs__input:checked~.tabs__content {
  display: block;
}

<a href="#">A link so you can see where your focus indicator is</a>
<div class="tabs">
  <ul class="tabs__list">
    <li class="tabs__tab">
      <input class="tabs__input" type="radio" id="tab-0" name="tab-group" checked>
      <label for="tab-0" class="tabs__label" role="button">Tab 0</label>
      <div class="tabs__content">
        Tab 0 content
      </div>
    </li>
    <li class="tabs__tab">
      <input class="tabs__input" type="radio" id="tab-1" name="tab-group">
      <label for="tab-1" class="tabs__label" role="button">Tab 1</label>
      <div class="tabs__content">
        Tab 1 content
      </div>
    </li>
  </ul>
</div>

这篇关于可访问的仅 CSS 选项卡视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆