Застосовуйте стилі CSS до елемента залежно від його дочірніх елементів


203

Чи можна визначити стиль CSS для елемента, який застосовується лише у тому випадку, якщо відповідний елемент містить конкретний елемент (як прямий дочірній елемент)?

Я думаю, що це найкраще пояснити на прикладі.

Примітка . Я намагаюся стилізувати батьківський елемент , залежно від того, які дочірні елементи він містить.

<style>
  /* note this is invalid syntax. I'm using the non-existing
   ":containing" pseudo-class to show what I want to achieve. */
  div:containing div.a { border: solid 3px red; }
  div:containing div.b { border: solid 3px blue; }
</style>

<!-- the following div should have a red border because
     if contains a div with class="a" -->
<div>
  <div class="a"></div>
</div>

<!-- the following div should have a blue border -->
<div>
  <div class="b"></div>
</div>

Примітка 2 : Я знаю, що я можу досягти цього за допомогою javascript, але мені просто цікаво, чи можливо це за допомогою деяких невідомих (мені) функцій CSS.


1
Можливо, ви хочете оновити питання так, щоб, мовляв, блимаючи жирним текстом, уточнити, що ви намагаєтеся створити стиль розділення PARENT, а не його дітей. Я знаю, що інформація полягає в самому питанні, але якщо ви не хочете отримати точну кількість неправильних відповідей, напевно, варто докласти зусиль.
Сет Петрі-Джонсон

Дякуємо @Seth. Я намагався вдосконалити назву питання та текст. Будь ласка, відредагуйте питання, якщо ви вважаєте, що це все ще незрозуміло.
M4N


Це ідеальний приклад того, чому такий тип підтримки в CSS був би ідеальним: ol < li:nth-child(n+10) { margin-left: 2rem; } ol < li:nth-child(n+100) { margin-left: 3rem; } ol < li:nth-child(n+1000) { margin-left: 4rem; }в ідеальному світі це збільшило б запас olзалежних від кількості liдітей, що містяться, так що поле зліва буде лише таким же широким, як і потрібно було.
Йонмарк Вебер

Відповіді:


124

Наскільки мені відомо, стилізація батьківського елемента на основі дочірнього елемента не є доступною особливістю CSS. Ймовірно, для цього вам знадобляться сценарії.

Було б чудово, якби ви могли зробити щось на кшталт div[div.a]або div:containing[div.a]як ви сказали, але це неможливо.

Ви можете розглянути питання про jQuery . Його селектори дуже добре працюють із типами "містять". Ви можете вибрати div, виходячи з його дочірнього вмісту, а потім застосувати CSS-клас до батьківського в одному рядку.

Якщо ви використовуєте jQuery, щось може працювати (неперевірено, але теорія існує):

$('div:has(div.a)').css('border', '1px solid red');

або

$('div:has(div.a)').addClass('redBorder');

у поєднанні з класом CSS:

.redBorder
{
    border: 1px solid red;
}

Ось документація для селектора jQuery "має" .


15
Побічна примітка: для кращої продуктивності сторінка jQuery doc для :hasселектора радить використовувати .has()метод ( api.jquery.com/has ) => застосований до поточного питання, який він дасть, наприклад$('div').has('div.a').css('border', '1px solid red');
Frosty Z

Для цього потрібно використовувати спостережувача мутації, щоб перевірити, чи дитина змінила його стан ...
Легенди

Це не відповідає справді на питання, яке є "Чи є спосіб це зробити за допомогою CSS". У ній чітко сказано: "Я знаю, що я можу досягти цього за допомогою JavaScript, але я просто задумався, чи можливо це, використовуючи якісь невідомі (мені) функції CSS".
SunshinyDoyle

developer.mozilla.org/en-US/docs/Web/CSS/:має , я думаю, що цей :hasселектор може працювати, але він знаходиться в проекті версії, і жоден браузер його не підтримує.
AliF50

62

В основному, ні. Наступним було б те, що ви хотіли теоретично:

div.a < div { border: solid 3px red; }

На жаль, його не існує.

Існує кілька записів на тему "чому, чорт, ні". Дуже добре виглядає тендітна Шаун Інман:

http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors


34
лише оновлення через 8 років: досі немає підтримки цього методу вибору.
Прем'єр-міністр Краанг

1
Існує робочий проект для цієї функції у вигляді :has()псевдокласу, але ми використаємо її лише в CSS4. На сьогодні (наприкінці 2019 року) JS все ще є єдиним способом досягти цієї функціональності.
zepp.lee

Я вважаю, що це не ввімкне стилі css, для використання селектора все одно знадобиться javascript. Якщо це не змінилося?
Джастін

3
9 років і чи вважають вони цю особливість непотрібною?
Лой Нгуен

1

Зверху на відповідь @ kp:

Я маю справу з цим, і в моєму випадку я повинен показати дочірній елемент і відповідно скорегувати висоту батьківського об'єкта (автоматичний розмір не працює в заголовку завантажувальної програми чомусь не маю часу налагоджувати) .

Але замість того, щоб використовувати javascript для зміни батьків, я думаю, що я буду динамічно додавати клас CSS до батьківського і CSS-вибірково показувати дітям відповідно. Це дозволить підтримувати рішення в логіці, а не на основі стану CSS.

tl; dr; застосуйте стилі aта bстилі до батька <div>, а не до дитини (звичайно, не кожен зможе це зробити, тобто кутові компоненти, що приймають власні рішення).

<style>
  .parent            { height: 50px; }
  .parent div        { display: none; }
  .with-children     { height: 100px; }
  .with-children div { display: block; }
</style>

<div class="parent">
  <div>child</div>
</div>

<script>
  // to show the children
  $('.parent').addClass('with-children');
</script>

0

У моєму випадку мені довелося змінити прошивку комірок елемента, який містив прапорець для введення таблиці, яка динамічно відображається за допомогою даних DataTables:

<td class="dt-center">
    <input class="a" name="constCheck" type="checkbox" checked="">
</td>

Після реалізації наступного коду рядка у функції initComplete я зміг створити правильну підкладку, яка фіксувала відображення рядків з аномально великою висотою

 $('tbody td:has(input.a)').css('padding', '0px');

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

<td class=" dt-center" style="padding: 0px;">
    <input class="a" name="constCheck" type="checkbox" checked="">
</td>

По суті, ця відповідь є розширенням відповіді @ KP, але чим більше співпраця щодо її реалізації, тим краще. Підводячи підсумок, я сподіваюся, що це допомагає комусь іншому, бо це працює! І нарешті, велике спасибі @KP за те, що ви повели мене в правильному напрямку!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.