Новые селекторы CSS (is(), where(), has())

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

Тренажер CSS

Этот набор упражнений посвящен новым мощным селекторам CSS: `:is()`, `:where()` и `:has()`. Селектор `:is()` позволяет сократить запись, объединяя несколько селекторов в один, не увеличивая специфичность так сильно, как список селекторов. Селектор `:where()` работает похоже на `:is()`, но имеет нулевую специфичность, что делает его идеальным для создания базовых стилей, которые легко переопределить. Селектор `:has()`, часто называемый 'родительским селектором', позволяет стилизовать элемент на основе его дочерних элементов или последующих соседних элементов. Эти упражнения помогут вам на практике освоить синтаксис и возможности данных селекторов, решая задачи от простых до более сложных.

Список тем

Группировка заголовков с :is()

Вам предоставлен HTML-код с различными заголовками внутри статьи. Ваша задача - используя селектор `:is()`, применить стиль подчеркивания ко всем заголовкам `h2` и `h3` внутри элемента с классом `content-area`. Это позволит сделать код CSS короче и читаемее.

CSS
.content-area input1(h2, h3) {
  text-decoration: underline;
}
HTML
<article class="content-area">
  <h1>Главный заголовок</h1>
  <p>Какой-то текст...</p>
  <h2>Подзаголовок 1</h2>
  <p>Еще текст...</p>
  <h3>Под-подзаголовок</h3>
  <p>Текст...</p>
  <h2>Подзаголовок 2</h2>
</article>
<aside>
  <h2>Заголовок вне статьи</h2>
</aside>
Используйте селектор `:is()` для перечисления нужных тегов (`h2`, `h3`) внутри него. Затем примените этот селектор к элементам внутри `.content-area`. Примерная структура: `.content-area :is(selector1, selector2) { ... }`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация ссылок с нулевой специфичностью (:where())

Необходимо задать базовый синий цвет для всех ссылок (`a`) внутри шапки (`header`) и подвала (`footer`), но сделать это так, чтобы специфичность этого правила была нулевой. Это позволит легко переопределять цвет ссылок другими, более специфичными правилами. Используйте селектор `:where()`.

CSS
input1(header, footer) a {
  color: blue;
}

/* Это правило должно легко переопределить цвет */
footer a {
  color: gray;
}
HTML
<header>
  <nav>
    <a href="#">Главная</a>
    <a href="#">Контакты</a>
  </nav>
</header>
<main>
  <a href="#">Ссылка в основном контенте</a>
</main>
<footer>
  <a href="#">Политика</a>
  <a href="#">О нас</a>
</footer>
Псевдокласс `:where()` принимает список селекторов так же, как `:is()`, но обнуляет их специфичность. Вам нужно выбрать `header` и `footer` с помощью `:where()` и затем указать, что стилизуете ссылки `a` внутри них. Структура: `:where(selector1, selector2) a { ... }`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация при наведении или фокусе с :is()

Сделайте так, чтобы кнопки (`button`) и ссылки с классом `.button-like` меняли цвет фона на светло-серый (`lightgray`) при наведении курсора (`:hover`) или получении фокуса (`:focus`). Используйте `:is()` для группировки псевдоклассов.

CSS
:is(button, .button-like)input1(:hover, :focus) {
  background-color: lightgray;
  outline: none; /* Убираем стандартный контур фокуса для наглядности */
}

button, .button-like {
  display: inline-block;
  padding: 10px 15px;
  margin: 5px;
  border: 1px solid #ccc;
  background-color: #eee;
  text-decoration: none;
  color: black;
  cursor: pointer;
}
HTML
<button>Кнопка 1</button>
<a href="#" class="button-like">Ссылка-кнопка</a>
<button>Кнопка 2</button>
Селектор `:is()` можно использовать не только для тегов или классов, но и для псевдоклассов. Сначала выберите элементы (`button`, `.button-like`), а затем добавьте `:is()` с псевдоклассами `:hover` и `:focus` внутри. Структура: `selector1:is(pseudo1, pseudo2), selector2:is(pseudo1, pseudo2) { ... }` или более кратко: `:is(selector1, selector2):is(pseudo1, pseudo2) { ... }`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Разница специфичности :is() и :where()

