Как стилизовать родительский элемент при зависании дочернего элемента?

Я знаю, что не существует родительский селектор CSS, но возможно ли стиль элемента родительского элемента при наведении дочернего элемента без такого селектора?

Чтобы привести пример: рассмотрим кнопку удаления, которая при наведении указала на элемент, который должен быть удален:

<div>
    <p>Lorem ipsum ...</p>
    <button>Delete</button>
</div>

С помощью чистого CSS, как изменить цвет фона этого раздела, когда мышь над кнопкой?

Ответ 1

Ну, этот вопрос задают много раз раньше, а короткий типичный ответ: это не может быть сделано чистым CSS. Это в названии: Cascading Style Sheets поддерживает только стиль в каскадном направлении, а не вверх.

Но в большинстве случаев, когда этот эффект желателен, как и в данном примере, все еще есть возможность использовать эти каскадные характеристики для достижения желаемого эффекта. Рассмотрим эту псевдо-разметку:

<parent>
    <sibling></sibling>
    <child></child>
</parent>

Хитрость заключается в том, чтобы дать брату тот же размер и позицию, что и родительский, и стиль брака вместо родителя. Это будет выглядеть как родительский стиль!

Теперь, как стиль брата?

Когда ребенок завис, родитель тоже, но брата нет. То же самое касается брата и сестры. Это завершает три возможных пути выбора селектора CSS для стилизации родного брата:

parent sibling { }
parent sibling:hover { }
parent:hover sibling { }

Эти разные пути допускают некоторые приятные возможности. Например, развязка этого трюка на примере в вопросе приводит к этой скрипке:

div {position: relative}
div:hover {background: salmon}
div p:hover {background: white}
div p {padding-bottom: 26px}
div button {position: absolute; bottom: 0}

Style parent image example

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

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

Ответ 2

Я знаю, что это старый вопрос, но мне просто удалось сделать это без псевдо-ребенка (кроме псевдооболочки).

Если вы устанавливаете родительский объект без pointer-events, а затем дочерний элемент div с pointer-events установленными на auto, это работает :)
Обратите внимание, что <img> (например) не работает.
Также не забудьте установить pointer-events на auto для других дочерних элементов, у которых есть собственный прослушиватель событий, иначе они потеряют свою функцию щелчка.

div.parent {  
    pointer-events: none;
}

div.child {
    pointer-events: auto;
}

div.parent:hover {
    background: yellow;
}    
<div class="parent">
  parent - you can hover over here and it won't trigger
  <div class="child">hover over the child instead!</div>
</div>

Ответ 3

нет селектора CSS для выбора родительского элемента выбранного дочернего элемента.

вы можете сделать это с помощью JavaScript

Ответ 4

Другой, более простой подход (к старому вопросу).
было бы разместить элементы как братьев и сестер и использовать:

Селектор соседнего брата (+) или общий селектор брака (~)

<div id="parent">
  <!-- control should come before the target... think "cascading" ! -->
  <button id="control">Hover Me!</button>
  <div id="target">I'm hovered too!</div>
</div>
#parent {
  position: relative;
  height: 100px;
}

/* Move button control to bottom. */
#control {
  position: absolute;
  bottom: 0;
}

#control:hover ~ #target {
  background: red;
}

enter image description here

Демо-скрипка здесь.

Ответ 5

Как уже упоминалось ранее, "нет селектора CSS для выбора родительского элемента выбранного дочернего элемента".

Итак, вы либо:


Ниже приведен пример решения javascript/jQuery

Со стороны javascript:

$('#my-id-selector-00').on('mouseover', function(){
  $(this).parent().addClass('is-hover');
}).on('mouseout', function(){
  $(this).parent().removeClass('is-hover');
})

И на стороне CSS у вас будет что-то вроде этого:

.is-hover {
  background-color: red;
}

Ответ 6

Это решение полностью зависит от дизайна, но если у вас есть родительский div, на который вы хотите изменить фон при наведении на ребенка, вы можете попытаться имитировать родителя с помощью ::after/::before.

<div class="item">
    design <span class="icon-cross">x</span>
</div>

CSS:

.item {
    background: blue;
    border-radius: 10px;
    position: relative;
    z-index: 1;
}
.item span.icon-cross:hover::after {
    background: DodgerBlue;
    border-radius: 10px;
    display: block;
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    content: "";
}

Смотрите полный пример скрипки здесь

Ответ 7

Простое решение jquery для тех, кто не нуждается в чистом решении CSS:

    $(".letter").hover(function() {
      $(this).closest("#word").toggleClass("hovered")
    });
.hovered {
  background-color: lightblue;
}

.letter {
  margin: 20px;
  background: lightgray;
}

.letter:hover {
  background: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="word">
  <div class="letter">T</div>
  <div class="letter">E</div>
  <div class="letter">S</div>
  <div class="letter">T</div>
</div>