【问题标题】:How to affect other elements when one element is hovered一个元素悬停时如何影响其他元素
【发布时间】:2019-01-27 13:15:49
【问题描述】:

我想要做的是当某个div 悬停时,它会影响另一个div 的属性。

例如,在this JSFiddle demo 中,当您将鼠标悬停在#cube 上时,它会更改background-color,但我想要的是,当我将鼠标悬停在#container 上时,#cube 会受到影响。

div {
  outline: 1px solid red;
}

#container {
  width: 200px;
  height: 30px;
}

#cube {
  width: 30px;
  height: 100%;
  background-color: red;
}

#cube:hover {
  width: 30px;
  height: 100%;
  background-color: blue;
}
<div id="container">
  <div id="cube">
  </div>
</div>

【问题讨论】:

    标签: html css hover


    【解决方案1】:

    如果立方体直接在容器内:

    #container:hover > #cube { background-color: yellow; }
    

    如果立方体在容器旁边(在容器结束标记之后):

    #container:hover + #cube { background-color: yellow; }
    

    如果立方体在容器内的某处:

    #container:hover #cube { background-color: yellow; }
    

    如果立方体是容器的兄弟:

    #container:hover ~ #cube { background-color: yellow; }
    

    【讨论】:

    • 不要忘记通用兄弟组合 ~ '立方体在 DOM 中的容器之后的某个位置并共享一个父'
    • 这很酷。是否有一些来源可以找到有关此的更多信息?它是否被所有浏览器支持,是 CSS3 吗?有更多关于此的信息会很棒。非常感谢!
    • +1 很好的答案@Mike。如果#container#cube 旁边,即#container#cube 之后怎么办?
    • 如果悬停的元素在容器内(我们希望受到影响)怎么办???例如:#cube:hover #container{一些 CSS 效果}
    • 好答案!如果我想在悬停孩子时更改父母怎么办。我认为没有选择器。
    【解决方案2】:

    在此特定示例中,您可以使用:

    #container:hover #cube {
        background-color: yellow;   
    }
    

    此示例仅适用于 cubecontainer 的子代。对于更复杂的场景,您需要使用不同的 CSS,或者使用 JavaScript。

    【讨论】:

      【解决方案3】:

      使用同级选择器是在将鼠标悬停在给定元素上时设置其他元素样式的一般解决方案,它只有在其他元素跟随 DOM 中的给定元素时才有效。当其他元素实际上应该在悬停的元素之前时,我们能做什么?假设我们要实现一个信号条评级小部件,如下所示:

      这实际上可以使用 CSS flexbox 模型轻松完成,通过将flex-direction 设置为reverse,以便元素以与它们在 DOM 中的顺序相反的顺序显示。上面的截图来自这样一个小部件,使用纯 CSS 实现。

      Flexbox is very well supported 被 95% 的现代浏览器所采用。

      .rating {
        display: flex;
        flex-direction: row-reverse;
        width: 9rem;
      }
      .rating div {
        flex: 1;
        align-self: flex-end;
        background-color: black;
        border: 0.1rem solid white;
      }
      .rating div:hover {
        background-color: lightblue;
      }
      .rating div[data-rating="1"] {
        height: 5rem;
      }
      .rating div[data-rating="2"] {
        height: 4rem;
      }
      .rating div[data-rating="3"] {
        height: 3rem;
      }
      .rating div[data-rating="4"] {
        height: 2rem;
      }
      .rating div[data-rating="5"] {
        height: 1rem;
      }
      .rating div:hover ~ div {
        background-color: lightblue;
      }
      <div class="rating">
        <div data-rating="1"></div>
        <div data-rating="2"></div>
        <div data-rating="3"></div>
        <div data-rating="4"></div>
        <div data-rating="5"></div>
      </div>

      【讨论】:

      • 是否可以对其进行编辑,以便在将鼠标从一个栏移动到另一个栏时突出显示不会消失?闪烁有点分散注意力。
      • 在你的第一个 sn-p 中试试这个:在 .rating div 上,删除边距,然后添加 border-right: 4px solid white;
      • Flex 方向(IE 不太支持)或 1) 默认为黑色 2) 鼠标悬停在容器上时全为蓝色 3) 栏悬停时下一个兄弟为黑色 :)
      • 我制作了这个小提琴(至少对我而言),它使这里发生的事情更加清晰。 jsfiddle.net/maxshuty/cj55y33p/3
      • 这是个好主意!对于只需要一个元素来触发 dom 悬停的情况,我认为最好使用 flexbox order 属性,这样如果只有一个元素需要,您就不必以相反的顺序维护整个列表触发悬停。
      【解决方案4】:

      只有这对我有用:

      #container:hover .cube { background-color: yellow; }
      

      .cube#container 内部某处的 CssClass。

      FirefoxChromeEdge 中测试。

      【讨论】:

        【解决方案5】:

        非常感谢 Mike 和 Robertc 的有用帖子!

        如果您的 HTML 中有两个元素,并且您希望 :hover 超过一个并针对另一个中的样式更改,则这两个元素必须直接相关 - 父级、子级或兄弟级。这意味着这两个元素要么必须在另一个元素中,要么必须都包含在同一个更大的元素中。

        当我的用户阅读我的网站和:hover 突出显示的术语时,我想在浏览器右侧的框中显示定义;因此,我不希望 'definition' 元素显示在 'text' 元素内。

        我几乎放弃了,只是在我的页面中添加了 javascript,但这就是未来!我们不应该忍受来自 CSS 和 HTML 的 back sass 告诉我们必须将元素放置在哪里才能实现我们想要的效果!最后我们妥协了。

        虽然文件中的实际 HTML 元素必须嵌套或包含在单个元素中才能使 :hover 相互有效,但 css position 属性可用于显示任何位置的任何元素你要。我使用 position:fixed 将 :hover 操作的目标放置在用户屏幕上我想要的位置,而不管它在 HTML 文档中的位置。

        html:

        <div id="explainBox" class="explainBox"> /*Common parent*/
        
          <a class="defP" id="light" href="http://en.wikipedia.or/wiki/Light">Light                            /*highlighted term in text*/
          </a> is as ubiquitous as it is mysterious. /*plain text*/
        
          <div id="definitions"> /*Container for :hover-displayed definitions*/
            <p class="def" id="light"> /*example definition entry*/ Light:
              <br/>Short Answer: The type of energy you see
            </p>
          </div>
        
        </div>
        

        CSS:

        /*read: "when user hovers over #light somewhere inside #explainBox
            set display to inline-block for #light directly inside of #definitions.*/
        
        #explainBox #light:hover~#definitions>#light {
          display: inline-block;
        }
        
        .def {
          display: none;
        }
        
        #definitions {
          background-color: black;
          position: fixed;
          /*position attribute*/
          top: 5em;
          /*position attribute*/
          right: 2em;
          /*position attribute*/
          width: 20em;
          height: 30em;
          border: 1px solid orange;
          border-radius: 12px;
          padding: 10px;
        }
        

        在此示例中,来自 #explainBox 内元素的 :hover 命令的目标必须是 #explainBox 或也位于 #explainBox 内。分配给 #definitions 的位置属性会强制它出现在所需的位置(#explainBox 之外),即使它在技术上位于 HTML 文档中不需要的位置。

        我理解为多个 HTML 元素使用相同的 #id 被认为是错误的形式;但是,在这种情况下,#light 的实例可以独立地描述,因为它们在唯一的#id'd 元素中各自的位置。在这种情况下,有什么理由不重复id#light

        【讨论】:

        • 对于这么短的观点来说,答案很长,但这里有一个 jsfiddle jsfiddle.net/ubershmekel/bWgq6/1
        • 当您多次使用相同的ID 时,一些浏览器会吓坏。只需使用class
        【解决方案6】:

        这是另一个想法,它允许您在不考虑任何特定选择器的情况下仅使用主元素的:hover 状态来影响其他元素。

        为此,我将依赖自定义属性(CSS 变量)的使用。正如我们在specification 中看到的那样:

        自定义属性是普通属性,因此可以在 任何元素,通过正常继承级联解决 规则 ...

        我们的想法是在主元素中定义自定义属性并使用它们来设置子元素的样式,由于这些属性是继承的,我们只需要在悬停时在主元素中更改它们。

        这是一个例子:

        #container {
          width: 200px;
          height: 30px;
          border: 1px solid var(--c);
          --c:red;
        }
        #container:hover {
          --c:blue;
        }
        #container > div {
          width: 30px;
          height: 100%;
          background-color: var(--c);
        }
        <div id="container">
          <div>
          </div>
        </div>

        为什么这比使用特定选择器结合悬停更好?

        我可以提供至少 2 个理由让这种方法成为值得考虑的好方法:

        1. 如果我们有许多共享相同样式的嵌套元素,这将避免我们复杂的选择器在悬停时将所有元素作为目标。使用自定义属性,我们只需在将鼠标悬停在父元素上时更改值。
        2. 自定义属性可用于替换任何属性的值以及它的部分值。例如,我们可以为颜色定义一个自定义属性,并在borderlinear-gradientbackground-colorbox-shadow 等中使用它。这将避免我们在悬停时重置所有这些属性。

        这是一个更复杂的例子:

        .container {
          --c:red;
          width:400px;
          display:flex;
          border:1px solid var(--c);
          justify-content:space-between;
          padding:5px;
          background:linear-gradient(var(--c),var(--c)) 0 50%/100% 3px no-repeat;
        }
        .box {
          width:30%;
          background:var(--c);
          box-shadow:0px 0px 5px var(--c);
          position:relative;
        }
        .box:before {
          content:"A";
          display:block;
          width:15px;
          margin:0 auto;
          height:100%;
          color:var(--c);
          background:#fff;
        }
        
        /*Hover*/
        .container:hover {
          --c:blue;
        }
        <div class="container">
        <div class="box"></div>
        <div class="box"></div>
        </div>

        正如我们在上面看到的,我们只需要一个 CSS 声明来改变不同元素的许多属性。

        【讨论】:

          【解决方案7】:

          警告:如果您能够使用 CSS:请在没有 Javascript 的情况下使用 CSS!

          如果你想选择一个元素未知/或不可到达的位置你可以使用JavaScript。

          const cube = document.getElementById('cube')
          const container = document.getElementById('container')
          
          cube.addEventListener('mouseover', () => container.style.backgroundColor = "blue")
          cube.addEventListener('mouseleave', () => container.style.backgroundColor = "white")
          div {
            outline: 1px solid red;
            width: 200px;
            height: 30px;
          }
          
          #cube {
            background-color: red;
          }
          <main>
            <div id="container">
            </div>
          </main>
          <div id="cube">
          </div>

          【讨论】:

            【解决方案8】:
            #imageDiv:hover ~ #detailDiv
            {
                z-index: -999 !important;
            }
            

            这里

            #imageDiv 是第一个要悬停的 div 和

            #detailDiv 是 CSS 将在悬停时应用的第二个 div

            所以如果我将鼠标悬停在第一个 div 上,那么 zindex 将分配给第二个 div

            为我工作

            【讨论】:

              猜你喜欢
              • 2011-05-29
              • 1970-01-01
              • 1970-01-01
              • 2023-03-21
              • 2013-08-01
              • 2022-12-05
              相关资源
              最近更新 更多