Основы веба: HTML и CSS для быстрого старта

Курс закладывает фундамент веб-разработки, обучая созданию структуры и визуального стиля страниц. Вы пройдете путь от пустой страницы до верстки каркаса интерфейса, который станет основой для вашего будущего приложения на Vue.

Анатомия веб-страницы: структура HTML и семантика

Анатомия веб-страницы: структура HTML и семантика

Любой сайт, который вы открываете в браузере, — от простого блога до сложного интерактивного приложения — изначально представляет собой обычный текстовый файл. Браузер получает этот текст и превращает его в кнопки, картинки и абзацы. Как он понимает, где что находится? Для этого используется HTML — язык разметки, который работает как чертеж или визуальный каркас будущего интерфейса.

Если вы планируете создавать современные Single Page Applications (SPA) на Vue, React или чистом JavaScript, всё начинается с HTML. Фреймворки будут динамически менять этот каркас, но сама основа остается неизменной.

Теги: строительные блоки веба

Основа языка HTML — это теги. Они работают как контейнеры, которые сообщают браузеру смысл обернутого в них текста.

Обычно тег состоит из открывающей и закрывающей части:

<button>Нажми меня</button>

Некоторые теги не имеют содержимого и пишутся в единственном числе, например, тег изображения:

<img src="logo.png" alt="Логотип сайта">

В этом примере src и alt — это атрибуты. Они дают тегу дополнительные настройки: откуда загрузить картинку и какой текст показать, если картинка не загрузится.

Каркас документа: невидимое и видимое

Каждая веб-страница имеет строгую базовую структуру. Это фундамент, без которого браузер может неправильно отобразить содержимое.

<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="UTF-8">
    <title>Мое первое SPA</title>
  </head>
  <body>
    <h1>Добро пожаловать</h1>
    <p>Это интерфейс нашего приложения.</p>
  </body>
</html>

Эта структура делится на две принципиально разные зоны:

  1. head (голова) — служебная информация для браузера и поисковиков. То, что написано внутри <head>, пользователь не видит на самой странице. Здесь задается кодировка, название вкладки (<title>) и подключаются будущие стили CSS.
  2. body (тело) — всё, что отображается на экране. Тексты, формы, кнопки, списки — весь интерфейс живет внутри <body>.

Обратите внимание на то, как теги вложены друг в друга. HTML — это строгая иерархия, похожая на матрешку. Элемент <h1> находится внутри <body>, а <body>внутри <html>. В будущем, когда вы начнете работать с JavaScript и Vue, вы будете управлять именно этим «деревом» элементов (оно называется DOM-деревом).

Семантика: почему нельзя строить всё из «коробок»

Исторически сложилось так, что существуют два универсальных тега: <div> (для крупных блоков) и <span> (для строчных элементов, например, выделения слова в тексте). Они не несут в себе никакого смысла. Это просто пустые коробки.

Технически, весь сайт можно сверстать, используя только <div>:

<div class="header">Логотип и меню</div>
<div class="main-content">
  <div class="article">Текст статьи...</div>
</div>

Браузер отобразит это нормально. Но такой подход считается грубой ошибкой. Современный веб требует семантической разметки — использования тегов, которые прямо говорят о своем назначении.

Вместо безликих коробок мы должны использовать осмысленные элементы:

  • <header> — шапка сайта или раздела.
  • <nav> — блок навигации (меню).
  • <main> — главное уникальное содержимое страницы.
  • <article> — самостоятельная смысловая единица (пост в блоге, карточка товара).
  • <footer> — подвал сайта.

Семантика — это использование HTML-тегов по их прямому смысловому назначению, а не только ради визуального отображения.

Зачем нужна семантика, если выглядит одинаково?

Визуально семантические теги ничем не отличаются от обычных <div>. Разница кроется «под капотом»:

  1. Доступность (Accessibility). Люди с нарушениями зрения используют скринридеры — программы, которые читают сайт вслух. Скринридер не понимает, что <div class="menu"> — это меню. Но он точно знает, что такое <nav>, и предложит пользователю удобную навигацию по нему.
  2. SEO (Поисковая оптимизация). Поисковые роботы Google и Яндекса анализируют теги, чтобы понять структуру контента. Текст внутри <h1> и <article> ценится алгоритмами выше, чем текст в безымянном <div>.
  3. Читаемость кода. Когда вы (или ваши коллеги) откроете код компонента Vue через полгода, гораздо проще ориентироваться в <header> и <section>, чем в бесконечной простыне из <div>.

Мы разобрали, из чего состоит скелет веб-страницы и как сделать его понятным для браузеров и поисковиков. Но прямо сейчас наш правильный семантический HTML выглядит как скучный черно-белый документ из 90-х. Чтобы превратить этот текст в современный интерфейс, нам нужно добавить правила оформления. Этим мы займемся на следующем шаге.

