Введение в CSS
Cascading Style Sheets (CSS) – это язык описания стилей, используемый для определения внешнего вида документов, написанных на HTML или XML. CSS отвечает за визуальное оформление веб-страниц: цвета, шрифты, расположение элементов, отступы, анимации и прочие аспекты дизайна. HTML обеспечивает структуру контента, а CSS – то как этот контент выглядит на экране, бумаге или других носителях.
CSS - один из основных веб-стандартов и поддерживается всеми современными браузерами в соответствии со спецификациями W3C. Само название отображает один из основных принципов CSS - каскадность. Это механизм, согласна которому несколько стилевых правил могут применяться к одному элементу, а конечный вид определяется приоритетами этих правил.
Подключение стилей к странице
Существует несколько способов подключить стили к странице:
1. Наиболее распространенный подход - подключение внешнего файла стилей (например, styles.css). Подключить к основному index.html (или любому другому файлу с html-разметкой) файлу его можно в <head> секции с помощью тега <link>:
<head>
<link rel="stylesheet" href="styles.css" />
</head>Хранение стилей в отдельном файле облегчает поддержку и повторное использование CSS на нескольких страницах.
2. Также стили можно встраивать напрямую в HTML-документ в секции <style>, которая располагается внутри секции <head>:
<head>
<style>
/* Пример CSS внутри HTML */
body {
background-color: #fafafa;
font-family: Arial, sans-serif;
}
p {
color: blue;
}
</style>
</head>Этот способ полезен для небольших страниц или примеров, но для крупных проектов менее удобен, чем вынос стилей во внешний файл.
3. Также существует еще один способ чтобы задать стили для конкретно взятого элемента - инлайн-стили. В этом случае атрибут style прописывается для конкретного тега:
<p style="color: blue; font-size: 18px;">Этот текст с синим цветом и размером 18px.</p>Обычно инлайн-стили применяются лишь для динамически сгенерированных элементов или единичных случаев.
Например, при оформлении html-писем для почтовых клиентов принято использовать табличную верстку и стили для всех тегов писать в виде инлайн-элементов, т.к. такой подход обеспечивает наилучшую совместимость с большинством почтовых клиентов.
Синтаксис
Синтаксис CSS состоит из правил (rules). Правило CSS включает селектор и блок деклараций. Например:
селектор {
свойство1: значение1;
свойство2: значение2;
}Селектор определяет, к каким элементам HTML применяется правило, а внутри фигурных скобок перечислены пары «свойство: значение», определяющие, как эти элементы будут выглядеть. Каждая пара завершается точкой с запятой. Например, правило:
p {
color: blue;
font-size: 18px;
}задаёт всем <p> (абзацам) синий цвет текста и размер шрифта 18px.
Комментарий в CSS оформляется между /* и */. Он не влияет на отображение и служит для заметок внутри CSS-кода:
/* Это комментарий, браузер его игнорирует */Скомбинируем и объединим описанные выше подходы:
<head>
<link rel="stylesheet" href="styles.css" />
<style>
/* Встроенный CSS: делаем все заголовки зелёными */
h1, h2 {
color: green;
}
</style>
</head>
<body>
<h1 style="text-decoration: underline;">Заголовок с подчёркиванием</h1>
<p>Параграф, стиль которого задаётся во внешнем файле styles.css.</p>
</body>/* styles.css */
body {
font-family: Arial, sans-serif;
margin: 20px;
}
p {
color: navy;
}Таким образом заголовок <h1> станет зелёным и подчёркнутым (зелёный цвет из встроенного CSS, подчёркивание из инлайн-стиля), а текст абзаца <p> будет тёмно-синим согласно правилам из файла styles.css. Здесь применяется принцип каскадности: на элемент могут одновременно влиять стили из разных источников, объединяясь по определённым правилам.
Селекторы CSS
Селекторы позволяют выбрать (target) HTML-элементов, к которым будут применяться CSS-стили. Всего можно выделить несколько видов селекторов:
- По тегу (типу): выбирает все элементы данного тега. Пример:
p { ... }– применит стили ко всем абзацам<p>на странице. - Классы: выбирают элементы, у которых задан определённый класс (атрибут
class). В CSS класс обозначается точкой перед именем. Пример:.highlight { background: yellow; }– выберет все элементы сclass="highlight"и задаст им жёлтый фон. В HTML можно применять класс к любому элементу, например:<span class="highlight">текст</span>. - ID: выбирает элемент по его уникальному идентификатору (атрибут
id). В CSS селектор ID записывается с символом решётки:#header { ... }– применится к элементу сid="header".Идентификатор на ВСЕГДА странице должен быть уникальным.
- Комбинированные селекторы: позволяют уточнять выборку. Например, селектор потомка
article p– выберет абзацы<p>, которые находятся внутри элемента<article>. Селектор дочернего элементаdiv > span– выберет<span>, являющиеся непосредственными дочерними элементами<div>. Селектор по соседствуh1 + p– выберет первый<p>сразу после<h1>. С другими CSS комбинаторы (например+, показанный ранее) можно ознакомиться в официальной документации MDN.Посмотреть что именно и как будет применяться можно при наведении мышки на конкретную комбинацию селекторов при просмотре файлов со стилями в VS Code.
- Группировка селекторов: если для разных селекторов применяются одинаковые стили, их можно объединить через запятую.
Сделает текст всех заголовков первого, второго и третьего уровня тёмно-синим.
h1, h2, h3 { color: darkblue; } - Атрибутные селекторы: позволяют выбирать элементы по наличию атрибута или его значению. Примеры:
[href] { text-decoration: underline; }– все элементы с атрибутом href (например, ссылки<a>) будут подчёркнуты.input[type="checkbox"] { margin: 5px; }– все чекбоксы получат отступ 5px.
- Псевдоклассы: селекторы, применяющиеся к элементу в определённом состоянии или контексте. Начинаются с двоеточия. Очень распространённый псевдокласс –
:hover, который срабатывает при наведении курсора.В примере выше ссылка окрасится в красный при наведении на неёё курсора. К другим популярным псевдоклассам можно отнести:a:hover { color: red; }:focus(к элементу, получившему фокус, например, в поле ввода),:active(к моменту нажатия на элемент),:nth-child(3)(третий дочерний элемент в родительском контейнере) и т.д. - Псевдоэлементы: позволяют стилизовать определенные части элемента или добавлять содержимое. Записываются с двумя двоеточиями. Например,
p::first-line { font-weight: bold; }сделает первую строку каждого абзаца полужирной. А селектор::beforeи::afterчасто используется для вставки декоративного контента до или после содержимого элемента (через CSS-свойство content). Например, [прорисовка линий при помощи::before].
Попробуем применить рассмотренные выше селекторы:
<div id="content">
<h2 class="title">Заголовок</h2>
<p class="text highlight">Абзац с <a href="#">ссылкой</a>.</p>
<p class="text">Ещё один абзац.</p>
</div>/* Сделать все элементы с классом "text" серым */
.text { color: gray; }
/* Сделать элемент с ID "content" светло-серым фоном */
#content { background-color: #f9f9f9; }
/* Сделать заголовок внутри #content синим (используем селектор потомка + ID) */
#content h2 { color: blue; }
/* Подчеркнуть все ссылки при наведении */
a:hover { text-decoration: underline; }
/* Элемент с классом "highlight" внутри абзаца .text выделить желтым фоном */
.text .highlight { background: yellow; }
/* Каждому второму абзацу (.text) задать курсив через псевдокласс :nth-child */
.text:nth-child(2n) { font-style: italic; }Последний селектор .text:nth-child(2n) сработает, только если родительским элементом для абзацев является их общий контейнер (например, <div id="content"> в данном случае), и считает порядковый номер среди родных братьев. Таким образом можно стилизовать чётные/нечётные строки списков, таблиц и т.п.
Каскадность и приоритеты в CSS
Как мы уже ранее упоминали, название CSS (Cascading Style Sheets) – прямо указывает на каскадность, то есть механизм объединения стилевых правил из разных источников. Браузер получает стили из нескольких таблиц и из разных селекторов, которые зачастую конфликтуют друг с другом. Каскад определяет, какое именно значение свойства будет применено в итоге, если на элемент воздействуют несколько правил одновременно.
При этом учитываются три основных фактора:
- Источник стилей (origin): стили браузера (по умолчанию) < стили автора страницы (ваши CSS-файлы) < стили пользователя (если заданы в настройках браузера) – обычно стили автора имеют приоритет над встроенными стилями браузера.
Также действует правило !important (см. ниже).
- Специфичность селектора: более точечный селектор имеет больший вес. Например, селектор по ID (
#header) победит селектор по классу (.header), а селектор по классу – селектор по тегу (header). Специфичность рассчитывается по числу ID, классов и тегов в селекторе. Чем более уникально правило идентифицирует элемент, тем выше приоритет его стилей. Если специфичность равна, вступает в силу следующий фактор. - Порядок в коде: при одинаковой специфичности последнее объявление (ниже по файлу или подключённое позже) перекрывает предыдущие. То есть, если два равносильных правила конфликтуют, сработает то, что загружено или прописано последним.
Наследование (inheritance) – ещё один важный принцип CSS. Многие свойства автоматически передаются дочерним элементам от их родителя, если у потомков не задано собственного значения. Например, цвет текста (color) или семейство шрифта (font-family) наследуются: если вы задали весь <body> текст белым на чёрном фоне, то и абзацы, и заголовки внутри него по умолчанию тоже будут белыми. Однако некоторые свойства (например, margin, padding, border, background) не наследуются автоматически – они применяются только к тому элементу, которому прописаны.
Например, можно использовать следующий набор свойств для сброса > стилей по умолчанию:
*, *::before, *::after { padding: 0; margin: 0; box-sizing: border-box; } html { height: 100dvh; } body { height: 100%; } h1, h2, h3, h4, h5, h6 { margin: 0; padding: 0; font-weight: normal; font-size: inherit; } * { -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
Браузеры вычисляют вес селектора по формуле, соотнося число ID, классов/атрибутов/псевдоклассов и тегов. Например: селектор #content .title p имеет вес 1-1-1 (1 ID, 1 класс, 1 тег), а селектор h1 – 0-0-1. Правило с селектором #content .title p превысит по специфичности простое h1. Таким образом можно выделить следующие общие правила определения конечных стилей, которые будут применены к элементу:
- Типы селекторов в порядке увеличения специфичности: тег (например, div) < класс/атрибут/псевдокласс (например, .button, [type=“text”], :hover) < ID (например, #main);
- Универсальный селектор * специфичности не добавляет
- Inline-стили непосредственно в атрибуте элемента имеют очень высокую специфичность (считается, что больше, чем любой селектор в таблице стилей)
- Правило с
!importantособым образом перебивает обычные правила. Если к объявлению свойства добавить!important, оно приобретает наибольший приоритет, игнорируя обычную каскадность. Например:.note { background: white !important; }– белый фон применится к элементу с классом note даже если другие правила хотели бы его перекраситьЧастое использование
!important- плохая практика, это гарантированно приведет к усложнению поддержки кода в будущем.
Рассмотрим пример:
<div id="example" class="block highlight">Пример текста</div>.block { color: black; } /* селектор по классу */
#example { color: blue; } /* селектор по ID */
.highlight { color: green !important; } /* класс с !important */
div { color: red; } /* селектор по тегу */Какого цвета будет итоговый текст? Правило div делает красным, .block – чёрным, #example – синим, .highlight – зелёным с !important. По специфичности #example (ID) сильнее .block (класс) и div (тег), поэтому синий перекрыл бы черный и красный. Но .highlight имеет такой же тип селектора, как .block (класс), и без !important сработало бы правило, которое позже объявлено (в нашем порядке .highlight идёт после .block, значит зелёный победил бы чёрный).
Здесь же .highlight содержит !important, а значит, итоговый цвет элемента будет зеленый, обойдя по приоритету более специфичный #example. Таким образом, !important изменил ход каскада, переборов и специфичность, и порядок правил.
Ключевые слова
inherit,initial,unset,revert– иногда применяются, чтобы явно управлять значениями свойств в каскаде:
color: inheritзаставит элемент принять цвет родителя (обычно это происходит автоматически для color, но для не наследуемых свойств такое указание позволяет принудительно получить значение предка);initialсбрасывает свойство к начальному значению по умолчанию, а unset – к значению по умолчанию, учитывая наследование (для наследуемых свойств работает какinherit, для остальных какinitial);revertоткатывает значение к тому, которое было бы без пользовательских стилей (например, к стилям браузера по умолчанию). Эти механизмы полезны для более точного контроля, но используются относительно редко.
CSS-модель коробки (Box Model)

Каждый блочный элемент на странице можно представить в виде вложенной прямоугольной коробки. “Модель коробки” CSS описывает эту структуру и определяет, как размер и расположение каждого блока складываются из отдельных частей.
Content box(область содержимого) – собственно содержимое элемента (текст, изображение и т.д.). Размерcontent boxопределяется свойствамиwidthиheight, если они заданы явно. Иначе элемент обычно растягивается на всю доступную ширину контейнера по умолчанию.Padding(внутренний отступ) – пространство между содержимым и границей элемента. Устанавливается свойствомpadding(можно задавать отдельные отступы:padding-top,padding-right, …). При помощи паддингов обычно добавляются пустое пространство вокруг контента, увеличивая внутренний размер коробки.Border(граница) – рамка вокруг содержимого и внутренних отступов. Задаётся свойствомborder(а также отдельными свойствамиborder-width,border-style,border-colorили сторонамиborder-topи т.д.). Граница имеет толщину (ширину) в пикселях или других единицах, цвет и стиль линии (сплошная, пунктир, и т.п.). Она тоже увеличивает общий размер элемента.Margin(внешний отступ) – пространство снаружи границы, отделяющее элемент от других на странице. Задаётся свойствомmargin(и его вариациями для каждой стороны). Маржин не относится к самому элементу, но влияет на расстояние между соседними элементами.Отступы не суммируются между двумя соседними блоками вертикально – вместо этого срабатывает правило схлопывания margin: больший из двух смежных вертикальных margin перекрывает меньший.
При этом margin влияет на расстояние между элементами, но не входит в «коробку» элемента. Пример:
.box {
width: 300px;
height: 150px;
padding: 20px;
border: 5px solid black;
margin: 10px;
}Данный элемент .box получит видимую область содержимого 300×150 пикселей (width×height), вокруг него будет 20px внутреннего отступа (со всех сторон), обрамленного 5px границей. Таким образом, видимый размер коробки с контентом и рамкой станет 300 + 220 + 25 = 350px по ширине и 150 + 220 + 25 = 200px по высоте. Но кроме этого, вне рамки будет ещё margin 10px, отделяющий этот блок от других вокруг (margin в расчет видимого размера блока не входит, это внешний отступ).
По умолчанию браузеры используют стандартную модель коробки: box-sizing: content-box. Однако, есть альтернативная модель: border-box, тогда заданные width и height будут считаться не для content box, а для всей области элемента включая padding и border. В этом случае padding и границы не увеличивают итоговый размер, а «вписываются» внутрь указанных width/height. Например, если для .box из примера выше добавить box-sizing: border-box, то его общая видимая ширина останется 300px, а внутреннее содержимое автоматически уменьшится, чтобы учесть 20px паддинги и 5px рамки с каждой стороны.
Альтернативная модель часто упрощает расчёт макета. Именно поэтому она была указана в примере выше со сбросом базовых стилей.
Подробнее об этой технике можно прочитать в статье CSS-Tricks про box-sizing.