Селекторы, блочная модель и позиционирование
Самые важные темы CSS: как точно выбрать элемент, как устроен «ящик» и как управлять положением блоков.
Селекторы
Селектор решает, к каким элементам применить правила. Основные виды:
p /* тег */
.card /* класс */
#header /* id */
nav a /* потомок (внутри nav) */
ul > li /* прямой ребёнок */
h1, h2, h3 /* группа */
a:hover /* псевдокласс состояния */
input:focus /* элемент в фокусе */
li:nth-child(2)/* каждый второй элемент */
id — сильнее класса, класс — сильнее тега. Специфичность (сила) складывается из количества id → классов → тегов. «Каскад» плюс специфичность называются «каскадностью CSS».Блочная модель (box model)
Каждый элемент — это «ящик» с четырьмя слоями. Внутрь наружу:
- content — контент;
- padding — внутренний отступ (фон тоже красится);
- border — граница;
- margin — внешний отступ от соседей.
.card {
width: 300px;
padding: 20px; /* внутри */
border: 1px solid #334155;
margin: 16px auto; /* снаружи, по центру */
box-sizing: border-box; /* важный трюк */
}
* { box-sizing: border-box }. Иначе width не включает в себя padding и border, и блоки неожиданно «распухают».Типы отображения: display
| Свойство | Поведение |
|---|---|
block | Блок на всю ширину, каждый на новой строке |
inline | В строку с текстом, нельзя ширину/высоту |
inline-block | Как inline, но с размерами и отступами |
none | Элемент исчезает из потока |
flex / grid | Раскладка (следующий урок) |
Позиционирование: position
Атрибут управляет, как элемент размещается относительно чего-либо.
.static { position: static; } /* по умолчанию */
.relative { position: relative; top: 10px; } /* сдвиг от своего места */
.absolute { position: absolute; top: 0; right: 0; } /* относительно ближайшего positioned родителя */
.fixed { position: fixed; bottom: 20px; } /* относительно окна браузера */
.sticky { position: sticky; top: 0; } /* прилипает при прокрутке */
z-index (работает только у positioned-элементов). absolute привязывается к ближайшему родителю с relative/absolute/fixed.Фоновые эффекты
.hero {
background: linear-gradient(135deg, #0ea5e9, #6366f1);
box-shadow: 0 8px 30px rgba(0,0,0,.3);
border-radius: 16px;
padding: 40px;
}
Специфичность селекторов
Когда несколько правил претендуют на одно свойство, побеждает самое «сильное» по специфичности. Сила считается как баллы:
id— 1 0 0 (счётчик идентификаторов);- класс, атрибут, псевдокласс — 0 1 0;
- тег и псевдоэлемент — 0 0 1.
#btn /* 100 — сильнейший */
.btn /* 010 */
button.link /* 011 — тег + класс */
button /* 001 — слабейший */
id-селекторов и !important превращает стили в войну. Правило команды: работаем классами, id оставляем для JS, а !important — вообще никогда.Псевдоэлементы ::before и ::after
Псевдоэлементы добавляют на страницу «невидимые» сущности, видимые только в CSS. Идеальны для декоративных деталей без лишнего HTML:
.badge::after {
content: " ⭐";
color: #fbbf24;
}
.card::before {
content: "";
display: block;
width: 40px;
height: 4px;
background: linear-gradient(90deg, #38bdf8, #818cf8);
border-radius: 99px;
margin-bottom: 12px;
}
::before и ::after обязательно должен быть content — даже пустой, иначе они не отобразятся. «Пунктирная линия» и иконки-акценты — их коронные приёмы.box-shadow и border-radius
Тень задаётся сдвигом, размытием и растяжением, а скругление может быть разным для каждого угла:
.card {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
border-radius: 12px 12px 0 0; /* верх круглый, низ квадратный */
border-radius: 50%; /* из квадрата — круг */
}
| Части box-shadow | Значение |
|---|---|
0 4px | сдвиг по X и Y |
6px | размытие |
-1px | растяжение (отрицательное — сжатие) |
rgba(...) | цвет с прозрачностью |
overflow и видимость
Что делать, когда контент не помещается в блок? Управляем свойством overflow:
.scroll { overflow: auto; } /* появится полоса прокрутки */
.hidden { overflow: hidden; } /* всё лишнее обрежется */
.ellipsis {
overflow: hidden;
text-overflow: ellipsis; /* многоточие в конце */
white-space: nowrap; /* без переносов */
}
z-index и контексты наложения
Свойство z-index поднимает элементы над соседями — но только среди позиционированных (relative, absolute, fixed и sticky):
.modal { position: fixed; z-index: 100; }
.toast { position: fixed; z-index: 200; } /* выше модалки */
opacity, transform или filter (не значение none), внутри него создаётся собственный «контекст наложения» — и z-index детей перестанет вылезать «наружу» из родителя.Плавные переходы: transition
Без transition изменения свойств происходят мгновенно и «дёрганно». Переходы делают их плавными:
.btn {
background: #1e293b;
transition: background-color .3s ease, transform .3s ease;
}
.btn:hover {
background-color: #38bdf8;
transform: translateY(-2px);
}
ease — разумное значение по умолчанию.transform: translate, rotate, scale
Свойство смещает, поворачивает и масштабирует элемент — все соседи остаются на месте, что дёшево для браузера:
.moving { transform: translate(20px, 10px); } /* сдвиг */
.rotated { transform: rotate(45deg); } /* поворот */
.zoomed { transform: scale(1.2); } /* масштаб */
.skewed { transform: skew(10deg); } /* наклон */
/* комбинация: тогда ставьте все через пробел */
.combo { transform: translate(10px) rotate(15deg) scale(1.1); }
translate(...) rotate(...) и rotate(...) translate(...) дают разный результат композиции.margin и padding: хитрости
Отрицательный margin «выедает» пространство у соседей, а margin: auto центрирует горизонтально при ограниченной ширине:
.overlap { margin-top: -20px; } /* натянуть блок на предыдущий */
.center { margin: 0 auto; width: 600px; } /* блок по центру */
.tight { padding: 20px; } /* сразу все стороны */
/* padding сокращённо: сверху правый низу левый */
.box { padding: 10px 20px 30px 40px; }
margin сражается с границей родителя (эффект схлопывания). Не решайте это стилями — просто вешайте на родителя padding или border.Скрыть элемент: display vs visibility vs opacity
Скрыть блок можно тремя способами — у каждого своё поведение:
| Свойство | Место на странице | События |
|---|---|---|
display: none | убирает полностью | не срабатывают |
visibility: hidden | остаётся пустым | не срабатывают |
opacity: 0 | виден на месте | срабатывают |
opacity: 0 + hover — готовый «появляющийся» элемент, который не двигает соседей. А display: none переключают аккордеоны и вкладки.Курсор и выделение: cursor, user-select
Курсор подсказывает, что элемент интерактивен, а выделение можно запрещать из интерфейсных соображений:
.clickable { cursor: pointer; }
.drag { cursor: grab; }
.blocked { cursor: not-allowed; }
.no-select { user-select: none; }
.text { cursor: text; }
user-select: none ставится точечно (кнопки, иконки), но не на весь текст — иначе люди не смогут скопировать цитату. Доступность важнее.Универсальный селектор и «сброс»
Звёздочка берёт все элементы сразу. Классика — выравнивание «коробки»:
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
min-width и max-width
Ограничить диапазон ширины блока:
.container {
max-width: 1080px; /* не шире */
margin: 0 auto;
}
.sidebar {
min-width: 180px; /* не уже */
}
min-height и растяжение
Блок гарантированно занимает минимум высоты, но может расти:
.hero { min-height: 60vh; }
.card { min-height: 220px; }
vh — 1% высоты окна. Такой «диван» с hero-секцией гарантирует полноэкранный первый экран без указок.Вертикальное центрирование текста
Старый трюк: высота строки = высоте блока центрирует одну строку:
.pill {
height: 40px;
line-height: 40px;
text-align: center;
}
Перенос длинных слов
Домены и URL не умещаются в узкие блоки. Скажите им переноситься:
.url {
word-break: break-all;
overflow-wrap: anywhere; /* перенос по допустимым точкам */
}
Одна строка с многоточием
Рецепт из трёх строк — «Текст, который не помещается…»:
.title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Бейджи на отрицательных margin
Отрицательный margin «выедает» пространство — так бейдж наезжает на край карточки:
.card { position: relative; padding-top: 30px; }
.badge {
position: absolute;
top: -12px;
left: 16px;
background: #38bdf8;
border-radius: 99px;
}
object-fit для картинок
Вписать изображение в рамку блока, не искажая пропорции:
.thumb {
width: 200px;
height: 150px;
object-fit: cover; /* заполнить, обрезав лишнее */
object-fit: contain; /* целиком внутри, с полями */
}
aspect-ratio: пропорции блоков
Задать соотношение сторон без знания конкретной высоты:
.video-frame {
aspect-ratio: 16 / 9;
}
.avatar {
aspect-ratio: 1; /* квадрат */
}
outline против border
«Обводка» не влияет на размеры и не «схлопывается», а border вёрстку двигает:
button:focus {
outline: 3px solid #38bdf8;
outline-offset: 2px;
}
outline повторяет border-radius примерно, но отстаёт в современных браузерах — уводите и её через outline-offset.filter: перекрасить мир
Фильтры применяются к картинкам и фонам без фотошопа:
.bw { filter: grayscale(100%); }
.bright { filter: brightness(1.15); }
.blur-in { filter: blur(4px); }
.sepia { filter: sepia(0.6); }
filter: grayscale(0.8) brightness(1.1).Загрузка CSS и порядок
Файлы стилей подключаются в <head>; тот, что объявлен позже, перекрывает раннего при прочих равных:
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="style.css"> /* выше в приоритете */
Иерархия: оформление через класс
Стиль по тегу быстро «перерастает». Для переиспользуемых деталей правильнее классы:
<button class="btn">Сохранить</button>
<a class="btn" href="/profile">Профиль</a>
.btn {
padding: 10px 18px;
border-radius: 8px;
background: #1e293b;
}
pointer-events: доступность кликов
Клики и наведение можно «прокалывать» сквозь декоративный слой:
.overlay {
position: fixed;
inset: 0;
pointer-events: none; /* клики уходят вниз */
}
pointer-events: none лучший друг. Для игровых интерфейсов: auto вернёт клики.Тренировка
- Сделайте карточку (класс
.card) с полями, границей, скруглением и тенью. - Поместите бейдж
😎поверх угла карточки черезposition: absolute. - Сделайте пункт меню
:hoverс изменением фона и подчёркиванием. - Закрепите шапку «липкой» через
position: sticky; top: 0.