Введение

CSS: селекторы и блочная модель

В этом занятии разберём, как подключать стили к странице, как браузер выбирает «победившее» правило (специфичность и каскад), и как устроена блочная модель — основа вёрстки.

Потом закрепим на практике: подключение CSS, стилизация шапки, отступы и отладка в DevTools. Компонент — это повторяемый кусок интерфейса: кнопка, карточка товара, шапка сайта; у него свои стили и часто свой кусок разметки.

Подключение CSS

Три способа подключить стили

CSS можно добавить к странице тремя способами: (1) inline — атрибут style у элемента; (2) internal — тег <style> в <head>; (3) external — отдельный файл через <link>.

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

Подключение CSS · способ 1

Способ 1. Стили в атрибуте style

Inline — это запись правил прямо в разметке, в атрибуте style. Например: <p style="color: red;">. Подходит для разовых правок или стилей, сгенерированных скриптом.

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

Подключение CSS · способ 2

Способ 2. Тег <style> в <head>

Internal — это один или несколько тегов <style> внутри <head> (или в теле страницы). Все правила пишутся там же, в HTML-файле.

Плюс: всё в одном файле, не нужны дополнительные запросы. Минус: стили не переиспользуются между страницами. Удобно для одной страницы или прототипа.

Подключение CSS · способ 3

Способ 3. Подключение через <link>

External (внешняя таблица стилей) — отдельный файл .css, подключаемый в <head>: <link rel="stylesheet" href="styles.css">.

Один файл можно подключить ко многим страницам, стили легко править в одном месте и кэшировать. Для больших проектов это основной способ.

Мария
То есть в реальных проектах в основном link на .css?
История

Откуда взялся CSS

Хокон Виум Ли (Håkon Wium Lie), один из создателей CSS

CSS предложил в 1994 году Хокон Виум Ли (Håkon Wium Lie), тогда сотрудник CERN. Идея — вынести оформление из HTML в отдельный язык стилей.

Были и другие предложения (например, стили прямо в браузере через свои расширения). В итоге победил именно CSS: его поддержали разработчики браузеров, и он стал стандартом W3C. Так разделение структуры (HTML) и оформления (CSS) вошло в основу веба.

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

Рекомендации по способам

Для вёрстки страниц и компонентов (кнопки, карточки, шапки) обычно используют external (внешний файл .css): один файл — для многих страниц, удобно править. Inline (атрибут style) — только в самом крайнем случае; лучше вообще не полагаться на inline, чтобы не наделать ошибок и не усложнять поддержку.

Internal (встроенные стили в теге <style>) уместен, когда стилей мало и всё в одном файле: одна страница-визитка, лендинг, прототип. Пример: у вас пять правил и одна HTML-страница — можно не заводить отдельный .css.

Про !important: он перебивает обычные правила и нужен редко — например, чтобы переопределить стили из чужой библиотеки, когда по-другому не получается. Использовать его в своём коде не стоит: из-за него потом сложно управлять каскадом, и «важное» правило начинает побеждать везде. Лучше решать конфликты через более точные селекторы или порядок правил.

Специфичность

Что такое специфичность

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

Считается по типам селекторов: элемент (тег), класс, id, inline-стиль. Чем «конкретнее» селектор, тем выше специфичность.

Специфичность

Порядок силы (от слабого к сильному)

