- CSS Child Selector: Learn to Select the First, Second and Last Child
- Contents
- What child selectors are
- Creating a combinator
- Selecting the first child elements
- Using CSS to select the second child
- :nth-of-type vs. :nth-child
- Finding the last child
- Descendant selectors
- General Sibling Selectors
- Adjacent sibling selectors
- CSS child selector: useful tips
- CSS :has() селектор
- Вступление
- Проблема
- Знакомство с :has селектором
- Селектор :has не только про родителя
- Поддержка браузерами
- Можем ли мы использовать это внутри @supports?
- Примеры использования CSS :has
- Заголовок раздела
- Latest articles
- Компонент карточки, Пример 1
- Компонент карточки, Пример 2
- Компонент карточки, Пример 3
- Компонент фильтрации
- Показать или скрыть элементы формы по условию
- Элемент навигации с подменю
- Обёртка для шапки
- Акцент на алертах
- Смена темы
- Стилизация сгенерированного HTML
- Кнопка с иконкой
- Несколько кнопок
- Информационные модули
- Изменить сетку в зависимости от количества элементов
- Figure и Figcaption
- Заключение
CSS Child Selector: Learn to Select the First, Second and Last Child
TL;DR – The > symbol creates a CSS child selector used for finding the direct children of elements.
Contents
What child selectors are
To create a CSS child selector, you use two selectors. The child combinator selects elements that match the second selector and are the direct children of the first selector.
Operators make it easier to find elements that you want to style with CSS properties.
Creating a combinator
The CSS child selector has two selectors separated by a > symbol.
- The first selector indicates the parent element.
- The second selector indicates the child element CSS will style.
div > p < background-color: lightblue; >
Selecting the first child elements
The CSS selector using the > symbol only selects direct children. To find the first child, CSS needs to include :first-child .
The following example shows the outcome when we write p:first-child in CSS and select only the first child to style:
div > p:first-child < background-color: lightblue; >
Using CSS to select the second child
You can find a second child that has a specific type and a parent with :nth-of-type(2) .
The example below uses the :nth-of-type(2) selector from CSS to select the second child of :
div > p:nth-of-type(2) < background-color: lightblue; >
Tip: in the brackets of :nth-of-type, you specify which child you want to select.
:nth-of-type vs. :nth-child
The :nth-child() selector is very similar to :nth-of-type() . Here are the main differences:
- :nth-child() selects all specified (for instance, second) children regardless of the type of their parents.
- :nth-of-type() selects the specified children of a specific parent.
- Easy to use with a learn-by-doing approach
- Offers quality content
- Gamified in-browser coding experience
- The price matches the quality
- Suitable for learners ranging from beginner to advanced
- Free certificates of completion
- Focused on data science skills
- Flexible learning timetable
- Simplistic design (no unnecessary information)
- High-quality courses (even the free ones)
- Variety of features
- Nanodegree programs
- Suitable for enterprises
- Paid Certificates of completion
Finding the last child
To style the last child with CSS properties, you need to select it with the :last-child selector.
The following example chooses the last child of the element, which will be styled with the CSS background-color property.
div > p:last-child < background-color: lightblue; >
Note: at first, the elements that the :last-child selected had to have parents. Now, you can select the last child among other siblings.
Descendant selectors
Descendant selectors do not have combinators. Instead, CSS separates these selectors with a white space between them.
The descendant selector finds all descendants of a specified element regardless of their position in the DOM tree.
This example selects all descendants of :
div p < background-color: lightblue; >
General Sibling Selectors
The combinator ~ separates two selectors and selects the second element when it comes after the first element, and both selectors have the same parent.
div ~ p < background-color: lightblue; >
Adjacent sibling selectors
The + combinator separates two selectors and selects the second element when it comes immediately after the first selector, and both share a parent.
div + p < background-color: lightblue; >
CSS child selector: useful tips
- The CSS child combinator selects only direct children and goes only one level down the DOM tree. The descendant selector finds elements that are even three levels deep in the DOM.
- :last-child selector is the same as :nth-last-child(1) .
CSS :has() селектор
Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.
Вступление
Вы когда-нибудь задумывались о селекторе CSS, где вы проверяете, существует ли конкретный элемент внутри родителя? Например, если у компонента карточки есть миниатюра, нам нужно добавить к нему display: flex. Это было невозможно в CSS, но теперь у нас будет новый селектор CSS :has, который поможет нам выбрать родителя определенного элемента и многое другое.
В этой статье я объясню проблему, которую решает :has, как он работает, где и как мы можем его использовать с некоторыми вариантами использования и примерами, и, самое главное, как мы можем использовать его уже сегодня.
Проблема
Возможность стилизовать родительский элемент отсутствует. Мы должны создавать классы CSS и переключать их в зависимости от того, что нам нужно.
Рассмотрим следующий базовый пример.
У нас есть компонент карточки в двух вариациях: 1) С изображением 2) Без изображения. В CSS мы могли бы сделать что-то вроде этого:
/* A card with an image */ .card < display: flex; align-items: center; gap: 1rem; >/* A card without an image */ .card--plain
Как вы видели выше, мы создали класс специально для карточки без изображения, поскольку нам не нужен display: flex на родительском элементе. Вопрос в том, можем ли мы это сделать в CSS, без второго класса?
Ну, вот где CSS :has приходит на помощь. Это может помочь нам проверить, есть ли у элемента .card изображение .card__image или нет.
Например, мы можем проверить, есть ли у карточки изображение, и если да, то нам нужно применить flexbox.
Знакомство с :has селектором
Согласно спецификации CSS, селектор :has проверяет, содержит ли родитель хотя бы один конкретный элемент или выполняется ли условие, например, если инпут сфокусирован.
Вернемся к предыдущему фрагменту кода.
Мы проверяем, содержит ли родительский элемент .card дочерний элемент .card__image . Рассмотрим следующий рисунок:
Проще говоря, приведенный выше CSS эквивалентен следующему: «Есть ли в карточке элемент .card__image ?»
Разве это не восхитительно? В CSS есть логика!
Селектор :has не только про родителя
Речь идет не только о проверке того, содержит ли родитель дочерний элемент, но мы также можем проверить, следует ли за элементом, например,
. Рассмотрим следующее:
Это проверяет, следует ли непосредственно за
. Или мы можем использовать его с элементом формы, например, чтобы проверить, есть ли сфокусированный инпут.
Поддержка браузерами
На момент написания статьи CSS :has работал в Safari 15.4 и в Chrome Canary. Следите за поддержкой на Can I use.
Можем ли мы использовать это внутри @supports?
Хватит теории, давайте перейдем к примерам использования!
Примеры использования CSS :has
Заголовок раздела
Когда я работаю над заголовком раздела, у меня в основном будет два варианта: один только с заголовком, а другой содержит и заголовок, и якорную ссылку.
В зависимости от того, есть ли ссылка или нет, я хочу оформить его по-разному.
Latest articles
.section-header < display: flex; justify-content: space-between; >/* If there is a link, add the following */ .section-header:has(> a)
Компонент карточки, Пример 1
Вернемся немного назад к примеру с исходной картой. У нас есть два варианта, один с изображением, а другой без него.
Мы даже можем проверить, нет ли на .card изображения, и применить определенные стили. В нашем случае это border-top .
Без :has нам пришлось бы иметь два класса, чтобы сделать это.
Компонент карточки, Пример 2
В этом примере у нас есть два варианта набора действий у каждой карточки: одна карточка с одним элементом (ссылка), а другая с несколькими действиями (сохранить, поделиться и т. д.).
Когда действия карточки имеют две разные обёртки для действий, мы хотим активировать display: flex следующим образом (пожалуйста, не обращайте внимания на приведенную ниже разметку, она предназначена исключительно для демонстрационных целей!).
.card__actions:has(.start, .end)
Вот что нам придётся делать без :has.
.card--with-actions .card__actions
Компонент карточки, Пример 3
Вам когда-нибудь приходилось сбрасывать border-radius для компонента в зависимости от того, есть ли изображение или нет? Это идеальное использование CSS :has.
Рассмотрим следующий рисунок. Когда изображение удалено, border-radius верхнего левого и правого углов равен нулю, что выглядит странно.
.card:not(:has(img)) .card__content < border-top-left-radius: 12px; border-top-right-radius: 12px; >.card img < border-top-left-radius: 12px; border-top-right-radius: 12px; >.card__content
Вот что нам придётся написать без использования :has.
Компонент фильтрации
В этом примере у нас есть компонент с несколькими параметрами. Когда ни один из них не отмечен, кнопки сброса нет. Однако, когда хотя бы один отмечен, нам нужно показать кнопку сброса.
Мы можем легко сделать это с помощью CSS :has.
.btn-reset < display: none; >.multiselect:has(input:checked) .btn-reset
Мы вообще не можем сделать это в CSS без :has. Это один из сценариев, когда мы откажемся от Javascript, если :has будет поддерживаться в современных браузерах.
Показать или скрыть элементы формы по условию
Возможно, нам потребуется показать конкретное поле формы на основе предыдущего ответа или выбора. В этом примере нам нужно показать поле «other», если пользователь выбрал «other» в меню выбора.
С помощью CSS :has мы можем проверить, выбрано ли в меню значение «other», и показать поле «other» на основе этого.
.other-field < display: block; >form:has(option[value="other"]:checked) .other-field
Разве это не восхитительно? Нам не нужно беспокоиться об исходном порядке HTML, если поле выбора и формы находится внутри родительского элемента .box .
Элемент навигации с подменю
В этом примере у нас есть элемент навигации с подменю, которое появляется при наведении или фокусе.
Обёртка для шапки
При создании компонента заголовка мы можем быть уверены в том, хотим ли мы, чтобы заголовок занимал всю ширину страницы или был в обёртке.
В любом случае нам нужно применить flexbox для распределения элементов заголовка определенным образом. Если .wrapper есть, мы применим к нему стили. Если нет, то применим их непосредственно к элементу .site-header .
.site-header:not(:has(.wrapper)) < display: flex; justify-content: space-between; align-items: center; padding-inline: 1rem; >/* If it has a wrapper */ .site-header .wrapper
Акцент на алертах
На некоторых панелях мониторинга может быть важное предупреждение, о котором должен знать пользователь. В этом случае оповещения на странице может быть недостаточно. В таком случае мы могли бы, например, добавить красную рамку и приглушенный красный цвет фона к элементу заголовка.
Это повысит вероятность того, что пользователь быстро заметит предупреждение.
С помощью CSS :has мы можем проверить, есть ли предупреждение в элементе .main , и если да, мы можем добавить следующие стили в заголовок.
Смена темы
Мы можем использовать CSS :has для изменения цветовой схемы веб-сайта. Например, если у нас есть несколько тем, созданных с помощью переменных CSS, мы можем изменить их через
И когда мы выбираем другой вариант из списка, вот что происходит в CSS. В зависимости от выбранной опции переменные CSS будут изменены.
html:has(option[value="blueish"]:checked)
Стилизация сгенерированного HTML
В некоторых случаях у нас нет никакого контроля над HTML. Например, в теле статьи. Система управления контентом (CMS) может генерировать элементы неожиданным образом, или автор может встроить видео или что-то в этом роде.
Предположим, что мы хотим выбрать тот , за которым не следует абзац, и увеличить интервал под ним.
Или вам нужно выбрать , за которым следует и что-то сделать. Такие ситуации не могут быть обработаны без CSS :has!
Кнопка с иконкой
В этом примере у нас есть стиль кнопки по умолчанию. Когда у нас есть иконка, мы хотим использовать flexbox для центрирования и выравнивания содержимого кнопки.
Несколько кнопок
В дизайн-системе нам часто требуется группа кнопок. Если у нас есть более двух кнопок, последняя должна отображаться на дальней противоположной стороне.
Для этого мы можем использовать количественные запросы. Следующий CSS проверит, равно ли количество кнопок трём или больше, и если да, последний элемент будет сдвинут вправо с помощью margin-left: auto .
.btn-group < display: flex; align-items: center; gap: 0.5rem; >.btn-group:has(.button:nth-last-child(n + 3)) .button:last-child
Информационные модули
Я получил этот пример из дизайна pinterest. Когда инпут имеет ошибку, мы хотим, чтобы заголовок изменился и указывал на это.
.module:has(.input-error) .headline
Изменить сетку в зависимости от количества элементов
С сеткой CSS мы можем использовать функцию minmax() для создания отзывчивых элементов сетки с автоматическим размером. Однако этого может быть недостаточно. Мы также хотим изменить сетку в зависимости от количества элементов.
Рассмотрим следующий рисунок.
Когда у нас будет 5 элементов, последний будет перенесен в новую строку.
Мы можем преодолеть это, проверив, содержит ли .wrapper 5 или более элементов. Опять же, здесь используется концепция количественных запросов.
.wrapper:has(.item:nth-last-child(n + 5))
Figure и Figcaption
В этом примере у нас есть HTML . Если есть стиль должен немного отличаться:
Заключение
Мне не терпится увидеть, что вы создадите с помощью CSS :has. Сценарии использования в этой статье — лишь малая часть! Я уверен, что мы обнаружим много полезных применений по пути.
Как говорится, самое подходящее время для изучения CSS. Я очень, очень взволнован тем, что будет дальше. Большое спасибо за чтение!