【问题标题】:Accessible CSS-only tab view可访问的纯 CSS 选项卡视图
【发布时间】:2020-04-14 10:30:39
【问题描述】:

我正在开发一个需要 (a) 无需 JavaScript 且 (b) 可通过键盘访问的网站。

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

.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>

【问题讨论】:

  • 我认为没有 JS 是不可能的。请与我分享代码。
  • 为您接受的答案添加了一些修复,因为它存在一些大问题,希望对您有所帮助!

标签: css accessibility wai-aria


【解决方案1】:

接受的答案不是可访问的解决方案。

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

以下答案修复了一些 CSS 问题,使其更易于访问。

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

我可以理解有一个很好的后备(我在下面给出的修复示例),但你无法制作一组完全可访问的纯 CSS 选项卡。

首先,您应该使用 WAI-ARIA 来补充您的 HTML,让屏幕阅读器更加清晰。请参阅tabs examples on W3C 以了解您应该使用哪些 WAI-ARIA 角色。如果没有 JavaScript,这是不可能的,因为状态需要改变(例如,aria-hidden 应该改变)。

其次,您应该能够使用某些快捷键。例如,按下 home 键以返回到第一个选项卡,您只能借助一点 JS 帮助来做到这一点。

话虽如此,我用公认的答案解决了一些问题,至少可以为您提供一个良好的起点,因为您的“没有 JavaScript fallback”。

问题 1 - 标签上的tabindex

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

为了解决这个问题,我只是从标签中删除了tabindex

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

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

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

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

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

这是另一种需要消除的不良做法,始终以不同的方式显示悬停和焦点状态。一些屏幕阅读器和屏幕放大镜用户将使用他们的鼠标来检查他们是否拥有正确的焦点并在页面上定位自己。如果没有单独的悬停状态,则很难检查您是否悬停在焦点项目上。

/*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;
}

示例

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

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

.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>

【讨论】:

    【解决方案2】:

    这只是单选按钮...可以使用键盘在它们之间导航,使用制表符和空格键来检查它们。

    我会使用:focus 突出显示选定的选项卡和tabindex 属性以使其按我的意愿工作。

    如果您对与之相关的特定问题有疑问,请提供更多部门,并在此处提供基本代码示例,不要链接。

    由于无法通过键盘选择隐藏的输入,因此使其可见...

    .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__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>

    【讨论】:

    • 我已经添加了代码并制作了一个 JSFiddle 来演示代码。单选按钮是隐藏的,因此无法使用箭头键选择或选择它们。焦点也不合适,因为如果选项卡失去焦点(如果用户单击任何地方或选择页面上的任何其他元素,就会发生这种情况),那么选项卡内容将不再显示。
    • 使用焦点显示悬停状态,而不是激活选项卡。为什么是jsfiddle?可以使用 SO 的 fiddler,我们更容易提供帮助...
    • 我正在使用焦点来显示悬停状态。不知道SO的fiddler,怎么找到呢?
    猜你喜欢
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    相关资源
    最近更新 更多