Как повлиять на другие элементы при наведении div - PullRequest
376 голосов
/ 21 декабря 2010

Я думаю, что это очень простой вопрос, но я не уверен, как это можно сделать.

То, что я хочу сделать, - это когда определенный div зависает, это повлияет на свойствадругого div.

Например, в этом простом примере , когда вы наводите курсор мыши на #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>

Ответы [ 6 ]

816 голосов
/ 21 декабря 2010

Если куб находится непосредственно внутри контейнера:

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

Если куб находится рядом с (после закрывающего тега контейнера) контейнера:

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

Если куб находится где-то внутриконтейнер:

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

Если куб является родственником контейнера:

#container:hover ~ #cube { background-color: yellow; }
36 голосов
/ 21 декабря 2010

В этом конкретном примере вы можете использовать:

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

Это работает только потому, что cube является потомком container.Для более сложных сценариев вам нужно использовать JavaScript.

26 голосов
/ 09 сентября 2015

Использование родственного селектора является общим решением для стилизации других элементов при наведении курсора на заданный элемент, , но , он работает , только если другие элементы следуют заданному элементу в DOM .Что мы можем сделать, когда другие элементы должны быть на самом деле раньше наведенного?Скажем, мы хотим реализовать виджет рейтинга сигнальной полосы, как показано ниже:

Signal bar rating widget

Это на самом деле можно легко сделать с помощью модели flexbox CSS, установивflex-direction до reverse, так что элементы отображаются в порядке, противоположном тому, в котором они находятся в DOM.Снимок экрана выше взят из такого виджета, реализованного с использованием чистого CSS.

Flexbox очень хорошо поддерживается 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>
6 голосов
/ 10 мая 2013

Большое спасибо Майку и Роберту за их полезные посты!

Если у вас есть два элемента в вашем HTML, и вы хотите :hover над одним и нацелить изменение стиля в другом, эти два элемента должны бытьнапрямую связаны - родители, дети или братья и сестры.Это означает, что два элемента либо должны быть один внутри другого, либо оба должны содержаться в одном и том же элементе большего размера.

Я хотел отобразить определения в поле справа от браузера, когда мои пользователи читали мой сайт и :hover поверх выделенных терминов;поэтому я не хотел, чтобы элемент 'definition' отображался внутри элемента 'text'.

Я почти сдался и просто добавил javascript на свою страницу, но это будущее, черт возьми!Нам не нужно мириться с тем, что back sass из CSS и HTML говорит нам, где мы должны разместить наши элементы для достижения желаемого эффекта!В итоге мы скомпрометировали.

Хотя фактические элементы 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;
}

В этом примере цель команды :hover для элемента в пределах #explainBox должна быть либо #explainBox, либо также в пределах #explainBox.Атрибуты позиции, назначенные #definitions, заставляют его появляться в нужном месте (за пределами #explainBox), даже если он технически расположен в нежелательной позиции в документе HTML.

Я понимаю, что это считается плохой формойиспользуйте один и тот же #id для более чем одного HTML-элемента;однако в этом случае экземпляры #light могут быть описаны независимо из-за их соответствующих позиций в уникально #id 'd элементах.Есть ли причина не повторять id #light в этом случае?

5 голосов
/ 15 сентября 2015

Только у меня это сработало:

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

Где .cube CssClass класса #cube.

Протестировано в Firefox , Chrome и Край .

0 голосов
/ 03 июня 2018

Вот еще одна идея, которая позволяет вам влиять на другие элементы, не принимая во внимание какой-либо конкретный селектор и используя только состояние :hover основного элемента.

Для этого я буду полагаться на использование пользовательских свойств (переменных CSS).Как мы можем прочитать в спецификации :

Пользовательские свойства обычные свойства , поэтому они могут быть объявлены для любого элемента, разрешаются с помощьюнормальное наследование и каскад правила ...

Идея состоит в том, чтобы определить пользовательские свойства в основном элементе и использовать их для стилизации дочернего элемента.элементы и поскольку эти свойства наследуются, нам просто нужно изменить их в главном элементе при наведении.

Вот пример:

#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. Пользовательское свойство может использоваться для замены значения любого свойства, а также его частичного значения.Например, мы можем определить пользовательское свойство для цвета и использовать его в border, linear-gradient, background-color, box-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 , чтобы изменить много свойств различных элементов.

...