【问题标题】:Only highlight currently hovered nested list item [duplicate]仅突出显示当前悬停的嵌套列表项[重复]
【发布时间】:2018-08-10 12:19:07
【问题描述】:

假设一个ulli 项,其中一些又有ul 和内部li 项:

    <div class="nav-main">
        <ul>
            <li>First Level First Item</li>
            <li>First Level Second item
                <ul><li>Level 2 First item</li></ul>
            </li>    
            <li>Level 1 Second item</li>
        </ul>
    </div>
</body>

将鼠标悬停在外部列表的 li 项目上会突出显示此项目,但将鼠标悬停在嵌套列表项目上会悬停此项目和封闭的列表项目。

li:hover { border: 1px solid black; }

如何总是只突出显示一项?最好不要使用任何 JavaScript。

li:hover { border: 1px solid blue; }
        <div class="nav-main">
            <ul>
                <li>First Level First Item</li>
                <li>First Level Second item
                    <ul><li>Level 2 First item</li></ul>
                </li>    
                <li>Level 1 Second item</li>
            </ul>
        </div>

【问题讨论】:

    标签: html css


    【解决方案1】:

    一种选择是在列表中的每个文本项周围添加一个&lt;span&gt;,然后您可以将其用作 CSS 选择器:

    li&gt;span:hover { border: 1px solid blue; }
    <div class="nav-main">
      <ul>
        <li><span>First Level First Item</span></li>
        <li><span>First Level Second item</span>
          <ul><li><span>Level 2 First item</span></li></ul>
        </li>    
        <li><span>Level 1 Second item</span></li>
      </ul>
    </div>

    【讨论】:

    • 这样,第二个li上的悬停不会覆盖整个li
    • 我相信这是本意
    • 我明白了.. 仍然我想知道是否没有办法不更改标记。
    【解决方案2】:

    我建议您使用::before 伪元素的以下解决方案:

    • 始终使用position: relativeli 元素和height: 1em; 来确定伪元素(边框)的大小,
    • lis 的hover 上,显示边框/伪元素,
    • 在子uls 的hover 上,添加白色边框以隐藏父li 边框。

    工作sn-p:

    li {
      position: relative;
      margin-top: 5px; /* Added this to prevent some dead-zones triggering the ul:hover */
    }
    
    li::before, ul::before {
      content: '';
      display: none;
      position: absolute;
      height: 1em;
      top: -1px;
      left: -4px;
      right: 0;
      padding: 1px 0;
    }
    
    li:hover::before {
      display: block;
      border: 1px solid blue;
    }
    
    li ul:hover::before {
      display: block;
      border: 1px solid white;
    }
    <div class="nav-main">
      <ul>
        <li>First Level First Item</li>
        <li>First Level Second item
          <ul>
            <li>Level 2 First item</li>
          </ul>
        </li>
        <li>Level 1 Second item</li>
      </ul>
    </div>

    希望对你有帮助。

    【讨论】:

    • 这有点像我的把戏:p
    • 好吧@TemaniAfif,如果是的话,我不是故意的!我承诺。 :) 事实上,我在你的第一个 sn-p 中并没有理解所有内容。所以,我试着做我的,并避免当你悬停子 li 并返回悬停父 li 时出现不工作的行为。 (这对你不起作用)
    【解决方案3】:

    这是隐藏外部突出显示的技巧,因为我认为您不能禁用它,因为子元素的悬停总是会触发父元素的悬停:

    li:hover {
      border: 1px solid blue;
    }
    
    .nav-main>ul>li {
      position: relative;
    }
    
    ul>li>ul>li:before {
      content: "";
      position: absolute;
      top: -1px;
      left: -1px;
      right: -1px;
      bottom: -1px;
      display:none;
      border: 1px solid #fff;
    }
    
    ul>li>ul>li:hover:before {
      display:block;
    }
    <div class="nav-main">
      <ul>
        <li>First Level First Item</li>
        <li>First Level Second item
          <ul>
            <li>Level 2 First item</li>
          </ul>
        </li>
        <li>Level 1 Second item</li>
      </ul>
    </div>

    这是另一个可以用伪元素替换边框的技巧:

    li {
      position: relative;
    }
    
    li span:before {
      content: "";
      position: absolute;
      top: 0px;
      left: 0px;
      right: 0px;
      bottom: 0px;
      display:none;
      border: 1px solid blue;
    }
    
    li span:hover:before {
      display:block;
    }
    <div class="nav-main">
      <ul>
        <li><span>First Level First Item</span></li>
        <li><span>First Level Second item</span>
          <ul>
            <li><span>Level 2 First item</span></li>
          </ul>
        </li>
        <li><span>Level 1 Second item</span></li>
      </ul>
    </div>

    【讨论】:

      【解决方案4】:

      在嵌套之前关闭

    • 一次只会高亮 1 个
      <div class="nav-main">
              <ul>
                  <li>First Level First Item</li>
                  <li>First Level Second item</li>
                      <ul><li>Level 2 First item</li></ul>  
                  <li>Level 1 Second item</li>
              </ul>
          </div>
      

      <style type="text/css">li:hover { border: 1px solid blue; }</style>
      
      <div class="nav-main">
        <ul>
          <li>First Level First Item</li>
          <li>First Level Second item</li>
            <ul><li>Level 2 First item</li></ul>   
          <li>Level 1 Second item</li>
        </ul>
      </div>
    • 【讨论】:

      • 这不是一个有效的 html,ul 只能有 li 作为直接子节点