带有子菜单方向和换行符的CSS Flex菜单

时间:2018-06-04 21:52:31

标签: html css flexbox

考虑以下菜单代码JSFiddle here

<div class="menu">
<nav>
  <ul>
    <li>Logo</li>
    <li>
      Services
      <div class="menu-submenu">
        <ul>
          <li>Very big text here in this option</li>
          <li>Option</li>
          <li>Option 2</li>
          <li>Option 3</li>
        </ul>
      </div>
    </li>
    <li>Support</li>
    <li>Contact</li>
  </ul>
  </nav>
</div>

和CSS:

.menu {
  width: 100%;
  background-color: white;
  margin-bottom: 5px;
}

.menu nav ul {
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 0px;
  margin: 0px;
  list-style-type: none;
}

.menu nav ul li:first-child {
  padding-left: 10%;
  padding-top: 5px;
  padding-right: 30px;
}

.menu nav ul li:not(:first-child) {
  line-height: 30px;
  padding-top: 10px;
  padding-left: 10px;
  padding-right: 10px;
  padding-bottom: 10px;
}

.menu nav ul li:first-child {
  height: 30px;
}

.menu nav ul li:last-child {
  margin-left: auto;
  margin-right: 10%;
  align-self: flex-end;
}

.menu nav ul li:hover:not(:first-child) {
  background-color: blue;
  color: white;
}

.menu nav ul li {
  position: relative;
}

.menu-submenu {
  display: none;
}

.menu nav ul li:hover .menu-submenu {
  display: flex;
}

.menu-submenu ul {
  position: absolute;
  top: 30px;
  display: flex;
  flex-direction: column;
}

.menu-submenu ul li {
  flex: 1;
  background-color: red;
  z-index: 10;
}

一个。如何使子菜单在垂直而不是水平打开?

湾如何允许子菜单文本不要制动(打开的宽度超过其父级)?

2 个答案:

答案 0 :(得分:2)

a)您在flex-direction: column上正确设置了.menu-submenu ul。问题是您还在flex-direction: row.menu nav ul设置了相同(但已应用) specificity 。要更正此问题,只需为.menu-submenu ul选择器提供更多特异性(例如,将其更改为.menu-submenu > ul)。

b)您的.menu nav ul li:first-child已应用于两者导航栏和子菜单。由于heightpadding限制,这会导致子菜单的显示混乱。我相信你只想把它应用到主导航栏。因此,只需更改此规则即可将 child combinator (>) 用作.menu nav > ul > li:first-child

您需要将>应用于ul的任意一侧以定位您的导航栏。要定位子菜单,您应该使用.menu .menu-submenu > ul.menu .menu-submenu > ul > li,这样就不会对哪个菜单定位目标感到困惑。

这是一个展示子菜单垂直的示例,同时删除所有其他(可能)错误地应用于它的规则:

.menu {
  width: 100%;
  background-color: white;
  margin-bottom: 5px;
}

.menu nav ul {
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 0px;
  margin: 0px;
  list-style-type: none;
}

.menu nav > ul > li:first-child {
  padding-left: 10%;
  padding-top: 5px;
  padding-right: 30px;
}

.menu nav > ul > li:not(:first-child) {
  line-height: 30px;
  padding-top: 10px;
  padding-left: 10px;
  padding-right: 10px;
  padding-bottom: 10px;
}

.menu nav > ul > li:first-child {
  height: 30px;
}

.menu nav > ul > li:last-child {
  margin-left: auto;
  margin-right: 10%;
  align-self: flex-end;
}

.menu nav > ul > li:hover:not(:first-child) {
  background-color: blue;
  color: white;
}

.menu nav ul li {
  position: relative;
}

.menu-submenu {
  display: none;
}

.menu nav ul li:hover .menu-submenu {
  display: flex;
}

.menu .menu-submenu > ul {
  position: absolute;
  top: 30px;
  display: flex;
  flex-direction: column;
}

.menu .menu-submenu > ul > li {
  flex: 1;
  background-color: red;
  z-index: 10;
}
<div class="menu">
<nav>
  <ul>
    <li>Logo</li>
    <li>
      Services
      <div class="menu-submenu">
        <ul>
          <li>Very big text here in this option</li>
          <li>Option</li>
          <li>Option 2</li>
          <li>Option 3</li>
        </ul>
      </div>
    </li>
    <li>Support</li>
    <li>Contact</li>
  </ul>
  </nav>
</div>

答案 1 :(得分:1)

您可以使用更少的代码使其更好:

&#13;
&#13;
.menu, .menu * {margin: 0; padding: 0; box-sizing: border-box}

.menu {
  background: white;
  margin-bottom: 5px;
}

.menu ul {
  list-style: none;
  display: flex;
  align-items: center;
}

.menu ul li {
  margin: 0 5px; /* adjust */
  padding: 5px; /* adjust */
}

.menu ul li:last-child {
  margin-left: auto;
}

.menu ul li:hover:not(:first-child) {
  background: blue;
  color: white;
}

.menu ul li:hover .menu-submenu {
  display: flex;
}

.menu-submenu {
  display: none;
  position: relative; /* added */
}

.menu-submenu ul {
  position: absolute;
  top: 5px; /* modified; adjust; needs to match the padding of the ".menu ul li" */
  left: -5px; /* added; adjust; needs to match the padding of the ".menu ul li" (negative) */
  display: flex;
  flex-direction: column;
}

.menu-submenu ul li {
  width: 100%; /* added */
  padding: 5px; /* adjust */
  white-space: nowrap; /* added */
  background: red;
  z-index: 10;
}
&#13;
<nav class="menu">
  <ul>
    <li>Logo</li>
    <li>
      Services
      <div class="menu-submenu">
        <ul>
          <li>Very big text here in this option</li>
          <li>Option 1</li>
          <li>Option 2</li>
          <li>Option 3</li>
        </ul>
      </div>
    </li>
    <li>Support</li>
    <li>Contact</li>
  </ul>
</nav>
&#13;
&#13;
&#13;

否则,重点在于使用white-space: nowrap来防止换行,width: 100%使其在宽度上均匀。由于.menu-submenu ulposition: absoluteposition: relative需要位于其父元素上。