Может ли CSS определить количество дочерних элементов?


304

Я, наверное, отвечаю на свой вопрос, но мне очень любопытно.

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

например

container:children(8) {
  // style the parent this way if there are 8 children
}

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


2
Количество Запрос SCSS Mixin
Якоб Э

Ответы:


695

Разъяснение:

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


Оригинальный ответ:

Невероятно, но теперь это возможно только в CSS3.

/* one item */
li:first-child:nth-last-child(1) {
/* -or- li:only-child { */
    width: 100%;
}

/* two items */
li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li {
    width: 50%;
}

/* three items */
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33.3333%;
}

/* four items */
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {
    width: 25%;
}

Хитрость заключается в том, чтобы выбрать первого ребенка, когда он также является последним дочерним элементом. Это эффективно выбирает в зависимости от количества братьев и сестер.

Кредит на эту технику достается Андре Луису (открыто) и Леа Веру (изысканно).

Разве вы не просто любите CSS3? 😄

Пример CodePen:

Источники:


7
Очень кстати. Я написал миксин SASS, который использует эту технику: codepen.io/anon/pen/pJeLdE?editors=110
SimpleJ

1
@IanSteffy Я только что проверил это на Chrome 45.0.2454.85 (64-разрядная версия), и он отлично работает…?
Математика

2
Если это работает в Codepen, но не с моим проектом, то это, безусловно, моя вина. Виноват. Этот ответ правильный! Правильно говорю!
Ян С

3
Было бы неплохо добавить, почему это работает, для людей, не привыкших к нескольким псевдо-селекторам (как я был до сих пор;). Здесь происходит следующее: выбирается дочерний элемент, являющийся одновременно дочерним элементом x из начала / вершины и дочерним элементом y из конца. И поэтому он выбирает что-то, только если есть ровно x + y детей.
Леголас

7
Обратите внимание, что вместо :first-child:nth-last-child(1)вас также можно использовать :only-child.
Адам Рейс

40

Нет, не совсем. Есть пара селекторов, которые могут немного приблизить вас, но, вероятно, не сработают в вашем примере и не имеют лучшей совместимости с браузером.

:only-child

Это :only-childодин из немногих селекторов с истинным счетом в том смысле, что он применяется только тогда, когда есть один дочерний элемент родительского элемента. Используя ваш идеализированный пример, он действует как, children(1)вероятно, будет.

:nth-child

:nth-childСелектор может реально получить , где вы хотите пойти в зависимости от того, что вы действительно хотите сделать. Если вы хотите стилизовать все элементы, если есть 8 детей, вам не повезло. Однако, если вы хотите применить стили к 8-му и более поздним элементам, попробуйте это:

p:nth-child( n + 8 ){
    /* add styles to make it pretty */
}

К сожалению, это, вероятно, не те решения, которые вы ищете. В конце концов, вам, вероятно, потребуется использовать некоторые Javascript Wizardry для применения стилей, основанных на количестве - даже если бы вы использовали один из них, вам нужно было бы внимательно взглянуть на совместимость браузера, прежде чем переходить с чистого CSS решение.

W3 CSS3 Spec по псевдоклассам

РЕДАКТИРОВАТЬ Я читаю ваш вопрос немного по-другому - есть пара других способов стилизации родителей , а не детей. Позвольте мне добавить несколько других селекторов по-вашему:

:empty и :not

Это стили элементов, которые не имеют детей. Не очень полезно само по себе, но в сочетании с :notселектором вы можете стилизовать только те элементы, которые имеют дочерние элементы:

div:not(:empty) {
    /* We know it has stuff in it! */
}

Вы не можете сосчитать, сколько детей доступно с чистым CSS, но это еще один интересный селектор, который позволяет вам делать классные вещи.


Стоит отметить, что первоначальный вопрос был отредактирован, в результате чего первоначальное «Нет» немного вводило в заблуждение (просто так 😛)
Matthemattics

18

ПРИМЕЧАНИЕ. Это решение возвращает дочерние элементы наборов определенной длины, а не родительский элемент, как вы просили. Надеюсь, это все еще полезно.

Андре Луис разработал метод: http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/ К сожалению, он работает только в IE9 и выше.