В коде задан стиль для ссылок внутри `aside` с использованием `:where()`. Ниже добавлено правило, которое стилизует *все* ссылки (`a`) на странице. Ваша задача - изменить первое правило, заменив `:where()` на `:is()`, чтобы оно стало более специфичным и переопределило стиль для ссылок в `aside`, сделав их красными.

CSS
/* Измените эту строку */
input1(aside) a {
  color: red;
}

/* Это правило имеет специфичность (0,0,1) */
a {
  color: blue;
  display: block;
  margin-bottom: 10px;
}
HTML
<main>
  <a href="#">Основная ссылка</a>
</main>
<aside>
  <a href="#">Ссылка в боковой панели</a>
</aside>
Замените `:where(aside)` на `:is(aside)`. Поскольку `:is()` принимает специфичность самого специфичного селектора в списке (в данном случае `aside`), правило станет более специфичным, чем простое правило для `a`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация родителя, содержащего изображение (:has())

Используя селектор `:has()`, добавьте рамку (`border`) толщиной 2px сплошного черного цвета (`solid black`) ко всем элементам `div` с классом `card`, которые содержат внутри себя изображение (`img`).

CSS
div.cardinput1(img) {
  border: 2px solid black;
}

.card {
  padding: 15px;
  margin-bottom: 10px;
  background-color: #f0f0f0;
}
HTML
<div class="card">
  <p>Карточка с текстом</p>
</div>
<div class="card">
  <img src="https://naytikurs.ru/img/1.png" alt="Image 1" width="100">
  <p>Карточка с изображением</p>
</div>
<div class="card">
  <p>Еще одна карточка с текстом</p>
</div>
Псевдокласс `:has()` позволяет выбрать элемент на основе его содержимого. Используйте селектор `.card` и добавьте к нему `:has(img)`. Структура: `selector:has(inner_selector) { ... }`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Выбор элемента с конкретным прямым потомком (:has())

Необходимо стилизовать элемент `figure`, добавив ему серый фон (`background-color: lightgray;`), но только в том случае, если он *непосредственно* содержит элемент `figcaption`. Используйте комбинатор прямого потомка (`>`) внутри `:has()`.

CSS
figureinput1(> figcaption) {
  background-color: lightgray;
  padding: 10px;
}

figure {
  margin: 10px 0;
  border: 1px dashed #ccc;
  display: inline-block; /* Для наглядности */
}

figcaption {
  text-align: center;
  font-style: italic;
}
HTML
<figure>
  <img src="https://naytikurs.ru/img/2.png" alt="Image 2" width="150">
  <figcaption>Подпись к изображению</figcaption>
</figure>

<figure>
  <img src="https://naytikurs.ru/img/4.png" alt="Image 4" width="150">
  <div><figcaption>Подпись внутри div</figcaption></div>
</figure>

<figure>
   <img src="https://naytikurs.ru/img/5.png" alt="Image 5" width="150">
</figure>
Внутри псевдокласса `:has()` можно использовать комбинаторы. Чтобы выбрать `figure`, который имеет `figcaption` как прямого потомка, используйте `:has(> figcaption)`. Структура: `figure:has(> figcaption) { ... }`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация формы с несколькими условиями (:has())

Добавьте зеленую рамку (`border: 2px solid green;`) форме (`form`), но только если она содержит *одновременно* и поле для ввода email (`input[type="email"]`) и поле для ввода пароля (`input[type="password"]`). Используйте `:has()` с несколькими селекторами.

CSS
forminput1(input[type="email"])input2(input[type="password"]) {
  border: 2px solid green;
  padding: 15px;
}

form {
  margin-bottom: 15px;
  border: 1px solid #ccc;
  padding: 10px;
}
label {
  display: inline-block;
  margin-bottom: 5px;
}
HTML
<form id="form1">
  <label>Email: <input type="email"></label><br>
  <label>Имя: <input type="text"></label><br>
  <button type="submit">Отправить</button>
</form>

<form id="form2">
  <label>Email: <input type="email"></label><br>
  <label>Пароль: <input type="password"></label><br>
  <button type="submit">Войти</button>
</form>

<form id="form3">
  <label>Пароль: <input type="password"></label><br>
  <button type="submit">Ок</button>
