Применение стилей 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.

M4N
источник
1
Возможно, вы захотите обновить вопрос, указав, возможно, мигающим жирным текстом, что вы пытаетесь стилизовать элемент div PARENT, а не его дочерние элементы. Я знаю, что информация находится в самом вопросе, но если вы не хотите получить массу неправильных ответов, это, вероятно, стоит усилий.
Сет Петри-Джонсон
Спасибо @Seth. Я пытался улучшить заголовок и текст вопроса. Пожалуйста, отредактируйте вопрос, если считаете, что он все еще неясен.
M4N
3
Возможный дубликат Есть ли родительский селектор CSS?
Джеймс Доннелли
Это прекрасный пример того, почему этот тип поддержки в 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 .

KP.
источник
15
Примечание: для повышения производительности на странице документа jQuery для :hasселектора рекомендуется использовать .has()метод ( api.jquery.com/has ) =>, примененный к текущему вопросу, который он даст, например$('div').has('div.a').css('border', '1px solid red');
Frosty Z
Чтобы это работало, нужно было использовать наблюдателя мутаций, чтобы проверить, изменил ли ребенок свое состояние ...
Legends
Это действительно не отвечает на вопрос «Есть ли способ сделать это с помощью 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.

ТЛ; др; применять 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 за то, что вы направили меня в правильном направлении!

миль
источник