Современная семантичная вёрстка: практика HTML/CSS, Flexbox, Grid и позиционирование

Практический курс по созданию валидной, семантичной и адаптивной вёрстки на основе реальных макетов. Закрывает пробелы в архитектуре страницы, позиционировании (position) и уверенной работе с Flexbox и Grid.

1. Семантика, валидность и базовая архитектура страницы

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

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

Что такое семантика и зачем она нужна

Семантичная вёрстка — это использование таких элементов и структур, которые описывают смысл контента, а не его внешний вид.

Когда разметка семантична:

  • Браузер и вспомогательные технологии (например, скринридеры) лучше понимают страницу.
  • Поисковые системы точнее интерпретируют структуру.
  • Вам проще поддерживать проект: блоки имеют понятные роли.
  • Стилизация становится устойчивее: меньше случайных зависимостей и переопределений.
  • Важно: семантика не отменяет классы и не запрещает универсальные контейнеры. Она задаёт каркас смысла, а CSS уже отвечает за внешний вид.

    Валидность: что это и почему важна

    Валидность HTML — это соответствие разметки правилам спецификации: правильная вложенность, корректные атрибуты, обязательные части документа, допустимые значения.

    Практический смысл валидности:

  • Меньше «магических» багов, когда браузер молча «чинит» ваш документ по-своему.
  • Легче отлаживать: ошибка обычно локализуется точнее.
  • Выше шанс, что доступность (a11y) будет работать ожидаемо.
  • Проще масштабировать проект и подключать новые компоненты.
  • Проверять валидность стоит регулярно, а не только в конце.

    Полезные инструменты:

  • W3C Markup Validation Service — проверка валидности HTML.
  • MDN: HTML elements reference — справочник по элементам и их назначению.
  • Базовая архитектура страницы: как думать блоками

    Главная привычка, которую нужно выработать: сначала вы строите смысловую карту страницы, и только потом выбираете раскладку (Flexbox/Grid/position) и стили.

    Удобный порядок действий:

  • Определить крупные области страницы: шапка, основное содержимое, подвал.
  • Внутри основного содержимого выделить независимые смысловые части.
  • Для каждой части подобрать семантичный элемент (если он подходит) или использовать нейтральный контейнер.
  • Добавить классы для стилизации и будущих сеток.
  • !Схематичный каркас страницы и связь основных семантических областей

    Ключевые семантические области и когда их применять

    Ниже — базовый набор, который встречается почти в каждом проекте.

  • header — вводная область страницы или конкретного раздела: логотип, заголовок, поисковая строка, навигация.
  • nav — блок навигации по сайту или разделу. Важная идея: nav — для значимых наборов ссылок, а не для любых ссылок в подвале.
  • main — уникальное основное содержимое страницы. Обычно на странице один main.
  • section — тематический раздел страницы. Хорошее правило: section обычно имеет заголовок (явный или доступный).
  • article — самостоятельная единица контента, которая имеет смысл вне контекста страницы: пост, карточка новости, комментарий, товар.
  • aside — боковой или дополнительный контент: рекомендации, связанные ссылки, виджеты, вторичная информация.
  • footer — подвал страницы или раздела: контакты, копирайт, вспомогательная навигация.
  • Быстрая шпаргалка: section, article и div

    | Что выбрать | Когда подходит | Типичный пример | |---|---|---| | article | Контент самодостаточный и может быть переиспользован отдельно | Новость, карточка статьи, отзыв | | section | Это логический раздел страницы, объединяющий несколько элементов | Блок «Преимущества», «Тарифы», «FAQ» | | div | Семантичного элемента нет или вы делаете техническую обёртку для сетки/стилей | Обёртка для Grid, группировка кнопок |

    Пример каркаса документа без привязки к дизайну

    Ниже — пример того, как может выглядеть архитектура типовой страницы. Здесь используются сущности < и >, чтобы показать структуру, не привязываясь к конкретной вёрстке.

    Что важно в этом каркасе:

  • Сначала выделены крупные области, и только потом детали.
  • nav имеет смысловую роль: это именно навигация.
  • main содержит уникальный контент страницы.
  • article используется там, где элементы похожи на независимые сущности (например, карточки материалов).
  • Типовые ошибки архитектуры и как их избегать

  • Использовать div везде: это ухудшает читаемость структуры. Решение: сначала попытаться подобрать семантический элемент, а div оставить для технических обёрток.
  • Делать несколько main на странице: это ломает смысл «главного содержимого». Решение: один main, всё важное — внутри него.
  • Путать section и div: section — это не «просто контейнер», а раздел темы. Решение: если вы не можете назвать этот блок заголовком и темой, вероятно нужен div.
  • Считать nav обязательным в любой группе ссылок: nav — для ключевых маршрутов. Решение: вторичные ссылки в подвале не всегда должны быть nav.
  • Строить сетку до смысла: когда сначала рисуют колонки, а потом пытаются «впихнуть» в них контент, появляются странные обёртки и костыли. Решение: сперва смысловые блоки, затем раскладка.
  • Как это связано с Flexbox, Grid и position

    Семантика и архитектура отвечают на вопрос «что это за блок и зачем он существует». А Flexbox, Grid и position отвечают на вопрос «как этот блок расположен на странице».

    В следующих материалах курса мы будем:

  • раскладывать элементы внутри header, секций и карточек через Flexbox;
  • строить двухколоночные и модульные сетки через Grid;
  • разбирать, где position действительно нужен, а где он создаёт лишние проблемы.
  • Сильная архитектура уменьшает количество ситуаций, когда приходится «чинить» раскладку сложным позиционированием.

    2. Проектирование структуры: header, main, section, footer и компоненты

    Проектирование структуры: header, main, section, footer и компоненты

    В предыдущей статье мы разобрали семантику, валидность и общий каркас страницы. Теперь закрепим это на практике: научимся проектировать структуру до CSS, правильно делить страницу на header, main, section, footer и собирать её из компонентов так, чтобы Flexbox, Grid и позиционирование подключались без костылей.

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

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

    Как думать структурой: области, разделы, компоненты

    Чтобы вёрстка была устойчивой, полезно разделить проектирование на три уровня.

  • Области страницы: крупные части документа, которые встречаются почти всегда. Примеры: header, main, footer, иногда aside.
  • Разделы внутри области: тематические блоки внутри main (или внутри другой области). Обычно это section, иногда article.
  • Компоненты: повторяемые строительные элементы, из которых собираются разделы. Примеры: карточка товара, кнопка, поле ввода, навигационный пункт, модальное окно.
  • Если перепутать уровни, появляются типичные проблемы:

  • сетка начинает диктовать структуру, появляются лишние обёртки;
  • сложно переиспользовать блоки, потому что они «пришиты» к конкретной странице;
  • приходится много использовать position, чтобы «дотянуть» элементы до нужного места.
  • Область header: что в ней должно быть, а что нет

    header — это вводная часть страницы или вводная часть конкретного раздела. Он не равен «верх страницы в пикселях», он про смысл.

    Типичное содержимое header страницы:

  • логотип и название;
  • основная навигация (часто вместе с nav);
  • поиск;
  • кнопки входа/профиля;
  • переключатели языка/темы.
  • Что обычно не стоит помещать в header страницы:

  • основное содержание (каталог, статья, список товаров);
  • уникальный контент страницы, ради которого пользователь пришёл.
  • Важное уточнение: header может быть не только один

    header страницы обычно один, но header допустим и внутри section или article как «шапка раздела»: заголовок, мета-информация, фильтры, управляющие элементы.

    Официальная справка:

  • MDN: header
  • Навигация: когда выделять nav

    nav — это семантическое обозначение значимой навигации. Выделяйте nav, когда набор ссылок реально является маршрутом по сайту или по крупному разделу.

    Хорошие кандидаты на nav:

  • главное меню сайта;
  • навигация по разделу документа;
  • хлебные крошки;
  • пагинация.
  • Сомнительные кандидаты:

  • список «мы в соцсетях»;
  • россыпь случайных ссылок в тексте.
  • Если на странице несколько навигаций, им полезно давать различимые подписи через aria-label на стороне HTML, чтобы вспомогательные технологии отличали их по назначению. На уровне проектирования структуры это означает: каждому nav — своя роль.

    Справка:

  • MDN: nav
  • main: единственное место для уникального содержимого

    main — контейнер для уникального основного содержимого страницы. Это то, что отличает страницу от остальных.

    Правила, которые помогают избежать ошибок:

  • на странице обычно один main;
  • main не должен содержать повторяющиеся элементы интерфейса, которые одинаковы на всех страницах (например, глобальную шапку и подвал);
  • внутри main располагайте разделы, которые описывают содержимое страницы.
  • Справка:

  • MDN: main
  • section: тематический раздел, который можно назвать

    section — это тематический раздел. Практическое правило: если вы можете дать этому блоку заголовок (хотя бы мысленно), section подходит.

    Хорошие примеры section:

  • «Преимущества»;
  • «Тарифы»;
  • «Отзывы»;
  • «Частые вопросы».
  • Плохой пример section:

  • обёртка «просто чтобы сделать сетку»;
  • контейнер «для отступов», который не несёт смысловой темы.
  • Справка:

  • MDN: section
  • article внутри section: когда карточки становятся самостоятельными

    Если внутри секции есть элементы, которые можно представить отдельно от страницы, часто уместнее article.

    Типичные примеры:

  • карточка новости;
  • карточка товара;
  • отзыв;
  • комментарий.
  • Справка:

  • MDN: article
  • footer: подвал страницы и подвал раздела

    footer работает аналогично header:

  • бывает footer страницы (контакты, копирайт, ссылки на документы);
  • бывает footer внутри section или article (например, действия карточки: «в избранное», «поделиться», «читать дальше»).
  • Не делайте footer «контейнером для всего внизу» без смысла: лучше отделять тематические блоки внутри main, а footer оставлять для завершающей информации.

    Справка:

  • MDN: footer
  • Практический алгоритм проектирования страницы

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

  • Опишите страницу одним предложением: что это за страница и что в ней главное.
  • Выпишите области: header, main, footer и при необходимости aside.
  • Разбейте main на тематические части и назовите их.
  • Для каждой тематической части выберите контейнер:
  • 1. section, если есть тема и ожидается заголовок; 2. article, если элементы самодостаточны; 3. нейтральный контейнер, если блок технический (например, обёртка для сетки).
  • Внутри разделов выделите компоненты: карточки, кнопки, формы, списки.
  • Только после этого решайте, где Flexbox, где Grid, а где вообще хватит обычного потока документа.
  • Компоненты: как отделять переиспользуемое от уникального

    Компонент — это часть интерфейса, которую можно:

  • повторить на странице;
  • перенести на другую страницу;
  • использовать в другом контексте без изменения смысла.
  • Признаки хорошего компонента

  • у него одна роль: карточка показывает сущность, кнопка инициирует действие;
  • он не зависит от конкретного места на странице;
  • его внутренности можно стилизовать, не ломая окружение;
  • ему не нужен position ради базовой раскладки.
  • Контейнеры и обёртки: как не утонуть в лишних слоях

    Частая причина «каши» в разметке — когда каждый отступ и каждое выравнивание требуют новую обёртку. В реальности обычно хватает трёх типов контейнеров:

  • контейнер области (например, header страницы);
  • контейнер раздела (например, section «Преимущества»);
  • контейнер сетки/ограничения ширины (технический, без семантической роли).
  • Остальные обёртки добавляйте только если они:

  • объединяют элементы для конкретной раскладки;
  • помогают переиспользовать компонент;
  • отделяют фон секции от контента (частая практическая причина).
  • Типовые схемы, которые удобно применять

    «Каркас + контейнер ширины»

    В большинстве проектов встречается паттерн: смысловая область и вложенный ограничитель ширины.

  • Область отвечает за смысл и фон.
  • Внутренний контейнер отвечает за ширину, центрирование и горизонтальные отступы.
  • Это позволяет делать фон секции на всю ширину экрана, а контент держать в читаемой колонке.

    «Секция = заголовок + контент»

    Если вы делаете section, думайте так:

  • у секции есть заголовок;
  • ниже идёт контент (сетка карточек, список, текст, форма).
  • Так проще держать порядок заголовков, а также удобно переключаться между Flexbox и Grid внутри секции.

    Частые ошибки при проектировании структуры

  • Сначала сетка, потом смысл: появляются случайные обёртки, а компонент невозможно вынести. Сначала смысловые области, потом раскладка.
  • section без темы: если блок нельзя назвать, он обычно не section.
  • Переиспользуемое смешано с уникальным: например, карточка зависит от конкретного родителя и ломается на другой странице. Компонент должен жить сам.
  • main используется как «обёртка для всего»: main только для уникального содержания страницы.
  • Ожидание, что position решит архитектуру: позиционирование помогает точечно, но не заменяет структуру.
  • Мини-шпаргалка выбора элементов

    | Задача | Что выбрать | Почему | |---|---|---| | Верх страницы с логотипом и меню | header + nav | Вводная часть + значимая навигация | | Единственное уникальное содержимое страницы | main | Семантическая зона основного контента | | Блок «Преимущества» с заголовком | section | Тематический раздел, который можно назвать | | Список карточек новостей | section с несколькими article | Секция задаёт тему, карточки самодостаточны | | Низ страницы с контактами и копирайтом | footer | Завершающая информация страницы |

    Как это подготовит вас к Flexbox, Grid и position

    Когда структура спроектирована правильно:

  • Flexbox чаще применяется внутри компонентов и небольших групп (меню, панель действий, выравнивание элементов карточки).
  • Grid чаще применяется на уровне раскладки секции (сетка карточек, двухколоночные блоки, галереи).
  • position остаётся для точечных задач (бейджи, подсказки, декоративные элементы), а не для «сборки макета целиком».
  • В следующих материалах курса мы будем раскладывать типовые области и компоненты через Flexbox и Grid, опираясь на тот каркас и границы ответственности, которые вы научились проектировать здесь.

    3. Блочная модель, отступы и типовые ошибки в раскладке

    Блочная модель, отступы и типовые ошибки в раскладке

    В прошлых статьях вы научились собирать смысловой каркас страницы: header, main, section, footer и компоненты. Теперь нужна вторая опора практической вёрстки: понимание как браузер считает размеры элементов и как отступы реально влияют на раскладку.

    Большая часть «затыков» с Flexbox, Grid и position на практике возникает не из-за самих технологий, а из-за ошибок в базовой геометрии: неожиданно вылез горизонтальный скролл, отступы «схлопнулись», блок не центрируется, а размер «не помещается» в контейнер.

    Блочная модель: из чего состоит размер элемента

    Каждый элемент на странице можно представить как прямоугольник из слоёв.

    !Наглядно показывает, какие части участвуют в размере и в отступах

    Порядок слоёв изнутри наружу:

  • Content — сам контент (текст, изображение, вложенные элементы).
  • Padding — внутренний отступ между контентом и границей.
  • Border — рамка вокруг padding.
  • Margin — внешний отступ до соседних элементов.
  • Важно различать:

  • padding увеличивает «внутреннее пространство» элемента.
  • margin не принадлежит элементу визуально, он задаёт дистанцию снаружи.
  • Как браузер считает ширину и высоту

    В CSS есть два основных подхода к вычислению width и height:

  • box-sizing: content-box — значение width задаёт только content, а padding и border добавляются сверху.
  • box-sizing: border-box — значение width включает content + padding + border, поэтому элемент проще контролировать по размерам.
  • Практическая проблема по умолчанию:

  • у большинства элементов box-sizing равен content-box;
  • вы задаёте width: 300px и padding: 20px;
  • итоговый видимый размер становится больше 300px, что часто ломает сетку.
  • Поэтому в современном подходе почти всегда делают глобальное правило:

    Справка:

  • MDN: box-sizing
  • MDN: Introduction to the CSS box model
  • Отступы: margin и padding как инструмент архитектуры

    Чтобы структура (из прошлых статей) оставалась устойчивой, полезно заранее договориться, где живут отступы.

    Рабочие правила для проектов с компонентами:

  • padding чаще используйте для внутреннего воздуха компонента или секции.
  • margin чаще используйте для разделения соседних блоков.
  • Внутри рядов и сеток предпочитайте gap, а не «маргины у детей».
  • Почему gap удобнее:

  • он задаётся в одном месте (у контейнера);
  • не нужно бороться с «лишними» отступами по краям;
  • лучше читается как правило раскладки.
  • Пример для Flexbox:

    Пример для Grid:

    Справка:

  • MDN: gap
  • Схлопывание внешних отступов: почему «пропал» margin

    Одна из самых частых неожиданностей в начале практики — схлопывание вертикальных margin.

    Суть:

  • у некоторых блочных элементов вертикальные margin не суммируются, а схлопываются в один;
  • это чаще всего происходит между соседними блоками по вертикали и между родителем и первым или последним ребёнком.
  • Пример ситуации:

  • у заголовка сверху margin-top: 24px;
  • вы ожидаете, что внутри секции будет «внутренний» отступ;
  • но margin-top заголовка может «выпасть» наружу секции, визуально создавая отступ над секцией, а не внутри неё.
  • !Поясняет, почему вертикальные margin ведут себя не как "сложение"

    Как решать в реальной вёрстке:

  • добавлять padding-top у родителя вместо надежды на margin-top у первого элемента;
  • добавлять border-top или padding у родителя, если нужно «закрепить» внутренний отступ;
  • использовать display: flow-root у контейнера, когда нужно изолировать поведение потоков в некоторых случаях.
  • Справка:

  • MDN: Collapsing margins
  • MDN: flow-root
  • Центрирование и авто-отступы

    Горизонтальное центрирование блочного элемента фиксированной или ограниченной ширины обычно делается так:

    Ключевые условия:

  • у элемента должна быть ширина меньше доступной (например, через width, max-width или конструкцию min(...));
  • margin-inline: auto распределяет свободное место слева и справа поровну.
  • Справка:

  • MDN: margin-inline
  • MDN: min()
  • Типовые ошибки в раскладке и как их диагностировать

    Ниже — самые частые проблемы, которые маскируются под «не понимаю Flex/Grid/position», но на деле упираются в блочную модель и отступы.

    Горизонтальный скролл «ниоткуда»

    Частые причины:

  • элемент шире контейнера из-за content-box и большого padding;
  • использование width: 100vw для секций, когда вместе с вертикальным скроллбаром это даёт лишнюю ширину;
  • длинная строка без переносов (URL, длинное слово), которая раздвигает блок.
  • Что делать:

  • включить box-sizing: border-box глобально;
  • вместо 100vw чаще использовать width: 100% для блочных секций;
  • для текста применять переносы по ситуации: overflow-wrap: anywhere или более мягкий вариант overflow-wrap: break-word.
  • Справка:

  • MDN: overflow-wrap
  • Вертикальные отступы ведут себя «странно»

    Частые причины:

  • схлопывание margin;
  • у последнего элемента внутри секции есть margin-bottom, который «выпадает» наружу.
  • Что делать:

  • держать вертикальные внутренние отступы секции через padding-block у секции;
  • для списков и заголовков явно контролировать margin в базовых стилях.
  • «Почему между картинкой и низом блока есть щель?»

    Частая причина:

  • изображения по умолчанию строчные и выравниваются по базовой линии текста, из-за чего остаётся место под «хвост» строки.
  • Решение:

    Справка:

  • MDN: display
  • Margin как способ «выравнивать в сетке»

    Симптом:

  • у карточек сетки стоят margin-left и margin-right, появляются лишние отступы по краям и сложные исключения для первого и последнего элемента.
  • Решение:

  • для рядов используйте gap;
  • маргины оставляйте для вертикального разделения независимых блоков.
  • «Высота 100% не работает»

    Частая причина:

  • height: 100% считается от высоты родителя, а у родителя высота не задана явно.
  • Практический подход:

  • для экранных блоков используйте min-height: 100vh (или более современно 100dvh, если вы учитываете мобильные панели);
  • height: 100% применяйте, когда вы точно контролируете высоту цепочки родителей.
  • Справка:

  • MDN: vh
  • Минимальный набор базовых стилей, который экономит время

    В реальных проектах почти всегда применяют базовую «нормализацию», чтобы браузерные дефолты не мешали прогнозируемой раскладке.

    Минимальный практичный старт:

    Если нужен готовый вариант нормализации, посмотрите:

  • normalize.css
  • Как это связано с Flexbox, Grid и position

  • Flexbox и Grid хорошо решают раскладку, но они не отменяют того, что размеры считаются по блочной модели.
  • Большая часть «почему не влезает» — это content-box и неучтённые padding и border.
  • Большая часть «почему отступ не там» — это вертикальные margin и схлопывание.
  • position часто начинают использовать, когда отступы и размеры уже сломаны, но это обычно только усложняет.
  • Когда у вас:

  • продумана архитектура страницы (области, секции, компоненты);
  • включён предсказуемый box-sizing;
  • отступы распределены по правилам (padding внутри, gap в раскладке, margin между независимыми блоками);
  • тогда Flexbox, Grid и позиционирование становятся инструментами, а не «спасательными кругами».

    4. Position: нормальный поток, absolute, relative, fixed, sticky и z-index

    Position: нормальный поток, absolute, relative, fixed, sticky и z-index

    В предыдущих статьях курса мы выстроили архитектуру страницы (семантические области и компоненты) и закрепили геометрию элементов (блочная модель, отступы, box-sizing, gap). Теперь добавим третий слой практики: позиционирование.

    Важно понимать позиционирование правильно: position не заменяет структуру, Flexbox или Grid. В устойчивой вёрстке позиционирование решает точечные задачи — бейджи, иконки, выпадающие панели, «липкие» шапки, перекрытия, слои.

    Нормальный поток документа

    Нормальный поток — это базовое поведение браузера, когда элементы идут один за другим согласно типу отображения (display) и правилам блочной/строчной модели.

  • Блочные элементы занимают всю доступную ширину и идут сверху вниз.
  • Строчные элементы текут внутри строки и переносятся по словам.
  • Flex и Grid меняют правила раскладки детей контейнера, но сами контейнеры по-прежнему живут в нормальном потоке (если их не выводить из него позиционированием).
  • Ключевая мысль: пока вы не применили position (или похожие механики), браузер сам решает, где будет элемент, исходя из потока и раскладки.

    !Сравнение нормального потока и элемента, выведенного из потока

    Какие бывают режимы позиционирования

    Свойство position задаёт режим позиционирования элемента.

    | Значение position | В потоке? | Что меняется | Типичные применения | |---|---|---|---| | static (по умолчанию) | Да | Никаких смещений через top/right/bottom/left | Обычная вёрстка | | relative | Да | Можно сместить элемент относительно его места в потоке | Небольшие подстройки, создание якоря для absolute | | absolute | Нет | Элемент позиционируется относительно ближайшего позиционированного предка | Бейджи, иконки, выпадающие меню, оверлеи внутри блока | | fixed | Нет | Элемент закреплён относительно окна просмотра (viewport) | Липкая панель действий, кнопка «вверх» | | sticky | Да (до порога) | Элемент ведёт себя как relative, но «прилипает» при прокрутке | Липкая шапка секции, заголовки таблиц |

    Справка:

  • MDN: position
  • position: relative

    position: relative оставляет элемент в нормальном потоке, но позволяет визуально сдвинуть его с помощью top, right, bottom, left.

    Главные свойства relative:

  • Место элемента в потоке сохраняется, даже если вы его сдвинули.
  • Сдвиг происходит относительно того места, где элемент был бы в потоке.
  • relative часто используют как контейнер-якорь для абсолютно позиционированных детей.
  • Пример: сдвиг на 4px вниз и 8px вправо.

    Практическое правило: не используйте relative как способ «подогнать» раскладку, если проблему можно решить потоком, gap, Flexbox или Grid. relative хорош для небольших подстроек и для управления слоями/якорями.

    position: absolute

    position: absolute выводит элемент из нормального потока.

    Это означает:

  • Элемент перестаёт занимать место в раскладке.
  • Соседи ведут себя так, будто элемента нет.
  • Элемент можно точно разместить через top/right/bottom/left.
  • Относительно чего считается absolute

    Абсолютное позиционирование считается относительно контейнера позиционирования (containing block). В типичном случае это ближайший предок, у которого position не static.

    Практическая формула поведения:

  • Если у родителя (или ближайшего предка) стоит position: relative (или absolute/fixed/sticky), то absolute-элемент будет позиционироваться относительно этого предка.
  • Если такого предка нет, позиционирование пойдёт относительно начального контейнера (обычно это область документа/viewport, поведение зависит от конкретного кейса и спецификации).
  • Справка:

  • MDN: Containing block
  • Базовый паттерн: бейдж внутри карточки

    Карточка остаётся в потоке, бейдж выводим из потока и крепим к углу.

    Почему здесь уместен absolute:

  • Бейдж декоративен/вспомогателен и не должен влиять на размеры карточки.
  • Бейдж логически принадлежит карточке, поэтому якорим его на .card через position: relative.
  • Центрирование absolute-элемента

    Один из самых устойчивых способов центрировать абсолютный элемент внутри контейнера — через трансформацию.

    Важно: transform меняет визуальное положение, но не возвращает элемент в поток.

    Типовые ошибки с absolute

  • Элемент «улетел» не туда.
  • Элемент перекрывает соседей и ломает кликабельность.
  • Размеры контейнера не учитывают содержимое.
  • Частая причина — отсутствие позиционированного предка. Обычно лечится постановкой position: relative на нужный контейнер-компонент.

    position: fixed

    position: fixed фиксирует элемент относительно окна просмотра. Элемент также выводится из потока.

    Свойства fixed:

  • Элемент «прибит» к viewport и не двигается при прокрутке страницы.
  • Как и absolute, управляется через top/right/bottom/left.
  • Часто используется для плавающих кнопок, фиксированных панелей, уведомлений.
  • Пример: кнопка «наверх» в правом нижнем углу.

    Справка:

  • MDN: position: fixed
  • Практическая осторожность: фиксированные элементы легко перекрывают контент. Обычно им нужно место, либо они должны быть компактными, либо должен быть продуман отступ у body/main.

    position: sticky

    position: sticky — гибрид: элемент остаётся в потоке как обычный, но при прокрутке внутри области прокрутки начинает вести себя как «прилипший».

    Ключевые свойства sticky:

  • Пока не достигнут порог, элемент ведёт себя как relative.
  • Когда достигнут порог, элемент «прилипает» как fixed, но в пределах своего контейнера прокрутки.
  • Для sticky нужно задать хотя бы одно смещение: обычно top.
  • Пример: липкая шапка секции.

    Условия, без которых sticky не работает

    Чаще всего sticky «не работает» по одной из причин:

  • Не задано top (или bottom/left/right).
  • Нет прокрутки (контент не длиннее контейнера).
  • Родитель/предок создаёт неподходящие условия из-за overflow.
  • По overflow: липкость вычисляется в контексте ближайшего прокручиваемого контейнера. Если вы неожиданно задали overflow: hidden или overflow: auto не там, где думали, липкость может ограничиться другим контейнером.

    Справка:

  • MDN: position: sticky
  • Слои, перекрытие и z-index

    Когда элементы перекрывают друг друга, порядок отображения определяется контекстом наложения и z-index.

    Базовая логика слоёв

  • Если два элемента перекрываются, побеждает тот, который выше по правилам наложения.
  • z-index работает только там, где элемент участвует в слоёвом контексте.
  • Справка:

  • MDN: z-index
  • MDN: Stacking context
  • Когда z-index имеет смысл

    Упрощённое практическое правило:

  • z-index применяется к позиционированным элементам (у которых position не static).
  • Также z-index применяется к flex- и grid-элементам, даже если они не позиционированы.
  • Это означает, что z-index: 10 на обычном блочном элементе в потоке может не дать эффекта, если элемент не участвует в нужном контексте.

    Stacking context: почему z-index «не пробивает» наружу

    Самая частая ловушка: вы поставили z-index: 9999, а элемент всё равно под чем-то.

    Причина часто в том, что родитель создал свой контекст наложения, и z-index детей сравнивается только внутри этого контекста.

    Распространённые причины появления нового stacking context (практически важные):

  • position (не static) вместе с z-index (не auto).
  • transform со значением отличным от none.
  • opacity меньше 1.
  • !Почему большой z-index не всегда перекрывает соседний блок

    Практический паттерн: выпадающее меню поверх шапки

  • На шапке задаём слой.
  • На меню задаём слой выше внутри того же контекста.
  • Важно: если вы задаёте z-index на разных «ветках» DOM, сначала убедитесь, что они сравниваются в одном контексте наложения.

    Как выбирать инструмент: поток, Flex/Grid или position

    Чтобы вёрстка была устойчивой и соответствовала архитектуре из прошлых уроков:

  • Используйте нормальный поток для базового вертикального построения страницы.
  • Используйте Flexbox для выравнивания элементов в строке/колонке и управления расстояниями через gap.
  • Используйте Grid для сеток секций, карточек и двухмерных раскладок.
  • Используйте position для локальных задач перекрытия и «прилипания», а не для построения основного макета.
  • Полезный тест: если вы начинаете собирать целую секцию на absolute, скорее всего вы пытаетесь компенсировать плохую структуру, неудачные размеры или неправильную раскладку.

    Мини-чеклист отладки position и z-index

  • Элемент должен смещаться, но не смещается.
  • - Проверьте, что position не static. - Проверьте, что вы задали top/right/bottom/left.
  • absolute позиционируется «от страницы», а не от блока.
  • - Проверьте ближайшего предка с position не static.
  • sticky не липнет.
  • - Проверьте top. - Проверьте, есть ли прокрутка. - Проверьте overflow у предков.
  • z-index не работает.
  • - Проверьте, участвует ли элемент в слоёвом контексте. - Найдите, не создаёт ли родитель отдельный stacking context.

    Связь с архитектурой страницы и компонентами

    Позиционирование становится предсказуемым, если у вас:

  • есть понятные контейнеры компонентов (например, .card), на которые можно поставить position: relative как якорь;
  • отступы и размеры контролируются через блочную модель и gap, а не через хаотичные сдвиги;
  • крупная раскладка делается Flexbox/Grid, а position оставлен для точечных «слоёв».
  • В следующих материалах мы будем применять эти правила к типовым компонентам: выпадающим меню, модальным окнам и сложным секциям, где важно не перепутать раскладку сетками и позиционирование.

    5. Flexbox на практике: оси, выравнивание, перенос и типовые паттерны

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

    Flexbox — это инструмент раскладки в одном измерении: либо по горизонтали, либо по вертикали. Он идеален для интерфейсных «полос» и «групп»: меню в шапке, панель действий, строка фильтров, карточка с кнопками, выравнивание элементов внутри компонента.

    Связь с предыдущими материалами курса такая:

  • Семантика и архитектура определяют, какие блоки существуют (header, nav, main, section, компоненты).
  • Блочная модель и отступы определяют, как элементы считаются по размерам (box-sizing, padding, gap).
  • position решает точечные задачи перекрытия и прилипания.
  • Flexbox теперь отвечает на вопрос: как удобно выстроить и выровнять элементы внутри области или компонента, не ломая поток и не прибегая к position.
  • Модель Flexbox: контейнер и элементы

    Flexbox включается у родителя:

  • Элемент с display: flex — это flex-контейнер.
  • Его непосредственные дети — flex-элементы.
  • Важно: Flexbox влияет только на расположение детей контейнера. Внешняя архитектура страницы (области, секции) при этом остаётся в нормальном потоке, как мы обсуждали в теме про position.

    Оси Flexbox: главный источник большинства ошибок

    В Flexbox всегда есть две оси:

  • главная ось (main axis) — вдоль неё элементы выстраиваются «в ряд»
  • поперечная ось (cross axis) — перпендикулярна главной
  • Главная ось зависит от flex-direction.

    !Как меняются главная и поперечная оси при row и column

    flex-direction

    flex-direction задаёт направление главной оси.

  • row — главная ось слева направо
  • column — главная ось сверху вниз
  • row-reverse и column-reverse меняют направление (используйте осторожно, чтобы не путать порядок чтения)
  • Выравнивание: justify-content, align-items, align-content

    Три свойства звучат похоже, но работают по-разному. Большая часть путаницы — из-за того, что люди не привязывают их к осям.

    justify-content: распределение по главной оси

    justify-content распределяет элементы вдоль главной оси.

    Типовые значения:

  • flex-start — прижать к началу
  • center — центрировать
  • space-between — равные промежутки между элементами
  • space-around и space-evenly — варианты распределения с учётом краёв
  • align-items: выравнивание по поперечной оси

    align-items выравнивает каждый элемент по поперечной оси.

    Типовые значения:

  • stretch (по умолчанию) — растянуть по поперечной оси, если есть место
  • center — выровнять по центру
  • flex-start / flex-end — прижать к краю
  • align-content: выравнивание строк при переносе

    align-content работает только если:

  • включён перенос (flex-wrap: wrap)
  • есть несколько строк элементов
  • есть свободное место по поперечной оси
  • Это свойство распределяет строки как группы, а не отдельные элементы.

    Быстрая таблица «что куда»

    | Задача | Свойство | Ось | |---|---|---| | Сдвинуть элементы по горизонтали в row | justify-content | главная | | Сдвинуть элементы по вертикали в row | align-items | поперечная | | Управлять вертикальным распределением нескольких строк в row при wrap | align-content | поперечная |

    Справка:

  • MDN: justify-content
  • MDN: align-items
  • MDN: align-content
  • Отступы во Flexbox: gap вместо маргинов

    Как мы обсуждали в теме про блочную модель, в рядах и сетках удобнее использовать gap, потому что:

  • правило задаётся в одном месте
  • нет «лишних» отступов по краям
  • не нужно исключений для первого и последнего элемента
  • Справка:

  • MDN: gap
  • Перенос: flex-wrap и типичная «поломка» на маленьких экранах

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

    !Разница между nowrap и wrap

    Полезный шаблон для «плитки» на Flexbox:

    Идея такая:

  • 280px — желаемая минимальная ширина карточки
  • контейнер сам решит, сколько карточек помещается в ряд
  • при нехватке места элементы переносятся
  • Справка:

  • MDN: flex-wrap
  • Размеры flex-элементов: flex-grow, flex-shrink, flex-basis и сокращение flex

    Три свойства управляют тем, как элемент занимает место вдоль главной оси.

  • flex-basis — базовый размер элемента по главной оси
  • flex-grow — может ли элемент расти, если есть свободное место
  • flex-shrink — может ли элемент сжиматься, если места не хватает
  • Обычно это пишут сокращённо:

    Формат: flex: grow shrink basis.

    Практически полезные варианты:

    | Задача | Рекомендуемый flex | Что получится | |---|---|---| | Элемент фиксирован по содержимому и не растёт | flex: 0 0 auto | держит ширину контента | | Элемент занимает всё оставшееся место | flex: 1 1 auto | «резиновый» блок | | Карточки с минимальной шириной и переносом | flex: 1 1 280px | адаптивная плитка |

    Справка:

  • MDN: flex
  • MDN: flex-basis
  • MDN: flex-grow
  • MDN: flex-shrink
  • Важная практика: min-width и «почему не сжимается»

    Иногда flex-элемент отказывается сжиматься, даже если места не хватает. Частая причина: у flex-элементов есть ограничение по минимальному размеру из-за содержимого.

    Если внутри длинный текст, ссылка или неразрывная строка, элемент может «продавить» контейнер.

    Частое решение для элемента, который должен уметь сжиматься:

    И отдельно, для текста:

    Справка:

  • MDN: min-width
  • MDN: overflow-wrap
  • Авто-отступы как приём выравнивания

    В Flexbox margin со значением auto может «съесть» свободное место и раздвинуть элементы.

    Классический паттерн: справа прижать блок действий.

    Это часто лучше, чем justify-content: space-between, потому что:

  • логотип и меню остаются группой
  • действия гарантированно прижаты вправо
  • Справка:

  • MDN: margin
  • Типовые паттерны Flexbox в реальной вёрстке

    Ниже — набор схем, которые вы будете повторять в большинстве интерфейсов. Они опираются на архитектуру из первых статей: мы раскладываем внутри смысловых областей и компонентов.

    Шапка сайта: логотип, меню, действия

    Структурно это обычно header и внутри nav.

    Что важно:

  • gap задаёт расстояния между пунктами меню
  • margin-left: auto уводит действия вправо
  • всё остаётся в потоке, без position
  • «Media object»: иконка слева, текст справа

    Паттерн для карточек, уведомлений, пунктов списка.

    Почему это устойчиво:

  • иконка не растягивается
  • текст занимает остаток
  • min-width: 0 помогает не раздувать строку
  • Кнопки в строку с переносом

    Часто нужно: кнопки идут в ряд, но на узком экране переносятся.

    «Прижать к низу карточки»: кнопки всегда снизу

    Это очень частая задача, и для неё Flexbox подходит лучше, чем позиционирование.

    Идея:

  • карточка — колонка
  • тело карточки растягивается и занимает свободное пространство
  • футер остаётся внизу без absolute
  • Центрирование по двум осям

    Для простых случаев (например, заглушка загрузки) можно центрировать так:

    Осторожность: если вы делаете так целую страницу, контролируйте высоту контейнера через min-height.

    Типовые ошибки и как их быстро чинить

    Перепутали оси и «не то выравнивается»

    Проверьте:

  • flex-direction
  • какое свойство отвечает за главную ось (justify-content) и за поперечную (align-items)
  • Использовали margin у детей вместо gap

    Если вы видите правила вроде :last-child { margin-right: 0; }, почти всегда проще заменить это на gap у контейнера.

    Пытаетесь собрать макет целиком на Flexbox

    Flexbox силён в одном измерении. Если вам нужна полноценная двухмерная сетка секции (строки и колонки одновременно), чаще правильнее использовать Grid. В следующих материалах курса мы это разберём и научимся выбирать инструмент.

    При переносе не работает align-content

    Проверьте по порядку:

  • Включён ли flex-wrap: wrap
  • Есть ли реально несколько строк
  • Есть ли свободное место по поперечной оси
  • Как выбирать Flexbox относительно Grid и position

    Практическое правило, которое связывает все темы курса:

  • Если нужно выстроить элементы в линию или колонку и управлять расстояниями — используйте Flexbox.
  • Если нужна сетка секции с контролем и строк, и колонок — используйте Grid.
  • Если нужно перекрытие, слой, «бейдж поверх», «липкое» или «поверх всего» — используйте position точечно.
  • Справка по Flexbox:

  • MDN: CSS Flexible Box Layout
  • MDN: Basic concepts of flexbox
  • 6. CSS Grid: области, треки, авторазмещение и адаптивные сетки

    CSS Grid: области, треки, авторазмещение и адаптивные сетки

    Grid — это инструмент раскладки в двух измерениях: одновременно по колонкам и по строкам. Если Flexbox идеален для «полос» (меню, панель действий, ряд кнопок), то Grid удобнее, когда вы раскладываете секцию целиком: сетку карточек, двухколоночный блок, галерею, страницу с сайдбаром.

    Связь с предыдущими темами курса:

  • Семантика и архитектура отвечают на вопрос что за блоки на странице (header, main, section, компоненты).
  • Блочная модель и отступы отвечают как считаются размеры (в том числе почему выгодно использовать gap).
  • position отвечает за слои и точечные эффекты (бейджи, выпадашки, sticky).
  • Grid отвечает за двухмерную раскладку внутри смысловых областей и секций.
  • !Карта терминов Grid: линии, треки, области и неявная сетка

    Базовая модель Grid: контейнер, треки и линии

    Grid включается у родителя:

  • Элемент с display: gridgrid-контейнер.
  • Его непосредственные дети — grid-элементы.
  • Треки

    Трек — это колонка или строка сетки.

  • Колонки задаются через grid-template-columns.
  • Строки задаются через grid-template-rows.
  • Пример: 3 колонки и автостроки по высоте контента:

    Линии сетки

    Линии — это границы между треками. В Grid многие вещи задаются не размерами элементов, а линиями, между которыми элемент растягивается.

    На практике это полезно, когда нужно:

  • растянуть блок на 2 колонки;
  • сделать «герой»-блок шире остальных;
  • разместить элемент в конкретной области.
  • Единицы и функции, без которых Grid неудобен

    fr

    fr — это доля доступного пространства.

  • grid-template-columns: 1fr 2fr означает: свободное место делится на 3 части, первая колонка получит 1 часть, вторая — 2 части.
  • Справка: MDN: fr unit

    repeat()

    repeat() сокращает запись одинаковых колонок/строк.

    Справка: MDN: repeat()

    minmax()

    minmax(минимум, максимум) задаёт диапазон размера трека.

    Типовой смысл:

  • минимум защищает от слишком узкой колонки;
  • максимум позволяет треку растягиваться.
  • Справка: MDN: minmax()

    Явная и неявная сетка

    Явная сетка

    Явная (explicit) сетка — это то, что вы объявили через grid-template-columns и grid-template-rows.

    Неявная сетка

    Неявная (implicit) сетка появляется, если элементов больше, чем ячеек в явной сетке, либо если вы разместили элемент на линиях, которые выходят за объявленную сетку.

    Управлять неявными треками можно так:

  • grid-auto-rows задаёт высоту строк, которые создаются автоматически.
  • Аналогично есть grid-auto-columns.
  • Справка: MDN: grid-auto-rows

    Grid Areas: раскладка «словами» через области

    grid-template-areas позволяет описать раскладку как схему из имён областей. Это особенно удобно для архитектуры страницы и крупных секций: видно, что где находится, и легче поддерживать.

    Пример: страница с сайдбаром

    Структура (псевдокод, без HTML-тегов):

    CSS:

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

  • Имена областей задаются строками, где каждый токен — это ячейка.
  • Одна и та же область должна образовывать прямоугольник.
  • Точку . используют для пустой ячейки.
  • Справка: MDN: grid-template-areas

    Когда области лучше, чем «линии»

  • Когда раскладка крупная и читаемость важнее микрооптимизации.
  • Когда вы хотите быстро менять макет в медиазапросах.
  • Когда элементы логически соответствуют областям (шапка, меню, контент, подвал).
  • Авторазмещение: как Grid сам раскладывает элементы

    Если вы не задаёте явные координаты (grid-column, grid-row), Grid использует алгоритм авторазмещения.

    Ключевые настройки:

  • grid-auto-flow — направление заполнения и поведение.
  • Пример: элементы заполняют сетку по строкам:

    Иногда полезен dense, чтобы «уплотнять» раскладку и стараться заполнять пустоты:

    Важная осторожность: dense может визуально менять порядок элементов. Это не всегда подходит, если порядок чтения критичен.

    Справка: MDN: grid-auto-flow

    Размещение элементов: span и работа по линиям

    Вы можете управлять тем, сколько колонок/строк занимает элемент.

    Span: занять несколько треков

  • span 2 означает: занять две колонки от текущей позиции.
  • Справка: MDN: grid-column

    Тонкий момент про отступы

    Как и во Flexbox, для сеток почти всегда лучше использовать gap, а не маргины у детей:

  • меньше исключений;
  • проще поддержка;
  • предсказуемые края сетки.
  • Справка: MDN: gap

    Адаптивные сетки: рабочие паттерны

    Адаптивность в Grid чаще строится не на «магии», а на сочетании:

  • minmax() для безопасного минимума;
  • auto-fit или auto-fill для автоматического количества колонок;
  • медиазапросов там, где макет реально меняется.
  • Плитка карточек без медиазапросов

    Частый паттерн для секций в main: количество колонок подстраивается само.

    Как это читать:

  • minmax(240px, 1fr) говорит: карточка не должна быть уже 240px, но может растягиваться.
  • auto-fit говорит: помещай столько колонок, сколько влезет.
  • Справка:

  • MDN: repeat()
  • MDN: minmax()
  • auto-fit и auto-fill: коротко про разницу

  • auto-fit старается «схлопывать» пустые колонки и отдавать место существующим элементам.
  • auto-fill может оставлять пустые колонки как треки, даже если элементов меньше.
  • В большинстве интерфейсных плиток чаще подходит auto-fit, потому что он визуально ожидаем.

    Справка: MDN: repeat()

    Перестройка areas на мобильном

    Там, где меняется сама архитектура раскладки, проще явно переключить grid-template-areas.

    Это хорошо стыкуется с темой архитектуры страницы: header, main (content), aside (sidebar), footer остаются смысловыми блоками, а Grid лишь меняет их расположение.

    Выбор инструмента: Grid, Flexbox или position

    Практическая логика курса остаётся той же:

  • Flexbox берите для выравнивания и распределения в линии (меню, панель, «медиа-объект»).
  • Grid берите для двухмерной сетки секции или компоновки страницы.
  • position оставляйте для слоёв и точечных эффектов, а не для построения сетки.
  • Если вы ловите себя на том, что пытаетесь «собрать всю секцию» на position: absolute, обычно проблема не в Grid, а в архитектуре, размерах или неверном выборе инструмента.

    Мини-чеклист отладки Grid

  • Сетка «не появилась».
  • - Проверьте, что display: grid стоит на родителе. - Проверьте, что вы задаёте колонки (grid-template-columns).
  • Элемент не занимает нужное место.
  • - Убедитесь, что вы задаёте размещение именно grid-элементу (не вложенному ребёнку). - Если используете areas, проверьте совпадение имени grid-area и схемы grid-template-areas.
  • Сетка ломается по ширине.
  • - Проверьте, что базово включён box-sizing: border-box. - Для текстовых блоков подумайте о переносах (overflow-wrap).
  • Появились странные «дыры».
  • - Проверьте, не создаёте ли вы их ручным размещением. - Осторожно применяйте grid-auto-flow: dense, помня про возможную перестановку.

    Справка по Grid: MDN: CSS Grid Layout

    7. Сборка страницы из макета: адаптивность, состояния и финальная проверка

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

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

    !Общая карта этапов, чтобы понимать последовательность работ

    Как читать макет перед вёрсткой

    Цель на старте — превратить макет в план структуры и компонентов, а не сразу писать CSS.

    Удобный порядок:

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

  • Семантика и архитектура отвечают за пункты 1–3.
  • Блочная модель и отступы защищают от «не влезает» и «поехали края».
  • Flexbox и Grid закрывают пункты 4–5.
  • position закрывает пункт 6.
  • Стратегия адаптивности

    Адаптивность — это не набор хаотичных медиазапросов, а правила, по которым ваш макет меняется на разных ширинах.

    Базовая идея

  • Сначала делайте устойчивую раскладку, которая сама сжимается: проценты, min() и сетки auto-fit.
  • Потом добавляйте медиазапросы только там, где реально меняется архитектура: порядок блоков, количество колонок, видимость элементов.
  • Контейнер ширины как «рельсы» для всей страницы

    Чаще всего вам нужен повторяемый технический контейнер, который:

  • ограничивает ширину контента;
  • центрирует;
  • даёт безопасные внутренние отступы.
  • Пример на CSS:

    Так вы отделяете:

  • фон секции на всю ширину;
  • контент секции в читаемой колонке.
  • Справка: MDN: min(), MDN: margin-inline

    Медиазапросы: где они действительно нужны

    Используйте медиазапросы для изменений, которые нельзя получить «резиновыми» размерами.

    Типовые случаи:

  • переход с 3 колонок на 2 и на 1, если автосетка не подходит визуально;
  • перестройка областей страницы (например, боковая колонка переезжает вниз);
  • упрощение шапки (меню превращается в кнопку);
  • изменение отступов и размеров кликабельных элементов под мобильные.
  • Пример базового медиазапроса:

    Справка: MDN: @media

    Адаптивные сетки карточек без медиазапросов

    Паттерн, который часто покрывает 80% задач в секциях:

    Что это даёт:

  • карточки не становятся слишком узкими;
  • колонок столько, сколько помещается;
  • меньше точек перелома.
  • Справка: MDN: repeat(), MDN: minmax()

    Резиновая типографика и отступы без «скачков»

    Если в макете размеры шрифтов и отступов «ступенчатые», не обязательно делать много переломов. Часто помогает clamp().

    Пример:

    Как это читать:

  • 24px — минимум;
  • 3vw — плавный рост от ширины окна;
  • 40px — максимум.
  • Справка: MDN: clamp()

    Сборка секций: как выбирать Flexbox, Grid и поток

    Ниже — практическая логика выбора, которая связывает весь курс.

  • Нормальный поток используйте для вертикального «скелета» страницы.
  • Flexbox используйте для групп в одну линию или колонку: меню, панель действий, «иконка + текст», ряд кнопок.
  • Grid используйте для сеток секций и двухмерных раскладок: карточки, галереи, двухколоночные блоки.
  • position используйте точечно: бейджи, выпадающие панели, липкие элементы, перекрытия.
  • Если вы ловите себя на попытке собрать целую секцию на position: absolute, почти всегда проблема в структуре или в неверно выбранном инструменте.

    Состояния компонентов: интерактивность и доступность

    В макетах обычно показывают только «идеальное» состояние. В реальном интерфейсе нужно заложить ещё несколько.

    Минимальный набор состояний

    Для интерактивных элементов обычно нужны:

  • обычное состояние;
  • :hover для мыши;
  • :focus-visible для клавиатуры;
  • :active на момент нажатия;
  • :disabled для недоступного состояния.
  • Практическое правило: фокус должен быть видимым. Не убирайте фокус «ради красоты», лучше стилизуйте.

    Пример:

    Справка: MDN: :focus-visible, MDN: :disabled

    Состояния форм: что часто забывают

    В полях ввода важно продумать:

  • фокус;
  • ошибка (например, красная рамка и текст подсказки);
  • успешное состояние;
  • :disabled.
  • Полезно держать стили ошибок отдельным классом состояния (а не пытаться собрать всё селекторами), чтобы их было проще включать из логики приложения.

    Анимации и уважение к настройкам пользователя

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

    Справка: MDN: prefers-reduced-motion

    Финальная проверка: чеклист перед сдачей

    Структура и семантика

  • На странице есть одна основная область контента.
  • Заголовки идут в логичном порядке.
  • Навигация размечена как навигация, а не просто списком ссылок.
  • Повторяемые компоненты одинаково устроены в разных местах.
  • Если сомневаетесь, прогоните разметку через валидатор.

    Инструмент: W3C Markup Validation Service

    Геометрия, отступы и переполнения

  • Глобально включён box-sizing: border-box.
  • В сетках используется gap, а не сложные маргины у детей.
  • Нет горизонтального скролла на типовых ширинах.
  • Изображения не ломают контейнеры.
  • Полезные проверки:

  • в DevTools включить подсветку overflow;
  • временно поставить outline на крупные блоки, чтобы видеть границы.
  • Справка: MDN: box-sizing, MDN: gap

    Адаптивность

    Проверьте минимум такие сценарии:

  • узкий экран: одна колонка, читабельные отступы, кнопки не «слиплись»;
  • средний экран: 2 колонки там, где ожидается;
  • широкий экран: контент не растягивается до неудобной длины строки.
  • Если у вас есть перестройка сетки, убедитесь, что она сделана Grid-ом или медиазапросом, а не absolute.

    Состояния и управление с клавиатуры

  • Все интерактивные элементы имеют понятные :hover и :focus-visible.
  • Фокус не «прячется».
  • Можно пройтись по странице клавишей Tab, и порядок логичен.
  • Справка: MDN: :hover, MDN: outline

    Слои и перекрытия

  • Выпадающие элементы не прячутся под соседними блоками.
  • z-index используется осознанно и не превращается в гонку «9999».
  • Липкие элементы не перекрывают контент.
  • Справка: MDN: z-index, MDN: Stacking context

    Производительность как часть качества

  • Изображения не больше, чем нужно по фактическому размеру.
  • Нет лишних тяжёлых эффектов, которые не влияют на смысл.
  • Шрифтов не слишком много по начертаниям.
  • Для быстрой диагностики используйте отчёт Lighthouse в DevTools.

    Справка: Google Lighthouse

    Итог: что значит «страница собрана правильно»

    Страница считается собранной качественно, когда:

  • архитектура понятна и семантична;
  • основная раскладка сделана потоком, Flexbox и Grid по назначению;
  • position решает точечные задачи, а не «держит макет»;
  • адаптивность предсказуема и не разваливается между ширинами;
  • состояния и фокус оформлены, интерфейс можно пройти клавиатурой;
  • финальные проверки не находят критичных проблем.
  • Это и есть практический результат курса: не набор отдельных свойств, а последовательный процесс сборки, который масштабируется на любые макеты.