Оформление интерфейса: основы CSS и каскадность

Оформление интерфейса: основы CSS и каскадность

Разметка, которую мы построили, дает браузеру четкое понимание, где находится шапка сайта, а где — основная статья. Однако визуально это все еще выглядит как текстовый документ из начала девяностых: черный шрифт на белом фоне, элементы выстроены строго друг под другом. Чтобы превратить этот сырой каркас в современный интерфейс будущего SPA-приложения, нам нужен инструмент управления внешним видом.

Анатомия CSS-правила

CSS (Cascading Style Sheets) не меняет саму структуру документа. Это набор инструкций, которые браузер накладывает поверх HTML-дерева в момент отрисовки.

Каждая инструкция в CSS состоит из двух обязательных частей:

селектор {
    свойство: значение;
}

Селектор работает как поисковый запрос: он указывает браузеру, какие именно элементы в DOM-дереве нужно найти. Блок внутри фигурных скобок — это объявление стиля, где мы перечисляем, что именно хотим изменить (цвет, размер, отступы) и на какое значение.

Например, чтобы сделать текст во всех абзацах серым, мы пишем:

p {
    color: gray;
}

Как прицелиться точно: виды селекторов

Если мы будем стилизовать только по названиям тегов, все кнопки на сайте станут одинаковыми. В реальных интерфейсах нам нужно отличать главную кнопку отправки формы от второстепенной кнопки отмены. Для этого используются атрибуты class и id, которые мы добавляем к HTML-тегам.

Тип селектора Синтаксис в CSS Пример в HTML Когда использовать
По тегу button { ... } <button> Для задания базовых стилей по умолчанию (шрифт, сброс рамок).
По классу .primary-btn { ... } <button class="primary-btn"> Основной рабочий инструмент. Класс можно применять к любому количеству элементов на странице.
По ID #submit-order { ... } <button id="submit-order"> Для уникальных элементов, которые встречаются на странице строго один раз (например, глобальный контейнер приложения).

Столкновение правил: каскадность

В сложных приложениях к одному и тому же тегу неизбежно будут применяться разные правила. Представьте ситуацию:

<button class="warning-btn" id="delete-account">Удалить</button>
button { background-color: gray; }
.warning-btn { background-color: yellow; }
#delete-account { background-color: red; }

Браузер нашел тег <button>. Ему сказано быть серым, желтым и красным одновременно. Какого цвета будет кнопка?

Здесь вступает в силу каскад — алгоритм вычисления приоритета (веса) каждого правила.

Браузер всегда отдает предпочтение более точным селекторам. ID уникален, поэтому он сильнее класса. Класс точнее тега, поэтому он сильнее тега.

ID > Класс > Тег

В нашем примере кнопка станет красной, потому что селектор по ID перевешивает остальные. Если бы селектора #delete-account не было, кнопка стала бы желтой, так как класс .warning-btn сильнее простого тега button.

Если же элементы стилизуются селекторами одинакового веса (например, двумя разными классами), побеждает то правило, которое написано в CSS-файле ниже (позже по коду).

Наследование по DOM-дереву

CSS умеет использовать иерархию вложенности, которую мы заложили в HTML. Некоторые свойства автоматически передаются от тега-родителя ко всем его потомкам. Это называется наследованием.

Если вы зададите базовый шрифт и цвет текста для всего тега <body>:

body {
    font-family: Arial, sans-serif;
    color: #333333;
}

Вам не придется прописывать эти свойства для каждого заголовка, абзаца или списка внутри <body>. Они унаследуют этот стиль автоматически. Однако наследуются не все свойства: например, рамки (border) или фоновый цвет (background) не передаются детям, иначе каждый вложенный элемент обводился бы рамкой родителя, превращая интерфейс в хаос.

Теперь мы умеем находить любые элементы на странице и раскрашивать их. Но элементы все еще идут друг за другом сплошным потоком. Чтобы превратить этот поток в интерфейс с боковыми панелями, карточками и выровненными меню, нам нужно научиться управлять расположением блоков в пространстве.

Позиционирование и сетки: создание каркаса через Flexbox

Позиционирование и сетки: создание каркаса через Flexbox

Вы покрасили стены и купили мебель, но прямо сейчас все кресла, шкафы и столы свалены в одну кучу в коридоре. Браузер по умолчанию выводит HTML-элементы строго друг за другом сверху вниз. Стилизация цветом и шрифтами делает интерфейс красивым, но чтобы превратить сплошную ленту текста в настоящее веб-приложение — с боковым меню, фиксированной шапкой и центральной рабочей областью — нужно взять управление пространством в свои руки.

Блочная модель: из чего состоят элементы

Прежде чем двигать элементы по экрану, необходимо понять, что именно мы двигаем. Для браузера абсолютно любой тег, будь то огромный контейнер main или крошечная кнопка, представляет собой прямоугольную коробку.

