close

CSS

CSS Core

Что такое CSS и как браузер применяет его к HTML?

Короткий ответ

CSS описывает presentation документа. Браузер разбирает stylesheets в CSSOM, сопоставляет selectors с DOM, разрешает cascade и inheritance, вычисляет значения, а затем использует их для layout, paint и compositing.

Полный ответ

CSS задает правила presentation для DOM: какие элементы участвуют в layout, какие у них размеры, цвета, шрифты, эффекты и как эти значения меняются в разных состояниях.

Упрощенно browser проходит несколько этапов:

  1. разбирает stylesheets и строит CSSOM;
  2. находит rules, selectors которых подходят DOM elements;
  3. для каждого property разрешает cascade;
  4. применяет inheritance и CSS-wide values;
  5. получает computed values;
  6. использует результат при построении layout, paint и compositing.

Например:

Кодпример
.button {
  color: white;
  background: royalblue;
  padding: 0.75rem 1rem;
}

Selector .button определяет область применения rule, а declarations становятся кандидатами на значения конкретных properties. Если другой rule тоже задает color, browser не просто берет «последний CSS»: сначала учитываются cascade origin, importance/layer, specificity и другие этапы cascade.

CSS parsing устойчив к ошибкам. Если browser не понимает отдельную declaration, например неизвестное property или невалидное value, он обычно игнорирует ее и продолжает разбирать stylesheet. Это позволяет писать progressive fallback:

Кодпример
.card {
  background: rgb(20 20 20);
  background: color(display-p3 0.1 0.1 0.1);
}

Если DOM, class, media/container condition или используемая custom property меняется, browser может выполнить style recalculation. Но изменение CSS не означает автоматически полный layout: color в основном влияет на paint, а width может потребовать layout; transform часто можно обработать на compositing stage.

На интервью полезно связать CSS с rendering pipeline: selector matching и cascade дают computed styles, после чего конкретные properties определяют, понадобится ли layout, paint или только compositing.

Что такое selector и declaration?

Короткий ответ

Selector выбирает элементы, declaration задает пару property: value внутри rule. Несколько rules могут задавать одно property одному элементу, после чего cascade выбирает итоговое значение.

Полный ответ

CSS rule обычно состоит из selector и блока declarations:

Кодпример
.card > .title {
  color: darkslateblue;
  font-weight: 600;
}

.card > .title — selector. Он описывает, каким DOM elements подходит правило.

Внутри блока две declarations:

Кодпример
color: darkslateblue
font-weight: 600

У каждой declaration есть property и value. Browser рассматривает конфликт по каждому property отдельно: один rule может победить для color, а другое подходящее правило — для font-size.

Selectors бывают разного типа:

Кодпример
button {
} /* type selector */
.action {
} /* class selector */
[aria-expanded='true'] {
} /* attribute selector */
.card > .title {
} /* combinators */
.button:hover {
} /* pseudo-class */
.button::before {
} /* pseudo-element */

Shorthand declaration может задавать сразу несколько longhand properties:

Кодпример
.card {
  margin: 1rem 2rem;
}

Она влияет на margin-top, margin-right, margin-bottom и margin-left, поэтому более поздний longhand способен переопределить только одну сторону.

Важно не связывать selector с application state сильнее необходимого. Например, .sidebar > ul > li > button сильно зависит от DOM structure, а .sidebar-action переживет дополнительный wrapper гораздо легче.

На интервью: selector отвечает «кому», declaration — «какое property/value», а cascade разрешает конфликты между подходящими declarations независимо для каждого property.

Что такое cascade?

Короткий ответ

Cascade разрешает конфликт declarations по relevance, origin/importance, cascade layer, specificity, scope proximity и порядку объявления. Specificity — только один из этапов.

Полный ответ

Cascade отвечает на вопрос: какая declaration победит, если одному element подходят несколько значений одного property?

Упрощенный порядок принятия решения:

  1. Relevance — rule вообще должен быть активен, например совпадает ли @media condition.
  2. Origin и importance — user-agent, user и author styles, normal/!important, animations/transitions.
  3. Cascade layers — внутри origin учитывается порядок @layer.
  4. Specificity — сравнивается вес selectors, которые еще остаются кандидатами.
  5. Scoping proximity — для конфликтующих @scope rules ближний scope root может получить приоритет.
  6. Order of appearance — если предыдущие условия равны, побеждает более поздняя declaration.

Пример layers:

Кодпример
@layer reset, components, overrides;

@layer components {
  .button {
    color: blue;
  }
}

@layer overrides {
  .button {
    color: purple;
  }
}

Для обычных declarations более поздний layer имеет больший приоритет, поэтому purple победит без увеличения specificity. Это позволяет управлять архитектурой cascade явно вместо гонки selectors.

Важный нюанс: !important не «добавляет specificity». Сначала declaration попадает в другой importance bucket, и уже внутри конкурирующих important declarations применяются остальные правила. Порядок layers для important declarations также инвертируется, чтобы ранние защитные layers нельзя было случайно перебить поздними overrides.

Поэтому такой подход хрупок:

Кодпример
#app .page .form .button.primary {
  color: red !important;
}

Он создает escalation: следующему разработчику приходится писать еще более сильный selector или новый !important. Чаще лучше уменьшить specificity, использовать component boundary или cascade layers.

На интервью сильный ответ: specificity не равна cascade; сначала browser определяет cascade bucket/layer, затем сравнивает specificity, scope proximity и только потом source order.

Что такое inheritance в CSS?

Короткий ответ

Некоторые properties, например color и font-family, по умолчанию наследуют computed value родителя; box/layout properties обычно нет. inherit позволяет запросить наследование явно.

Полный ответ

Inheritance позволяет descendant element получить значение property от parent, если у него нет собственного результата cascade и само property является inherited.

Типичные inherited properties относятся к тексту:

Кодпример
body {
  color: #222;
  font-family: system-ui;
}

Большая часть текста внутри body автоматически получит эти значения без отдельного rule для каждого element.

Layout properties обычно не наследуются:

Кодпример
.parent {
  margin: 2rem;
  border: 1px solid;
}

Child не получает margin и border, иначе layout быстро стал бы непредсказуемым.

Наследуется не source text declaration, а computed value родителя. Это особенно заметно с relative values:

Кодпример
.parent {
  color: currentColor;
}

и custom properties, которые по умолчанию тоже наследуются:

Кодпример
.theme-dark {
  --surface: #111;
}

.card {
  background: var(--surface);
}

Наследование можно включить явно даже для non-inherited property:

Кодпример
.child {
  border-color: inherit;
}

или сбросить через initial, unset, revert и другие CSS-wide keywords.

Важно не путать inheritance с descendant selectors. Rule .parent .child применяется из-за selector matching, а не потому, что CSS property «унаследовалось».

Практически inheritance полезно использовать для typography, color и design tokens, но опасно строить на нем скрытые component contracts. Если component работает только потому, что где-то далеко ancestor задает случайную custom property, его reuse становится сложнее.

На интервью: inheritance — это передача computed value по DOM parent-child relation для определенных properties, а не механизм выбора selector.

Что такое initial value и что делают inherit, initial, unset, revert?

Короткий ответ

Каждое property имеет specification initial value. inherit берет значение parent, initial возвращает specification default, unset выбирает inherit или initial по природе property, revert откатывает текущий cascade origin. Для отката текущего layer есть revert-layer.

Полный ответ

У каждого CSS property есть initial value, определенное спецификацией. Это не обязательно то, что browser визуально показывает элементу по умолчанию, потому что поверх initial values работают user-agent styles.

Например:

Кодпример
div {
  display: initial;
}

Initial value для displayinline, поэтому это не то же самое, что browser default display: block для div.

CSS-wide keywords решают разные задачи.

inherit — взять computed value parent независимо от того, наследуется ли property обычно:

Кодпример
.child {
  border-color: inherit;
}

initial — использовать specification initial value:

Кодпример
.element {
  color: initial;
}

unset — вести себя как inherit для inherited property и как initial для остальных:

Кодпример
.component {
  all: unset;
}

all: unset выглядит как удобный reset, но может убрать display, interaction-related styles и ожидаемые browser defaults, поэтому использовать его нужно осознанно.

revert — убрать влияние declarations текущего cascade origin и вернуться к результату предыдущего origin. Для author styles это часто позволяет снова увидеть user/user-agent behavior:

Кодпример
button {
  font: revert;
}

revert-layer — более локальный вариант: игнорирует declaration текущего cascade layer и ищет значение в предыдущих layers того же origin.

Кодпример
@layer base, components;

@layer components {
  .special {
    color: revert-layer;
  }
}

На интервью важно не говорить «initial возвращает browser default». Initial — значение из specification, revert — возврат по cascade origin, revert-layer — возврат по layer.

Что такое CSS box model?

Короткий ответ

Box состоит из content, padding, border и margin. При content-box width/height относятся к content, при border-box включают padding и border. Margin находится снаружи border box.

Полный ответ

Большинство visual elements browser представляет как boxes. Классическая box model состоит из четырех областей:

Кодпример
margin
  border
    padding
      content

При default box-sizing: content-box:

Кодпример
.card {
  width: 200px;
  padding: 20px;
  border: 2px solid;
}

200px относится только к content box. Фактическая ширина border box будет:

Кодпример
200 + 20 + 20 + 2 + 2 = 244px

При box-sizing: border-box те же width: 200px уже включают content + padding + border, поэтому внешний размер предсказуемее.

Margin находится за border и не входит в width border box. У vertical margins обычных block elements в normal flow есть еще один важный edge case — margin collapsing: соседние vertical margins могут схлопываться вместо простого сложения. Во Flexbox/Grid такого классического collapsing между items нет.

Не все visual effects входят в box model. Например, outline и box-shadow могут рисоваться за border box, но обычно не увеличивают layout size элемента.

Sizing также ограничивают min-width, max-width, intrinsic sizes и правила конкретного layout mode. Поэтому width: 100% не всегда означает «ровно ширина родителя» — padding, box-sizing, min-content constraints и containing block тоже имеют значение.

На интервью: box model объясняет, из каких областей складывается layout size; затем нужно связать ее с box-sizing, margin collapsing и тем, что paint effects не обязательно участвуют в layout.

Чем единицы em, rem, %, vw, vh и px отличаются?

Короткий ответ

rem зависит от root font size, em — от font size контекста, % — от правила конкретного property, viewport units — от viewport, px — CSS pixel. Единицу выбирают по тому, относительно чего значение должно масштабироваться.

Полный ответ

Универсально «лучшей» CSS unit нет. Вопрос в том, какую зависимость мы хотим выразить.

px — CSS pixel, логическая единица browser, а не гарантированно один physical pixel экрана. Удобен для значений, которые не должны зависеть от typography: например, тонкий border или конкретный minimum size.

rem зависит от computed font-size root element (html):

Кодпример
.card {
  padding: 1rem;
}

Это удобно для глобальной typography/spacing scale, которая реагирует на root font size.

em зависит от font size текущего контекста. Для font-size самого element reference берется из parent font size, а для большинства других properties — из computed font size самого element:

Кодпример
.badge {
  font-size: 0.875rem;
  padding-inline: 0.75em;
}

Так padding badge масштабируется вместе с его текстом.

% зависит от property. Например, width: 50% обычно связан с containing block, а percentage в transform может относиться к box самого transformed element. Поэтому % нельзя объяснить одной фразой «процент от родителя».

Viewport units:

Кодпример
.hero {
  min-height: 100dvh;
}

vw/vh относятся к viewport, но на mobile классический 100vh исторически неудобен из-за browser chrome. Современные svh, lvh, dvh различают small, large и dynamic viewport size и позволяют выбрать нужное поведение.

Практический выбор часто выглядит так:

  • typography и scalable spacing — rem;
  • размеры, связанные с локальным text — em;
  • fluid layout — %, fr, container/viewport units;
  • точные технические ограничения — иногда px.

Не стоит запрещать px догматически. Accessibility определяется тем, может ли интерфейс zoom/reflow и уважает ли пользовательские настройки, а не самим наличием символов px в stylesheet.

На интервью: unit — это dependency. Сильный ответ объясняет reference value каждой единицы и выбирает ее из desired responsive behavior.

Что такое CSS custom properties?

Короткий ответ

