Як стилізувати батьківський елемент при наведенні на нього дочірнього елемента?


160

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

Щоб навести приклад: розгляньте кнопку видалення, яка при наклеюванні виділить елемент, який збирається видалити:

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

Як за допомогою чистого CSS, як змінити колір тла цього розділу, коли миша знаходиться над кнопкою?


3
Можливий дублікат Чи існує селектор вибору CSS?
TylerH

Відповіді:


134

Ну, це питання задавали багато разів раніше, і коротка типова відповідь така: Це не може зробити чистий CSS. Це в назві: Каскадні таблиці стилів підтримують лише стилі в каскадному напрямку, а не вгору.

Але в більшості обставин, коли бажається цього ефекту, як у наведеному прикладі, все ж є можливість використовувати ці каскадні характеристики для досягнення бажаного ефекту. Розглянемо цю псевдорозмітку:

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

Приклад батьківського образу стилю

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

Іноді для вибору конкретного елемента доводиться використовувати більш кваліфікований шлях вибору, як показано в цій скрипці, яка реалізує трюк кілька разів у меню дерева. Дуже приємно насправді.


1
Це добре для підсвічування, але не вийде, якщо ви спробуєте змінити колір шрифту, я прав?
Джаханзеб Хан

1
@JahanzebKhan Зміна кольору шрифту - це не проблема .
NGLN

116

Я знаю, що це давнє запитання, але мені просто вдалося це зробити без дитини-псевдо (але псевдо обгортки).

Якщо встановити батько не бути з не 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>

Редагувати:
Як ласкаво зазначив майстер Shadow Wizard : варто згадати, що це не буде працювати для IE10 та нижче. (Старі версії FF та Chrome також дивіться тут )


3
Варто зазначити, що це не спрацює для IE10 та нижче. (Старі версії FF та Chrome теж дивіться тут )
Shadow Wizard is Ear for You

2
Якщо встановити події покажчика ні на одному, це також означає, що слухачі подій на цьому елементі не працюватимуть ..!
Разен

1
@rhazen ви абсолютно праві. Хоча з мого досвіду це використання зазвичай пов'язане з областю / елементом одного клацання, тому ви можете призначити слухача кліків батьків
guy_m

Як щодо того, якщо у мене дворівневий, батько, дитина1 та дитина дитини1. Я додав покажчик-події жоден до батьківського та покажчика-події автоматично для дитини. Я хочу навести на дитину1, крім дитини дитини 1. Демо тут: codepen.io/lion5893/pen/WNQgyVx
Nam Lê Quý

13

Іншим, більш простим підходом (до старого питання) ..
було б розмістити елементи як братів і сестер і використовувати:

Суміжний вибір сестри ( +) або загальний вибір сестри ( ~)

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

введіть тут опис зображення

Демо скрипка тут .


1
Варто зауважити, що це працює тільки #targets з'являється після #control у DOM (тобто ви не можете впливати на попередні брати та сестри, лише наступні брати і сестри)
Gio

10

не існує селектора CSS для вибору батька вибраної дитини.

ви можете зробити це за допомогою JavaScript


3
правда. щось на зразок $ (child) .hover (function () {$ (this) .closest (parentSelector) .addClass ('hoverClass')}, function () {$ (this) .closest (parentSelector) .removeClass ('hoverClass') )});
Аамір Афріді

8
@AamirAfridi Це не є чистим JS, з цим вам доведеться використовувати jQuery.
Ivotje50

6

Як вже було сказано раніше, "немає 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;
}

3

Це рішення повністю залежить від дизайну, але якщо у вас є батьківський дів, на який ви хочете змінити тло під час зависання дитини, ви можете спробувати наслідувати батька з ::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: "";
}

Дивіться повний приклад скрипки тут


-1

Просте рішення 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>


-8

Це надзвичайно просто зробити в Сассі! Для цього не заглиблюйтесь у JavaScript. Селектор & & sass робить саме це.

http://thesassway.com/intermediate/referencing-parent-selectors-using-ampersand


6
-1 Sass не додає більше функціональних можливостей css, це просто полегшує написання. Все, що ви можете зробити в sass, можна зробити у форматі css та visverse.
Дастур

3
@Dastur Враховуючи змінні та міксини, я б сказав, що Sass додає дуже багато до CSS. Ви можете зробити все це в CSS, так само як і раніше можете писати складне програмне забезпечення, використовуючи звичайний старий С. Сучасні мови додають багато, не вмикаючи те, що раніше не можна було зробити. Те саме з Sass та CSS.
Кобус Крюгер

6
@Cobus Kruger Ви частково маєте рацію, але порівняння ви не можете зробити. Оскільки такі мови, як c ++ c # і javascript, можуть бути відключені від C, вони не перетворюються на C до часу виконання. Sass перетворюється в css перед початком виконання, тому ваш ніколи не завантажує справді таблицю стилів Sass, а лише css.
Дастур
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.