Модуль 2: CSS
Разберём синтаксис и способы подключения CSS, каскадность и специфичность, типографику, модель коробки, позиционирование, Flexbox, Grid, адаптивность и анимации.
Введение в CSS. Синтаксис и подключение
CSS (Cascading Style Sheets — каскадные таблицы стилей) — это язык, который управляет внешним видом и оформлением HTML-элементов. Если HTML — это скелет страницы, то CSS — это её "кожа и одежда", которая делает страницу красивой и привлекательной.
Что такое CSS и зачем он нужен
CSS позволяет:
- Изменять цвета, шрифты, размеры элементов
- Создавать макеты и расположение элементов на странице
- Добавлять анимации и интерактивные эффекты
- Делать страницы адаптивными для разных устройств
- Создавать единый стиль для всего сайта
Преимущества отделения стилей от структуры:
- Один CSS-файл может стилизовать множество HTML-страниц
- Легко изменить дизайн всего сайта, изменив один файл
- HTML остаётся чистым и семантическим
- Браузер может кэшировать CSS-файлы, ускоряя загрузку
Синтаксис CSS
CSS состоит из правил (rules). Каждое правило имеет следующую структуру:
селектор {
свойство: значение;
другое-свойство: другое-значение;
}
Компоненты правила:
- Селектор — указывает, к каким элементам применяется правило
- Декларация — пара "свойство: значение" в фигурных скобках
- Свойство — что мы хотим изменить (цвет, размер, отступ и т.д.)
- Значение — как мы это изменяем (конкретный цвет, размер в пикселях и т.д.)
/* Пример правила */
h1 {
color: #4f46e5; /* свойство: значение; */
font-size: 2rem; /* каждое свойство на новой строке */
margin-bottom: 1rem; /* точка с запятой обязательна */
}
Способы подключения CSS
Есть три способа добавить CSS к HTML-странице. Каждый имеет свои преимущества и недостатки.
1. Встроенные стили (inline styles)
Стили пишутся прямо в атрибуте style HTML-элемента:
<h1 style="color: #4f46e5; font-size: 2rem;">Заголовок</h1>
Когда использовать: только для одноразовых стилей, которые уникальны для конкретного элемента и не будут переиспользоваться.
Минусы: нарушает принцип разделения структуры и стилей, сложно поддерживать, увеличивает размер HTML, нельзя переиспользовать стили.
Рекомендация: избегайте встроенных стилей, используйте только в крайних случаях (динамические стили через JavaScript, email-верстка).
2. Внутренние стили (embedded styles)
Стили пишутся в теге <style> внутри <head>:
<head>
<style>
h1 {
color: #4f46e5;
font-size: 2rem;
}
.card {
border-radius: 10px;
padding: 1rem;
}
</style>
</head>
Когда использовать: для стилей, специфичных для одной страницы, для критического CSS (стили, необходимые для первого рендера).
Минусы: стили не переиспользуются между страницами, увеличивают размер HTML-файла.
Рекомендация: используйте для критического CSS или одностраничных приложений.
3. Внешний файл (external stylesheet) — РЕКОМЕНДУЕТСЯ
Стили находятся в отдельном .css файле и подключаются через <link>:
<head>
<link rel="stylesheet" href="../courses.css">
<!-- или несколько файлов -->
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="main.css">
</head>
Преимущества:
- Разделение структуры и стилей
- Переиспользование стилей на множестве страниц
- Кэширование браузером — файл загружается один раз
- Легче поддерживать и изменять
- Можно использовать препроцессоры (Sass, Less)
Рекомендация: это основной и предпочтительный способ подключения CSS.
Селекторы: как выбрать элементы для стилизации
Селекторы — это способ указать браузеру, к каким элементам применить стили. Понимание селекторов — основа работы с CSS.
Базовые селекторы
1. Селектор по тегу (элементу)
/* Стилизует все параграфы */
p {
line-height: 1.7;
margin-bottom: 1rem;
}
/* Стилизует все заголовки h1 */
h1 {
font-size: 2rem;
font-weight: 700;
}
Используется для базовых стилей, которые применяются ко всем элементам определённого типа.
2. Селектор по классу
/* Стилизует все элементы с классом "card" */
.card {
border-radius: 10px;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
<div class="card">Карточка 1</div>
<div class="card">Карточка 2</div>
Классы — самый гибкий и переиспользуемый способ стилизации. Один класс можно применять к множеству элементов.
3. Селектор по ID
/* Стилизует элемент с id="mainTitle" */
#mainTitle {
font-weight: 700;
color: #1e293b;
}
<h1 id="mainTitle">Главный заголовок</h1>
Важно: ID должен быть уникальным на странице. Используйте ID для уникальных элементов, но предпочитайте классы для стилизации (они более гибкие).
Комбинированные селекторы
Селектор потомков — выбирает элементы внутри других:
/* Все ссылки внутри навигации */
nav a {
text-decoration: none;
color: #4f46e5;
}
/* Все параграфы внутри .card */
.card p {
margin-bottom: 0.5rem;
}
Псевдоклассы — выбирают элементы в определённом состоянии:
/* Ссылка при наведении */
a:hover {
text-decoration: underline;
color: #6366f1;
}
/* Последний элемент списка */
li:last-child {
margin-bottom: 0;
}
/* Чётные строки таблицы */
tr:nth-child(even) {
background-color: #f8fafc;
}
/* Первая буква параграфа */
p::first-letter {
font-size: 2em;
font-weight: bold;
}
Группировка селекторов — применяйте одно правило к нескольким селекторам:
/* Одинаковые стили для h1, h2, h3 */
h1, h2, h3 {
font-family: 'Montserrat', sans-serif;
margin-bottom: 1rem;
}
Практические советы по селекторам
- Используйте классы для переиспользуемых стилей
- Избегайте глубокой вложенности (более 2-3 уровней) — это увеличивает специфичность и усложняет поддержку
- Именуйте классы осмысленно:
.button-primaryлучше, чем.btn1 - Не используйте ID для стилизации — только для уникальных элементов и JavaScript
- Используйте семантические селекторы:
article h2лучше, чем.article-titleв некоторых случаях
Практика
Подключите внешний CSS-файл к вашей HTML-странице и создайте стили для:
- Заголовков разных уровней (h1-h3) с разными размерами и цветами
- Класса
.cardс рамкой, скруглением и тенью - Ссылок с эффектом при наведении (hover)
- Списков с кастомными маркерами
Экспериментируйте с разными селекторами и посмотрите, как они работают.
Каскадность, наследование и специфичность
Понимание каскадности, наследования и специфичности — это основа работы с CSS. Эти концепции определяют, какие стили будут применены к элементу, когда несколько правил конфликтуют друг с другом.
Каскадность (Cascade)
CSS называется "каскадным" потому, что стили применяются в определённом порядке, как водопад. Когда несколько правил могут применяться к одному элементу, браузер использует каскад для определения приоритета.
Порядок применения стилей (от низкого к высокому приоритету):
- Стили браузера (user agent stylesheet) — базовые стили, которые браузер применяет по умолчанию
- Пользовательские стили — стили, установленные пользователем в браузере
- Авторские стили — ваши CSS-файлы
- Стили с
!important— имеют наивысший приоритет (избегайте их использования)
В рамках одного источника: если два правила имеют одинаковую специфичность, применяется то, которое идёт ниже в коде (позже в файле).
/* Первое правило */
h1 { color: black; }
/* Второе правило — оно применится, так как идёт ниже */
h1 { color: blue; }
/* Результат: h1 будет синим */
Наследование (Inheritance)
Некоторые CSS-свойства наследуются дочерними элементами от родительских. Это означает, что если вы задали цвет текста для <body>, все элементы внутри унаследуют этот цвет, если не переопределить его явно.
Свойства, которые наследуются:
color— цвет текстаfont-family,font-size,font-weight— свойства шрифтаline-height— межстрочный интервалtext-align— выравнивание текстаlist-style— стиль списков
Свойства, которые НЕ наследуются:
width,height— размерыmargin,padding— отступыborder— рамкиbackground— фонdisplay— тип отображения
/* Задаём базовые стили для body */
body {
color: #1e293b; /* наследуется всеми элементами */
font-family: 'Arial', sans-serif; /* наследуется */
line-height: 1.6; /* наследуется */
margin: 0; /* НЕ наследуется */
padding: 0; /* НЕ наследуется */
}
/* Все параграфы унаследуют color, font-family, line-height */
/* Но margin и padding нужно задавать отдельно */
Принудительное наследование: можно заставить свойство наследоваться, используя значение inherit:
.card {
border: 1px solid #e5e7eb;
}
.card a {
border: inherit; /* наследует border от .card */
}
Специфичность (Specificity) — вес селектора
Специфичность определяет, какое правило применится, когда несколько правил могут стилизовать один элемент. Браузер вычисляет "вес" каждого селектора и применяет правило с наибольшим весом.
Как вычисляется специфичность
Специфичность вычисляется по формуле: (a, b, c, d)
- a — inline стили (style="...") = 1000
- b — количество ID в селекторе = 100 за каждый
- c — количество классов, атрибутов, псевдоклассов = 10 за каждый
- d — количество тегов и псевдоэлементов = 1 за каждый
/* Примеры специфичности */
/* (0, 0, 0, 1) = 1 */
p { color: black; }
/* (0, 0, 1, 0) = 10 */
.card { color: blue; }
/* (0, 1, 0, 0) = 100 */
#mainTitle { color: green; }
/* (0, 0, 2, 1) = 21 */
.card .title { color: red; }
/* (1, 0, 0, 0) = 1000 */
/* style="color: purple;" в HTML */
Правило: чем больше число, тем выше специфичность. При конфликте применяется правило с большей специфичностью.
/* Конфликт стилей */
h1 { color: black; } /* специфичность: 1 */
.title { color: blue; } /* специфичность: 10 */
#mainTitle { color: green; } /* специфичность: 100 */
/* Победит зелёный (id имеет большую специфичность) */
Важно понимать:
- Специфичность не складывается линейно: (0, 0, 11, 0) = 110, что больше, чем (0, 1, 0, 0) = 100
!importantпереопределяет всё, но его использование — плохая практика- Старайтесь поддерживать низкую специфичность — это упрощает поддержку кода
- Избегайте селекторов по ID для стилизации — они создают высокую специфичность
Единицы измерения в CSS
CSS предоставляет множество единиц измерения. Правильный выбор единиц критически важен для адаптивности и поддержки.
Абсолютные единицы
px(пиксели) — самая распространённая единица. 1px = 1 пиксель экрана. Используйте для мелких деталей (рамки, тени), но не для размеров шрифтов и отступов в адаптивных макетах.pt(пункты) — используется в печати, 1pt = 1/72 дюймаcm,mm,in— сантиметры, миллиметры, дюймы. Используются редко, в основном для печати
Относительные единицы (рекомендуются)
1. rem (root em) — относительно размера шрифта корневого элемента (<html>):
html { font-size: 16px; } /* базовый размер */
h1 { font-size: 2rem; } /* = 32px (2 × 16px) */
p { font-size: 1rem; } /* = 16px (1 × 16px) */
.card { padding: 1.5rem; } /* = 24px (1.5 × 16px) */
Преимущества: предсказуемость, легко масштабировать весь сайт, изменяя размер шрифта у html.
Когда использовать: для размеров шрифтов, отступов, размеров элементов. Рекомендуется как основная единица.
2. em — относительно размера шрифта родительского элемента:
.card { font-size: 18px; }
.card .title { font-size: 1.5em; } /* = 27px (1.5 × 18px) */
.card .small { font-size: 0.875em; } /* = 15.75px (0.875 × 18px) */
Особенность: может создавать каскадный эффект, когда вложенные элементы умножают размеры. Используйте осторожно.
Когда использовать: когда нужно, чтобы размер зависел от родителя (например, отступы относительно размера шрифта элемента).
3. % (проценты) — относительно размера родительского элемента:
.container { width: 1200px; }
.box { width: 50%; } /* = 600px (50% от 1200px) */
Когда использовать: для ширины, высоты, отступов относительно родителя. Отлично подходит для адаптивных макетов.
4. vw, vh (viewport units) — относительно размера окна браузера:
.hero {
height: 60vh; /* 60% высоты окна браузера */
width: 100vw; /* 100% ширины окна */
}
.sidebar { width: 25vw; } /* 25% ширины окна */
Когда использовать: для полноэкранных секций, адаптивных размеров относительно экрана.
Осторожно: на мобильных устройствах 100vw может создать горизонтальную прокрутку из-за полосы прокрутки. Используйте 100% вместо 100vw для ширины.
5. vmin, vmax — минимальный/максимальный размер viewport:
.square {
width: 50vmin; /* 50% от меньшей стороны (ширина или высота) */
height: 50vmin; /* всегда квадрат */
}
Современные единицы
ch— ширина символа "0" в текущем шрифте. Полезно для ограничения ширины текстаlh— высота строки (line-height) текущего элементаcqw,cqh— единицы контейнерных запросов (container queries)
Практические рекомендации
- Для шрифтов: используйте
rem— предсказуемо и масштабируемо - Для отступов: используйте
remдля вертикальных отступов,%илиremдля горизонтальных - Для ширины контейнеров: используйте
%,max-widthсpxилиrem - Для высоты: используйте
vhдля полноэкранных секций,autoилиremдля остального - Избегайте: смешивания единиц без необходимости, использования
pxдля всего в адаптивных макетах
/* Хороший пример использования единиц */
:root {
font-size: 16px; /* базовый размер */
}
.container {
max-width: 1200px; /* фиксированная максимальная ширина */
width: 100%; /* адаптивная ширина */
padding: 1.5rem; /* адаптивные отступы */
}
h1 {
font-size: 2.5rem; /* = 40px */
margin-bottom: 1rem; /* = 16px */
}
.card {
width: 100%; /* адаптивная ширина */
padding: 1.25rem; /* адаптивные внутренние отступы */
border: 1px solid; /* 1px всегда 1px */
}
Практика
Создайте страницу и поэкспериментируйте с единицами:
- Используйте
remдля размеров шрифтов и отступов - Создайте контейнер с
max-width: 1200pxиwidth: 100% - Используйте
vhдля создания полноэкранной секции - Сравните результат при изменении размера шрифта в браузере (Ctrl + колесо мыши)
Работа с текстом и шрифтами
Базовые свойства
body { font-family: 'Montserrat', system-ui, sans-serif; line-height: 1.7; }
h1 { font-size: 2rem; font-weight: 700; text-align: center; }
a { text-decoration: none; }
a:hover { text-decoration: underline; }
Подключение Google Fonts
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&display=swap" rel="stylesheet">
Практика
Задайте базовую типографику для портфолио: шрифты, размеры и межстрочные интервалы для заголовков/текста.
Модель коробки (Box Model)
Каждый элемент — прямоугольник: content + padding + border + margin.
.card {
width: 300px; /* ширина content */
padding: 16px; /* внутренние отступы */
border: 1px solid #e5e7eb; /* рамка */
margin: 12px auto; /* внешние отступы */
box-sizing: border-box; /* включает padding и border в width */
}
Практика
Сверстайте 3 карточки проекта: выровняйте по сетке, примените отступы, рамки и скругления.
Позиционирование элементов
.parent { position: relative; }
.child { position: absolute; top: 8px; right: 8px; }
.fixed-banner { position: fixed; bottom: 16px; right: 16px; }
.sticky-header { position: sticky; top: 0; }
Практика
Сделайте липкую шапку и значок (badge) в правом верхнем углу карточки через absolute.
Flexbox
.row {
display: flex;
gap: 16px;
justify-content: space-between; /* выравнивание по главной оси */
align-items: center; /* выравнивание по поперечной оси */
}
.card { flex: 1 1 300px; }
Практика
Сверстайте горизонтальное меню и сетку карточек на Flexbox с переносом строк.
Grid Layout
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.item:nth-child(1) { grid-column: span 2; }
Практика
Сделайте фотогалерею 3×N, одну из карточек растяните на 2 колонки.
Адаптивная верстка и медиазапросы
Mobile‑First: сначала стили для мобильных, затем усложняем для больших экранов.
.container { padding: 16px; }
@media (min-width: 768px) {
.container { max-width: 720px; margin: 0 auto; }
}
@media (min-width: 1024px) {
.container { max-width: 960px; }
}
Практика
Сделайте главную портфолио адаптивной: навигация, сетки карточек, отступы.
Трансформации, переходы и анимации
.btn { transition: transform .2s ease, box-shadow .2s ease; }
.btn:hover { transform: translateY(-2px); box-shadow: 0 8px 16px rgba(0,0,0,.1); }
@keyframes pulse { from { transform: scale(1); } to { transform: scale(1.05); } }
.card:hover { animation: pulse .8s ease-in-out alternate; }
Практика
Добавьте hover‑эффекты кнопкам и карточкам, анимируйте появление элементов.
Flexbox — углублённо
Разбираемся с алгоритмом распределения пространства, переносом строк и выравниванием многострочных рядов.
.row { display: flex; flex-wrap: wrap; gap: clamp(12px, 2vw, 24px); }
.card { flex: 1 1 clamp(220px, 30%, 360px); min-width: 220px; }
.row { align-content: start; /* выравнивание нескольких рядов */ }
.card { align-self: stretch; }
Известные ловушки
- Сжатие контента: используйте
min-widthиmin-height. - Неожиданное выравнивание — различайте
align-itemsиalign-content.
Grid — углублённо
Шаблоны областей, автоматическое размещение, функции minmax(), fit-content(), subgrid.
.layout {
display: grid;
grid-template-columns: [full-start] 1fr [content-start] minmax(0, 1200px) [content-end] 1fr [full-end];
}
.layout > * { grid-column: content; }
.gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; }
.article { display: grid; grid-template-columns: 1fr 320px; grid-template-rows: auto 1fr; grid-template-areas:
'title aside' 'content aside'; }
.article__title { grid-area: title; }
.article__content { grid-area: content; }
.article__aside { grid-area: aside; }
Subgrid: позволяет наследовать линии родителя для вложенных сеток (поддержка в современных браузерах).
Архитектуры CSS: БЭМ, ITCSS, Utility‑first
БЭМ
Именование: block__element--modifier. Пример: card, card__title, card--featured.
.card { /* блок */ }
.card__title { /* элемент */ }
.card--featured { /* модификатор */ }
ITCSS
Слои: Settings → Tools → Generic → Elements → Objects → Components → Utilities. От абстрактного к конкретному, уменьшает специфичность.
Правила поддержки
- Минимизируйте специфичность: избегайте селекторов по id, вложенности > 2 уровней.
- Компонентный подход: каждый блок изолирован, стили живут рядом.
- Используйте design tokens через
:rootи CSS Custom Properties.
:root { --space-1: 8px; --space-2: 12px; --brand: #4f46e5; }
.button { padding: var(--space-1) var(--space-2); background: var(--brand); }
Адаптив: контейнерные запросы, ретина, медиа
Container Queries
.card-grid { container-type: inline-size; }
.card { display: grid; grid-template-columns: 1fr; }
@container (min-width: 480px) {
.card { grid-template-columns: 1fr 1fr; }
}
Ретина и качество
image-set()для фоновых изображений;srcsetдля<img>.- Используйте
aspect-ratio, указывайтеwidth/heightу медиа для предотвращения CLS.
Производительность CSS
- Критический CSS: инлайните ключевые стили в
<head>, остальное отложенно. - Избегайте тяжёлых теней и анимаций layout/paint; анимируйте
transformиopacity.
Итоговый проект модуля 2
Полностью стилизуйте главную портфолио‑страницу: сетки (Flex/Grid), адаптивность, типографика, интерактивные hover‑эффекты.
- Навигация (desktop/mobile), секции «Проекты» (карточки), «Контакты» (форма)
- Светлая/тёмная темы — по желанию
- Анимации появления элементов при наведении/прокрутке