使用 CSS :target 实现侧边栏菜单

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您的旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费试用额度!

“侧边栏”模式 是在网页上布置内容的不同方式,而不仅仅是垂直排列。 例如,导航可以放置在“画布”(可见浏览器窗口)的左侧边缘之外,并根据需要滑入。 Anthony Colangelo 创建了 jPanelMenu 来实现这一点。 Hakim El Hattab 的 Meny 更花哨,但其功能类似。

它们都使用 JavaScript。 我认为尝试只使用 CSS 来重新创建 Anthony 的 jPanelMenu 会很有趣。 这是可行的——有几个优点和缺点。

cssPanelMenu
查看演示

两列,一列折叠

此处的布局技术本质上是一个两列网格。 默认情况下,只有左列宽度为 0%,右列宽度为 100%。 左列是我们打算根据需要显示的导航。 通过隐藏溢出,此列将完全隐藏。

<!-- I am collapsed by default -->
<nav id="main-navigation" class="navigation">
   <a href="#">Nav Links</a>
   <!-- more -->
</nav>

<!-- I am full width by default -->
<div class="page-wrap">
  <header>
    <a href="#main-navigation">Menu</a>
    <h1>Title</h1>
  </header>

  <!-- content -->
</div>
.navigation {
  
  /* Collapsed */
  width: 0; 

  overflow: hidden;
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
}

.page-wrap {
  width: 100%;
  float: right;
}

打开菜单状态,使用 :target

注意这个链接

<a href="#main-navigation">Menu</a>

与 ID 匹配

<nav id="main-navigation" class="navigation">

这是一个普通的哈希链接。 页面将“跳转”到该元素。 对我们来说更重要的是,它将使此选择器匹配

#main-navigation:target {

}

因此,单击该链接时,我们可以通过增加其宽度来取消隐藏菜单。 也可以让它很好地滑出来。

.navigation {
  transition: width 0.3s ease;
}
#main-nav:target {
  width: 20%; 
}

我们可以到此为止,菜单将与内容重叠(确保它具有更高的 z-index)。 这将是完全可以的。 但我们确实有选择。 我们可以将内容“推”到内容的右侧边缘。 例如,这就是 Facebook 在其移动应用程序中显示左侧菜单时所做的事情。 或者我们可以压缩主要内容,使其成为 20%/80% 的网格。 这就是我们在这里要做的。

但等等……我们如何在菜单打开时仅选择 .page-wrap 的特定状态? 我们可以使用 相邻兄弟选择器

#main-nav:target + .page-wrap {
  width: 80%;
}

就是这样。

要关闭菜单,我们只需要从 URL 中删除哈希链接。 本质上,在任何地方提供类似这样的链接

<a href="#">Close Menu</a>

如果您想变得更花哨,可以隐藏/显示位于完全相同位置的不同链接,以创建“切换链接”。

优点

全部都是 CSS! 总体代码量更少。 加载的资源更少。 在没有 JavaScript 的情况下也能正常工作。 过渡比 JavaScript 过渡更流畅。

缺点

浏览器支持有限。 :target 是 IE9+(如果 :target 不起作用,整个过程就会失败)。 过渡 是 IE 10+。 通过更改类或使用 JavaScript 隐藏/显示/动画,可以克服任何浏览器限制。 此外,您将拥有更多关于标记如何安排的自由,而不是被强制使用此处呈现的特定顺序。 也许语义上略好,不需要分别链接打开和关闭菜单。