В этом занятии разберём, как подключать стили к странице, как браузер выбирает «победившее» правило (специфичность и каскад), и как устроена блочная модель — основа вёрстки.
Потом закрепим на практике: подключение CSS, стилизация шапки, отступы и отладка в DevTools. Компонент — это повторяемый кусок интерфейса: кнопка, карточка товара, шапка сайта; у него свои стили и часто свой кусок разметки.
CSS можно добавить к странице тремя способами: (1) inline — атрибут style у
элемента; (2) internal — тег <style> в <head>;
(3) external — отдельный файл через <link>.
От выбора способа зависят переиспользование стилей, удобство поддержки и то, какое правило в итоге применится при конфликте.
Inline — это запись правил прямо в разметке, в атрибуте style. Например:
<p style="color: red;">. Подходит для разовых правок или стилей, сгенерированных скриптом.
Минусы: нельзя переиспользовать для других элементов, сложно поддерживать, у inline самая высокая специфичность — перебить такие стили из таблицы сложнее.
Internal — это один или несколько тегов <style> внутри <head> (или в
теле страницы). Все правила пишутся там же, в HTML-файле.
Плюс: всё в одном файле, не нужны дополнительные запросы. Минус: стили не переиспользуются между страницами. Удобно для одной страницы или прототипа.
External (внешняя таблица стилей) — отдельный файл .css, подключаемый в
<head>: <link rel="stylesheet" href="styles.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.
Каскад — это порядок, в котором браузер применяет стили: сначала стили браузера, потом внешние и внутренние таблицы, потом inline. Внутри одного источника порядок правил в коде важен: при равной специфичности побеждает то, что объявлено позже.
Если два правила с одинаковой специфичностью задают одно свойство, используется то, что в коде идёт ниже. Поэтому порядок подключения файлов и объявления правил внутри файла имеет значение.
Живой пример: в одном файле идут p { font-size: 14px; } и ниже
p { font-size: 18px; }. У всех параграфов будет 18px — сработало второе правило. Так же и с
подключёнными файлами: тот .css, что подключён позже, может перекрыть предыдущий.
Каждый элемент на странице рассматривается как прямоугольная коробка. Изнутри наружу: content (содержимое), затем padding (внутренний отступ), затем border (рамка), затем margin (внешний отступ).
Ширина и высота по умолчанию задают размер области content; padding и border добавляются к ним, если не
задано box-sizing: border-box.
Центр — контент. Вокруг него padding, потом border, потом margin. Margin с соседними элементами может «схлопываться» (margin collapse).
При 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).
Блочные элементы (display: block) занимают всю доступную ширину, каждый с новой строки; им можно
задать width, height, margin и padding со всех сторон. У части тегов это значение по
умолчанию: div, p, h1–h6, section,
ul, li. У других (например span, a) по умолчанию не block,
но можно задать: span { display: block; } — тогда элемент будет вести себя как блок.
Ниже — заголовок и блоки (все с новой строки):
Строчные элементы (display: inline) идут в одну линию с текстом; ширина и высота определяются
содержимым. Примеры: span, a, strong.
Ниже — фраза со строчными «пузырьками» в одну строку (как ссылки или выделения):
display: inline-block — гибрид: элемент в строке с соседями (как inline), но с заданной шириной
и отступами (как у блока).
Ниже — три «кнопки» в ряд (у каждой заданы width и padding, но они стоят в одну линию):
Когда содержимое блока больше заданных размеров (например, фиксированная высота 100px, а текста много), оно
может вылезать за границы. Свойство overflow задаёт, что делать: обрезать, показать прокрутку или
оставить по умолчанию.
Пример: блок «Отзывы» с высотой 200px. Без overflow длинный список уйдёт за пределы; с
overflow: auto внутри блока появится прокрутка, и всё останется аккуратно в рамках.
visible — по умолчанию, контент может выходить за границы. hidden — обрезать без
прокрутки. scroll — полосы прокрутки всегда. auto — полосы только при переполнении.
Попробуйте (лучше после включения режима «мобильное устройство» в консоли разработчика — F12 → иконка переключения устройства или Ctrl+Shift+M):
У браузеров есть стили по умолчанию (отступы у body, размеры заголовков, маргины у параграфов).
Чтобы вёрстка вела себя предсказуемо в разных браузерах, подключают либо жёсткий сброс (reset), либо
«нормализацию» (normalize).
Reset обнуляет многие стили по умолчанию (margins, paddings у элементов), чтобы начать с «чистого листа». Normalize.css не обнуляет, а приводит стили к единому разумному виду, сохраняя полезные значения. В большинстве проектов удобнее подключать normalize или современный reset (например, от авторов normalize).
Перетащите блоки так, чтобы сверху был самый слабый тип селектора, внизу — самый сильный.
Перетаскивайте блоки внутри зоны, чтобы изменить порядок.
У элемента <div class="card" id="main"> заданы два правила для
color. Какой цвет будет у текста?
#main { color: blue; }
.card { color: red; }
1) Сопоставьте тип селектора с примером.
2) Что делает box-sizing: border-box?
Ответьте на вопросы. Для доступа к практике нужно набрать не менее 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 и выполните:
<style> (или сначала в .css, затем
скопируйте их в <style> перед загрузкой).<header> или блок с классом/id для
шапки) с хотя бы одним визуальным свойством (цвет фона, текста, размер шрифта или рамка).margin или padding хотя бы у одного
элемента.box-sizing: border-box (например, для * или
основного контейнера).Проверьте в DevTools (F12), что отступы и стили применяются как задумано. Тестовые файлы для задания (образец и описание) — в папке test-files/.