Вёрстка: HTML, CSS, flexbox и адаптивность
Семантические теги HTML, блочная модель CSS, селекторы и их приоритет, flexbox и grid, адаптивность через медиазапросы, вёрстка формы.
Курсовая по веб-разработке начинается с вёрстки. Современный минимум — семантическая разметка, flexbox для строк, grid для сеток и медиазапросы для телефонов.
Семантическая структура
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Каталог комплектующих</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="header">
<nav>
<a href="/">Главная</a>
<a href="/catalog/">Каталог</a>
</nav>
</header>
<main>
<h1>Каталог</h1>
<section class="cards">
<article class="card">
<h2>Резистор 10 кОм</h2>
<p>Мощность 0,25 Вт, допуск 5 %.</p>
</article>
</section>
</main>
<footer>© 2026</footer>
<script src="app.js" defer></script>
</body>
</html>
Блочная модель
Ширина элемента по умолчанию:
width + padding + border (content-box)
С box-sizing: border-box:
width включает padding и border — считать удобнее
Поэтому в начало таблицы стилей ставят:
*, *::before, *::after { box-sizing: border-box; }
Селекторы и приоритет
| Селектор | Пример | Вес |
|---|---|---|
| Тег | p, h1 | 1 |
| Класс | .card | 10 |
| Атрибут | [type="text"] | 10 |
| Псевдокласс | :hover, :nth-child(2) | 10 |
| id | #header | 100 |
| Встроенный стиль | style="..." | 1000 |
| !important | color: red !important | Перебивает всё |
Правило с большим весом побеждает независимо от порядка в файле. При равном весе применяется последнее. Отсюда практический вывод: стройте стили на классах, id и !important оставьте на исключения — иначе переопределить что-либо станет невозможно.
Flexbox
.header {
display: flex;
justify-content: space-between; /* по главной оси */
align-items: center; /* по поперечной */
gap: 16px;
}
.cards {
display: flex;
flex-wrap: wrap; /* переносить на новую строку */
gap: 20px;
}
.card {
flex: 1 1 280px; /* расти, сжиматься, базовая ширина 280px */
}
/* Центрирование чего угодно */
.modal {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
| Свойство | Значения | Действие |
|---|---|---|
| flex-direction | row, column | Направление главной оси |
| justify-content | flex-start, center, space-between, space-around | Раскладка по главной оси |
| align-items | stretch, center, flex-start, baseline | Выравнивание по поперечной |
| flex-wrap | nowrap, wrap | Перенос элементов |
| gap | любая длина | Отступы между элементами |
| flex | grow shrink basis | Поведение при изменении размера |
Grid
.layout {
display: grid;
grid-template-columns: 250px 1fr; /* сайдбар и основная часть */
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 20px;
}
/* Автоматическая сетка карточек без медиазапросов */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 16px;
}
/* Именованные области */
.page {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
}
.page > header { grid-area: header; }
.page > aside { grid-area: sidebar; }
Адаптивность
/* Мобильные стили — база, затем расширяем для крупных экранов */
.cards { grid-template-columns: 1fr; }
@media (min-width: 640px) {
.cards { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
.cards { grid-template-columns: repeat(3, 1fr); }
.layout { grid-template-columns: 250px 1fr; }
}
/* Гибкий шрифт без медиазапросов */
h1 { font-size: clamp(1.5rem, 4vw, 2.5rem); }
/* Изображения не должны вылезать за контейнер */
img { max-width: 100%; height: auto; display: block; }
Подход mobile first — сначала стили для узкого экрана, потом min-width для широких — даёт более короткий и предсказуемый CSS, чем обратный порядок с max-width.
Переменные и тёмная тема
:root {
--accent: #0969da;
--text: #1f2328;
--bg: #ffffff;
--border: #d0d7de;
}
body {
color: var(--text);
background: var(--bg);
font: 16px/1.6 system-ui, -apple-system, 'Segoe UI', sans-serif;
}
@media (prefers-color-scheme: dark) {
:root {
--text: #e6edf3;
--bg: #0d1117;
--border: #30363d;
}
}
Форма
<form class="form" novalidate>
<label>
Имя
<input type="text" name="name" required minlength="2">
</label>
<label>
E-mail
<input type="email" name="email" required>
</label>
<label>
Количество
<input type="number" name="qty" min="1" step="1" value="1">
</label>
<button type="submit">Отправить</button>
</form>
- Оборачивайте поле в label или связывайте через for и id — иначе клик по подписи не переводит фокус в поле, а скринридеры не понимают структуру.
- Правильный type даёт мобильную клавиатуру нужного вида: email, tel, number.
- Атрибуты required, min, minlength дают базовую проверку без скриптов.
- Стилизуйте состояния :focus и :invalid — пользователь должен видеть, где ошибка.
Частые ошибки
- Вёрстка таблицами вместо grid — в курсовой по веб-разработке считается грубым нарушением.
- Абсолютные размеры в пикселях у контейнеров: страница ломается на другом экране.
- Отсутствие alt у изображений — минус к доступности и к валидации.
- Десяток !important подряд: признак того, что структура селекторов вышла из-под контроля.
- Нет проверки в валидаторе W3C — приложите отчёт валидатора к работе, это дешёвый плюс.
Частые вопросы
Flexbox или Grid?
Flexbox для одномерных раскладок: строка кнопок, шапка, вертикальное меню. Grid для двумерных: сетка карточек, каркас страницы. Их спокойно комбинируют — grid для макета, flex внутри его ячеек.
Зачем семантические теги, если можно всё сделать на div?
Поисковики и скринридеры понимают структуру страницы по тегам header, nav, main, article. Кроме того, семантическая разметка читается людьми — через месяц вы сами разберётесь в своём коде быстрее.
Нужен ли Bootstrap для курсовой?
Он ускоряет работу, но многие кафедры требуют собственную вёрстку — иначе непонятно, что сделали вы. Уточните у руководителя; если фреймворк разрешён, обязательно объясните в отчёте, какие его возможности использованы.