首页 > 解决方案 > 关于通过 CSS 使用或不使用 JavaScript 辅助实现具有多个选项卡的单个 HTML 页面

问题描述

我有兴趣使用一个 HTML 文件和多个选项卡构建一个网页。

由于一次只能选择一个选项卡,我认为处理用户选择显示哪个选项卡的最合适的方法是通过单选按钮,即<nav>包装一个<ul>包装一个 s 列表,<li>每个包装一个包装一个<input>后跟一个<label>(另见我之前的问题)。

在网上StackOverflow上搜索后,我想出了这个:

function f(t) {
  // the vector below should be obtainable programmatically from the HTML
  ['tab1', 'tab2'].map(x => document.getElementById(x).style.setProperty('display', 'none'));
  document.getElementById(t).style.setProperty('display', 'initial');
}
ul {
  list-style-type: none;
}

/* With this ruleset I effectively target an HTML element,
   `label`, based on a condition being true or false about
   a different HTML element, `input`. The only relation
   between them is that they are siblings. */
input:checked + label {
  color: red;
}

/* I can't do the same with the element `#tab1` because it
   is not child nor sibling of the one holding the condition,
   the `input` targeted above. So I have to do this */
.tabs {
  display: none;
}
#tab2 {
  display: initial;
}
<nav>
  <ul class="site-nav">
    <li>
      <input id="tab1-radio" value="tab1" type="radio" name="nav-tabs" onclick="f(value)">
      <label for="tab1-radio" class="box-shadow">Tab 1</label>
    </li>
    <li>
      <input id="tab2-radio" value="tab2" type="radio" name="nav-tabs" onclick="f(value)" checked="checked">
      <label for="tab2-radio" class="box-shadow">Tab 2</label>
    </li>
  </ul>
</nav>
<div id="tab1" class="tabs">
Tab 1 content
</div>
<div id="tab2" class="tabs">
Tab 2 content
</div>

但是我看到了一些弱点(或讨论):


另一方面,另一个答案提出了一种无需任何 JavaScript 即可完成任务的方法。我还在这里找到了更全面的指南,但是这种技术依赖于手动position处理和通过 处理堆栈z-index,但这开始看起来很困难、很麻烦,并且给程序员带来了很大的负担。

以下是我尝试简化该方法的尝试,但如链接文章中所述,它失败了

如果链接到没有哈希选择器的页面,则不显示任何选项卡内容,即链接到mypage.html而不是mypage.html#tab1.

ul {
  list-style-type: none;
}

.page {
  display: none;
}

.page:target {
  display: initial;
}
<nav>
  <ul class="site-nav">
    <li>Click <a href="#one">here</a> for page 1</li>
    <li>Click <a href="#two">here</a> for page 2</li>
  </ul>
</nav>

  <div class="page" id="one">
    Tab 1 content
  </div>

  <div class="page" id="two">
Tab 2 content
  </div>

标签: javascripthtmlcsstabsaccessibility

解决方案


我不建议将其用于生产,而是鼓励您使用适当的选项卡模式,以便您可以操作相关的WAI-ARIA属性或 SPA 模式(在导航发生后您将在其中管理焦点)等。

但是话虽如此,我确实想证明这确实是可能的(具有初始内容)使用:target选择器,只要您不介意 DOM 顺序有点奇怪(它不应该有任何可访问性问题)部分被隐藏)。

我添加的“主页”链接实际上并不需要,我只是将其放在那里以保持完整性/为您提供选择。

还要注意一些不寻常的事情 - 因为以这种方式更改页面并不总是<h1>- 我实际上不确定(我将不得不考虑)如何最好地处理这个问题,但现在我已经<h1>在每个部分添加了一个每个“页面”都有一个<h1>.

ul {
  list-style-type: none;
}

.page{
   display: none;
} 

.page:target {
  display: initial;
}

.page:target ~ .initial  {
  display: none;
}
<nav>
  <ul class="site-nav">
   <li><a href="#home">home</a></li>
    <li><a href="#one">page 1</a> </li>
    <li><a href="#two">page 2</a> </li>
  </ul>
</nav>
<main>
  <section class="page" id="one" aria-labelledby="section1Heading">
    <h1 id="section1Heading">Tab 1 content</h1>
  </section>

   <section class="page" id="two" aria-labelledby="section2Heading">
    <h1 id="section2Heading">Tab 2 content</h1>
  </section>
  
  <section class="initial" id="home" aria-labelledby="homeHeading">
    <h1 id="homeHeading">Initial Page Content / Home Page</h1>
  </section>
  </main>


推荐阅读