Блочная модель (Box Model) — это фундаментальный принцип рендеринга, согласно которому каждый элемент состоит из центрального контента и трех слоев пустого пространства вокруг него.

Эти слои определяют, сколько физического места элемент займет на экране:

  1. Content (Контент) — само содержимое: текст, изображение или вложенные теги.
  2. Padding (Внутренний отступ) — пространство между контентом и границей элемента. Увеличивает размер элемента изнутри. Цвет фона элемента заливает и padding.
  3. Border (Рамка) — видимая граница элемента.
  4. Margin (Внешний отступ) — пустое пространство снаружи рамки. Оно расталкивает соседние элементы в стороны.

По умолчанию браузер рассчитывает ширину элемента нелогично: если вы задали блоку ширину 300 пикселей, а затем добавили внутренний отступ в 20 пикселей со всех сторон, итоговая ширина блока станет 340 пикселей. Элемент «разбухнет» и сломает вам сетку.

Чтобы заставить браузер включать внутренние отступы и рамки в заданную ширину, в современной верстке всегда используют свойство box-sizing. Это правило обычно применяют ко всем элементам на странице с помощью универсального селектора *:

* {
  box-sizing: border-box;
}

Теперь блок с шириной 300 пикселей всегда будет занимать ровно 300 пикселей, а внутренние отступы будут «съедать» пространство внутри, сжимая контент, а не раздувая сам блок.

Flexbox: гибкое управление потоком

Когда размеры блоков предсказуемы, их можно выстраивать в сложные структуры. Исторически верстальщики использовали множество хаков для создания колонок, но сегодня стандартом для создания одномерных макетов (строк или столбцов) является Flexbox (Flexible Box Layout).

Flexbox работает на основе отношений «родитель — ребенок». Как только вы применяете к родительскому тегу свойство display: flex, он превращается во flex-контейнер, а все его прямые потомки автоматически становятся flex-элементами.

.nav-menu {
  display: flex;
}

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

Оси координат

Вся магия Flexbox строится на управлении двумя осями.

  • Главная ось (Main Axis) — направление, вдоль которого выстраиваются элементы. По умолчанию она направлена слева направо (в строку).
  • Поперечная ось (Cross Axis) — перпендикулярна главной оси. По умолчанию направлена сверху вниз.

Вы можете изменить направление главной оси с помощью свойства flex-direction. Если задать flex-direction: column, элементы снова выстроятся в столбик, но теперь вы сможете применять к ним мощные инструменты выравнивания Flexbox.

Выравнивание в пространстве

Для позиционирования элементов вдоль осей используются два главных свойства. Их значения зависят от того, по какой оси происходит выравнивание.

Свойство За что отвечает Популярные значения
justify-content Выравнивание элементов вдоль главной оси. Распределяет свободное место между блоками. center (по центру), flex-end (прижать к концу), space-between (раскидать по краям), space-around (равное пространство вокруг).
align-items Выравнивание элементов вдоль поперечной оси. center (по центру оси), flex-start (прижать к началу), stretch (растянуть на всю высоту контейнера — по умолчанию).

Например, чтобы в шапке сайта логотип находился строго слева, а кнопка профиля — строго справа, достаточно задать контейнеру шапки justify-content: space-between.

Сборка каркаса SPA-приложения

Объединим семантическую структуру и гибкие сетки, чтобы создать классический каркас веб-приложения: верхняя панель управления (header), боковое меню навигации (sidebar) и центральная часть для контента.

<div class="app-container">
  <header class="topbar">
    <div class="logo">MySPA</div>
    <div class="profile">User</div>
  </header>

  <div class="main-layout">
    <aside class="sidebar">
      <nav>Меню</nav>
    </aside>

    <main class="content">
      <h1>Рабочая область</h1>
    </main>
  </div>
</div>

Чтобы этот HTML-код превратился в интерфейс, нам понадобится два flex-контейнера. Первый выстроит логотип и профиль в шапке. Второй — поставит боковое меню и рабочую область рядом друг с другом.

/* 1. Сброс отступов и настройка блочной модели */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* 2. Шапка: элементы раскиданы по краям, выровнены по вертикали */
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 30px;
  background-color: #2c3e50;
  color: white;
}

/* 3. Основная раскладка: боковое меню и контент в один ряд */
.main-layout {
  display: flex;
  /* Растягиваем на всю оставшуюся высоту экрана */
  min-height: 100vh;
}

.sidebar {
  width: 250px;
  background-color: #ecf0f1;
  padding: 20px;
}

/* 4. Контент занимает всё оставшееся свободное место */
.content {
  flex: 1;
  padding: 40px;
}

Свойство flex: 1 у класса .content — это команда элементу: «Расти и занимай всё свободное пространство главной оси, которое осталось после того, как боковое меню забрало свои 250 пикселей».

