- PVSM.RU - https://www.pvsm.ru -

Ко мне обращаются проверить знание CSS у разработчиков. Это может быть при найме или для составления плана обучения сотрудника.
В этом году я обновил свой список вопросов. Интересно, сможете ли вы на них ответить. Сразу предупреждаю, что многие вопросы каверзные. В них есть подвох. К тому же они о последних нововведениях в CSS.
Так, вы готовы? Давайте посмотрим, что я вам подготовил.
<body>
<div class="awesome-box">1</div>
<div class="awesome-block">2</div>
<div class="awesome-box">3</div>
<div class="awesome-block">4</div>
</body>
:nth-child(2 of .awesome-box, .awesome-block) {
outline: 0.3rem dashed lightblue;
}
Когда мы объявляем псевдо-класс nth-child с помощью синтаксиса of S, мы передаём список селекторов. В спецификации его называют complex-selector-list. Браузеры ищут HTML-элементы, основываясь на нём.
В нашем примере сначала найдутся все элементы, у которых есть атрибут class и значения .awesome-box и awesome-block. Далее среди них браузеры применят правило ко второму элементу.
Правильный ответ: К элементу с цифрой два.
Псевдо-классы :valid и :user-valid отличаются принципом работы. Первый срабатывает всегда, если у элемента некорректное значение. Второй же будет ждать момент, когда пользователь закончит взаимодействие с элементом.
Например, если псевдо-класс user-valid применим к текстовому полю, то он сработает после того, как пользователь покинет поле.
Правильный ответ: Псевдо-класс :user-valid срабатывает после окончания взаимодействия пользователя с элементом формы, а псевдо-класс :valid срабатывает после готовности документной модели.
<body>
<div class="awesome-block">
<span>Великолепный текст</span>
</div>
</body>
.awesome-block:has(span, #awesome-block) {
background-color: lightblue;
}
При обработке псевдо-класса :has() браузеры воспринимают указанные селекторы как список селекторов (complex-selector-list). При его составлении не важно, будет ли найден HTML-элемент или нет.
В нашем примере браузеры применят правило, потому что есть селектор span, а в HTML у элемента с классом .awesome-block есть вложенный элемент span.
Правильный ответ: Ложь. Правило применится.
.awesome-block {
display: block flex;
min-height: 50dvh;
}
.awesome-block::before {
content: "";
width: 1rem;
height: 1rem;
margin: auto;
background-color: tomato;
}
Свойство display поддерживает синтаксис с двумя ключевыми словами, установленными через пробел. Первое будет обозначать, каким типом является элемент в потоке документа. В стандарте ему дали название display-outside. Я его буду называть внешний тип отображения.
Для его обозначения мы можем использовать три ключевых слова, а именно: block, inline и run-in.
block
Если к элементу будет применено ключевое слово block, то он становится элементом block-level.
inline
При использовании ключевого слова inline создаётся inline-level элемент. Правда есть исключение. Это значение inline.
В этом случае создаётся элемент inline box. Как описано в стандарте [1], это элемент inline-level, у которого в качестве внутреннего типа отображения задано ключевое слово flow.
run-in
Ключевое слово run-in создаёт элемент run-in box. По сути это тот же элемент inline box, только с определёнными правилами [2].
Второе ключевое слово указывает, какой тип элементов он создаёт внутри себя. В стандарте он называется display-inside. Я его буду называть внутренний тип отображения.
Существует шесть ключевых слов для обозначения. Это: flow, flow-root, flex, grid, table и ruby.
flow и flow-root
Создаётся контейнер, в котором могут существовать block-level и inline-level элементы. Разница между ними в том, что второй создаёт новый блочный контекст.
flex
Ключевое слово создаёт флекс-контейнер, в котором появляются основная и дополнительная оси. Они используются для позиционирования дочерних элементов.
grid
При использовании ключевого слова grid создаётся контейнер, в котором есть строки, столбцы и сетки.
table
Специальная обёртка над блочным контейнером, создающая сетку для имитации таблицы.
ruby
Ключевое слово создаёт контейнер, внутри которого можно создать фрагмент текста, являющейся аннотацией к другому фрагменту текста.
На практике значение для свойства display можно задать двумя способами. Оба варианта будут корректными. Например, значение flex можно написать как flex или block flex.
.awesome-block {
display: flex; /* или display: block flex */
}
Разработчики привыкли к более короткой записи flex, а браузеры видят его как block flex.
Правильный ответ: Ложь. В коде нет ошибки. Элемент будет расположен по центру по горизонтали и вертикали.
.awesome-block {
position: fixed;
display: inline-block;
}
При использовании свойств position и display нужно понимать, что значения absolute и fixed трансформируют значение свойства display. Браузеры будут использовать блочные альтернативы.
В нашем примере используется значение inline-block. Его блочной альтернативой является значение block. Оно будет вычислено.
Правильный ответ: Ложь. Браузеры вычислят значение block.
.awesome-block {
box-sizing: border-box;
width: 50rem;
min-height: 20dvh;
padding: 20px;
border: 1px solid;
}
.awesome-block::before {
content: "";
width: 1rem;
height: 1rem;
position: absolute;
background-color: tomato;
}
При объявлении свойства position со значением absolute браузеры вытаскивают элемент из обычного потока документа, но не двигают его. Он остаётся на месте, где был ранее.
В нашем примере изначально элемент был сдвинут на 20px относительно левой границы родительского элемента. Это же значение сохранится после добавления свойства position.
Правильный ответ: 20px.
.awesome-block {
width: 50%;
min-height: 20dvh;
will-change: transform;
background-color: pink;
position: absolute;
top: 3rem;
left: 3rem;
}
.awesome-block::before {
content: "";
width: 1rem;
height: 1rem;
background-color: lightblue;
position: fixed;
top: 0;
}
При использовании свойств top, right, bottom и left для расчётов координат браузеры используют специальную область containing block. Если мы используем свойство position со значением fixed, то вьюпорт будет являться такой областью.
Но есть ряд свойств, которые это изменят. Одним из них является свойство will-change со значением transform. По этой причине областью containing block станет элемент, у которого установлено это свойство.
В нашем примере браузеры будут элемент с классом .awesome-block. Относительно его границ будут рассчитаны координаты.
Правильный ответ: Правда. Координаты будут рассчитаны относительно границ элемента с классом .awesome-block.
.awesome-block {
width: 20rem;
min-height: 5rem;
background-color: lightblue;
display: flex;
flex-direction: column;
align-items: safe center;
justify-content: center;
overflow: hidden;
}
По умолчанию свойства justify-content и align-items не учитывает размеры родительского элемента. В результате дочерние элементы могут выйти за его пределы.
Ключевое слово safe исправляет это поведение. Браузеры начинают учитывать размеры родительского элемента. В результате если размеры дочерних элементов будут больше родительских, то они будут прижаты к границам родителя, не выходя за его пределы.
Правильный ответ: Ключевое слово safe заставляет браузеры контролировать размеры родительского и дочерних элементов.
:root {
--page-background-color: purple;
background-color: tomato;
}
body {
--page-background-color: inherit;
background-color: var(--page-background-color);
min-height: 100dvh;
}
Для правильного ответа нужно помнить, что для пользовательских свойств также работает механизм наследования. Они наследуют значение между друг другом, если у них одинаковое наименование. В нашем примере это --page-background-color.
По этой причине браузеры наследуют значение purple из пользовательского свойства --page-background-color из первого правила, а потом передают его в свойство background-color.
Правильный ответ: purple.
:root {
--page-width: 1200px;
}
body {
width: calc(var(--page-width) + var(--page-default-gap, 0));
}
При работе с математической функцией calc() нужно помнить, что значение 0 вызывает проблемы. Если оно используется для свойства, ожидающего значение типом length, и указано без единиц измерения, то будет ошибка. В стандарте сказано, что значение 0 без единиц измерения не поддерживается [3].
По этой причине браузеры не могут сложить два операнда.
Правильный ответ: Значение не будет вычислено, потому что значение 0 без единиц измерения не поддерживается для свойств, которые ожидают значение с типом length. В нашем примере это свойство width.
Однако браузеры вычислят значение. Оно будет соответствовать ширине вьюпорта.
<body>
<div id="awesome-block" class="awesome-block">
<span>Я дочерний элемент</span>
</div>
</body>
@layer basic, components;
@layer components {
.awesome-block {
background-color: tomato;
}
}
@layer basic {
#awesome-block {
background-color: green;
}
}
В нашем примере используются CSS-слои, поэтому специфичность селекторов будет рассчитана с учётом них. Есть правило, что последний объявленный слой с помощью правила @layer является самым приоритетным.
У нас это слой components. Следовательно, значение tomato будет приоритетнее, чем значение green из слоя basic.
Правильный ответ: Будет вычислено значение tomato.
.awesome-block {
inline-size: 1000px;
min-block-size: 300px;
background-color: pink;
position: relative;
}
.awesome-block::before {
content: "";
inline-size: 50%;
block-size: 20%;
background-color: lightblue;
position: absolute;
}
В нашем примере используются логические свойства inline-size, block-size и min-block-size. Они являются альтернативой свойствам width, height и min-height.
.awesome-block {
width: 1000px;
min-height: 300px;
background-color: pink;
position: relative;
}
.awesome-block::before {
content: "";
width: 50%;
height: 20%;
background-color: lightblue;
position: absolute;
}
Данный вид свойств реагирует на изменение направления текста. В остальном же они ведут себя как привычные свойства. Поэтому принцип расчёта значения для свойств inline-size и block-size такой же, как для widthи height.
У элементов с установленным свойством position со значением absolute значение будет рассчитано относительно элемента с нестатическим типом позиционироавния.
В нашем примере браузеры выполнят вычисления относительно элемента с классом .awesome-block.
Правильный ответ: Для свойства inline-size будет вычислено значение 500px, а для свойства block-size — 60px.
Вот и все мои вопросы. Поделитесь в комментариях своими впечатлениями. Какие вопросы понравились, а какие нет. Интересно узнать ваше мнение.
На прошлой неделе я ещё рассказал про странные CSS свойства [4]. Загляните, посмотрите!
Спасибо за чтение!
P. S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn't magic. Присоединяйтесь. Ссылка в профиле.
© 2025 ООО «МТ ФИНАНС»
Автор: melnik909
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/css/432936
Ссылки в тексте:
[1] Как описано в стандарте: https://drafts.csswg.org/css-display/#inline-box
[2] только с определёнными правилами: https://www.w3.org/TR/css-display-3/#run-in
[3] В стандарте сказано, что значение 0 без единиц измерения не поддерживается: https://www.w3.org/TR/css-values-3/#calc-type-checking
[4] я ещё рассказал про странные CSS свойства: https://habr.com/ru/companies/ruvds/articles/950476
[5] Источник: https://habr.com/ru/companies/ruvds/articles/952546/?utm_source=habrahabr&utm_medium=rss&utm_campaign=952546
Нажмите здесь для печати.