Из чего состоит страница и как её видит браузер
Веб-страница — это текстовый файл. Браузер получает его с сервера по протоколу HTTP (подробно — в курсе «Основы компьютерных сетей»), читает и рисует на экране. В файле три языка, у каждого своя роль:
| Язык | Отвечает за | Пример |
|---|---|---|
| HTML | Содержание и структуру: что на странице — заголовок, абзац, ссылка, форма | <h1>Кафе «Нева»</h1> |
| CSS | Внешний вид: цвета, шрифты, расположение блоков | h1 { color: navy; } |
| JavaScript | Поведение: реакцию на действия пользователя без перезагрузки | Открыть меню по нажатию |
Этот курс — про первые два. Порядок работы браузера: получить HTML → разобрать его в дерево элементов (DOM) → загрузить файлы, на которые HTML ссылается (стили, картинки, шрифты) → применить стили → нарисовать. Страница сайта nevabit.ru, которую вы читаете, устроена так же: один HTML-файл на модуль и один общий CSS-файл.
HTML размечает текст тегами — словами в угловых скобках. Открывающий тег <p>, закрывающий </p> с косой чертой, между ними — содержимое. Всё вместе называется элементом.
<p>Это абзац текста.</p>
<a href="https://nevabit.ru/">Ссылка на сайт</a>
<img src="logo.png" alt="Логотип кафе">
У тегов бывают атрибуты — дополнительные сведения в открывающем теге, в виде имя="значение". href у ссылки — куда она ведёт, src у картинки — где лежит файл, alt — текст вместо картинки. Некоторые элементы не имеют содержимого и закрывающего тега — их называют пустыми: <img>, <br>, <meta>, <input>.
Элементы вкладываются друг в друга, как матрёшки: закрывать нужно в обратном порядке. <p><strong>…</strong></p> — верно, <p><strong>…</p></strong> — ошибка. Браузер не сообщает об ошибках разметки, а молча «чинит» их по своим правилам — и результат бывает неожиданным:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Вложенность</title>
</head>
<body>
<p>Абзац, в котором <strong>важное слово</strong> выделено.</p>
<p>Абзац с ошибкой: <strong>тег не закрыт</p>
<p>Следующий абзац тоже стал жирным.</p>
</body>
</html>

Незакрытый <strong> браузер перенёс в следующий абзац. На странице из сотни строк такую ошибку ищут долго — поэтому разметку проверяют валидатором (раздел 07). Имена тегов пишут строчными буквами, значения атрибутов — в двойных кавычках.
У каждой HTML-страницы одинаковый каркас. Создайте каталог site, в нём файл index.html:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Моя первая страница</title>
</head>
<body>
<h1>Привет, веб!</h1>
<p>Это моя первая страница. Её показывает браузер,
а написана она в обычном текстовом редакторе.</p>
</body>
</html>
| Строка | Зачем |
|---|---|
<!DOCTYPE html> | Сообщает браузеру, что это современный HTML. Без неё браузер включает «режим совместимости» со старыми ошибками вёрстки |
<html lang="ru"> | Корневой элемент. lang — язык страницы: по нему экранный диктор выбирает произношение, браузер — переносы и перевод |
<head> | Служебная часть: на экране не видна |
<meta charset="UTF-8"> | Кодировка файла. Без неё кириллица может превратиться в «кракозябры» |
<meta name="viewport" …> | Ширина страницы на телефоне равна ширине экрана. Без неё телефон показывает страницу уменьшенной копией настольной (модуль 08) |
<title> | Название во вкладке браузера, в закладках и в результатах поиска |
<body> | Всё, что видно на странице |
Откройте файл в браузере: двойной щелчок или перетаскивание в окно браузера. Адрес в строке начнётся с file:// — страница открыта с диска, без сервера:

Браузер показал заголовок крупно и жирно, абзац — обычным текстом, хотя никаких стилей мы не писали. Это стили браузера по умолчанию: у каждого элемента есть начальный вид, CSS его меняет. Отступы в коде (четыре пробела перед <h1>) нужны только человеку — на результат они не влияют.
index.html. Веб-сервер отдаёт её, когда в адресе указан только каталог: nevabit.ru/html-css-basics/ — это файл html-css-basics/index.html.Браузер схлопывает любую последовательность пробелов, табуляций и переводов строк в один пробел. Поэтому в коде абзац можно разбивать на строки как удобно, а принудительный перенос делается тегом <br>:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Пробелы</title>
</head>
<body>
<p>Слова разделены
многими пробелами
и переводами строк.</p>
<p>Перенос строки внутри абзаца —<br>только тегом br.</p>
</body>
</html>

<br> — для переноса внутри одного абзаца: строки адреса, стихи. Отступ между частями текста делают не пустыми <br><br>, а новым абзацем <p> и CSS.
Текст между <!-- и --> браузер не показывает. Комментарии оставляют для себя и коллег или временно «выключают» кусок разметки:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Комментарии</title>
</head>
<body>
<!-- Шапка: заменить на логотип, когда он будет готов -->
<h1>Кафе «Нева»</h1>
<p>Открыто ежедневно с 9:00 до 22:00.</p>
<!-- <p>Скидка 10 % до конца месяца</p> -->
</body>
</html>

Для вёрстки подойдёт любой редактор кода. В курсе — VS Code: он подсвечивает теги, сам закрывает их, а набор ! и Tab в пустом файле .html вставляет скелет документа. Расширение Live Server открывает страницу через небольшой локальный сервер и обновляет её при каждом сохранении файла.
В любом браузере есть инструменты разработчика — F12 или Ctrl+Shift+I (в Яндекс Браузере, Chrome, Firefox одинаково). Главное на старте:
strong оказался внутри трёх абзацев.Ctrl+U показывает исходный HTML, каким его прислал сервер. Откройте так любой сайт — это лучший способ увидеть, как сделаны чужие страницы.
Браузер прощает ошибки, валидатор — нет. Сервис validator.w3.org/nu проверяет HTML по стандарту: загрузите файл (вкладка «Validate by File Upload») или вставьте код (вкладка «Validate by Direct Input»). Сообщения — на английском, с номером строки и столбца. Для файла nested.html из раздела 02:
Error: End tag “p” seen, but there were open elements. (строка 9)
Error: Unclosed element “strong”. (строка 9)
Error: Element “p” not allowed as child of element “strong” in this context. (строка 10)
Исправлять начинают с первой ошибки: остальные часто — её следствия. Здесь все три исчезнут, если закрыть </strong> перед </p>.
<!DOCTYPE html>, lang или <meta charset>.alt.id у двух элементов (модуль 04).<span> и подобное.<!DOCTYPE html>, <html lang="ru">, в head — charset, viewport, title; видимое — в body<br>, новый абзац — <p>