Именно так создается жесткий, но адаптивный визуальный каркас. Элементы больше не свалены в кучу — у каждого смыслового блока есть свое законное, геометрически выверенное место на экране.

Практикум: верстка макета для будущего SPA-приложения

Практикум: верстка макета для будущего SPA-приложения

Знать устройство молотка и пилы — не то же самое, что уметь построить дом. В предыдущих частях мы разобрали веб-страницу на атомы: семантические теги, каскадные стили и оси Flexbox. Теперь предстоит обратный процесс — собрать из этих деталей классический визуальный каркас Single Page Application (SPA), который станет фундаментом для вашего будущего проекта на Vue.

Архитектура интерфейса

Типичное веб-приложение (будь то CRM-система, панель управления или почтовый клиент) имеет предсказуемую структуру. Мы сверстаем макет, состоящий из трех ключевых зон.

Визуальный блок Семантический тег Роль в приложении
Верхняя панель <header> Глобальная навигация, логотип, профиль пользователя.
Боковая панель <aside> Локальное меню разделов приложения.
Рабочая область <main> Динамический контент, который будет меняться при переходах по SPA без перезагрузки страницы.

Главная задача каркаса SPA — занимать ровно 100% экрана пользователя. Верхняя и боковая панели должны быть зафиксированы, а прокручиваться может только содержимое рабочей области.

Шаг 1: HTML-скелет и подготовка холста

Чтобы расположить боковую панель и рабочую область рядом, нам потребуется обернуть их в дополнительный контейнер.

<div class="app-container">
  <header class="topbar">Логотип и Профиль</header>

  <div class="content-wrapper">
    <aside class="sidebar">Навигация</aside>
    <main class="main-content">Главный экран</main>
  </div>
</div>

Прежде чем писать стили для этих классов, необходимо очистить «холст». Браузеры по умолчанию добавляют отступы к тегу <body> и некоторым другим элементам. Если их не убрать, наш макет не сможет идеально прилегать к краям экрана и появятся ненужные полосы прокрутки.

/* Базовый CSS-сброс */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: sans-serif;
  background-color: #f4f4f9;
}

Шаг 2: Глобальная сетка приложения

Наш корневой элемент .app-container должен растянуться на всю высоту окна браузера. Для этого используется единица измерения vh (viewport height), где 1vh1vh равен 1% от высоты видимой области. Соответственно, полная высота — это 100vh100vh.

Сделаем главный контейнер Flex-родителем и направим его ось вертикально:

.app-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.topbar {
  height: 60px;
  background-color: #2c3e50;
  color: white;
  padding: 0 20px;
  /* Выравниваем контент шапки по горизонтали и вертикали */
  display: flex;
  justify-content: space-between;
  align-items: center;
}

Теперь у нас есть шапка фиксированной высоты. Оставшееся пространство под ней должен занять блок .content-wrapper. Мы уже знаем, как заставить элемент поглотить всё свободное место — используем свойство flex: 1.

.content-wrapper {
  flex: 1;
  display: flex; /* Включаем Flexbox для вложенных aside и main */
}

Шаг 3: Разделение рабочей зоны

Контейнер .content-wrapper теперь сам является Flex-родителем, но его главная ось направлена по умолчанию — горизонтально. Это именно то, что нужно для размещения сайдбара и основного контента.

Если бы мы не использовали Flexbox, нам пришлось бы математически высчитывать ширину главной области: Widthmain=100%250pxWidth_{main} = 100\% - 250px (где 250px — ширина сайдбара). Flexbox делает эту математику за нас.

.sidebar {
  width: 250px;
  background-color: #ffffff;
  border-right: 1px solid #e0e0e0;
  padding: 20px;
}

.main-content {
  flex: 1; /* Занимает всю ширину, оставшуюся от сайдбара */
  padding: 30px;
  overflow-y: auto; /* Добавляем прокрутку, если контента слишком много */
}

Свойство overflow-y: auto в блоке .main-content — это критически важный штрих для SPA. Если текст или таблицы на главном экране не поместятся в высоту окна, прокручиваться будет только этот блок, а шапка и боковое меню останутся на своих местах.

Итог сборки

Объединив HTML-скелет и CSS-правила, вы получаете жесткий, адаптивный каркас. Вложенность Flex-контейнеров (один управляет вертикалью всего приложения, второй — горизонталью нижней части) позволяет создавать сложные интерфейсы без использования громоздких таблиц или абсолютного позиционирования.

Мы завершили создание визуальной оболочки. Прямо сейчас это красивый, но абсолютно статичный макет. В следующих модулях курса мы начнем изучать JavaScript, чтобы научиться «оживлять» этот интерфейс: заставлять кнопки реагировать на клики, открывать модальные окна и динамически подгружать данные в нашу рабочую область.