🎨 CSS
Полный справочник: селекторы и специфичность, каскад и слои, блочная модель, flexbox, grid, позиционирование, единицы, цвета, типографика, адаптивность и container queries, переменные, анимации, паттерны и отладка.
Шпаргалки · Данные · #css #css3 #web #styles #responsive #flexbox #grid
Подключение и синтаксис
селектор { свойство: значение; другое-свойство: значение; }
<link rel="stylesheet" href="style.css"> <style>…</style> <p style="color: red"> <!-- inline: избегайте -->
@import url("base.css"); /* медленнее <link> */
/* комментарий */
Современные браузеры поддерживают вложенность, :has(), container queries, @layer, color-mix(): проверяйте на caniuse.com и MDN.
Селекторы
| Селектор | Выбирает |
|---|---|
* |
все |
p, .card, #main |
по тегу, классу, id |
a, b |
любой из |
ul li |
потомок любой глубины |
ul > li |
прямой потомок |
h2 + p |
следующий сосед |
h2 ~ p |
все следующие соседи |
[href], [type="text"], [href^="https"], [href$=".pdf"], [class*="btn"] |
по атрибуту |
:hover, :focus, :focus-visible, :active, :disabled, :checked, :required, :invalid |
состояния |
:first-child, :last-child, :nth-child(2n+1), :nth-of-type(3), :only-child, :empty |
позиция |
:not(.x), :is(h1, h2), :where(...), :has(img) |
логические (:has родитель по содержимому) |
::before, ::after, ::first-line, ::first-letter, ::placeholder, ::selection, ::marker |
псевдоэлементы (content обязателен) |
& |
вложенность: .card { &:hover {} .title {} } |
Каскад и специфичность
Правило побеждает по порядку: важность (!important) → слой (@layer) → специфичность → порядок в файле (позднее выигрывает).
Специфичность считается тройкой (id, классы/атрибуты/псевдоклассы, теги): #a .b p = (1,1,1) сильнее .a .b .c = (0,3,0). Inline-стили сильнее селекторов. :where() даёт нулевую специфичность, :is() берёт максимальную из списка.
@layer reset, base, components, utilities; /* порядок слоёв задаёт приоритет, а не специфичность */
@layer components { .btn { padding: .5rem 1rem; } }
Избегайте !important и глубоких селекторов, держите специфичность низкой и ровной (классы, БЭМ).
Наследование
Наследуются: color, font-*, line-height, text-align, visibility, cursor, list-style. Не наследуются: размеры, поля, рамки, фон, позиционирование. Принудительно: inherit, initial, unset, revert.
Блочная модель
*, *::before, *::after { box-sizing: border-box; } /* ширина включает padding и border */
.box {
width: 300px; height: auto; min-width: 0; max-width: 100%;
padding: 16px 24px; /* top/bottom left/right (1–4 значения по часовой стрелке) */
margin: 0 auto; /* центрирование блока по горизонтали */
border: 1px solid #ccc; border-radius: 8px;
outline: 2px solid blue; outline-offset: 2px;
}
Схлопывание отступов: вертикальные margin соседних блоков объединяются (берётся больший). Не схлопываются во flex- и grid-контейнерах.
Логические свойства (удобны для RTL): margin-inline, padding-block, inset-inline-start, inline-size, block-size.
display
| Значение | Поведение |
|---|---|
block |
на всю ширину, с новой строки |
inline |
в строке, без width/height и вертикальных отступов |
inline-block |
в строке, но с размерами |
flex / inline-flex |
гибкий контейнер (одно измерение) |
grid / inline-grid |
сетка (два измерения) |
none |
не отображается и не занимает места |
contents |
убирает сам блок, оставляя детей |
visibility: hidden |
скрыт, но место занимает |
Flexbox
.row {
display: flex;
flex-direction: row; /* row | column | row-reverse | column-reverse */
flex-wrap: wrap;
justify-content: space-between; /* по главной оси: flex-start | center | flex-end | space-around | space-evenly */
align-items: center; /* по поперечной: stretch | flex-start | center | flex-end | baseline */
align-content: flex-start; /* несколько строк */
gap: 12px 16px;
}
.item { flex: 1 1 200px; } /* grow shrink basis */
.item { flex: 1; } /* равные доли */
.item { flex: none; } /* фиксированный */
.item { align-self: flex-end; order: 2; margin-left: auto; } /* margin-left: auto — прижать вправо */
Типичные приёмы: центрирование display: flex; place-items: center; justify-content: center;, «липкий» подвал (body { min-height: 100vh; display: flex; flex-direction: column } main { flex: 1 }), min-width: 0 у flex-элемента, чтобы длинный текст не распирал контейнер.
Grid
.grid {
display: grid;
grid-template-columns: 200px 1fr 2fr; /* fr — доли свободного места */
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); /* адаптивные карточки без media */
grid-template-rows: auto 1fr auto;
gap: 16px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
place-items: center;
}
.header { grid-area: header; }
.wide { grid-column: span 2; } .item { grid-column: 1 / -1; grid-row: 2 / 4; }
auto-fill сохраняет пустые колонки, auto-fit растягивает элементы. subgrid наследует линии родителя. Выравнивание: justify-items, align-items, justify-content, align-content, place-*. Flexbox для одного ряда или колонки, grid для двумерной раскладки.
Позиционирование
| Значение | Поведение |
|---|---|
static |
по умолчанию, обычный поток |
relative |
сдвиг от своего места; становится опорой для absolute внутри |
absolute |
относительно ближайшего позиционированного предка, вне потока |
fixed |
относительно окна |
sticky |
прилипает при прокрутке (top: 0); нужен прокручиваемый предок без overflow: hidden |
.overlay { position: fixed; inset: 0; z-index: 100; } /* inset = top/right/bottom/left */
.badge { position: absolute; top: -4px; right: -4px; }
z-index работает у позиционированных элементов и flex/grid-детей; контексты наложения создают position + z-index, opacity < 1, transform, filter.
Единицы измерения
| Единица | Смысл |
|---|---|
px |
пиксель |
rem |
от размера шрифта html (удобно для масштабируемого интерфейса) |
em |
от шрифта текущего элемента |
% |
от размера родителя |
vw, vh, vmin, vmax |
доли окна; dvh, svh, lvh учитывают панели мобильных браузеров |
ch, ex |
ширина «0», высота «x» (max-width: 65ch для читаемых строк) |
fr |
доля в grid |
deg, turn, s, ms |
углы и время |
width: clamp(280px, 90%, 1200px); font-size: clamp(1rem, 2vw + .5rem, 1.5rem); /* min, предпочтительное, max */
width: calc(100% - 2rem); height: min(50vh, 400px); max(1rem, 2vw)
Цвета и фон
color: #1d4ed8; color: rgb(29 78 216 / 80%); color: hsl(221 83% 53%); color: oklch(60% .2 260); color: currentColor;
background: linear-gradient(135deg, #7c3aed, #2563eb); background: radial-gradient(circle at top, #fff, transparent);
background: url(bg.jpg) center / cover no-repeat; background-color: color-mix(in srgb, var(--brand) 20%, white);
opacity: .5; mix-blend-mode: multiply; backdrop-filter: blur(8px); filter: grayscale(1) blur(2px);
Контраст текста не ниже 4.5:1 (WCAG AA).
Типографика
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; /* системный стек */
font-size: 1rem; font-weight: 400|600|700; font-style: italic; line-height: 1.5; letter-spacing: .02em;
text-align: left|center|right|justify; text-transform: uppercase; text-decoration: underline dotted;
text-overflow: ellipsis; white-space: nowrap; overflow: hidden; /* обрезка одной строки */
display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; /* обрезка по числу строк */
word-break: break-word; overflow-wrap: anywhere; hyphens: auto; text-wrap: balance; tab-size: 2;
@font-face { font-family: "Inter"; src: url(inter.woff2) format("woff2"); font-display: swap; font-weight: 100 900; }
Рамки, тени, трансформации
border: 1px solid; border-radius: 50%; box-shadow: 0 4px 12px rgb(0 0 0 / .15), inset 0 0 0 1px #eee; text-shadow: 0 1px 2px #0004;
transform: translate(10px, 20px) rotate(15deg) scale(1.1) skew(5deg); transform-origin: top left; /* не влияют на поток */
aspect-ratio: 16 / 9; object-fit: cover; object-position: center; overflow: hidden | auto | scroll | clip;
Переходы и анимации
.btn { transition: transform .2s ease, background-color .2s; }
.btn:hover { transform: translateY(-2px); }
@keyframes fade-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.card { animation: fade-in .4s ease-out both; animation-delay: .1s; animation-iteration-count: infinite; }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }
Для плавности анимируйте transform и opacity (GPU), а не width, top, margin. Подсказка: will-change: transform только на время анимации. Прокрутка по ссылкам: scroll-behavior: smooth. Анимации по скроллу и переходы между страницами: animation-timeline: scroll(), View Transitions API.
Адаптивный дизайн
<meta name="viewport" content="width=device-width, initial-scale=1"> /* в HTML */
.container { width: min(100% - 2rem, 1200px); margin-inline: auto; }
img, video { max-width: 100%; height: auto; display: block; }
/* mobile first: базовые стили для телефона, расширяем */
.cards { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 640px) { .cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .cards { grid-template-columns: repeat(3, 1fr); } }
@media (hover: hover) { .btn:hover { … } } @media (pointer: coarse) { .btn { min-height: 44px; } }
@media (orientation: landscape) {} @media print { nav { display: none; } }
Типичные точки: 480, 640, 768, 1024, 1280 пикселей; выбирайте по содержимому. Container queries подстраивают компонент под размер своего контейнера:
.card-wrap { container-type: inline-size; container-name: card; }
@container card (min-width: 420px) { .card { display: flex; } }
Переменные и тёмная тема
:root {
--brand: #7c3aed; --gap: 1rem; --radius: .5rem;
--bg: #fff; --text: #111;
color-scheme: light dark;
}
@media (prefers-color-scheme: dark) { :root { --bg: #0b0b10; --text: #eee; } }
[data-theme="dark"] { --bg: #0b0b10; --text: #eee; }
body { background: var(--bg); color: var(--text); }
.btn { background: var(--brand, #333); padding: var(--gap); border-radius: var(--radius); }
@property --angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; } /* анимируемые переменные */
Переменные наследуются и переопределяются в любом селекторе, читаются из JavaScript: el.style.setProperty('--x', '10px').
Формы и интерактив
input, button, select, textarea { font: inherit; }
button:focus-visible, a:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; } /* не убирайте outline без замены */
input:user-invalid { border-color: crimson; } input[type="checkbox"] { accent-color: var(--brand); }
.btn:disabled { opacity: .5; cursor: not-allowed; } ::placeholder { color: #888; }
textarea { resize: vertical; } a { text-underline-offset: .15em; }
caret-color: var(--brand); user-select: none; pointer-events: none; touch-action: manipulation; scroll-snap-type: x mandatory;
Типичные приёмы
/* центрирование */
.center { display: grid; place-items: center; min-height: 100vh; }
/* карточки без media-запросов */
.cards { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
/* кнопка-иконка и скрытие для визуальных, но не для скринридеров */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* липкая шапка */
header { position: sticky; top: 0; z-index: 10; backdrop-filter: blur(8px); }
/* стек отступов */
.stack > * + * { margin-block-start: 1rem; }
/* разделитель */
.divider { border: 0; border-top: 1px solid color-mix(in srgb, currentColor 20%, transparent); }
/* скелетон */
.skeleton { background: linear-gradient(90deg, #eee 25%, #f5f5f5 50%, #eee 75%); background-size: 200% 100%; animation: shimmer 1.2s infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }
Сброс и основа
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; line-height: 1.5; font-family: system-ui, sans-serif; -webkit-font-smoothing: antialiased; }
img, picture, svg, video { max-width: 100%; display: block; }
Готовые: modern-normalize, Josh Comeau's reset, normalize.css.
Организация CSS
| Подход | Суть |
|---|---|
| БЭМ | .block__element--modifier, плоские селекторы |
| Utility-first | Tailwind, UnoCSS: много мелких классов |
| CSS Modules | локальные имена классов на компонент |
| CSS-in-JS | styled-components, Emotion, vanilla-extract |
| Препроцессоры | Sass / SCSS, Less (переменные, миксины, вложенность) |
| PostCSS | autoprefixer, nesting, минификация |
Современный CSS заменяет многое из препроцессоров: переменные, вложенность, color-mix, calc().
Отладка
DevTools (F12): панель «Styles» (откуда значение и что перебито), «Computed» (итог), блок «Layout» (flex/grid оверлеи), outline: 1px solid red на * для просмотра границ. Типичные причины «не применяется»: специфичность, опечатка, свойство не работает для этого display, перекрыто позднее правило, неверный путь к файлу, кэш (Ctrl+F5).
Частые ошибки
- Забыт
box-sizing: border-boxиviewport. - Фиксированные высоты и размеры в
pxдля текста. 100vhна мобильных (используйтеdvh).overflow: hiddenу предка ломаетsticky.- Убран
outlineбез замены (недоступно с клавиатуры). - Анимация
width,height,topвместоtransform. - Длинные селекторы и
!important. - Горизонтальный скролл из-за элементов шире окна (
max-width: 100%,min-width: 0).