По сути, вы комбинируете: nth-child () с другими псевдоклассами, которые имеют дело с позицией элемента. Этот подход позволяет указывать элементы из наборов элементов с определенной длиной .

Например, :nth-child(1):nth-last-child(3)соответствует первый элемент в наборе, а также является третьим элементом от конца набора. Это делает две вещи: гарантирует, что набор имеет только три элемента и что у нас есть первый из трех. Чтобы указать второй элемент из набора из трех элементов, мы будем использовать :nth-child(2):nth-last-child(2).


Пример 1. Выберите все элементы списка, если set имеет три элемента:

li:nth-child(1):nth-last-child(3),
li:nth-child(2):nth-last-child(2),
li:nth-child(3):nth-last-child(1) {
    width: 33.3333%;
}

Пример 1 альтернативы от Lea Verou:

li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33.3333%;
}


Пример 2 - целевой последний элемент множества с тремя элементами списка:

li:nth-child(3):last-child {
    /* I'm the last of three */
}

Пример 2 варианта:

li:nth-child(3):nth-last-child(1) {
    /* I'm the last of three */
}


Пример 3 - целевой второй элемент множества с четырьмя элементами списка:

li:nth-child(2):nth-last-child(3) {
    /* I'm the second of four */
}

1
опять же, это число братьев и сестер, а не детей
TMS

@TMS см. Редактирование принятого ответа - вопрос ОП был неуклюже сформулирован
ифугу

Этот подход идеально подходит для случаев, когда каждый элемент должен быть оформлен по-разному в зависимости от его положения в списке, например, чтобы получить даже круговые преобразования: li:nth-child(3):nth-last-child(1) { transform: rotate(120deg); } li:nth-child(2):nth-last-child(2) { transform: rotate(240deg); }и так далее ...
Грег Смит

11

Отрабатывая решение Мэтта, я использовал следующую реализацию Compass / SCSS.

@for $i from 1 through 20 {
    li:first-child:nth-last-child( #{$i} ),
    li:first-child:nth-last-child( #{$i} ) ~ li {
      width: calc(100% / #{$i} - 10px);
    }
  }

Это позволяет быстро расширить количество предметов.


4
Вместо этого вы могли бы легко использовать Flexbox ...
Михал Мишшишин

6

да, мы можем сделать это с помощью nth-child, как так

div:nth-child(n + 8) {
    background: red;
}

Это заставит восьмого ребенка в возрасте становиться красным. Надеюсь это поможет...

Кроме того, если кто-то скажет: «эй, они не могут быть выполнены в стиле css, используйте JS !!!» Сомневайся в них немедленно. CSS чрезвычайно гибок в наше время

Пример :: http://jsfiddle.net/uWrLE/1/

В примере первые 7 детей - синие, затем 8 лет - красные ...


1
Возможно, добавить примечание о неудачном отсутствии поддержки ?
Бенеш

2
Я не думаю, что это именно то, о чем спрашивает Броди - это будет стилизовать дочерние элементы после заданной суммы, но не может выбрать элемент-предок / содержащий элемент в зависимости от количества его дочерних элементов.
Бен Халл

Это на самом деле довольно хорошая информация, хотя, спасибо, Алан, но Би прав, я пытался сказать, «если у элемента много детей, этот стиль». Если я не ошибаюсь, ваш метод будет стилизовать 8-й дочерний элемент, но Первые 7 будут одиноки и обнажены.
Броди

@primatology - единственный браузер, который не поддерживает nth-child, это IE <9. Все остальные поддерживают его две версии назад или более.
Роб

-1 Это не сделает div child красным, это сделает div red красным на основе его числа в его братьях и сестрах ! Никоим образом не связан с ребенком div!
TMS

5

Если вы собираетесь делать это в чистом CSS (используя scss), но у вас есть разные элементы / классы внутри одного родительского класса, вы можете использовать эту версию !!

  &:first-of-type:nth-last-of-type(1) {
    max-width: 100%;
  }

  @for $i from 2 through 10 {
    &:first-of-type:nth-last-of-type(#{$i}),
    &:first-of-type:nth-last-of-type(#{$i}) ~ & {
      max-width: (100% / #{$i});
    }
  }

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.