可伸缩弹性Flexbox导航

Avatar of Chris Coyier
Chris Coyier

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

前几天我在 The New Tropic 上看到了一个关于画布外导航的有趣案例。并不是画布外部分很吸引人。而是导航内元素占据空间的方式。它们会拉伸以占据所有可用空间,但绝不会挤压得太厉害。这些概念使用flexbox很容易表达!让我们深入了解一下。

这是导航,一段展示我意思的视频

我最喜欢的一部分是它有子菜单。当子菜单展开时,相同的规则适用。如果发生了拉伸,导航项的高度会缩小,为子菜单腾出空间。但永远不会缩小太多。如果没有空间,菜单只会滚动。

标准的两级导航HTML

使用 Emmet 模拟出来非常容易

<nav class="main-nav">
  <ul class="nav-list">
    <li><a href="">Lorem ipsum.</a></li>
    <li>
      <button class="submenu-toggle-button">+</button>
      <a href="">Explicabo, perspiciatis.</a>
      <ul class="submenu nav-list">
        <li><a href="">Lorem ipsum.</a></li>
        <li><a href="">Culpa, qui!</a></li>
        <li><a href="">Repudiandae, eaque.</a></li>
      </ul>
    </li>
    <li><a href="">Sit, dolor.</a></li>
    <li><a href="">Dicta, possimus?</a></li>
    
    <!-- etc -->

  </ul>
</nav>

Flexbox 列

让我们确保列表的高度与浏览器窗口一样高,这使用视口单位很容易实现。然后确保每个列表项都拉伸以填充空间

.main-nav > ul {
  height: 100vh;
  display: flex;
  flex-direction: column;
}
.main-nav > ul > li {
  flex: 1;
}

我们已经完成了大部分工作!拉伸效果很好,只有在有空间时才会发生,就像我们想要的那样

快速切换

我们有一个 <button> 用于切换子菜单(可以说,我们可能应该使用JavaScript来放置这些按钮,因为如果没有JavaScript它们什么也做不了)。以下是它们的工作原理。子菜单默认隐藏

.submenu {
  max-height: 0;
  transition: 0.5s;
  overflow: hidden;
}

我们可以使用一个类来打开它

.submenu.open {
  max-height: 200px; /* non-ideal magic number */
}

我们在这里正在动画到一个未知的高度,这很棘手。我们希望很快能有一篇好文章来解决这个问题(有一些选择)。

切换类非常容易:

var buttons = document.querySelectorAll('.submenu-toggle-button');

[].forEach.call(buttons, function(button) {
  button.addEventListener('click', function() {
    var submenu = button.parentNode.querySelector('.submenu');
    submenu.classList.toggle('open');
  });
});

这样可以让子菜单按照我们想要的方式工作

演示

您可能需要访问CodePen 来体验垂直拉伸效果。

查看CodePen上的Chris Coyier (@chriscoyier) 编写的 可伸缩弹性导航