Custom properties объявляются как --token и используются через var(). Они участвуют в cascade, по умолчанию наследуются и вычисляются runtime; @property может задать тип, initial value и управление inheritance.

Полный ответ

CSS custom property — настоящее CSS property с именем, начинающимся на --:

Кодпример
:root {
  --color-accent: #5b5bd6;
}

.button {
  background: var(--color-accent);
}

В отличие от Sass variable, custom property существует в browser runtime. Поэтому она участвует в cascade и inheritance, может меняться под class/media condition и через DOM API.

Это делает custom properties удобной основой themes/design tokens:

Кодпример
:root {
  --surface: white;
  --text: #222;
}

[data-theme='dark'] {
  --surface: #151515;
  --text: #f5f5f5;
}

.card {
  color: var(--text);
  background: var(--surface);
}

У var() есть fallback:

Кодпример
.card {
  color: var(--card-color, currentColor);
}

Fallback используется, когда custom property недоступна/invalid для substitution, а не как polyfill для browsers без поддержки custom properties.

Есть важный edge case: обычная --custom-property принимает почти произвольный token stream. Ошибка может проявиться только at computed-value time:

Кодпример
:root {
  --theme-color: 45deg;
}

.card {
  background-color: var(--theme-color);
}

--theme-color сама по себе syntactically допустима, но после substitution 45deg не является цветом. Итоговое background-color станет invalid at computed-value time и откатится по правилам property, что иногда дает неожиданный результат.

@property позволяет зарегистрировать typed custom property:

Кодпример
@property --progress {
  syntax: '<number>';
  inherits: false;
  initial-value: 0;
}

Это дает validation, initial value, контроль inheritance и более предсказуемую animation/interpolation.

Ограничение: var() подставляет values, но не может динамически создавать property names, selectors или conditions в @media/container query.

На интервью: custom properties — часть cascade/runtime model CSS, а не просто текстовая замена переменных; нужно упомянуть inheritance, fallback и @property.

Что такое currentColor?

Короткий ответ

currentColor означает computed значение property color. Его используют в borders, SVG, shadows и других color positions, чтобы visual parts автоматически следовали цвету текста/состоянию компонента.

Полный ответ

currentColor — CSS keyword, который подставляет текущее computed значение color элемента.

Например:

Кодпример
.link {
  color: royalblue;
  border-bottom: 1px solid currentColor;
}

При :hover достаточно изменить одно property:

Кодпример
.link:hover {
  color: darkblue;
}

Border автоматически станет darkblue, потому что его цвет связан с currentColor.

Особенно полезен этот pattern для monochrome SVG icons:

Кодпример
<svg
  viewBox="0 0 24 24"
  class="icon"
  aria-hidden="true"
>
  <path
    fill="currentColor"
    d="..."
  />
</svg>
Кодпример
.icon-button {
  color: var(--icon-color);
}

Так icon следует hover/disabled/theme state без отдельного asset или selector для внутреннего path.

Некоторые properties и так используют currentColor как initial color behavior, например border colors. Явная запись все равно может быть полезна как documentation intent в component API.

Trade-off: currentColor связывает два визуальных канала. Для multi-color illustration или border, который должен иметь независимый semantic token, такая связь уже не подходит.

На интервью: currentColor позволяет выразить dependency «этот цвет такой же, как text color» и уменьшает количество синхронизируемых state rules.

Веса в CSS

Короткий ответ

Specificity selector обычно сравнивают как ID - class/attribute/pseudo-class - type/pseudo-element. !important, origin и cascade layer не являются частью specificity и обрабатываются раньше в cascade.

Полный ответ

Specificity — один из tie-breakers cascade. Ее удобно представлять тремя группами:

Кодпример
ID | CLASS | TYPE

Примеры:

Кодпример
* {
} /* 0-0-0 */
button {
} /* 0-0-1 */
.button {
} /* 0-1-0 */
[type='button'] {
} /* 0-1-0 */
.button:hover {
} /* 0-2-0 */
#checkout .button {
} /* 1-1-0 */

Если competing declarations уже находятся в одном cascade bucket/layer, более высокая specificity побеждает. При равной specificity дальше учитываются scope proximity и source order.

Есть важные modern pseudo-class rules.

:where() имеет нулевую specificity:

Кодпример
:where(.card .title) {
  margin: 0;
}

Это удобно для defaults, которые consumers должны легко переопределять.

:is(), :not() и :has() сами не добавляют обычный class-weight; их specificity определяется наиболее специфичным selector из переданного списка:

Кодпример
:is(.button, #critical) {
  /* specificity учитывает #critical */
}

Поэтому случайный ID внутри :is() способен неожиданно усилить rule.

Inline style имеет отдельный высокий author priority относительно обычных selector rules. !important тоже не является «четвертой цифрой» specificity: он переводит declaration в important cascade, где затем снова сравниваются layers, specificity и остальные criteria.

Практическая проблема — specificity escalation. Если component требует selectors вроде #app .page .dialog .button, переопределения становятся дорогими. Cascade layers, low-specificity defaults через :where() и component boundaries обычно масштабируются лучше.

На интервью: specificity нужно уметь считать, но еще важнее сказать, где она находится внутри cascade и почему !important/layers нельзя смешивать с ее весом.

img.png
Иллюстрация

Что такое user agent style?

Короткий ответ

User agent stylesheet — встроенные browser styles для HTML elements. Благодаря им headings, links, buttons, inputs и другие native elements имеют базовый вид и behavior даже без author CSS.

Полный ответ

Browser поставляет собственный user agent stylesheet. Поэтому страница без единой author declaration все равно не выглядит как неформатированный текст:

Кодпример
<h1>Hello</h1>
<p>Text</p>
<button>Click</button>

Browser обычно задает heading размер/weight/margins, link — color/decoration, button/input — platform form appearance. Конкретные defaults могут отличаться между browser/OS.

Упрощенный пример UA rules:

Кодпример
h1 {
  display: block;
  font-size: 2em;
  font-weight: bold;
}

Author styles в обычной ситуации переопределяют normal UA declarations через cascade:

Кодпример
h1 {
  margin: 0;
}

Но важно различать UA default и specification initial value. Например, display: initial не означает «верни обычный display этого HTML tag»: initial value displayinline, тогда как UA stylesheet делает div block. Для возврата к более раннему cascade origin чаще подходит revert.

UA styles также несут полезное platform behavior: focus outlines, form control appearance, disabled states. Aggressive reset вида button { all: unset; } может удалить важные affordances, которые потом придется восстанавливать вручную.

В DevTools user agent rules обычно видны рядом с author styles, поэтому при странном margin/input appearance стоит сначала проверить cascade, а не считать это «магией браузера».

На интервью: UA stylesheet — самый базовый style origin browser; reset/normalize взаимодействуют именно с этими defaults, а не меняют HTML semantics.

Что делает box-sizing: border-box?

Короткий ответ

При box-sizing: border-box заданные width и height включают content, padding и border. Это делает внешние размеры компонента предсказуемее.

Полный ответ

Default box-sizing для большинства elements — content-box. Поэтому:

Кодпример
.card {
  width: 300px;
  padding: 20px;
  border: 2px solid;
}

дает border box шириной 344px.

С border-box:

Кодпример
.card {
  box-sizing: border-box;
  width: 300px;
  padding: 20px;
  border: 2px solid;
}

внешняя ширина до margin остается 300px, а content area уменьшается, чтобы освободить место padding/border.

Поэтому многие projects задают global baseline:

Кодпример
*,
*::before,
*::after {
  box-sizing: border-box;
}

или наследуемый вариант:

