将嵌套列表呈现到列中

Present nested lists into columns

我有一个最大深度为 3 的嵌套导航列表,例如:

<!-- Depth 1 -->
<ul>
    <li>...</li>
    <li>
       <li>...</li>

       <!-- Depth 2 -->
        <ul>
            <li>
                <li>...</li>

                <!-- Depth 3 -->
                <ul>
                    <li>...</li>
                </ul>
            </li>
        </ul>

    </li>
    <li>...</li>
</ul>

我希望每个嵌套级别在悬停时显示在父级列表的右侧,但与祖级列表齐平。

到目前为止我有这个:

*,
*:before,
*:after {
  box-sizing: border-box;
}

nav {
  background: #eee;
  padding: 10px;
}

nav ul {
  display: block;
  list-style: none;
  padding: 0;
  margin: 0;
  border-right: 1px solid #333;
  width: 33.333vw;
}

nav ul>li {
  position: relative;
  display: block;
  margin: 0;
  padding: 0 10px;
}

nav ul>li.has-children>a:after {
  content: '»';
  float: right;
}

nav ul>li>a {
  display: block;
  padding: 8px 15px;
  transition: background-color 0.4s;
}

nav ul>li>ul.sub-menu {
  display: none;
  position: absolute;
  top: 0;
  left: 100%;
}

nav ul>li:hover>a {
  background-color: rgba(0, 0, 0, 0.04);
}

nav ul>li:hover>ul.sub-menu {
  display: block;
}
<nav>
  <ul>
    <li class="has-children">
      <a href="#">Item 1</a>
      <ul class="sub-menu">
        <li class="has-children">
          <a href="#">Sub 1.1</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 1.1.1</a></li>
            <li><a href="#">Sub 1.1.2</a></li>
            <li><a href="#">Sub 1.1.3</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 1.2</a></li>
        <li class="has-children">
          <a href="#">Sub 1.3</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 1.3.1</a></li>
            <li><a href="#">Sub 1.3.2</a></li>
            <li><a href="#">Sub 1.3.3</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 1.4</a></li>
      </ul>
    </li>
    <li class="has-children">
      <a href="#">Item 2</a>
      <ul class="sub-menu">
        <li class="has-children">
          <a href="#">Sub 2.1</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 2.1.1</a></li>
            <li><a href="#">Sub 2.1.2</a></li>
          </ul>
        </li>
        <li class="has-children">
          <a href="#">Sub 2.2</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 2.3.1</a></li>
            <li><a href="#">Sub 2.3.2</a></li>
            <li><a href="#">Sub 2.3.3</a></li>
            <li><a href="#">Sub 2.3.4</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 2.3</a></li>
      </ul>
    </li>
    <li><a href="#">Item 3</a></li>
    <li><a href="#">Item 4</a></li>
    <li class="has-children">
      <a href="#">Item 5</a>
      <ul class="sub-menu">
        <li class="has-children">
          <a href="#">Sub 5.1</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 5.1.1</a></li>
            <li><a href="#">Sub 5.1.2</a></li>
            <li><a href="#">Sub 5.1.3</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 5.2</a></li>
        <li class="has-children">
          <a href="#">Sub 5.3</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 5.3.1</a></li>
            <li><a href="#">Sub 5.3.2</a></li>
            <li><a href="#">Sub 5.3.3</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 5.4</a></li>
      </ul>
    </li>
  </ul>
</nav>

(https://jsfiddle.net/thelevicole/q4y8fxu0/)

但这会将子列表定位到在上方产生空格的父元素的顶部。

有没有办法用 CSS 实现这个,或者我必须用 javascript 修改 DOM 吗?

nav ul > li 中删除 position:relative; 添加到 nav ul

检查下面的代码。

*, *:before, *:after {
     box-sizing: border-box;
}
 nav {
     background: #eee;
     padding: 10px;
}
 nav ul {
     display: block;
     list-style: none;
     padding: 0;
     margin: 0;
     border-right: 1px solid #333;
     width: 33.333vw;
     position: relative;
}
 nav ul > li {
     display: block;
     margin: 0;
     padding: 0 10px;
}
 nav ul > li.has-children > a:after {
     content: '»';
     float: right;
}
 nav ul > li > a {
     display: block;
     padding: 8px 15px;
     transition: background-color 0.4s;
}
 nav ul > li > ul.sub-menu {
     display: none;
     position: absolute;
     top: 0;
     left: 100%;
   height: 100%;
}
 nav ul > li:hover > a {
     background-color: rgba(0, 0, 0, 0.04);
}
 nav ul > li:hover > ul.sub-menu {
     display: block;
}
<nav>
  <ul>
    <li class="has-children">
      <a href="#">Item 1</a>
      <ul class="sub-menu">
        <li class="has-children">
          <a href="#">Sub 1.1</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 1.1.1</a></li>
            <li><a href="#">Sub 1.1.2</a></li>
            <li><a href="#">Sub 1.1.3</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 1.2</a></li>
        <li class="has-children">
          <a href="#">Sub 1.3</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 1.3.1</a></li>
            <li><a href="#">Sub 1.3.2</a></li>
            <li><a href="#">Sub 1.3.3</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 1.4</a></li>
      </ul>
    </li>
    <li class="has-children">
      <a href="#">Item 2</a>
      <ul class="sub-menu">
        <li class="has-children">
          <a href="#">Sub 2.1</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 2.1.1</a></li>
            <li><a href="#">Sub 2.1.2</a></li>
          </ul>
        </li>
        <li class="has-children">
          <a href="#">Sub 2.2</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 2.3.1</a></li>
            <li><a href="#">Sub 2.3.2</a></li>
            <li><a href="#">Sub 2.3.3</a></li>
            <li><a href="#">Sub 2.3.4</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 2.3</a></li>
      </ul>
    </li>
    <li><a href="#">Item 3</a></li>
    <li><a href="#">Item 4</a></li>
    <li class="has-children">
      <a href="#">Item 5</a>
      <ul class="sub-menu">
        <li class="has-children">
          <a href="#">Sub 5.1</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 5.1.1</a></li>
            <li><a href="#">Sub 5.1.2</a></li>
            <li><a href="#">Sub 5.1.3</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 5.2</a></li>
        <li class="has-children">
          <a href="#">Sub 5.3</a>
          <ul class="sub-menu">
            <li><a href="#">Sub 5.3.1</a></li>
            <li><a href="#">Sub 5.3.2</a></li>
            <li><a href="#">Sub 5.3.3</a></li>
          </ul>
        </li>
        <li><a href="#">Sub 5.4</a></li>
      </ul>
    </li>
  </ul>
</nav>