Слабее всего — селектор по тегу (p, div). Сильнее — класс и псевдоклассы (.card, :hover). Ещё сильнее — id (#header). Максимум — inline-стили в атрибуте style.

При равной специфичности побеждает правило, которое в коде идёт позже (каскад). Пример из практики: в CSS два раза описан один класс — .title { color: blue; } и ниже .title { color: red; }. Заголовок будет красным: сработало последнее правило.

Специфичность

Пример

Для элемента <p class="intro" id="first"> правило p { color: blue; } слабее, чем .intro { color: green; }, а #first { color: red; } перебивает оба. Inline style="color: black;" перебил бы и id.

Поэтому для обычной вёрстки лучше опираться на классы и не злоупотреблять id и inline.

Дмитрий
Понятно, буду реже вешать id для стилей.
Каскад

Порядок и источники правил

Каскад — это порядок, в котором браузер применяет стили: сначала стили браузера, потом внешние и внутренние таблицы, потом inline. Внутри одного источника порядок правил в коде важен: при равной специфичности побеждает то, что объявлено позже.

Каскад

Последнее правило при равной специфичности

Если два правила с одинаковой специфичностью задают одно свойство, используется то, что в коде идёт ниже. Поэтому порядок подключения файлов и объявления правил внутри файла имеет значение.

Живой пример: в одном файле идут p { font-size: 14px; } и ниже p { font-size: 18px; }. У всех параграфов будет 18px — сработало второе правило. Так же и с подключёнными файлами: тот .css, что подключён позже, может перекрыть предыдущий.

Box Model

Из чего состоит «коробка»

Каждый элемент на странице рассматривается как прямоугольная коробка. Изнутри наружу: content (содержимое), затем padding (внутренний отступ), затем border (рамка), затем margin (внешний отступ).

Ширина и высота по умолчанию задают размер области content; padding и border добавляются к ним, если не задано box-sizing: border-box.

Box Model

Схема блочной модели

Центр — контент. Вокруг него padding, потом border, потом margin. Margin с соседними элементами может «схлопываться» (margin collapse).

Схема блочной модели CSS: content, padding, border, margin
Схема: концентрические прямоугольники — content, padding, border, margin
Box Model

box-sizing: content-box и border-box

При box-sizing: content-box (по умолчанию) width и height задают только область содержимого; padding и border добавляются снаружи. Блок с width: 200px и padding: 20px займёт по ширине 200 + 20 + 20 = 240px.

При box-sizing: border-box в эти 200px уже входят и padding, и border. Итоговая ширина блока — ровно 200px. Переключайте кнопкой — один и тот же блок (width: 160px, padding: 20px) то шире (content-box), то уже (border-box).

width: 160px
padding: 20px
border-box → итоговая ширина 160px
Александр
border-box реально спасает, когда считаешь проценты и отступы.
display

display: block

Блочные элементы (display: block) занимают всю доступную ширину, каждый с новой строки; им можно задать width, height, margin и padding со всех сторон. У части тегов это значение по умолчанию: div, p, h1h6, section, ul, li. У других (например span, a) по умолчанию не block, но можно задать: span { display: block; } — тогда элемент будет вести себя как блок.

Ниже — заголовок и блоки (все с новой строки):

Заголовок (h3 — блок по умолчанию)

Блок 1 (div)
Блок 2 (div)
display

display: inline

Строчные элементы (display: inline) идут в одну линию с текстом; ширина и высота определяются содержимым. Примеры: span, a, strong.

Ниже — фраза со строчными «пузырьками» в одну строку (как ссылки или выделения):

Один inline два inline три inline — всё в одну линию.
display

display: inline-block

display: inline-block — гибрид: элемент в строке с соседями (как inline), но с заданной шириной и отступами (как у блока).

Ниже — три «кнопки» в ряд (у каждой заданы width и padding, но они стоят в одну линию):

Кнопка 1 Кнопка 2 Кнопка 3
overflow

Зачем нужен overflow

Когда содержимое блока больше заданных размеров (например, фиксированная высота 100px, а текста много), оно может вылезать за границы. Свойство overflow задаёт, что делать: обрезать, показать прокрутку или оставить по умолчанию.

Пример: блок «Отзывы» с высотой 200px. Без overflow длинный список уйдёт за пределы; с overflow: auto внутри блока появится прокрутка, и всё останется аккуратно в рамках.

overflow

Значения: visible, hidden, scroll, auto

visible — по умолчанию, контент может выходить за границы. hidden — обрезать без прокрутки. scroll — полосы прокрутки всегда. auto — полосы только при переполнении.

Попробуйте (лучше после включения режима «мобильное устройство» в консоли разработчика — F12 → иконка переключения устройства или Ctrl+Shift+M):

Здесь много текста, чтобы показать переполнение. Свойство overflow управляет тем, как блок ведёт себя, когда содержимое не помещается: видно ли всё (visible), обрезать (hidden), показать прокрутку всегда (scroll) или только при необходимости (auto).
Reset и Normalize

Зачем сбрасывать стили браузера

У браузеров есть стили по умолчанию (отступы у body, размеры заголовков, маргины у параграфов). Чтобы вёрстка вела себя предсказуемо в разных браузерах, подключают либо жёсткий сброс (reset), либо «нормализацию» (normalize).

Reset и Normalize

reset.css и normalize.css

Reset обнуляет многие стили по умолчанию (margins, paddings у элементов), чтобы начать с «чистого листа». Normalize.css не обнуляет, а приводит стили к единому разумному виду, сохраняя полезные значения. В большинстве проектов удобнее подключать normalize или современный reset (например, от авторов normalize).

Мария
Готовы к заданиям?
Задание 1

Расставьте по силе специфичности

Перетащите блоки так, чтобы сверху был самый слабый тип селектора, внизу — самый сильный.

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

Задание 2

Какое правило применится?

У элемента <div class="card" id="main"> заданы два правила для color. Какой цвет будет у текста?

#main { color: blue; }
.card { color: red; }
Задание 3

Сопоставьте и ответьте

1) Сопоставьте тип селектора с примером.

Селектор по тегу
Селектор по классу
Селектор по id

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

Финальный допуск

Краткий тест (8 вопросов)

Ответьте на вопросы. Для доступа к практике нужно набрать не менее 80% (минимум 7 из 8 правильных ответов).

1. Какой способ подключения CSS даёт самую высокую специфичность?

2. При равной специфичности побеждает правило, которое в коде идёт…

3. В box model изнутри наружу идут: content, затем…

4. Элемент с display: inline-block…

5. overflow: auto — это…

6. Normalize.css по сравнению с reset…

7. Селектор по id сильнее селектора по классу?

8. Для подключения внешнего CSS в <head> используют…

Практика

Итоговое задание

Важно: загружайте один файл index.html, в котором все стили находятся в теге <style>. Если вы подключаете внешний CSS через <link>, для проверки перенесите содержимое .css в <style> в этом же HTML-файле — иначе критерии по header, отступам и box-sizing не смогут быть проверены.

Сделайте одностраничный HTML и выполните:

  • Подключение CSS — стили в <style> (или сначала в .css, затем скопируйте их в <style> перед загрузкой).
  • Стилизация header — шапка (тег <header> или блок с классом/id для шапки) с хотя бы одним визуальным свойством (цвет фона, текста, размер шрифта или рамка).
  • Отступы — используйте margin или padding хотя бы у одного элемента.
  • Box model — задайте box-sizing: border-box (например, для * или основного контейнера).

Проверьте в DevTools (F12), что отступы и стили применяются как задумано. Тестовые файлы для задания (образец и описание) — в папке test-files/.