代码之家  ›  专栏  ›  技术社区  ›  Mendes

带子菜单方向和换行符的css flex菜单

  •  1
  • Mendes  · 技术社区  · 7 年前

    考虑以下菜单代码 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;
    }
    

    a.如何使子菜单垂直打开,而不是水平打开?

    b.如何允许子菜单文本不制动(打开时宽度大于其父菜单)?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Obsidian Age    7 年前

    a)设置正确 flex-direction: column .menu-submenu ul . 问题是你也设定了 flex-direction: row .menu nav ul 相等(但适用) specificity . 要纠正这一点,只需 .菜单子菜单ul 选择器更特殊(通过将其更改为 .menu-submenu > ul 例如)。

    b)你的 .menu nav ul li:first-child 应用于 二者都 导航栏和子菜单。由于 height padding 限制,这会导致子菜单的显示混乱。我相信你只想把它应用到主导航栏上。因此,只需更改此规则以使用 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>
        2
  •  1
  •   VXp Kadir BuÅ¡atlić    7 年前

    你可以用更少的代码使它变得更好:

    .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;
    }
    <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>

    否则重点是使用 white-space: nowrap 防止断线和 width: 100% 使宽度均匀。自从 .menu-submenu ul position: absolute , position: relative 需要在它上面 父元素 .