Кодпример
html {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

Второй pattern позволяет отдельному subtree при необходимости сменить sizing model и передать ее descendants.

border-box не означает, что element всегда физически поместится в parent. min-width, intrinsic content, long unbreakable text, grid/flex sizing и margin все равно могут создать overflow.

Также margin никогда не включается в border-box, а outline/shadow не участвуют в вычислении declared width.

На интервью: border-box меняет интерпретацию declared width/height, но не отменяет остальные правила intrinsic и layout sizing.

Как браузер сопоставляет CSS selector с элементами?

Короткий ответ

Browser engines оптимизируют selector matching и концептуально проверяют selector от правой части к ancestors. Глубокие или слишком общие selectors могут увеличить работу, но чаще реальные CSS bottlenecks связаны со style invalidation, layout/paint и размером DOM.

Полный ответ

Для rule:

Кодпример
.sidebar .menu > li.active a {
  color: red;
}

browser должен найти elements, которые удовлетворяют всей цепочке relationships. Удобная mental model — matching идет справа налево: сначала рассматривается a, затем проверяются нужные ancestors/siblings/conditions слева.

Но современные engines используют индексы, bloom filters, caches и другие оптимизации, поэтому правило «любой длинный selector медленный» слишком грубое. На обычной странице замена .list .item на .item редко даст заметный performance win сама по себе.

Важнее style invalidation. Когда class/attribute/DOM relation меняется, browser должен понять, какие elements могли потерять или получить matching rules и для каких computed styles нужен пересчет.

Например relational selectors вроде :has() позволяют parent зависеть от descendants:

Кодпример
.card:has(.error) {
  border-color: red;
}

Engines оптимизируют и такие cases, но dependency graph становится шире, поэтому на очень больших/часто меняющихся trees важно измерять реальные invalidation costs, а не полагаться на intuition.

Еще одна причина избегать глубоких selectors — maintainability:

Кодпример
.page > .sidebar > ul > li > a {
}

сломается от дополнительного wrapper гораздо раньше, чем простой component class.

Для performance investigation полезнее смотреть DevTools Performance trace: время Recalculate Style, Layout, Paint, размер DOM и frequency mutations. Selector micro-benchmark без реального scenario часто оптимизирует не тот bottleneck.

На интервью: matching — только часть style calculation; архитектурно важны простые selectors, а performance решается через measurement style invalidation + rendering pipeline.

Чем reset CSS отличается от normalize CSS?

Короткий ответ

Reset CSS aggressively убирает browser defaults, Normalize сохраняет полезные defaults и точечно выравнивает browser различия. Современный project часто использует небольшой собственный base layer вместо полного универсального reset.

Полный ответ

Оба подхода пытаются сделать стартовые styles предсказуемее, но философия разная.

Reset CSS обычно удаляет большую часть UA styling:

Кодпример
h1,
h2,
p {
  margin: 0;
}

Плюс — design system получает почти чистый canvas. Минус — полезные defaults нужно восстановить: typography, list markers, focus indicators, form control behavior и spacing.

Normalize CSS старается сохранить нормальные browser conventions, но исправить известные cross-browser differences. То есть цель не «все обнулить», а «сделать разумные defaults более согласованными».

В современном application/design system часто достаточно небольшого base layer:

Кодпример
@layer base {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  body {
    margin: 0;
  }

  button,
  input,
  textarea,
  select {
    font: inherit;
  }
}

После этого component library явно определяет остальные contracts.

Опасный reset:

Кодпример
* {
  all: unset;
}

может убрать display, inherited behavior и accessibility-related visual defaults. Особенно опасно удалять focus outline без равноценной замены.

Выбор reset/normalize зависит от продукта: content site часто выигрывает от browser typography defaults, а строгая cross-platform design system может хотеть больше контроля.

На интервью: reset покупает контроль ценой восстановления defaults; normalize покупает совместимость, сохраняя platform behavior. Сильный production answer — иметь минимальный осознанный base layer.

Какие ошибки делают CSS неэффективным?

Короткий ответ

Проблемы бывают на разных стадиях: oversized/unused CSS, частый style recalculation, layout thrashing, дорогой paint, лишние layers и тяжелые animations. Оптимизировать нужно по Performance/Coverage data, а не по мифам о selectors.

Полный ответ

«Медленный CSS» полезно разделять по стадиям rendering pipeline.

1. Delivery/parsing

Большой global stylesheet с десятками килобайт unused rules увеличивает network, parse и style data. Code splitting, critical CSS strategy и удаление legacy rules часто дают больше, чем micro-optimization selector syntax.

2. Style recalculation

Частые DOM/class mutations на большом tree могут постоянно инвалидировать styles. Особенно стоит проверить components, которые на scroll/mousemove меняют classes у большого числа descendants.

3. Layout

Анимация geometry properties:

Кодпример
.panel {
  transition: width 300ms;
}

может запускать layout каждый frame и затрагивать соседние elements. Для purely visual movement часто лучше transform, если semantics/layout действительно не должны меняться.

4. Paint

Большие blurred shadows, filters, masks, gradients и massive areas с frequent repaint могут быть дорогими даже без layout.

5. Compositing

transform/opacity часто compositor-friendly, но это не означает «бесплатно». Принудительное создание множества layers через бессистемный will-change расходует memory и может ухудшить performance.

Типичные anti-patterns:

Кодпример
* {
  transition: all 300ms;
}

transition: all трудно контролировать: будущая declaration неожиданно начинает анимироваться. Лучше перечислять конкретные properties.

Также performance и maintainability часто деградируют вместе из-за огромных global selectors, duplicated rules и styles, жестко связанных с глубокой DOM structure.

Проверять нужно реальный scenario в DevTools: Coverage для unused CSS, Performance trace для Recalculate Style/Layout/ Paint, FPS/long frames для animations и field metrics для user-visible результата.

На интервью: не существует одной категории «CSS performance». Нужно определить stage — bytes, style, layout, paint или composite — и оптимизировать измеренный bottleneck.

CSS Layout

Что такое normal flow?

Короткий ответ

Normal flow — стандартное размещение элементов без positioning, float и специальных layout-контекстов. Block-элементы идут сверху вниз, inline-контент располагается внутри строк. Flex и Grid создают собственные правила раскладки для дочерних элементов.

Полный ответ

Normal flow — стандартное размещение элементов без positioning, float и специальных layout-контекстов. Block-элементы идут сверху вниз, inline-контент располагается внутри строк. Flex и Grid создают собственные правила раскладки для дочерних элементов.

Что такое block formatting context?

Короткий ответ

BFC — изолированный контекст раскладки block-элементов. Он удерживает floats и предотвращает схлопывание внешних margin с содержимым в ряде случаев. Его создают, например, display: flow-root, flex/grid containers и некоторые значения overflow.

Полный ответ

BFC — изолированный контекст раскладки block-элементов. Он удерживает floats и предотвращает схлопывание внешних margin с содержимым в ряде случаев. Его создают, например, display: flow-root, flex/grid containers и некоторые значения overflow.

Что такое inline formatting context?

Короткий ответ

В нем текст и inline boxes формируют строки внутри контейнера. На расположение влияют line-height, baseline, vertical-align и доступная ширина. Перенос строки создает новый line box.

Полный ответ

В нем текст и inline boxes формируют строки внутри контейнера. На расположение влияют line-height, baseline, vertical-align и доступная ширина. Перенос строки создает новый line box.

Что такое margin collapsing?

Короткий ответ

Вертикальные margin соседних block boxes в normal flow могут объединиться в один margin вместо суммы. Обычно остается наибольший положительный отступ, а отрицательные значения участвуют по отдельным правилам. Flex и Grid items не схлопывают margin.

Полный ответ

Вертикальные margin соседних block boxes в normal flow могут объединиться в один margin вместо суммы. Обычно остается наибольший положительный отступ, а отрицательные значения участвуют по отдельным правилам. Flex и Grid items не схлопывают margin.

Когда margin схлопывается?

Короткий ответ

Между соседними block-элементами, а также между parent и первым или последним child при отсутствии border, padding, inline content и разделяющей высоты. Может схлопываться margin пустого блока. Это относится к block formatting context.

Полный ответ

Между соседними block-элементами, а также между parent и первым или последним child при отсутствии border, padding, inline content и разделяющей высоты. Может схлопываться margin пустого блока. Это относится к block formatting context.

Как избежать схлопывания margin?

Короткий ответ

Предпочесть gap, добавить осмысленный padding/border или создать BFC через display: flow-root. Не стоит добавлять случайный overflow: hidden, если обрезание содержимого нежелательно. Решение должно соответствовать layout-смыслу.

Полный ответ

Предпочесть gap, добавить осмысленный padding/border или создать BFC через display: flow-root. Не стоит добавлять случайный overflow: hidden, если обрезание содержимого нежелательно. Решение должно соответствовать layout-смыслу.

Когда margin не схлопывается?

Короткий ответ

У flex/grid items, absolutely positioned elements, floats и элементов в разных BFC. Border, padding или inline content между parent и child также разделяют margin. Горизонтальные margin не схлопываются.

Полный ответ

У flex/grid items, absolutely positioned elements, floats и элементов в разных BFC. Border, padding или inline content между parent и child также разделяют margin. Горизонтальные margin не схлопываются.

Что такое positioning в CSS?

Короткий ответ

Свойство position определяет, участвует ли box в normal flow и относительно чего работают inset-свойства top, right, bottom, left. Positioning используют для overlays, sticky headers и локального смещения. Основной layout обычно лучше строить Flexbox или Grid.

Полный ответ

Свойство position определяет, участвует ли box в normal flow и относительно чего работают inset-свойства top, right, bottom, left. Positioning используют для overlays, sticky headers и локального смещения. Основной layout обычно лучше строить Flexbox или Grid.

Чем отличаются relative, absolute, fixed и sticky?

Короткий ответ

relative сохраняет место в flow и создает containing block для потомков. absolute исключается из flow, fixed обычно привязан к viewport, sticky ведет себя как normal flow до заданного scroll threshold. Sticky требует подходящего scroll container и inset, например top: 0.

Полный ответ

relative сохраняет место в flow и создает containing block для потомков. absolute исключается из flow, fixed обычно привязан к viewport, sticky ведет себя как normal flow до заданного scroll threshold. Sticky требует подходящего scroll container и inset, например top: 0.

Что такое stacking context?

Короткий ответ

Это локальная система наложения элементов. Новый context создают, например, positioned element с z-index, opacity меньше 1, transform и isolation: isolate. Дочерний элемент не может выйти своим z-index за пределы context родителя.

Полный ответ

Это локальная система наложения элементов. Новый context создают, например, positioned element с z-index, opacity меньше 1, transform и isolation: isolate. Дочерний элемент не может выйти своим z-index за пределы context родителя.

Что такое z-index и почему он иногда не работает?

Короткий ответ

z-index задает порядок внутри текущего stacking context, а не глобально на странице. Большое число проиграет элементу из context, который целиком расположен выше. Нужно искать родителей, создающих contexts, а не увеличивать значение.

Полный ответ

z-index задает порядок внутри текущего stacking context, а не глобально на странице. Большое число проиграет элементу из context, который целиком расположен выше. Нужно искать родителей, создающих contexts, а не увеличивать значение.

Что такое overflow?

Короткий ответ

Overflow описывает поведение содержимого, выходящего за padding box. Он может обрезать содержимое или создать scroll container. Это влияет на sticky positioning, доступность скрытого контента и layout.

Полный ответ

Overflow описывает поведение содержимого, выходящего за padding box. Он может обрезать содержимое или создать scroll container. Это влияет на sticky positioning, доступность скрытого контента и layout.

Чем отличаются overflow: hidden, auto, scroll и clip?

Короткий ответ

hidden обрезает содержимое, но контейнер остается программно прокручиваемым. auto показывает scrollbars при необходимости, scroll резервирует прокрутку всегда, clip обрезает без scroll container. Выбор должен сохранять доступность контента с клавиатуры.

Полный ответ

hidden обрезает содержимое, но контейнер остается программно прокручиваемым. auto показывает scrollbars при необходимости, scroll резервирует прокрутку всегда, clip обрезает без scroll container. Выбор должен сохранять доступность контента с клавиатуры.

Что такое scroll-snap?

Короткий ответ

Scroll Snap позволяет контейнеру после прокрутки остановиться у заданных snap positions. Контейнер задает ось и строгость, элементы — точки выравнивания. Это CSS-enhancement, а не замена доступной навигации carousel.

Полный ответ

Scroll Snap позволяет контейнеру после прокрутки остановиться у заданных snap positions. Контейнер задает ось и строгость, элементы — точки выравнивания. Это CSS-enhancement, а не замена доступной навигации carousel.

Кодпример
.carousel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

.slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

Когда стоит использовать scroll-snap?

Короткий ответ

Для горизонтальных галерей, paged sections и сценариев, где остановка на целом элементе ожидаема пользователем. Нужно оставить обычную прокрутку и элементы управления. Для длинного читаемого контента mandatory snapping часто мешает.

Полный ответ

Для горизонтальных галерей, paged sections и сценариев, где остановка на целом элементе ожидаема пользователем. Нужно оставить обычную прокрутку и элементы управления. Для длинного читаемого контента mandatory snapping часто мешает.

Какие проблемы бывают у scroll-snap на мобильных устройствах?

Короткий ответ

Слишком строгий snap может бороться с жестом пользователя, затруднять диагональную прокрутку и перескакивать после изменения размера контента. Safe areas и browser chrome меняют viewport. Поведение нужно проверять на touch devices и с увеличенным шрифтом.

Полный ответ

Слишком строгий snap может бороться с жестом пользователя, затруднять диагональную прокрутку и перескакивать после изменения размера контента. Safe areas и browser chrome меняют viewport. Поведение нужно проверять на touch devices и с увеличенным шрифтом.

Что такое containing block?

Короткий ответ

Containing block — прямоугольник, относительно которого вычисляются position и percentage sizes элемента. Его источник зависит от position, formatting context и properties ancestors; для absolute element это не всегда непосредственный родитель.

Полный ответ

Containing block — прямоугольник, относительно которого вычисляются position и percentage sizes элемента. Его источник зависит от position, formatting context и properties ancestors; для absolute element это не всегда непосредственный родитель.

Что такое float и почему сейчас его редко используют для layout?

Короткий ответ

float изначально нужен для обтекания изображений и вставок текстом. Раньше на нем строили колонки, но это требовало clearfix, ломало высоты контейнеров и плохо выражало намерение layout. Для современной раскладки обычно выбирают Flexbox или Grid, а float оставляют для настоящего text wrapping.

Полный ответ

float изначально нужен для обтекания изображений и вставок текстом. Раньше на нем строили колонки, но это требовало clearfix, ломало высоты контейнеров и плохо выражало намерение layout. Для современной раскладки обычно выбирают Flexbox или Grid, а float оставляют для настоящего text wrapping.

Какие способы clearing существуют и когда они нужны?

Короткий ответ

Clearing нужен, когда контейнер должен учитывать плавающие элементы. Исторически использовали clear: both и clearfix через pseudo-element; современный простой вариант — создать BFC через display: flow-root. Лучше сначала проверить, нужен ли float вообще, потому что Flexbox и Grid обычно снимают эту проблему.

Полный ответ

Clearing нужен, когда контейнер должен учитывать плавающие элементы. Исторически использовали clear: both и clearfix через pseudo-element; современный простой вариант — создать BFC через display: flow-root. Лучше сначала проверить, нужен ли float вообще, потому что Flexbox и Grid обычно снимают эту проблему.

Как решать browser-specific CSS issues?

Короткий ответ

Сначала нужно воспроизвести проблему в конкретном браузере, проверить поддержку свойства, cascade, computed styles и минимальный пример. Затем выбирают feature detection через @supports, progressive enhancement, fallback или ограниченный workaround. User agent sniffing оставляют как последний вариант для документированного browser bug.

Полный ответ

Сначала нужно воспроизвести проблему в конкретном браузере, проверить поддержку свойства, cascade, computed styles и минимальный пример. Затем выбирают feature detection через @supports, progressive enhancement, fallback или ограниченный workaround. User agent sniffing оставляют как последний вариант для документированного browser bug.

Что такое feature-constrained browser?

Короткий ответ

Это браузер или webview, где часть современных возможностей отсутствует или ограничена: старый engine, embedded webview, режим экономии, слабое устройство или корпоративная среда. Интерфейс должен иметь базовый рабочий слой и улучшаться при наличии возможностей. Это практическая причина использовать progressive enhancement и проверку @supports.

Полный ответ

Это браузер или webview, где часть современных возможностей отсутствует или ограничена: старый engine, embedded webview, режим экономии, слабое устройство или корпоративная среда. Интерфейс должен иметь базовый рабочий слой и улучшаться при наличии возможностей. Это практическая причина использовать progressive enhancement и проверку @supports.

Какие плюсы и минусы у CSS preprocessors?

Короткий ответ

Sass/Less дают nesting, mixins, functions, modules и удобства для дизайн-систем. Минусы: дополнительная сборка, риск глубокой вложенности, абстракций поверх CSS и расхождения с runtime-возможностями браузера. Многие задачи сегодня закрывают native CSS custom properties, nesting, cascade layers и modern selectors.

Полный ответ

Sass/Less дают nesting, mixins, functions, modules и удобства для дизайн-систем. Минусы: дополнительная сборка, риск глубокой вложенности, абстракций поверх CSS и расхождения с runtime-возможностями браузера. Многие задачи сегодня закрывают native CSS custom properties, nesting, cascade layers и modern selectors.

Зачем нужны CSS postprocessors?

Короткий ответ

CSS postprocessors обрабатывают уже написанный CSS: добавляют vendor prefixes, оптимизируют output, раскрывают современный синтаксис или проверяют правила. Типичный пример — PostCSS с Autoprefixer. Это снижает ручную работу, но должно опираться на реальную browser support policy, а не на настройки на всякий случай.

Полный ответ

CSS postprocessors обрабатывают уже написанный CSS: добавляют vendor prefixes, оптимизируют output, раскрывают современный синтаксис или проверяют правила. Типичный пример — PostCSS с Autoprefixer. Это снижает ручную работу, но должно опираться на реальную browser support policy, а не на настройки на всякий случай.

Как подключать нестандартные шрифты?

Короткий ответ

Шрифты подключают через @font-face, задают font-family, src, font-weight, font-style и font-display. Используют WOFF2, preload только для критичных начертаний и fallback stack с похожими метриками, чтобы снизить CLS. Слишком много начертаний ухудшает LCP и first render.

Полный ответ

Шрифты подключают через @font-face, задают font-family, src, font-weight, font-style и font-display. Используют WOFF2, preload только для критичных начертаний и fallback stack с похожими метриками, чтобы снизить CLS. Слишком много начертаний ухудшает LCP и first render.

Командные правила для fonts должны описывать источник файлов, разрешенные weights, fallback stack, font-display, preload strategy и связь с design tokens. Это защищает проект от ситуации, когда каждая feature случайно подключает новое тяжелое начертание.

Что такое FOUT и FOIT?

Короткий ответ

FOUT означает, что браузер сначала показывает fallback font, а потом заменяет его на custom font. FOIT означает, что текст временно невидим, пока custom font не загрузится. Обычно этим управляют через font-display, preload только критичных fonts, subset и fallback с близкими метриками.

Полный ответ

FOUT означает, что браузер сначала показывает fallback font, а потом заменяет его на custom font. FOIT означает, что текст временно невидим, пока custom font не загрузится. Обычно этим управляют через font-display, preload только критичных fonts, subset и fallback с близкими метриками.

Что такое pseudo-element?

Короткий ответ

Pseudo-element создает стилизуемую часть элемента, которой нет как отдельного DOM-узла: ::before, ::after, ::marker, ::placeholder, ::selection. Его используют для декоративного контента, markers и визуальных деталей. Смысловой текст лучше хранить в HTML, чтобы он был доступен assistive technologies и копированию.

Полный ответ

Pseudo-element создает стилизуемую часть элемента, которой нет как отдельного DOM-узла: ::before, ::after, ::marker, ::placeholder, ::selection. Его используют для декоративного контента, markers и визуальных деталей. Смысловой текст лучше хранить в HTML, чтобы он был доступен assistive technologies и копированию.

Что такое pseudo-class?

Короткий ответ

Pseudo-class выбирает элемент по состоянию или отношению: :hover, :focus-visible, :checked, :disabled, :first-child, :has(). Она не создает новый box, а уточняет selector. Для accessibility особенно важны :focus-visible, disabled states и состояния form controls.

Полный ответ

Pseudo-class выбирает элемент по состоянию или отношению: :hover, :focus-visible, :checked, :disabled, :first-child, :has(). Она не создает новый box, а уточняет selector. Для accessibility особенно важны :focus-visible, disabled states и состояния form controls.

Чем nth-child() отличается от nth-of-type()?

Короткий ответ

:nth-child() считает элемент среди всех siblings, а :nth-of-type() — только среди siblings того же tag name. Например, p:nth-child(2) выберет p, только если он второй child вообще, а p:nth-of-type(2) выберет второй p. Разница важна, когда структура содержит смешанные элементы.

Полный ответ

:nth-child() считает элемент среди всех siblings, а :nth-of-type() — только среди siblings того же tag name. Например, p:nth-child(2) выберет p, только если он второй child вообще, а p:nth-of-type(2) выберет второй p. Разница важна, когда структура содержит смешанные элементы.

Чем responsive layout отличается от mobile-first strategy?

Короткий ответ

Responsive layout адаптирует интерфейс к разным размерам и возможностям устройства. Mobile-first — стратегия написания CSS, где базовые стили рассчитаны на узкий экран, а более широкие состояния добавляются через min-width. Можно сделать responsive layout и без mobile-first, но mobile-first часто помогает приоритизировать content и performance.

Полный ответ

Responsive layout адаптирует интерфейс к разным размерам и возможностям устройства. Mobile-first — стратегия написания CSS, где базовые стили рассчитаны на узкий экран, а более широкие состояния добавляются через min-width. Можно сделать responsive layout и без mobile-first, но mobile-first часто помогает приоритизировать content и performance.

Что такое fixed, fluid и responsive layout?

Короткий ответ

Fixed layout использует жесткие размеры и почти не реагирует на viewport. Fluid layout растягивается в процентах или гибких единицах. Responsive layout меняет структуру, размеры и иногда порядок content через constraints, media queries, Flexbox, Grid и container queries.

Полный ответ

Fixed layout использует жесткие размеры и почти не реагирует на viewport. Fluid layout растягивается в процентах или гибких единицах. Responsive layout меняет структуру, размеры и иногда порядок content через constraints, media queries, Flexbox, Grid и container queries.

Чем display: block, inline, inline-block, flex, grid отличаются друг от друга?

Короткий ответ

block занимает доступную строку, inline участвует в тексте и не принимает обычные width/height, inline-block сохраняет inline-размещение с размером box. flex управляет элементами преимущественно по одной оси, grid — по строкам и колонкам. Выбор определяется задачей layout, а не внешним видом элемента.

Полный ответ

block занимает доступную строку, inline участвует в тексте и не принимает обычные width/height, inline-block сохраняет inline-размещение с размером box. flex управляет элементами преимущественно по одной оси, grid — по строкам и колонкам. Выбор определяется задачей layout, а не внешним видом элемента.

Как визуально скрыть элемент, но оставить его доступным для screen reader?

Короткий ответ

Используют visually-hidden class: элемент остается в DOM и accessibility tree, но визуально убран за счет clipping и минимального размера. Нельзя использовать display: none, visibility: hidden или aria-hidden=“true”, если текст должен быть прочитан screen reader. Для focusable skip-link скрытие должно сниматься при focus.

Полный ответ

Используют visually-hidden class: элемент остается в DOM и accessibility tree, но визуально убран за счет clipping и минимального размера. Нельзя использовать display: none, visibility: hidden или aria-hidden="true", если текст должен быть прочитан screen reader. Для focusable skip-link скрытие должно сниматься при focus.

Какие media types кроме screen существуют?

Короткий ответ

Чаще всего встречаются screen, print и all. print используют для печатной версии: убрать навигацию, раскрыть URL ссылок, настроить page breaks и контраст. Старые типы вроде speech имеют ограниченную практическую поддержку, поэтому важнее знать реальные media features.

Полный ответ

Чаще всего встречаются screen, print и all. print используют для печатной версии: убрать навигацию, раскрыть URL ссылок, настроить page breaks и контраст. Старые типы вроде speech имеют ограниченную практическую поддержку, поэтому важнее знать реальные media features.

Что такое retina graphics и какие техники использовать?

Короткий ответ

Retina graphics учитывает высокий device pixel ratio, где одному CSS pixel соответствует несколько device pixels. Для растровых изображений используют srcset с x или w descriptors, responsive images и подходящее сжатие. Иконки и простая графика часто лучше работают как SVG, потому что масштабируются без потери четкости.

Полный ответ

Retina graphics учитывает высокий device pixel ratio, где одному CSS pixel соответствует несколько device pixels. Для растровых изображений используют srcset с x или w descriptors, responsive images и подходящее сжатие. Иконки и простая графика часто лучше работают как SVG, потому что масштабируются без потери четкости.

Практика по CSS

CSS Flexbox

Практический пример: examples/css/flexbox

Что такое Flexbox?

Короткий ответ

Flexbox — одномерная модель раскладки для строки или колонки. Она распределяет свободное пространство, выравнивает элементы и управляет их ростом и сжатием. Подходит для toolbar, sidebar/content и элементов компонента.

Полный ответ

Flexbox — одномерная модель раскладки для строки или колонки. Она распределяет свободное пространство, выравнивает элементы и управляет их ростом и сжатием. Подходит для toolbar, sidebar/content и элементов компонента.

Кодпример
.layout {
  display: flex;
  gap: 16px;
}

.sidebar {
  flex: 0 0 280px;
}

.content {
  flex: 1 1 auto;
  min-width: 0;
}

Практика: Flexbox: оси и выравнивание

Какие задачи решает Flexbox?

Короткий ответ

Flexbox помогает строить одномерные раскладки: строку, колонку, toolbar, группу кнопок, карточку или пару sidebar и content. Он распределяет свободное место, выравнивает элементы, управляет переносом, ростом и сжатием flex items.

Полный ответ

Flexbox помогает строить одномерные раскладки: строку, колонку, toolbar, группу кнопок, карточку или пару sidebar и content. Он распределяет свободное место, выравнивает элементы, управляет переносом, ростом и сжатием flex items.

Практика: Flexbox: оси и выравнивание

Что такое main axis и cross axis?

Короткий ответ

Main axis задается flex-direction: горизонтально для row и вертикально для column. Cross axis перпендикулярна главной. Поэтому смысл justify-content и align-items зависит от направления контейнера.

Полный ответ

Main axis задается flex-direction: горизонтально для row и вертикально для column. Cross axis перпендикулярна главной. Поэтому смысл justify-content и align-items зависит от направления контейнера.

Практика: Flexbox: column direction

Что делает flex-direction?

Короткий ответ

flex-direction задает направление main axis: row, row-reverse, column или column-reverse. От него зависит, куда раскладываются flex items и по какой оси работает justify-content.

Полный ответ

flex-direction задает направление main axis: row, row-reverse, column или column-reverse. От него зависит, куда раскладываются flex items и по какой оси работает justify-content.

Практика: Flexbox: column direction

Что делает flex-wrap?

Короткий ответ

flex-wrap определяет, должны ли элементы оставаться в одной строке или могут переноситься на новые flex lines. При переносе расстояния между строками можно контролировать через row-gap, а распределение строк — через align-content.

Полный ответ

flex-wrap определяет, должны ли элементы оставаться в одной строке или могут переноситься на новые flex lines. При переносе расстояния между строками можно контролировать через row-gap, а распределение строк — через align-content.

Практика: Flexbox: wrap

Что делает gap во Flexbox?

Короткий ответ

gap задает расстояние между flex items и между flex lines, если элементы переносятся. Он принадлежит контейнеру и не добавляет внешний отступ по краям раскладки.

Полный ответ

gap задает расстояние между flex items и между flex lines, если элементы переносятся. Он принадлежит контейнеру и не добавляет внешний отступ по краям раскладки.

Практика: Flexbox: row-gap и column-gap

Что значит flex: 1?

Короткий ответ

В современном CSS это обычно раскрывается примерно в flex: 1 1 0%. Элемент начинает с нулевого basis, может расти и сжиматься, деля доступное пространство с соседями. Для контента часто дополнительно нужен min-width: 0.

Полный ответ

В современном CSS это обычно раскрывается примерно в flex: 1 1 0%. Элемент начинает с нулевого basis, может расти и сжиматься, деля доступное пространство с соседями. Для контента часто дополнительно нужен min-width: 0.

Практика: Flexbox: flex-grow

Как прижать кнопку или блок к низу карточки через Flexbox?

Короткий ответ

Карточку делают flex-контейнером с flex-direction: column, а нужному нижнему блоку задают margin-top: auto. Auto margin забирает свободное пространство и отталкивает блок к нижнему краю карточки.

Полный ответ

Карточку делают flex-контейнером с flex-direction: column, а нужному нижнему блоку задают margin-top: auto. Auto margin забирает свободное пространство и отталкивает блок к нижнему краю карточки.

Практика: Flexbox: auto margin

Как центрировать элемент по горизонтали и вертикали через Flexbox?

Короткий ответ

Контейнеру задают display: flex, justify-content: center и align-items: center. При flex-direction: row горизонтальное центрирование идет по main axis, а вертикальное — по cross axis.

Полный ответ

Контейнеру задают display: flex, justify-content: center и align-items: center. При flex-direction: row горизонтальное центрирование идет по main axis, а вертикальное — по cross axis.

Практика: Flexbox: центрирование items

Чем justify-content отличается от align-items?

Короткий ответ

justify-content распределяет элементы и свободное пространство вдоль main axis. align-items выравнивает flex items вдоль cross axis. Для отдельного элемента cross-axis выравнивание можно изменить через align-self.

Полный ответ

justify-content распределяет элементы и свободное пространство вдоль main axis. align-items выравнивает flex items вдоль cross axis. Для отдельного элемента cross-axis выравнивание можно изменить через align-self.

Практика: Flexbox: justify-content и align-items

Почему gap часто удобнее, чем margin между элементами?

Короткий ответ

gap описывает внутреннее расстояние между соседними элементами на уровне контейнера. Не нужны отдельные правила для первого или последнего элемента, отрицательные margin и компенсация краев. Margin лучше оставлять для внешнего расстояния между независимыми блоками.

Полный ответ

gap описывает внутреннее расстояние между соседними элементами на уровне контейнера. Не нужны отдельные правила для первого или последнего элемента, отрицательные margin и компенсация краев. Margin лучше оставлять для внешнего расстояния между независимыми блоками.

Практика: Flexbox: gap

Что делают flex-grow, flex-shrink и flex-basis?

Короткий ответ

flex-basis задает базовый размер до распределения пространства. flex-grow определяет долю положительного свободного места, flex-shrink — участие в сжатии при нехватке места. Итоговый размер также зависит от min/max constraints.

Полный ответ

flex-basis задает базовый размер до распределения пространства. flex-grow определяет долю положительного свободного места, flex-shrink — участие в сжатии при нехватке места. Итоговый размер также зависит от min/max constraints.

Практика: Flexbox: flex-grow и Flexbox: flex-shrink

Чем flex-basis: 0 отличается от flex-basis: auto?

Короткий ответ

flex-basis: 0 начинает распределение свободного места от нулевой базы, поэтому элементы с одинаковым flex-grow чаще получают равные доли. flex-basis: auto сначала учитывает width, height или размер содержимого, а уже потом распределяет оставшееся пространство.

Полный ответ

flex-basis: 0 начинает распределение свободного места от нулевой базы, поэтому элементы с одинаковым flex-grow чаще получают равные доли. flex-basis: auto сначала учитывает width, height или размер содержимого, а уже потом распределяет оставшееся пространство.

Практика: Flexbox: flex-grow

Почему во Flexbox часто нужен min-width: 0?

Короткий ответ

Flex items по умолчанию имеют automatic minimum size, часто равный min-content width. Длинный текст или вложенный блок может растягивать колонку и ломать layout. min-width: 0 разрешает элементу сжиматься внутри flex-контейнера, после чего работают wrapping, ellipsis или overflow.

Полный ответ

Flex items по умолчанию имеют automatic minimum size, часто равный min-content width. Длинный текст или вложенный блок может растягивать колонку и ломать layout. min-width: 0 разрешает элементу сжиматься внутри flex-контейнера, после чего работают wrapping, ellipsis или overflow.

Практика: Flexbox: flex-shrink

Как сделать две колонки, где одна занимает фиксированную ширину, а вторая все остальное место?

Короткий ответ

Контейнеру задают display: flex, фиксированной колонке — flex: 0 0 280px, а гибкой — flex: 1 1 auto и часто min-width: 0. Так sidebar сохраняет ширину, а content занимает оставшееся пространство.

Полный ответ

Контейнеру задают display: flex, фиксированной колонке — flex: 0 0 280px, а гибкой — flex: 1 1 auto и часто min-width: 0. Так sidebar сохраняет ширину, а content занимает оставшееся пространство.

Практика: Flexbox: flex-grow

Как сделать равные колонки через Flexbox?

Короткий ответ

Для равных колонок обычно задают элементам одинаковое сокращение, например flex: 1 1 0. Нулевой basis убирает влияние начального размера контента, а одинаковый flex-grow делит свободное место поровну.

Полный ответ

Для равных колонок обычно задают элементам одинаковое сокращение, например flex: 1 1 0. Нулевой basis убирает влияние начального размера контента, а одинаковый flex-grow делит свободное место поровну.

Практика: Flexbox: flex-grow

Какие типичные ошибки бывают при использовании Flexbox?

Короткий ответ

Частые ошибки: путать main axis и cross axis, ждать от Flexbox полноценной двумерной сетки, забывать про flex-wrap, использовать margin вместо gap для внутренних расстояний, не учитывать flex-shrink и не задавать min-width: 0 для колонок с длинным контентом.

Полный ответ

Частые ошибки: путать main axis и cross axis, ждать от Flexbox полноценной двумерной сетки, забывать про flex-wrap, использовать margin вместо gap для внутренних расстояний, не учитывать flex-shrink и не задавать min-width: 0 для колонок с длинным контентом.

Практика: Примеры Flexbox

CSS Grid

Практический пример: examples/css/grid

Что такое CSS Grid?

Короткий ответ

Grid — двумерная система раскладки со строками, колонками и областями. Она позволяет определить структуру контейнера, а элементам — занимать одну или несколько ячеек. Grid удобен для карточек и page-level layout.

Полный ответ

Grid — двумерная система раскладки со строками, колонками и областями. Она позволяет определить структуру контейнера, а элементам — занимать одну или несколько ячеек. Grid удобен для карточек и page-level layout.

Практика: CSS Grid: явная сетка 3 на 3 и CSS Grid: адаптивная сетка товаров

Что делают grid-template-columns и grid-template-rows?

Короткий ответ

Они описывают явные tracks сетки и их размеры. Можно использовать px, %, fr, minmax(), repeat() и intrinsic keywords. Неявные tracks создаются автоматически для элементов вне заданной сетки.

Полный ответ

Они описывают явные tracks сетки и их размеры. Можно использовать px, %, fr, minmax(), repeat() и intrinsic keywords. Неявные tracks создаются автоматически для элементов вне заданной сетки.

Практика: CSS Grid: фиксированные tracks и CSS Grid: fr-единицы

Когда лучше использовать Flexbox, а когда CSS Grid?

Короткий ответ

Flexbox выбирают для строки, колонки, выравнивания и неизвестного числа элементов. Grid — когда важны согласованные колонки, строки или двумерные области. Если приходится имитировать строки вложенными flex-контейнерами, Grid обычно проще.

Полный ответ

Flexbox выбирают для строки, колонки, выравнивания и неизвестного числа элементов. Grid — когда важны согласованные колонки, строки или двумерные области. Если приходится имитировать строки вложенными flex-контейнерами, Grid обычно проще.

Практика: Flexbox: wrap и CSS Grid: адаптивная сетка товаров

Чем Grid отличается от Flexbox?

Короткий ответ

Grid управляет двумя измерениями одновременно и начинает с структуры контейнера. Flexbox распределяет элементы вдоль одной основной оси и лучше адаптируется к содержимому. Их часто комбинируют: Grid для страницы, Flexbox внутри компонентов.

Полный ответ

Grid управляет двумя измерениями одновременно и начинает с структуры контейнера. Flexbox распределяет элементы вдоль одной основной оси и лучше адаптируется к содержимому. Их часто комбинируют: Grid для страницы, Flexbox внутри компонентов.

Практика: CSS Grid: именованные области и Flexbox: wrap

Когда лучше использовать Grid вместо Flexbox?

Короткий ответ

Grid лучше выбирать для двумерной структуры: согласованных строк, колонок, областей страницы и карточных сеток. Flexbox удобнее для одномерного распределения элементов внутри компонента. Если layout одновременно зависит и от строк, и от колонок, Grid обычно проще и устойчивее.

Полный ответ

Grid лучше выбирать для двумерной структуры: согласованных строк, колонок, областей страницы и карточных сеток. Flexbox удобнее для одномерного распределения элементов внутри компонента. Если layout одновременно зависит и от строк, и от колонок, Grid обычно проще и устойчивее.

Практика: CSS Grid: page layout и CSS Grid: grid-template-areas

Что такое minmax()?

Короткий ответ

minmax(min, max) задает диапазон размера grid track. Например, колонка может быть не уже 240px, но растягиваться до доли свободного пространства. Это основа многих responsive grids без media queries.

Полный ответ

minmax(min, max) задает диапазон размера grid track. Например, колонка может быть не уже 240px, но растягиваться до доли свободного пространства. Это основа многих responsive grids без media queries.

Практика: CSS Grid: адаптивная сетка товаров

Что такое auto-fit и auto-fill?

Короткий ответ

Оба значения создают столько повторяющихся tracks, сколько помещается. auto-fill сохраняет пустые tracks, а auto-fit схлопывает их и растягивает занятые. Разница заметна, когда элементов меньше доступных колонок.

Полный ответ

Оба значения создают столько повторяющихся tracks, сколько помещается. auto-fill сохраняет пустые tracks, а auto-fit схлопывает их и растягивает занятые. Разница заметна, когда элементов меньше доступных колонок.

Кодпример
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

Практика: CSS Grid: auto-fit и minmax

Что такое Grid stacking?

Короткий ответ

Grid stacking — прием, при котором несколько grid items размещают в одной и той же области сетки или в пересекающихся grid lines. Элементы накладываются друг на друга, а порядок слоя определяется обычными правилами stacking context: порядком в DOM, z-index, position, opacity, transform и другими свойствами.

Полный ответ

Grid stacking — прием, при котором несколько grid items размещают в одной и той же области сетки или в пересекающихся grid lines. Элементы накладываются друг на друга, а порядок слоя определяется обычными правилами stacking context: порядком в DOM, z-index, position, opacity, transform и другими свойствами.

Это удобно для overlay: текст поверх изображения, badge на карточке, декоративный слой или controlled overlap без position: absolute. Grid при этом продолжает задавать общую геометрию и размер области.

Кодпример
.card {
  display: grid;
}

.card img,
.card .content {
  grid-column: 1 / 2;
  grid-row: 1 / 2;
}

Практика: CSS Grid: пересекающиеся линии и CSS Grid: текст поверх изображения

Как сделать Grid wrapping?

Короткий ответ

В Grid нет прямого аналога flex-wrap, потому что grid items автоматически переходят в новые строки или колонки по правилам auto-placement. Для карточных сеток обычно задают повторяющиеся колонки через repeat(), auto-fit или auto-fill, а минимальный и максимальный размер колонки описывают через minmax().

Полный ответ

В Grid нет прямого аналога flex-wrap, потому что grid items автоматически переходят в новые строки или колонки по правилам auto-placement. Для карточных сеток обычно задают повторяющиеся колонки через repeat(), auto-fit или auto-fill, а минимальный и максимальный размер колонки описывают через minmax().

Так сетка сама вычисляет, сколько колонок помещается в контейнер, и переносит лишние элементы на следующую строку без media queries.

Кодпример
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

Практика: CSS Grid: auto-fit и minmax

CSS Responsive

Чем responsive design отличается от adaptive design?

Короткий ответ

Responsive layout плавно подстраивается под доступное пространство, а adaptive обычно выбирает несколько заранее подготовленных layouts для диапазонов устройств. На практике подходы комбинируют, а границы выбирают по content, не по моделям телефонов.

Полный ответ

Responsive layout плавно подстраивается под доступное пространство, а adaptive обычно выбирает несколько заранее подготовленных layouts для диапазонов устройств. На практике подходы комбинируют, а границы выбирают по content, не по моделям телефонов.

Что такое mobile-first?

Короткий ответ

Mobile-first начинает с базового layout для узкого экрана и добавляет возможности через min-width queries. Это помогает приоритизировать content и progressive enhancement, но не отменяет тестирование desktop, touch, keyboard и разных input capabilities.

Полный ответ

Mobile-first начинает с базового layout для узкого экрана и добавляет возможности через min-width queries. Это помогает приоритизировать content и progressive enhancement, но не отменяет тестирование desktop, touch, keyboard и разных input capabilities.

Что такое safe area?

Короткий ответ

Safe area учитывает вырезы, скругления и системные overlays устройства. Значения env(safe-area-inset-) добавляют необходимые padding при подходящем viewport configuration, особенно для fixed controls у краев экрана.

Полный ответ

Safe area учитывает вырезы, скругления и системные overlays устройства. Значения env(safe-area-inset-*) добавляют необходимые padding при подходящем viewport configuration, особенно для fixed controls у краев экрана.

Как учитывать разные плотности экранов?

Короткий ответ

Layout строят в CSS pixels, а raster assets предоставляют с подходящим resolution через srcset или image-set. SVG масштабируется независимо от DPR. Не следует умножать все CSS-размеры на device pixel ratio вручную.

Полный ответ

Layout строят в CSS pixels, а raster assets предоставляют с подходящим resolution через srcset или image-set. SVG масштабируется независимо от DPR. Не следует умножать все CSS-размеры на device pixel ratio вручную.

Как responsive images связаны с responsive layout?

Короткий ответ

Layout определяет отображаемую ширину, а sizes сообщает ее браузеру для выбора кандидата из srcset. Если sizes не соответствует реальному layout, браузер может загрузить слишком большой или размытый ресурс.

Полный ответ

Layout определяет отображаемую ширину, а sizes сообщает ее браузеру для выбора кандидата из srcset. Если sizes не соответствует реальному layout, браузер может загрузить слишком большой или размытый ресурс.

Что такое media query?

Короткий ответ

@media применяет rules при совпадении характеристик viewport, устройства или предпочтений пользователя: width, orientation, hover, pointer, prefers-reduced-motion, prefers-color-scheme и других признаков. Media queries используют не только для breakpoints, но и для адаптации input, motion и contrast. Breakpoints выбирают там, где ломается layout, а не по названиям устройств.

Полный ответ

@media применяет rules при совпадении характеристик viewport, устройства или предпочтений пользователя: width, orientation, hover, pointer, prefers-reduced-motion, prefers-color-scheme и других признаков. Media queries используют не только для breakpoints, но и для адаптации input, motion и contrast. Breakpoints выбирают там, где ломается layout, а не по названиям устройств.

Что такое container query и чем она отличается от media query?

Короткий ответ

Media query смотрит на viewport или device features, container query — на размер или styles ближайшего query container. Container queries делают компонент адаптивным к месту использования, независимо от ширины всей страницы.

Полный ответ

Media query смотрит на viewport или device features, container query — на размер или styles ближайшего query container. Container queries делают компонент адаптивным к месту использования, независимо от ширины всей страницы.

Что такое fluid typography и как работает clamp()?

Короткий ответ

Fluid typography плавно меняет размер между границами. clamp(min, preferred, max) ограничивает вычисленное значение:

Полный ответ

Fluid typography плавно меняет размер между границами. clamp(min, preferred, max) ограничивает вычисленное значение:

Кодпример
.title {
  font-size: clamp(1.5rem, 1rem + 2vw, 3rem);
}

Границы сохраняют читаемость на очень узких и широких экранах.

CSS Architecture

Что такое CSS methodology и зачем она нужна?

Короткий ответ

CSS methodology — это набор правил для организации CSS: например BEM, SMACSS, OOCSS, CSS Modules или utility-first подход. Методология помогает договориться, как называть классы, где хранить styles и как ограничивать область влияния. Важно не название методологии, а консистентность, понятные границы и documented exceptions.

Полный ответ

CSS methodology — это набор правил для организации CSS: например BEM, SMACSS, OOCSS, CSS Modules или utility-first подход. Методология помогает договориться, как называть классы, где хранить styles и как ограничивать область влияния. Важно не название методологии, а консистентность, понятные границы и documented exceptions.

Что такое design tokens?

Короткий ответ

Tokens — именованные design decisions: colors, spacing, typography, radii, motion. Их хранят в нейтральном source of truth и преобразуют в CSS custom properties, platform constants и design-tool variables. Семантические tokens вроде —color-danger устойчивее прямых названий оттенков.

Полный ответ

Tokens — именованные design decisions: colors, spacing, typography, radii, motion. Их хранят в нейтральном source of truth и преобразуют в CSS custom properties, platform constants и design-tool variables. Семантические tokens вроде --color-danger устойчивее прямых названий оттенков.

Что такое cascade layers @layer?

Короткий ответ

Cascade layers задают явный порядок групп styles до сравнения specificity. Например, reset, base, components и utilities можно упорядочить один раз, уменьшая войны selectors и !important.

Полный ответ

Cascade layers задают явный порядок групп styles до сравнения specificity. Например, reset, base, components и utilities можно упорядочить один раз, уменьшая войны selectors и !important.

Что такое Shadow DOM style encapsulation?

Короткий ответ

Shadow DOM создает отдельное tree boundary: обычные document selectors не проникают внутрь, а внутренние styles не выходят наружу. Наследуемые properties, CSS custom properties, ::part и ::slotted формируют контролируемые точки настройки.

Полный ответ

Shadow DOM создает отдельное tree boundary: обычные document selectors не проникают внутрь, а внутренние styles не выходят наружу. Наследуемые properties, CSS custom properties, ::part и ::slotted формируют контролируемые точки настройки.

Что такое BEM?

Короткий ответ

BEM делит CSS-имена на block, element и modifier:

Полный ответ

BEM делит CSS-имена на block, element и modifier:

Кодпример
.user-card {
}
.user-card__title {
}
.user-card--compact {
}

Соглашение делает связи явными и снижает конфликты глобальных стилей, но длинные имена и ручная дисциплина могут быть избыточны при надежной component style isolation.

Зачем команде нужны CSS principles?

Короткий ответ

CSS principles фиксируют подход к именованию, композиции, специфичности, layout, responsive design и переиспользованию. Без таких правил CSS быстро превращается в набор случайных overrides. Хороший ответ должен упомянуть локальность стилей, короткие selectors, осторожность с !important, общий base layer и понятные исключения.

Полный ответ

CSS principles фиксируют подход к именованию, композиции, специфичности, layout, responsive design и переиспользованию. Без таких правил CSS быстро превращается в набор случайных overrides. Хороший ответ должен упомянуть локальность стилей, короткие selectors, осторожность с !important, общий base layer и понятные исключения.

Когда отклонение от CSS methodology допустимо?

Короткий ответ

Отклонение допустимо, если стандартный подход плохо решает конкретную задачу: интеграция с внешним UI kit, legacy-код, performance-ограничение или нестандартный layout. Исключение должно быть локальным, объясненным и по возможности задокументированным, иначе оно быстро становится новой неявной методологией.

Полный ответ

Отклонение допустимо, если стандартный подход плохо решает конкретную задачу: интеграция с внешним UI kit, legacy-код, performance-ограничение или нестандартный layout. Исключение должно быть локальным, объясненным и по возможности задокументированным, иначе оно быстро становится новой неявной методологией.

Как выбрать CSS framework для проекта?

Короткий ответ

CSS framework выбирают по требованиям продукта: скорость разработки, accessibility компонентов, кастомизация, bundle size, качество документации, SSR-совместимость и связь с design system. Важно заранее решить, где команда следует framework, а где пишет собственный слой, иначе проект обрастает хаотичными overrides.

Полный ответ

CSS framework выбирают по требованиям продукта: скорость разработки, accessibility компонентов, кастомизация, bundle size, качество документации, SSR-совместимость и связь с design system. Важно заранее решить, где команда следует framework, а где пишет собственный слой, иначе проект обрастает хаотичными overrides.

Какие плюсы и минусы у БЭМ?

Короткий ответ

БЭМ дает предсказуемые глобальные имена и явно показывает block, element и modifier. Цена — длинные class names, дисциплина соглашений и возможное дублирование контекста там, где framework уже изолирует component styles.

Полный ответ

БЭМ дает предсказуемые глобальные имена и явно показывает block, element и modifier. Цена — длинные class names, дисциплина соглашений и возможное дублирование контекста там, где framework уже изолирует component styles.

Чем CSS Modules, CSS-in-JS и utility-first CSS отличаются?

Короткий ответ

CSS Modules генерируют локальные class names, CSS-in-JS связывает styles с JavaScript runtime или build step, utility-first собирает UI из небольших готовых classes. Выбор влияет на isolation, runtime cost, theming, tooling, server rendering и читаемость markup.

Полный ответ

CSS Modules генерируют локальные class names, CSS-in-JS связывает styles с JavaScript runtime или build step, utility-first собирает UI из небольших готовых classes. Выбор влияет на isolation, runtime cost, theming, tooling, server rendering и читаемость markup.

Какие плюсы и минусы у Tailwind-подхода?

Короткий ответ

Utilities ускоряют композицию, ограничивают произвольные значения и удаляют неиспользуемые rules при сборке. Минусы — шумная markup, необходимость соглашений для повторяющихся patterns и риск смешать design decisions со случайными utilities без tokens и component boundaries.

Полный ответ

Utilities ускоряют композицию, ограничивают произвольные значения и удаляют неиспользуемые rules при сборке. Минусы — шумная markup, необходимость соглашений для повторяющихся patterns и риск смешать design decisions со случайными utilities без tokens и component boundaries.

Как сделать theme и dark theme?

Короткий ответ

Компоненты используют semantic custom properties, а theme переопределяет их на root container. Начальный выбор может учитывать prefers-color-scheme, пользовательская настройка должна иметь приоритет и сохраняться. Проверяют contrast, media assets и browser controls через color-scheme.

Полный ответ

Компоненты используют semantic custom properties, а theme переопределяет их на root container. Начальный выбор может учитывать prefers-color-scheme, пользовательская настройка должна иметь приоритет и сохраняться. Проверяют contrast, media assets и browser controls через color-scheme.

Почему глобальные стили могут быть проблемой?

Короткий ответ

Широкие selectors создают неявные зависимости, conflicts и regressions в далеких features. Global layer оставляют для reset, tokens, typography и действительно общих primitives; component и feature styles ограничивают понятными boundaries.

Полный ответ

Широкие selectors создают неявные зависимости, conflicts и regressions в далеких features. Global layer оставляют для reset, tokens, typography и действительно общих primitives; component и feature styles ограничивают понятными boundaries.

Чем SCSS @import отличается от @use?

Короткий ответ

Legacy @import глобально объединяет файлы, может загружать их повторно и создает конфликты имен.

Полный ответ

Legacy @import глобально объединяет файлы, может загружать их повторно и создает конфликты имен.

@use загружает module один раз и предоставляет namespace:

Кодпример
@use 'tokens';

.button {
  color: tokens.$primary;
}

Для нового Sass-кода используют @use и @forward.

Какие есть способы изоляции стилей?

Короткий ответ

Основные варианты:

Полный ответ

Основные варианты:

  • соглашения именования, например BEM;
  • Angular style encapsulation;
  • CSS Modules;
  • Shadow DOM;
  • utility-классы;
  • ограничение стилей через feature/component boundaries.

Изоляция уменьшает конфликты, но global tokens, typography и overlays все равно требуют продуманного общего слоя.

Какие плюсы и минусы готового UI Kit?

Короткий ответ

Плюсы: единый дизайн, accessibility primitives, быстрый старт, готовые сложные компоненты и меньше дублирования.

Полный ответ

Плюсы: единый дизайн, accessibility primitives, быстрый старт, готовые сложные компоненты и меньше дублирования.

Минусы: ограниченная кастомизация, лишний bundle, зависимость от release cycle и сложные обновления. Перед выбором проверяют accessibility, theming, SSR, forms integration, поддержку Angular-версий и качество API.

CSS Rendering и Performance

Что такое critical CSS?

Короткий ответ

Critical CSS — минимальный набор стилей, нужный для первого видимого экрана. Его можно встроить в HTML или выделить отдельно, чтобы браузер быстрее показал initial view. В Angular SSR/prerender сценариях это может улучшить perceived performance, но усложняет build pipeline, cache и диагностику визуальных regressions.

Полный ответ

Critical CSS — минимальный набор стилей, нужный для первого видимого экрана. Его можно встроить в HTML или выделить отдельно, чтобы браузер быстрее показал initial view. В Angular SSR/prerender сценариях это может улучшить perceived performance, но усложняет build pipeline, cache и диагностику визуальных regressions.

Что такое reflow/layout?

Короткий ответ

Layout вычисляет геометрию render tree: размеры и координаты элементов. Изменение ширины, шрифта или структуры может потребовать пересчета части или всей страницы. Стоимость растет с размером и связанностью layout.

Полный ответ

Layout вычисляет геометрию render tree: размеры и координаты элементов. Изменение ширины, шрифта или структуры может потребовать пересчета части или всей страницы. Стоимость растет с размером и связанностью layout.

Почему GPU не делает любую анимацию бесплатной?

Короткий ответ

Compositor может дешево перемещать готовый layer, но его сначала нужно rasterize и хранить в GPU memory. Большие layers, filters, uploads и частые изменения content создают overhead. Производительность подтверждают trace, а не наличием transform: translateZ(0).

Полный ответ

Compositor может дешево перемещать готовый layer, но его сначала нужно rasterize и хранить в GPU memory. Большие layers, filters, uploads и частые изменения content создают overhead. Производительность подтверждают trace, а не наличием transform: translateZ(0).

Что делают contain и content-visibility?

Короткий ответ

contain ограничивает влияние layout, paint, size или style элемента на остальную страницу. content-visibility: auto позволяет пропускать rendering вне viewport, сохраняя content для поиска и accessibility tree. Для стабильной прокрутки часто задают contain-intrinsic-size.

Полный ответ

contain ограничивает влияние layout, paint, size или style элемента на остальную страницу. content-visibility: auto позволяет пропускать rendering вне viewport, сохраняя content для поиска и accessibility tree. Для стабильной прокрутки часто задают contain-intrinsic-size.

Что такое repaint?

Короткий ответ

Paint рисует пиксели для фона, текста, border, shadow и других визуальных свойств. Он может выполняться без нового layout, если геометрия не изменилась. Большие painted areas и сложные эффекты увеличивают стоимость.

Полный ответ

Paint рисует пиксели для фона, текста, border, shadow и других визуальных свойств. Он может выполняться без нового layout, если геометрия не изменилась. Большие painted areas и сложные эффекты увеличивают стоимость.

Что такое compositing?

Короткий ответ

Compositing собирает ранее нарисованные слои в итоговый кадр, применяя трансформации и прозрачность. Эту работу часто можно передать compositor thread/GPU. Но создание и хранение слоев расходует память.

Полный ответ

Compositing собирает ранее нарисованные слои в итоговый кадр, применяя трансформации и прозрачность. Эту работу часто можно передать compositor thread/GPU. Но создание и хранение слоев расходует память.

Чем reflow отличается от repaint?

Короткий ответ

Reflow пересчитывает геометрию и обычно приводит к последующему paint. Repaint меняет пиксели без обязательного пересчета размеров. Compositing может обновить итоговый кадр без обоих этапов для подходящих свойств.

Полный ответ

Reflow пересчитывает геометрию и обычно приводит к последующему paint. Repaint меняет пиксели без обязательного пересчета размеров. Compositing может обновить итоговый кадр без обоих этапов для подходящих свойств.

Какие CSS-свойства чаще вызывают layout?

Короткий ответ

Свойства размеров и геометрии: width, height, margin, padding, border, position offsets, font metrics и изменения DOM. Точная область пересчета зависит от layout и containment. Проверять нужно в Performance panel.

Полный ответ

Свойства размеров и геометрии: width, height, margin, padding, border, position offsets, font metrics и изменения DOM. Точная область пересчета зависит от layout и containment. Проверять нужно в Performance panel.

Какие CSS-свойства чаще вызывают paint?

Короткий ответ

Цвета, backgrounds, borders, shadows и часть filters обычно требуют paint, но не layout. Чем больше область и сложнее эффект, тем дороже операция. Реальная pipeline зависит от браузера и layer structure.

Полный ответ

Цвета, backgrounds, borders, shadows и часть filters обычно требуют paint, но не layout. Чем больше область и сложнее эффект, тем дороже операция. Реальная pipeline зависит от браузера и layer structure.

Почему transform и opacity обычно лучше для анимаций?

Короткий ответ

Они часто применяются на этапе compositing без повторного layout и paint содержимого. Это уменьшает работу main thread и делает кадры стабильнее. Гарантии нет: сложная сцена и лишние layers тоже могут быть дорогими.

Полный ответ

Они часто применяются на этапе compositing без повторного layout и paint содержимого. Это уменьшает работу main thread и делает кадры стабильнее. Гарантии нет: сложная сцена и лишние layers тоже могут быть дорогими.

Что выполняется на CPU, а что может уйти на GPU?

Короткий ответ

JavaScript, style calculation и layout в основном выполняются CPU/main thread. GPU часто ускоряет rasterization и compositing слоев. Он не делает произвольную CSS-анимацию бесплатной и не исправляет long JavaScript tasks.

Полный ответ

JavaScript, style calculation и layout в основном выполняются CPU/main thread. GPU часто ускоряет rasterization и compositing слоев. Он не делает произвольную CSS-анимацию бесплатной и не исправляет long JavaScript tasks.

Что такое compositor layer?

Короткий ответ

Это поверхность, которую браузер может независимо перемещать и смешивать при сборке кадра. Layers полезны для анимируемых элементов, fixed content и video. Каждый слой требует памяти и может увеличить raster/compositing work.

Полный ответ

Это поверхность, которую браузер может независимо перемещать и смешивать при сборке кадра. Layers полезны для анимируемых элементов, fixed content и video. Каждый слой требует памяти и может увеличить raster/compositing work.

Что такое layer promotion?

Короткий ответ

Браузер решает вынести элемент в отдельный compositor layer из-за transform, animation или других эвристик. Разработчик может подсказать намерение через will-change, но итог контролирует engine. Promotion нужно подтверждать Layers panel.

Полный ответ

Браузер решает вынести элемент в отдельный compositor layer из-за transform, animation или других эвристик. Разработчик может подсказать намерение через will-change, но итог контролирует engine. Promotion нужно подтверждать Layers panel.

Что делает will-change?

Короткий ответ

Он заранее сообщает браузеру, какое свойство скоро изменится, чтобы подготовить оптимизацию. Использовать его следует незадолго до анимации и для ограниченного числа элементов. После завершения долгой подготовки hint можно убрать.

Полный ответ

Он заранее сообщает браузеру, какое свойство скоро изменится, чтобы подготовить оптимизацию. Использовать его следует незадолго до анимации и для ограниченного числа элементов. После завершения долгой подготовки hint можно убрать.

Почему will-change нельзя ставить на все элементы?

Короткий ответ

Браузер может создать слишком много слоев и потратить GPU memory. Это увеличивает rasterization, compositing и иногда ухудшает производительность сильнее исходной проблемы. will-change — точечный hint, а не reset.

Полный ответ

Браузер может создать слишком много слоев и потратить GPU memory. Это увеличивает rasterization, compositing и иногда ухудшает производительность сильнее исходной проблемы. will-change — точечный hint, а не reset.

Почему top/left часто хуже для анимаций, чем transform?

Короткий ответ

Offsets меняют геометрию positioned element и могут запускать layout и paint. Transform обычно перемещает готовый слой на этапе compositing. Итог зависит от элемента, поэтому анимацию измеряют.

Полный ответ

Offsets меняют геометрию positioned element и могут запускать layout и paint. Transform обычно перемещает готовый слой на этапе compositing. Итог зависит от элемента, поэтому анимацию измеряют.

Кодпример
/* Плохо для частых анимаций */
.box {
  left: 100px;
}

/* Обычно лучше */
.box {
  transform: translateX(100px);
}

Почему box-shadow и filter могут быть дорогими?

Короткий ответ

Они требуют вычисления пикселей вокруг элемента, размытия и дополнительных offscreen surfaces. Большой blur radius и анимация на крупной области особенно дороги. Иногда дешевле использовать подготовленный asset или меньшую область.

Полный ответ

Они требуют вычисления пикселей вокруг элемента, размытия и дополнительных offscreen surfaces. Большой blur radius и анимация на крупной области особенно дороги. Иногда дешевле использовать подготовленный asset или меньшую область.

Что такое layout thrashing?

Короткий ответ

Это повторное чередование DOM writes и layout reads, вынуждающее браузер синхронно пересчитывать геометрию много раз за кадр. Проблема часто возникает в циклах. Чтения и записи нужно группировать.

Полный ответ

Это повторное чередование DOM writes и layout reads, вынуждающее браузер синхронно пересчитывать геометрию много раз за кадр. Проблема часто возникает в циклах. Чтения и записи нужно группировать.

Как избежать layout thrashing?

Короткий ответ

Сначала прочитать необходимые размеры, затем пакетно изменить DOM. Для кадра использовать requestAnimationFrame, для списков — class changes вместо множества inline writes. Профилировщик покажет forced synchronous layout.

Полный ответ

Сначала прочитать необходимые размеры, затем пакетно изменить DOM. Для кадра использовать requestAnimationFrame, для списков — class changes вместо множества inline writes. Профилировщик покажет forced synchronous layout.

Почему чтение offsetWidth после записи стилей может быть проблемой?

Короткий ответ

После write вычисленные размеры становятся устаревшими. Чтение offsetWidth требует актуального значения и заставляет браузер немедленно завершить style/layout вместо отложенной пакетной работы. Повторение этого паттерна создает forced reflow.

Полный ответ

После write вычисленные размеры становятся устаревшими. Чтение offsetWidth требует актуального значения и заставляет браузер немедленно завершить style/layout вместо отложенной пакетной работы. Повторение этого паттерна создает forced reflow.

Как DevTools Performance помогает искать reflow/repaint?

Короткий ответ

Запись trace показывает scripting, style recalculation, layout, paint и compositing по кадрам. Можно открыть дорогой event, увидеть call stack и affected nodes. Paint flashing и Layers дополняют анализ.

Полный ответ

Запись trace показывает scripting, style recalculation, layout, paint и compositing по кадрам. Можно открыть дорогой event, увидеть call stack и affected nodes. Paint flashing и Layers дополняют анализ.

Что такое FPS?

Короткий ответ

FPS — число отображенных кадров в секунду. Низкий или нестабильный FPS заметен как рывки анимации и scrolling. Важно смотреть не только среднее, но и пропущенные кадры.

Полный ответ

FPS — число отображенных кадров в секунду. Низкий или нестабильный FPS заметен как рывки анимации и scrolling. Важно смотреть не только среднее, но и пропущенные кадры.

Почему 60 FPS означает бюджет около 16.6ms на кадр?

Короткий ответ

Секунда делится на 60 интервалов: примерно 1000 / 60 = 16.6ms. В этот бюджет входят input, JavaScript, style, layout, paint и compositing. На дисплеях 120Hz бюджет еще меньше.

Полный ответ

Секунда делится на 60 интервалов: примерно 1000 / 60 = 16.6ms. В этот бюджет входят input, JavaScript, style, layout, paint и compositing. На дисплеях 120Hz бюджет еще меньше.

Как requestAnimationFrame помогает с анимациями?

Короткий ответ

Callback вызывается перед следующим paint и синхронизирует обновление с refresh cycle. Браузер может приостанавливать его в фоновой вкладке. Тяжелая работа внутри callback все равно блокирует кадр.

Полный ответ

Callback вызывается перед следующим paint и синхронизирует обновление с refresh cycle. Браузер может приостанавливать его в фоновой вкладке. Тяжелая работа внутри callback все равно блокирует кадр.

CSS rendering pipeline

Что такое FOUC и как его уменьшить?

Короткий ответ

FOUC, Flash of Unstyled Content, возникает, когда HTML уже отрисован, а нужные CSS или fonts еще не применились. Помогают critical CSS, корректное размещение stylesheet, preload важных fonts, стабильные fallback fonts и отказ от поздней загрузки базовых стилей через JavaScript. В Angular также важно, чтобы server-rendered HTML и client styles давали согласованный first render.

Полный ответ

FOUC, Flash of Unstyled Content, возникает, когда HTML уже отрисован, а нужные CSS или fonts еще не применились. Помогают critical CSS, корректное размещение stylesheet, preload важных fonts, стабильные fallback fonts и отказ от поздней загрузки базовых стилей через JavaScript. В Angular также важно, чтобы server-rendered HTML и client styles давали согласованный first render.

Как подключение custom fonts влияет на performance?

Короткий ответ

Custom fonts могут задерживать отображение текста, влиять на LCP и вызывать FOUT или FOIT. Нужно выбирать WOFF2, font-display, preload только критичных начертаний, subset и fallback stack с близкими метриками. Чем больше font files и weights, тем выше риск медленного first render.

Полный ответ

Custom fonts могут задерживать отображение текста, влиять на LCP и вызывать FOUT или FOIT. Нужно выбирать WOFF2, font-display, preload только критичных начертаний, subset и fallback stack с близкими метриками. Чем больше font files и weights, тем выше риск медленного first render.

Что такое CSSOM и почему CSS может блокировать рендеринг?

Короткий ответ

CSSOM — object model разобранных CSS rules. Браузеру нужен CSSOM, чтобы вычислить стили и построить render tree, поэтому внешний stylesheet обычно является render-blocking resource для первого render.

Полный ответ

CSSOM — object model разобранных CSS rules. Браузеру нужен CSSOM, чтобы вычислить стили и построить render tree, поэтому внешний stylesheet обычно является render-blocking resource для первого render.

Большой CSS, медленный CDN или @import могут задержать LCP. Помогают critical CSS, удаление unused CSS, разделение styles по routes и аккуратная загрузка fonts.

Что такое render tree?

Короткий ответ

Элементы вроде display: none не участвуют в render tree, хотя остаются в DOM.

Полный ответ

  • DOM представляет структуру HTML.
  • CSSOM содержит разобранные CSS-правила.
  • Render tree объединяет видимые DOM-узлы с вычисленными стилями.

Элементы вроде display: none не участвуют в render tree, хотя остаются в DOM.

Чем layout, paint и compositing отличаются друг от друга?

Короткий ответ

Layout, или reflow, вычисляет размеры и положение элементов. Paint превращает styled boxes, text, borders и shadows в пиксели или paint commands. Compositing собирает слои в итоговый кадр и часто может выполняться без нового layout и paint.

Полный ответ

Layout, или reflow, вычисляет размеры и положение элементов. Paint превращает styled boxes, text, borders и shadows в пиксели или paint commands. Compositing собирает слои в итоговый кадр и часто может выполняться без нового layout и paint.

Чередование чтения layout-свойств и записи стилей в цикле может вызвать layout thrashing. Операции лучше группировать и измерять через browser Performance panel.

Что такое Critical Rendering Path?

Короткий ответ

Это последовательность получения HTML/CSS, построения DOM и CSSOM, создания render tree, layout, paint и compositing до появления пикселей. Блокирующие ресурсы и long tasks удлиняют путь. Оптимизация должна улучшать измеряемый LCP и первый render, а не только число запросов.

Полный ответ

Это последовательность получения HTML/CSS, построения DOM и CSSOM, создания render tree, layout, paint и compositing до появления пикселей. Блокирующие ресурсы и long tasks удлиняют путь. Оптимизация должна улучшать измеряемый LCP и первый render, а не только число запросов.

Что такое render-blocking resources?

Короткий ответ

Это ресурсы, без обработки которых браузер откладывает первый render. К ним обычно относятся stylesheets и часть синхронных scripts. Critical CSS, code splitting и корректные defer/async уменьшают блокировку.

Полный ответ

Это ресурсы, без обработки которых браузер откладывает первый render. К ним обычно относятся stylesheets и часть синхронных scripts. Critical CSS, code splitting и корректные defer/async уменьшают блокировку.

Как улучшить scroll performance?

Короткий ответ

Нужно уменьшить работу на main thread во время scroll: использовать passive listeners, не читать и не писать layout в каждом событии, виртуализировать большие списки и избегать тяжелых shadows/filters на множестве элементов. Sticky, parallax и infinite scroll проверяют на реальных устройствах. В Angular важно не запускать лишние state updates и change detection на каждый пиксель прокрутки.

Полный ответ

Нужно уменьшить работу на main thread во время scroll: использовать passive listeners, не читать и не писать layout в каждом событии, виртуализировать большие списки и избегать тяжелых shadows/filters на множестве элементов. Sticky, parallax и infinite scroll проверяют на реальных устройствах. В Angular важно не запускать лишние state updates и change detection на каждый пиксель прокрутки.

Почему не стоит использовать transition: all?

Короткий ответ

transition: all анимирует любые изменившиеся свойства, включая неожиданные и дорогие для layout. Это усложняет поддержку и может создавать случайные анимации.

Полный ответ

transition: all анимирует любые изменившиеся свойства, включая неожиданные и дорогие для layout. Это усложняет поддержку и может создавать случайные анимации.

Лучше явно перечислить свойства:

Кодпример
.button {
  transition:
    transform 150ms ease,
    opacity 150ms ease;
}

Modern CSS

Что такое CSS nesting?

Короткий ответ

Native nesting позволяет вкладывать relative selectors внутрь style rule. Оно уменьшает повторение context, но глубокая вложенность повышает specificity и связанность. Синтаксис и результат следует отличать от дополнительных возможностей Sass.

Полный ответ

Native nesting позволяет вкладывать relative selectors внутрь style rule. Оно уменьшает повторение context, но глубокая вложенность повышает specificity и связанность. Синтаксис и результат следует отличать от дополнительных возможностей Sass.

Что такое :has()?

Короткий ответ

:has() выбирает element по совпадению relative selector внутри или рядом, например form group с invalid input. Это позволяет стилизовать parent без JavaScript, но слишком широкие selectors на больших деревьях следует применять осознанно.

Полный ответ

:has() выбирает element по совпадению relative selector внутри или рядом, например form group с invalid input. Это позволяет стилизовать parent без JavaScript, но слишком широкие selectors на больших деревьях следует применять осознанно.

Что такое style queries?

Короткий ответ

Style container queries применяют rules по computed style container, прежде всего по custom properties. Это позволяет компоненту реагировать на semantic state контекста. Поддержку конкретного синтаксиса нужно проверять для целевых браузеров.

Полный ответ

Style container queries применяют rules по computed style container, прежде всего по custom properties. Это позволяет компоненту реагировать на semantic state контекста. Поддержку конкретного синтаксиса нужно проверять для целевых браузеров.

Что такое logical properties?

Короткий ответ

Logical properties описывают flow-relative стороны: margin-inline-start, padding-block, inset-inline-end. В отличие от left и right, они адаптируются к writing mode и направлению LTR/RTL, уменьшая отдельные overrides для локализации.

Полный ответ

Logical properties описывают flow-relative стороны: margin-inline-start, padding-block, inset-inline-end. В отличие от left и right, они адаптируются к writing mode и направлению LTR/RTL, уменьшая отдельные overrides для локализации.

Какие frontend-проблемы появляются при RTL?

Короткий ответ

RTL влияет на direction, порядок inline content, иконки направления, отступы, scroll behavior, charts, drag and drop и анимации. CSS logical properties (margin-inline-start, inset-inline-end) уменьшают количество отдельных overrides.

Полный ответ

RTL влияет на direction, порядок inline content, иконки направления, отступы, scroll behavior, charts, drag and drop и анимации. CSS logical properties (margin-inline-start, inset-inline-end) уменьшают количество отдельных overrides.

Нельзя просто поменять text-align. Нужно проверить keyboard navigation, focus order, truncation, mixed LTR/RTL text, date/number formatting и screenshots основных экранов.

Кодпример
.toolbar {
  padding-inline-start: 1rem;
  padding-inline-end: 0.5rem;
}

Чем :is() отличается от :where()?

Короткий ответ

Обе pseudo-classes группируют selectors. Specificity :is() равна самому специфичному аргументу, а :where() всегда имеет нулевую specificity. Поэтому :where() удобен для легко переопределяемых defaults.

Полный ответ

Обе pseudo-classes группируют selectors. Specificity :is() равна самому специфичному аргументу, а :where() всегда имеет нулевую specificity. Поэтому :where() удобен для легко переопределяемых defaults.

Для чего нужны accent-color и color-scheme?

Короткий ответ

accent-color настраивает accent native form controls, сохраняя их поведение. color-scheme сообщает браузеру, какие цветовые схемы поддерживает область, чтобы он согласовал controls, scrollbars и системные colors.

Полный ответ

accent-color настраивает accent native form controls, сохраняя их поведение. color-scheme сообщает браузеру, какие цветовые схемы поддерживает область, чтобы он согласовал controls, scrollbars и системные colors.

Как работают prefers-color-scheme и prefers-reduced-motion?

Короткий ответ

Эти media features отражают системные предпочтения пользователя. Первая помогает выбрать начальную theme, вторая — уменьшить необязательное движение. Reduced motion означает не «выключить все», а убрать потенциально проблемные эффекты, сохранив понятную обратную связь.

Полный ответ

Эти media features отражают системные предпочтения пользователя. Первая помогает выбрать начальную theme, вторая — уменьшить необязательное движение. Reduced motion означает не «выключить все», а убрать потенциально проблемные эффекты, сохранив понятную обратную связь.

Для чего нужны aspect-ratio и object-fit?

Короткий ответ

aspect-ratio задает предпочтительное соотношение сторон box и помогает резервировать место. object-fit определяет, как replaced content вроде image или video вписывается в заданный box: contain сохраняет весь content, cover заполняет область с crop.

Полный ответ

aspect-ratio задает предпочтительное соотношение сторон box и помогает резервировать место. object-fit определяет, как replaced content вроде image или video вписывается в заданный box: contain сохраняет весь content, cover заполняет область с crop.

Что делают overscroll-behavior и scrollbar-gutter?

Короткий ответ

overscroll-behavior управляет scroll chaining и browser overscroll actions на границах container. scrollbar-gutter может заранее резервировать место под scrollbar, предотвращая layout shift. Оба свойства применяют точечно, не ломая ожидаемую прокрутку страницы.

Полный ответ

overscroll-behavior управляет scroll chaining и browser overscroll actions на границах container. scrollbar-gutter может заранее резервировать место под scrollbar, предотвращая layout shift. Оба свойства применяют точечно, не ломая ожидаемую прокрутку страницы.

Когда использовать subgrid?

Короткий ответ

subgrid позволяет вложенному grid наследовать tracks родителя по строкам или колонкам. Это полезно для карточек, табличных layouts и форм, где внутренние элементы разных карточек должны выровняться по общей сетке.

Полный ответ

subgrid позволяет вложенному grid наследовать tracks родителя по строкам или колонкам. Это полезно для карточек, табличных layouts и форм, где внутренние элементы разных карточек должны выровняться по общей сетке.

Кодпример
.card-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.card {
  display: grid;
  grid-template-rows: subgrid;
}

Перед применением нужно проверить поддержку целевых браузеров и fallback. Если выравнивание локальное, обычный grid проще и понятнее.

CSS layout и component tasks

Практическая задача: сделайте CSS-only star rating display.

Короткий ответ

Если нужен только display, можно использовать custom property и overlay. Для интерактивного rating нужны настоящие controls, keyboard support и доступное имя.

Полный ответ

Если нужен только display, можно использовать custom property и overlay. Для интерактивного rating нужны настоящие controls, keyboard support и доступное имя.

Кодпример
.rating {
  --rating: 3.5;
  --percent: calc(var(--rating) / 5 * 100%);
  display: inline-block;
  font-size: 1.25rem;
  line-height: 1;
}

.rating::before {
  content: '★★★★★';
  background: linear-gradient(90deg, currentColor var(--percent), #c8c8c8 var(--percent));
  background-clip: text;
  color: transparent;
}

Частая ошибка - сделать красивый виджет, но потерять accessibility. Для ввода рейтинга лучше использовать radio group или button group, а не только pseudo-elements.

Практическая задача: сверстайте responsive card grid без JavaScript.

Короткий ответ

Что проверяет: Grid, responsive layout, минимальные размеры, отсутствие layout shift.

Полный ответ

Что проверяет: Grid, responsive layout, минимальные размеры, отсутствие layout shift.

Кодпример
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: 1rem;
}

.card {
  min-width: 0;
}

На интервью важно объяснить, почему minmax(min(100%, 18rem), 1fr) не переполняет узкий viewport, чем auto-fit отличается от auto-fill, и как заранее задать размеры media через aspect-ratio.