CSS · Урок 5

Селекторы, блочная модель и позиционирование

Самые важные темы 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
■ content
■ padding
■ border
■ margin
.card {
  width: 300px;
  padding: 20px;       /* внутри */
  border: 1px solid #334155;
  margin: 16px auto;   /* снаружи, по центру */
  box-sizing: border-box; /* важный трюк */
}
⚠️
Запомните «правило №1» вёрстки: выставляйте * { 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;
}

Специфичность селекторов

Когда несколько правил претендуют на одно свойство, побеждает самое «сильное» по специфичности. Сила считается как баллы:

#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);
}
💡
Оптимальная длительность — 200–400 мс. Больше — тянется и раздражает, меньше — почти незаметно. 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;
}
⚠️
Трюк работает только для одной строки. Две строки текста — уже не выровняют, используйте Flexbox.

Перенос длинных слов

Домены и 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 вернёт клики.

Тренировка

  1. Сделайте карточку (класс .card) с полями, границей, скруглением и тенью.
  2. Поместите бейдж 😎 поверх угла карточки через position: absolute.
  3. Сделайте пункт меню :hover с изменением фона и подчёркиванием.
  4. Закрепите шапку «липкой» через position: sticky; top: 0.