</form>
Псевдокласс `:has()` можно использовать несколько раз или комбинировать селекторы внутри одного `:has()`. Чтобы проверить наличие обоих полей, можно использовать структуру `form:has(input[type="email"]):has(input[type="password"]) { ... }`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Комбинация :is() и :has() для списков

Сделайте так, чтобы пункты списка (`li`) внутри нумерованных (`ol`) или ненумерованных (`ul`) списков выделялись жирным шрифтом (`font-weight: bold;`), но только если пункт списка (`li`) содержит ссылку (`a`). Используйте комбинацию `:is()` и `:has()`.

CSS
input1(ol, ul) liinput2(a) {
  font-weight: bold;
}

li {
  margin-bottom: 5px;
}
HTML
<ul>
  <li>Простой пункт</li>
  <li><a href="#">Пункт со ссылкой</a></li>
</ul>

<ol>
  <li><a href="#">Нумерованный пункт со ссылкой</a></li>
  <li>Еще один простой пункт</li>
</ol>

<div>
  <li>Пункт вне списка</li>
</div>
Сначала выберите родительские списки с помощью `:is(ol, ul)`. Затем выберите дочерние `li`. К селектору `li` добавьте `:has(a)`, чтобы выбрать только те пункты, которые содержат ссылку. Структура: `:is(ol, ul) li:has(a) { ... }`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация секций без заголовков (:where() и :has())

Примените светло-серый фон (`background-color: #f5f5f5;`) ко всем элементам `<section>`, которые *не* содержат ни заголовок `<h2>`, ни заголовок `<h3>`. Используйте `:where()` для группировки заголовков внутри `:has()`, чтобы не увеличивать специфичность, и псевдокласс `:not()` для инвертирования условия.

CSS
section:not(input1(input2(h2, h3))) {
  background-color: #f5f5f5;
  padding: 10px;
}

section {
  border: 1px solid #ccc;
  margin-bottom: 10px;
  padding: 5px;
}
HTML
<section>
  <h2>Секция с H2</h2>
  <p>Текст...</p>
</section>
<section>
  <h3>Секция с H3</h3>
  <p>Текст...</p>
</section>
<section>
  <p>Секция без заголовка.</p>
  <p>Нужно применить фон.</p>
</section>
<section>
  <h4>Секция с H4</h4>
  <p>Текст...</p>
</section>
Нужно выбрать `section`, который НЕ `:not()` содержит `:has()` ни `h2`, ни `h3`. Группировку `h2, h3` лучше сделать с помощью `:where(h2, h3)`, чтобы селектор `:has()` не получил излишнюю специфичность от заголовков. Структура: `section:not(:has(:where(h2, h3))) { ... }`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Сложное условие с :has() для карточек

Стилизуйте карточки с классом `.product-card`. Если карточка содержит изображение (`img`), добавьте ей тонкую серую рамку (`border: 1px solid lightgray;`). Если карточка содержит кнопку с классом `.buy-now`, сделайте фон карточки светло-желтым (`background-color: lightyellow;`). Обратите внимание, что карточка может удовлетворять обоим условиям.

CSS
.product-cardinput1(img) {
  border: 1px solid lightgray;
}

.product-cardinput2(.buy-now) {
  background-color: lightyellow;
}

.product-card {
  padding: 10px;
  margin-bottom: 15px;
  background-color: white;
  border: 1px solid transparent; /* Резервируем место под рамку */
}
HTML
<div class="product-card">
  <h4>Товар 1</h4>
  <img src="https://naytikurs.ru/img/6.png" alt="Товар 1" width="80">
  <p>Описание товара 1.</p>
  <button class="buy-now">Купить</button>
</div>
<div class="product-card">
  <h4>Товар 2</h4>
  <p>Описание товара 2.</p>
  <button class="buy-now">Купить</button>
</div>
<div class="product-card">
  <h4>Товар 3</h4>
  <img src="https://naytikurs.ru/img/7.png" alt="Товар 3" width="80">
  <p>Описание товара 3.</p>
</div>
Вам понадобятся два отдельных правила с использованием `:has()`. Первое: `.product-card:has(img) { ... }` для рамки. Второе: `.product-card:has(.buy-now) { ... }` для фона.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку
НайтиКурс.Ру