
Я стабильно пишу здесь о CSS. Мне радостно, что моя работа вам полезна. Но хочется чего-то нового. Вызывающего споры. В общем, я к формату статей в виде вопрос-ответ. Вопросы будут те, что я спрашиваю на интервью. Так что у вас будет повод сказать: «А зачем это надо?».
При составлении вопросов я хотел проверить понимание базовых моментов, которые есть в вёрстке любого проекта. Ещё будут вопросы на знание более редких аспектов и «новинок» в CSS. В общем, я хочу вас завалить, чтобы казаться супер умным! (здесь ирония).
Пожалуйста, не воспринимайте мои вопросы серьёзно. Давайте просто весело проведём время. Плюс попробуем узнать что-то новое. Ведь у каждого вопроса будет мой ответ. И вы тоже можете оставить свой в комментариях. Я обязательно буду их читать.
Так, вы готовы? Давайте посмотрим, что я вам подготовил.
▍ Есть ли разница в работе псевдо-классов :focus-within
и :has(:focus-visible)
?
<body>
<div class="awesome-block">
<a href="https://habr.com/">Великолепная ссылка</a>
</div>
</body>
Случай №1
.awesome-block:focus-within {
background-color: lightblue;
}
Случай №2
.awesome-block:has(:focus-visible) {
background-color: lightblue;
}
Псевдо-класс :focus-within
срабатывает, когда пользователь сфокусировался на дочерний элемент. При этом неважно, каким способом. Проще говоря, псевдо-класс :focus-within
сразу отслеживает состояния :focus
и :focus-visible
. В отличие от него псевдо-класс :has(:focus-visible)
сработает только, если браузеры определили сработавшее состояние :focus-visible
.
Правильный ответ: Есть. Первым псевдо-класс сработает, если у дочерних элементов сработали псевдо-класс :focus
или :focus-visible
. Псевдо-класс has(:focus-visible)
срабатывает только, если у дочерних элементов сработал псевдо-класс :focus-visible
.
▍ Правильно ли я использую псевдо-класс :not()
в первом и во втором случае?
Случай №1
.awesome-block:not(:last-of-type) {
background-color: lightblue;
}
Случай №2
.awesome-block:not(:last-of-type, #unique-block) {
background-color: lightblue;
}
В качестве аргумента псевдо-класс :not()
принимает список селекторов. Это означает, что мы можем передать любое количество селекторов, перечисляя их через запятую. Поэтому оба фрагмента кода корректны.
Правильный ответ: Да. Оба фрагмента кода написаны правильно.
▍ Значение свойства height
у элементов с классом .awesome-block
будет одинаковым?
<body>
<div class="awesome-container">
<div class="awesome-block">Великолепный текст</div>
<div class="awesome-block">Великолепный текст</div>
</div>
</body>
Случай №1
.awesome-container {
display: grid;
gap: 20px;
height: 300px;
}
.awesome-block {
background-color: lightblue;
}
Случай №2
.awesome-container {
display: flex;
flex-direction: column;
gap: 20px;
height: 300px;
}
.awesome-block {
background-color: lightblue;
}
В первом случае используется свойство display
со значением grid
для элемента с классом .awesome-container
. По этой причине его дочерние элементы будут стремиться занимать всё доступное пространство по вертикали. Следовательно, они распределят его между собой равномерно.
Поскольку у родительского элемента также установлено свойство gap
, то его значение нужно вычесть из значения свойства height
и поделить на два. В итоге получаем, что у каждого элемента с классом .awesome-block
будет установлено значение 140px
.
Во втором случае для элемента с классом .awesome-container
используется свойство display
со значением flex
. Также есть свойство flex-direction
со значением column
. Это означает, что основная ось флекс-контейнера является вертикальной. По ней браузеры не растягивают размер флекс-элемента. Поэтому значение свойства height
будет рассчитано по высоте контента. Это явно меньше 140px
.
Правильный ответ: Нет. В первом случае значение свойства height
у элементов с классом .awesome-block
будет больше, чем во втором.
▍ Почему элементы с классом .awesome-text
не располагаются в строку?
<body>
<span class="awesome-text">Великолепный текст</span>
<span class="awesome-text">Великолепный текст</span>
</body>
body {
display: grid;
}
На позиционирование элементов влияет свойство display
. Самый главный нюанс заключается в том, что важно не только значение, установленное у самих элементов, но и значение, установленное у родительского элемента. Если у родителя используется значения block
, flow
или flow-root
, то элементы со значением inline
будут располагаться в строку.
В нашем же примере установлено значение grid
. При этом значении дочерние элементы располагаются в столбец. Неважно, какое значение для свойства display
используется у самих элементов.
Правильный ответ: У родительского элемента <body>
вместо стандартного значения block
установлено значение grid
для свойства display
. По этой причине браузеры перестают отображать дочерние элементы с классом .awesome-text
в строку. Теперь они будут отображены в столбец.
▍ Браузеры отобразят один и тот же результат в первом и втором случае. Правда или ложь?
<body>
<div class="awesome-block"></div>
</body>
Случай №1
.awesome-block::before {
content: "";
background-color: lightblue;
position: relative;
width: 1rem;
height: 1rem;
}
Случай №2
.awesome-block::before {
content: "";
background-color: lightblue;
position: absolute;
width: 1rem;
height: 1rem;
}
Значение relative
и absolute
по-разному влияют на значение свойства display
. Первое никак его не затрагивает, а второе меняет на блочную альтернативу. Рассмотрим, как это происходит в нашем вопросе.
По умолчанию у псевдо-элемента ::before
используется значение inline
для свойства display
. В первом случае используется значение relative
. Оно не изменяет значение свойства display
, поэтому браузеры не могут установить значение 1rem
для свойств width
и height
. Следовательно, мы не увидим элемент.
Во втором случае используется значение absolute
. Оно меняет значение inline
на блочную альтернативу, т.е. значение block
. При этом значении браузеры могут установить значение 1rem
для свойств width
и height
. В итоге мы видим квадрат.
Правильный ответ: Ложь. В первом случае мы ничего не увидим, а во втором будет отображён квадрат.
▍ Будет ли псевдо-элемент ::before
находиться на одной и той же позиции при прокрутке страницы?
.awesome-block {
transform: translate3d(0, 0, 0);
}
.awesome-block::before {
content: "";
background-color: lightblue;
position: fixed;
width: 1rem;
height: 1rem;
}
Для вычисления позиции и размеров элементов с установленным свойством position
браузеры используют родительскую область. В стандарте её называют containing block
. У элементов с position: fixed
такой областью обычно является вьюпорт. По этой причине элемент становится зафиксированным при прокрутке страницы.
Только мы можем изменить это поведение. В CSS есть ряд свойств, которые меняют область containing block
. Например, свойство transform
. Если оно будет объявлено с любым значением, кроме none, то этот элемент будет являться областью containing block
. По этой причине в нашем примере элемент перестаёт быть зафиксированным.
Правильный ответ: Нет, потому что используется свойства transform
для родительского элемента.
▍ Какое значение будет установлено для свойства padding
?
:root {
--padding-main: 10px;
--padding-extra: 15px;
--padding: var(--padding-main) var(--padding-extra);
}
.awesome-block {
--padding-main: 20px;
padding: var(--padding);
}
В интернете пользовательские CSS свойства называют CSS переменными. Такое название они получили по аналогии с языками программирования. Но есть один важный момент. Пользовательские CSS свойства не сохраняют значение, а только передают его. По этой причине мы не можем изменять уже переданное значение.
В нашем примере для пользовательского свойства --padding
будут переданы значения 10px
и 15px
в правиле с селектором :root
. Их уже дальше в коде изменить не получится. В итоге браузеры понимают, что в пользовательском свойстве --padding
используется значение 10px 15px
и передают его дальше до строки padding: var(--padding)
. Потом уже заменяют функцию var()
на значение. Таким образом мы получаем свойство padding
со значением 10px 15px
.
:root {
--padding-main: 10px;
--padding-extra: 15px;
--padding: var(--padding-main) var(--padding-extra);
}
.awesome-block {
--padding-main: 20px;
padding: var(--padding); /* после замены пользовательского свойства здесь будет padding: 10px 15px */
}
Правильный ответ: Для свойства padding
будет установлено значение 10px 15px
.
▍ Браузеры отобразят один и тот же результат в первом и втором случае. Правда или ложь?
Случай №1
@media (min-width: 1201px) {
body {
background-color: lightblue;
}
}
Случай №2
@media (width > 1201px) {
body {
background-color: lightblue;
}
}
При объявлении медиа-функции min-width
разработчик указывает значение, которое включается в диапазон. При использовании знака >
значение не включается. По этой причине в первом случае на ширине вьюпорта 1201px
браузеры применят стили, а во втором случае нет.
Правильный ответ: Ложь. Результат будет отличаться на ширине вьюпорта 1201px
.
▍ В каких задачах полезно использовать свойство scrollbar-gutter
?
Свойство scrollbar-gutter
управляет пространством, выделяемым под полосу прокрутки. Оно будет полезно при реализации элементов интерфейса, которые влияют на отображение полосы прокрутки. Например, модальные окна затрагивают полосу прокрутки окна браузера. В результате может произойти смещение контента. В этом случае свойство scrollbar-gutter
позволяет избежать этого.
Правильный ответ: Свойство будет полезным в задачах, где может появиться или исчезнуть полоса прокрутки. Оно поможет избежать нежелательного смещения контента.
▍ Заключение
В этой статье мы рассмотрели вопросы, касающиеся следующих аспектов:
- чем отличаются решения, основанные на использовании псевдо-классов
:focus-within
и:has(:focus-visible)
; - как действительно можно использовать псевдо-класс
:not()
; - правила расчёта свойства
height
внутри элемента с установленным свойствомdisplay
со значениямиflex
иgrid
; - как меняется расположение элементов при изменении значения свойства
display
; - что происходит со свойством
display
, если к элементу объявить свойствоposition
со значениемrelative
иabsolute
; - свойство
transform
влияет на работу свойстваposition
со значениемfixed
; - пользовательские свойства не сохраняют значение, а только его передают;
- особенности старого и нового синтаксиса медиа-запросов;
- пользу свойства
scrollbar-gutter
.
Другие статьи из серии можно найти по тегу «sm909_questions».
Спасибо за чтение!
P.S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn't magic. Присоединяйтесь. Ссылка в профиле.
© 2025 ООО «МТ ФИНАНС»
Автор: melnik909