HTML · Урок 1

Введение в HTML

Первый шаг в веб-разработке: узнаем, из чего состоит любая страница, и создадим свой первый документ.

Что такое HTML

HTML (HyperText Markup Language) — язык разметки гипертекста. Он не является языком программирования: HTML описывает структуру и смысл содержимого страницы, а не вычисления или логику.

Любой сайт, который вы видите, — это HTML, «одетый» в стили (CSS) и оживлённый скриптами (JavaScript). Сравните с человеком:

Из чего состоит тег

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

<p>Это абзац текста.</p>
ТегЧто делает
<h1>–<h6>Заголовки от самого важного до самого мелкого
<p>Абзац текста
<a>Ссылка
<img>Изображение (одиночный, без «пары»)
<div>Универсальный блок-контейнер
💡
Одиночные теги (например, <img>, <br>) не имеют закрывающей части — им нечего «закрывать».

Каркас HTML-документа

Любая страница начинается с одного и того же скелета. Создайте файл index.html и вставьте туда это:

<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="UTF-8">
    <title>Моя первая страница</title>
  </head>
  <body>
    <h1>Привет, мир!</h1>
    <p>Мой первый HTML.</p>
  </body>
</html>

Разберём по частям:

Живой пример

Вот что получится — это уже настоящая веб-страница:

Привет, мир!

Мой первый HTML.

⚠️
Когда сохраните файл, откройте его двойным кликом — он загрузится прямо в браузере по адресу file://. Хостинг для этого не нужен.

Комментарии в HTML

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

<!-- Это комментарий -->
<p>Пользователь видит только это.</p>
<!--
  Многострочный комментарий
  тоже допустим
-->
💡
Комментарием можно временно «выключать» куски разметки при отладке. Но помните: исходный код страницы виден в браузере — не пишите туда секреты.

Атрибут lang и язык документа

Атрибут lang сообщает браузеру и поисковикам, на каком языке написан документ. Это влияет на проверку орфографии, выбор шрифтов и озвучивание скринридерами:

<html lang="ru">   <!-- русская страница -->
ℹ️
Лучше указывать конкретный язык и страну, например lang="ru-RU" или lang="en-US". Если язык указан неверно, браузер может споткнуться о встроенный переводчик.

Анатомия URL

Любой адрес в интернете состоит из нескольких частей. Разберём на примере:

https://example.com:443/blog/post?page=2#comments
└──┘  └────────┘ └─┘ └───────┘ └──────┘ └──────┘
схема    домен   порт   путь    запрос   якорь
ЧастьЧто это
https://схема (протокол). https — шифрованное соединение
example.comдомен — адрес сайта
:443порт. Для https обычно 443, его не пишут
/blog/postпуть к ресурсу на сервере
?page=2запрос: параметры после ?
#commentsякорь: прокрутка к элементу с этим id

DevTools — инструменты разработчика

Самый полезный инструмент верстальщика встроен в каждый браузер. Открывается клавишей F12 или Ctrl+Shift+I.

💡
Наведите курсор на элемент страницы и нажмите Ctrl+Shift+C — откроется именно этот элемент в инспекторе.

Структура проекта и имя index.html

Главную страницу сайта принято называть index.html — сервер отдаёт её по умолчанию, когда открывают корень сайта. Держите порядок и в папках:

my-site/
├── index.html       <!-- главная -->
├── about.html
├── css/
│   └── style.css
├── js/
│   └── main.js
└── images/
💡
Имена файлов — только латиницей, в нижнем регистре, без пробелов: about-us.html, а не «О Нас.html». Пробелы в адресе кодируются и ломают вёрстку на части серверов.

Мета-теги: charset, viewport, description

В <head> живут невидимые настройки документа. Три самых важных мета-тега:

<meta charset="UTF-8">   <!-- кодировка, без неё кириллица сломается -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Краткое описание страницы">
ℹ️
charset ставят первым, viewport обязателен для телефонов, а description поисковики нередко показывают в сниппете результатов под названием страницы.

Текст: абзацы, переносы и линии

За абзац отвечает <p>. Внутри одного абзаца перенос вручную — это <br>, а тему отделяют горизонтальной линией <hr>:

<p>
  Первая строка,<br>
  вторая строка того же абзаца.
</p>

<hr>   <!-- разделитель между блоками -->

<p>Новый смысловой блок.</p>
⚠️
Не ставьте по <br> для отступов между абзацами — для этого существуют CSS-отступы. <br> нужен только внутри текста.

Валидность и стандарты W3C

Стандарты интернета пишет консорциум W3C. Его валидатор проверяет HTML на ошибки — разметка с ошибками может работать, но вести себя непредсказуемо в разных браузерах:

💡
Ошибку «страница сломалась» чаще всего видно глазами в DevTools: браузер сам подсвечивает неправильно закрытые теги в инспекторе.

Блочные и строчные элементы

Блочные теги существуют отдельной строкой и тянутся на всю ширину, строчные живут внутри строки как слова:

<div>Первый блок</div>   <!-- каждый на своей строке -->
<div>Второй блок</div>

<p>Текст со <span>строчным</span> вкраплением.</p>
💡
Всем тегам алгоритмам важно: p, div, заголовки — блочные; a, span, strong, code — строчные. CSS меняет это поведение через display.

Глобальные атрибуты: title и hidden

Некоторые атрибуты работают у любого тега. title даёт подсказку, hidden прячет элемент:

<p title="Подсказка при наведении">Наведите курсор</p>
<div hidden>Этого не покажем</div>

<abbr title="Гипертекстовая разметка">HTML</abbr>

Вложенные списки

Списки вкладываются друг в друга — получается иерархия, как в меню или оглавлении:

<ul>
  <li>HTML
    <ul>
      <li>Теги</li>
      <li>Атрибуты</li>
    </ul>
  </li>
</ul>
ℹ️
Вложенный список всегда живёт внутри <li>, а не «между» пунктами — иначе структура ломается.

Иерархия заголовков

Заголовки образуют дерево смысла. Одно <h1> на страницу, ниже <h2>, затем <h3>:

<h1>Статья</h1>
  <h2>Введение</h2>
    <h3>Цели курса</h3>
  <h2>Итоги</h2>
⚠️
Не перепрыгивайте уровни: с h1 сразу на h3 — плохо для доступности и SEO. И не используйте заголовки ради «жирного текста».

Кодировка UTF-8

Первый тег документа — <meta charset>. Без него браузер угадывает кодировку и часто ошибается — на странице «кракозябры»:

<meta charset="UTF-8">
💡
Сохраняйте файлы редактором тоже в UTF-8 (это почти всегда по умолчанию). Если текст «сломался» — проверьте и тег, и кодировку сохранения.

Ленивая загрузка изображений

Картинки вне первого экрана грузить сразу незачем — браузер подтянет их, когда прокрутишь до них:

<img src="photo.jpg" alt="Фото" loading="lazy">
ℹ️
Первому экрану loading="lazy" не ставят: эта картинка видна сразу, отложенная загрузка только задержит её.

Формы: базовые поля

Тег <form> и поля <input> собирают данные пользователя. Вспомогательный материал про формы увидим в следующих уроках, а вот каркас:

<form action="/send" method="post">
  <input name="email" type="email">
  <button type="submit">Отправить</button>
</form>

Чекбоксы и радиокнопки

Чекбокс — несколько «да/нет», радиокнопка — один из группы:

<label><input type="checkbox"> Согласен</label>

<label><input type="radio" name="opt" value="a"> Вариант А</label>
<label><input type="radio" name="opt" value="b"> Вариант Б</label>
ℹ️
Радиокнопки объединяются общим name — можно выбрать одну. Чекбокс с тем же name просто передаст массив отмеченных значений.

Валидация форм без JS

Браузер сам подскажет о незаполненном обязательном поле или неверном e-mail:

<input type="email" required>
<input type="text" minlength="3" maxlength="20">
<input type="number" min="1" max="10">

label и доступность форм

<label> связывает надпись и поле. Клик по надписи фокусирует поле — большая кнопка нажимаемости:

<label for="name">Имя</label>
<input id="name" type="text">

<!-- или вложенный вариант без for/id -->
<label>Имя<input type="text"></label>

Кнопки: <button>

Внутри формы у кнопки три режима: submit (по умолчанию), reset и button (просто кнопка):

<button type="submit">Отправить</button>
<button type="reset">Сбросить</button>
<button type="button">Нейтральная</button>
⚠️
Тип submit у кнопки в форме «по умолчанию» — случайный Enter в поле отправки «провалит» форму. Не дайте удивиться чужим кнопкам без type.

Якорная навигация

Ссылка с # прокручивает к элементу с соответствующем id:

<a href="#contacts">К контактам</a>
...
<section id="contacts">Контакты</section>
💡
href="#top" с id="top" у <body> — классическая «стрелка наверх» без единой строчки JS.

HTML-сущности

Спецсимволы записываются символом &, кодом и точкой с запятой. Главные — угловые скобки:

<p>Тег начинается с &lt; (это символ <).</p>
СущностьЧто даёт
&lt;<
&gt;>
&amp;&
&copy;©
&nbsp;неразрывный пробел

Как ускорить работу с кодом

Советы, которые экономят часы с первого дня живут в редакторе VS Code:

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

HTML появился в 1991 году как разметка научных статей. Дальше — версии: HTML 3.2, HTML 4.01, строгий XHTML, и наконец живой стандарт HTML5, который развивается и сейчас.

ℹ️
Важный пункт: HTML5 не «выпускался» один раз. Он обновляется ежегодно — поэтому браузеры добавляют теги без «новых версий языка».

Строение тега

Базовый синтаксис: открывающий тег, содержимое, закрывающий тег:

<p>Это параграф.</p>

<!-- тег с атрибутом: -->
<a href="https://example.com">Ссылка</a>

Самозакрывающиеся теги

Некоторые теги не имеют содержимого: img, br, input, hr, meta.

<img src="logo.png" alt="Логотип">
<br>  <!-- перенос строки -->
<hr>  <!-- разделитель -->

Регистр тегов

Теги пишут строчными буквами. Смешивать регистр можно, но это дурной тон:

<P>Так можно, но не надо</P>
<p>Так правильно</p>

Кавычки атрибутов

Классика — двойные кавычки. Если внутри нужны кавычки, используйте «ёлочки» или одиночные:

<a title="Читайте «это»">текст</a>
<input value='весь текст'>

Комментарии: <!-- -->

Комментарии не отображаются, но их видно в исходнике. Ими помечают разделы и временно выключают фрагменты:

<!-- ===== Шапка сайта ===== -->
<header>...</header>

<!-- <p>Баннер отключён</p> -->

Направление текста: dir

Атрибут dir управляет направлением письма — нужен арабскому и ивриту:

<p dir="rtl">مرحبا بكم</p>
ℹ️
На уровне страницы задают в теге <html dir="rtl"> или через CSS direction.

Тег bdo: управление порядком

Принудительно развернуть вывод строки — экзотика, но полезна:

<p>Страница<bdo dir="rtl">Страница</bdo></p>

Заголовок в поисковиках: title

Title — это почти реклама результата в Google. Кратко и с ключами:

<title>Курс веб-разработки с нуля · 2026</title>
💡
Держите до ~60 символов, ставьте главное первым словом — в результатах поиска хвост обрезается.

Мета-теги для ботов

Хочешь — чтобы не индексировать страницу. Пиши явно:

<meta name="robots" content="index, follow">
<meta name="author" content="Иван Иванов">
<meta name="theme-color" content="#0f172a">

Канонический адрес

Когда страница доступна по нескольким путям, укажите эталон:

<link rel="canonical" href="https://site.ru/page/">

Списки: начало и тип маркера

Нумерованный список начинается не всегда с 1 — и не всегда с цифр:

<ol start="5">   <!-- с пятого -->
  <li>Пять</li>
</ol>

<ol type="A">   <!-- A, B, C -->
<li>Буква</li>
</ol>

Обратный список: reversed

Отсчёт сверху вниз — топ-10 для списка «наоборот»:

<ol reversed>
  <li>Третье место</li>
  <li>Второе место</li>
  <li>Первое место</li>
</ol>

tabindex: порядок фокуса

Tab последовательно проходит интерактивные элементы. tabindex упорядочивает или исключает:

<button tabindex="2">Второй</button>
<button tabindex="1">Первый</button>
<button tabindex="-1">Скрыт из Tab</button>
⚠️
Логичный порядок в разметке лучше автоперестановок: код не рассинхронизируется с реальностью.

Ссылка в новую вкладку

Атрибут target="_blank" открывает цель отдельно, а rel закрывает уязвимость:

<a href="https://example.com" target="_blank" rel="noopener noreferrer">Открыть</a>
⚠️
Без noopener новая вкладка получает доступ к объекту window.opener вашей страницы — классическая дыра. Добавляйте rel всегда.

Якорь «наверх»

Ссылка наверх страницы — просто #top или к первому id:

<body id="top">
  ...
  <a href="#top">Наверх ↑</a>
</body>

Подсказка на ссылке

Атрибут title показывает всплывающую подсказку — но не заменяет текст:

<a href="/docs" title="Откроется в новом разделе">Документация</a>
💡
Подсказки не работают на тач-устройствах. Вся важная информация — в тексте ссылки.

Изображения: размеры против «прыжков»

Указывайте width и height — браузер зарезервирует место и страница не дёрнется при загрузке:

<img src="photo.jpg" alt="Фото" width="640" height="480">
ℹ️
В CSS можно затем задать width: 100%; height: auto — пропорции сохранятся.

Формы: method GET и POST

Способ отправки данных на сервер:

<form method="get">  <!-- данные в адресе -->
<form method="post">  <!-- данные в теле, безопаснее -->
ℹ️
GET — для поиска и фильтров (адрес можно сохранить). POST — для паролей и изменений. Пароли в GET попадут в историю — никогда так не делайте.

Формы: куда отправлять — action

Атрибут action указывает адрес обработчика формы:

<form action="/subscribe" method="post">
  <input type="email" name="email">
  <button>Подписаться</button>
</form>

Плейсхолдер: подробности

placeholder — подсказка внутри поля; исчезает при вводе и не является значением:

<input type="text" placeholder="Иван Иванов">
⚠️
Не оставляйте placeholder вместо label: по нему нельзя проверить, что уже введено, и он часто слишком бледный.

Многострочное поле: textarea

Для комментариев и сообщений:

<textarea name="comment" rows="4" cols="40">
Начальный текст
</textarea>
💡
Размеры лучше через CSS, но строки-столбцы — быстрое дефолт-решение.

Выпадающий список: select

Пользователь выбирает один вариант из списка:

<select name="city">
  <option value="msk">Москва</option>
  <option value="spb">Санкт-Петербург</option>
</select>

Группы опций: optgroup

Длинный список разбивается на категории:

<select name="city">
  <optgroup label="Россия">
    <option>Москва</option>
  </optgroup>
  <optgroup label="Беларусь">
    <option>Минск</option>
  </optgroup>
</select>

Выбор по умолчанию: selected

Одна из опций может быть предустановлена:

<option value="msk" selected>Москва</option>

Числа: min, max, step

Поле-число с диапазоном и шагом:

<input type="number" min="1" max="99" step="1" value="1">

Цвет и дата

Специальные типы полей — браузер нарисует пипетку и календарь:

<input type="color" value="#38bdf8">
<input type="date">
<input type="range" min="0" max="100">

Загрузка файла: file

Поле выбора файла с ограничением типов:

<input type="file" accept="image/png, image/jpeg" multiple>

Автозаполнение формы

Атрибут autocomplete помогает браузеру подставить сохранённые данные:

<input type="email" name="email" autocomplete="email">
<input type="password" name="pass" autocomplete="new-password">

Фокус сразу: autofocus

Поле получает фокус при открытии страницы:

<input type="search" autofocus>
⚠️
Autofocus уместен на странице входа или поиска. На лендинге он раздражает и «прыгает» на мобильных.

readonly и disabled

Два похожих запрета с разным смыслом:

<input value="ID-12" readonly>   <!-- можно выделить, но не менять -->
<input value="Скидка" disabled>  <!-- серый и не уходит на сервер -->

Группировка полей: fieldset

Логическая группа с подписью legend — для согласий и адресов:

<fieldset>
  <legend>Способ доставки</legend>
  <label><input type="radio" name="delivery"> Курьер</label>
  <label><input type="radio" name="delivery"> Пункт выдачи</label>
</fieldset>

Скрытые поля: hidden

Данные, которые не показываются, но отправляются на сервер:

<input type="hidden" name="utm_source" value="ads">
⚠️
Скрытые поля видны в исходнике кода. Никогда не храните в них цены или пароли — это обманчивая «защита».

submit или button

Тип кнопки определяет поведение внутри формы:

<button type="submit">Отправить</button>
<button type="button">Просто кнопка</button>
<button type="reset">Очистить</button>
ℹ️
Кнопка внутри формы по умолчанию submit. Если она не должна отправлять — пишите type="button", иначе странный «перезапуск» формы обеспечен.

Длина ввода: maxlength

Ограничение числа символов прямо в разметке:

<input type="text" maxlength="20" minlength="3">

Множественный выбор: multiple

Select позволяет выбрать несколько значений (удерживая Ctrl), а file — несколько файлов:

<select name="skills" multiple size="4">
  <option>HTML</option>
  <option>CSS</option>
  <option>JS</option>
</select>

Проверка по шаблону: pattern

Регулярное выражение для поля — например, номер из цифр:

<input type="text" pattern="[0-9]{10}" title="10 цифр">

Прогресс: progress

Полоса выполнения задачи с процентами:

<progress value="70" max="100">70%</progress>

Измерение: meter

Шкала с качественным диапазоном (низко/оптимально/высоко):

<meter value="0.8" min="0" max="1" low="0.3" high="0.7">80%</meter>

Результат вычисления: output

Место для значения, которое посчитает скрипт:

<form oninput="result.value = a.valueAsNumber + b.valueAsNumber">
  <input type="number" name="a" value="1"> +
  <input type="number" name="b" value="1"> =
  <output name="result">2</output>
</form>

Модальное окно: dialog

Нативный контейнер для всплывающего окна — без библиотек:

<dialog id="welcome">
  <p>Добро пожаловать!</p>
  <button onclick="welcome.close()">Закрыть</button>
</dialog>
💡
Открывается через welcome.showModal(). Диалог сам блокирует фон, ловит Escape и позиционируется по центру.

Редактируемый текст: contenteditable

Превращает любой блок в «живой» редактор:

<div contenteditable="true">Попробуйте отредактировать этот текст.</div>

Тренировка

Откройте отредактируйте свой index.html и попробуйте:

  1. Сменить заголовок во вкладке (тег <title>) на свою фамилию.
  2. Добавить второй абзац и заголовок <h2>.
  3. Посмотреть, чем <h1> отличается от <h6> по размеру.
ℹ️
Если что-то сломалось — не страшно. Браузер очень терпим к ошибкам и всё равно попытается показать страницу. Валидность проверяют сервисом W3C Validator.

Клиент и сервер

Любой сайт работает по схеме «запрос — ответ». Ваш браузер — это клиент: он просит данные. Программа на удалённом компьютере, которая их отдаёт, — сервер.

Браузер (клиент)  --запрос-->  Сервер
        <---ответ HTML/CSS/JS---
ℹ️
Один и тот же компьютер может быть и клиентом, и сервером. На своём ПК вы запускаете сервер на localhost и сразу тестируете обе роли.

DNS: как браузер находит сайт

Люди запоминают google.com, а компьютеры работают с IP-адресами вида 142.250.74.46. Переводит имена в адреса система DNS — «телефонная книга интернета».

Браузер: «где живёт google.com?»
DNS:     «это 142.250.74.46, соединяйтесь»
Браузер: «спасибо, открываю!»
💡
Проверить адрес сайта и его IP можно командой nslookup google.com в терминале.

Протокол HTTP: запрос и ответ

HTTP — правила, по которым браузер и сервер общаются. Запрос уходит с методом (чаще всего GET), ответ приходит со статусом: 200 — хорошо, 404 — не найдено, 500 — ошибка сервера.

GET /index.html HTTP/1.1
Host: example.com

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
⚠️
Статус 404 означает лишь «страницы нет», а не «сайт не работает». Сайт жив, просто адрес ошибочный.

Статические и динамические страницы

Статическая страница — заранее готовый файл .html, сервер отдаёт его как есть. Динамическая собирается программой на лету: для блогов, магазинов, личных кабинетов.

💡
Курс «WebDev Уроки» — чистый статический сайт: его можно выложить на любой бесплатный хостинг.

Фронтенд и бэкенд

Веб-разработка делится на две зоны ответственности. Фронтенд — то, что видно в браузере: HTML, CSS, JavaScript. Бэкенд — серверная логика: базы данных, авторизация, оплата.

Вы начали с фронтенда — и это правильно: пока нет страницы, нечего «оживать» на сервере.

ℹ️
Есть ещё третья роль — фулстек: специалист, который умеет и вёрстку, и сервер. Но начинают почти всегда с фронтенда.

Хостинг и публикация

Хостинг — место, где лежат файлы сайта, чтобы он был открывался по адресу. Бесплатные варианты для старта: GitHub Pages, Netlify, Vercel.

Файлы (index.html, css, js)
        |
        v
  GitHub Pages / Netlify / Vercel
        |
        v
  https://ваш-сайт.netlify.app
💡
Для первых уроков хостинг не нужен: открывайте файл двойным кликом. Публикацию отложим до финала курса.

Домены, поддомены и зоны

Полный домен читается справа налево: зона → имя → поддомен. В mail.example.com зона — .com, имя — example, а mail — поддомен.

mail.example.com
└поддомен┘└─имя──┘┘зона
blog.example.com — ещё один поддомен того же сайта
ℹ️
Поддомены не «снимаются» с основного домена сами — их настраивают в панели хостинг-провайдера.

Что такое гипертекст

«Гипер» — значит «сверх». Гипертекст — это текст со ссылками: вместо листания страниц вы мгновенно прыгаете между документами. Отсюда и название языка — HyperText Markup Language.

Обычный текст: читаете по порядку.
Гипертекст:    ссылка «см. пункт 7» ведёт туда сразу.
💡
Когда пишете ссылки, отвечайте на вопрос «куда приведёт?» — и страница останется гипертекстом, а не простой брошюрой.

Страница как документ

Хорошая веб-страница похожа на структурный документ: название, введение, разделы, выводы. Относитесь к странице как к тексту, а не как к «картинке с кнопками» — контент сам подскажет разметку.

⚠️
Не изображайте «документность» на глаз — для этого существуют семантические теги.

Браузеры и их движки

Браузер читает HTML по правилам веб-стандарта. Но реализации отличаются: Chrome и Edge используют движок Blink, Safari — WebKit, Firefox — Gecko.

Chrome / Edge     Blink
Safari            WebKit
Firefox           Gecko
⚠️
Почти всегда код проверяют в каждом из трёх. «Работает в Chrome» — не равно «работает везде».

Как открыть файл в браузере

Самый простой способ увидеть результат — открыть файл .html двойным кликом. В адресной строке появится file:///C:/... — компьютер открыл страницу напрямую, без сервера.

file:///C:/golld/site/index.html
ℹ️
Некоторые возможности (например, запросы к сторонним серверам) при file:// блокируются. Для них позже пригодится Live Server.

Именование файлов: регистр и дефис

Файлы и папки проекта называйте строчными буквами, цифрами, дефисом и подчёркиванием. Пробелы и кириллица в именах ломают ссылки на части серверов.

about-us.html    ✓ правильно
about us.html    ✗ пробел в имени
О_Нас.html       ✗ кириллица
AboutUs.html     допустимо, но капризно
⚠️
На серверах, где регистр важен, About.html и about.html — два разных файла. Привыкайте к нижнему регистру сразу.

Главная ошибка: незакрытый тег

Чаще всего «что-то сломалось» — из-за одного пропущенного </div>. Браузер не ругается: он сам пытается угадать, где вы хотели закрыть тег, и угадывает не всегда удачно.

<div>
  <p>Текст</p>
<!-- забыли </div> — вложенность «поплыла» -->
💡
Наведите курсор на тег в редакторе — VS Code подсветит парный. Нет подсветки — тег не закрыт.

Вложенность — правило «коробок»

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

<!-- ✗ неправильно: <p> прервал <div> -->
<div><p>текст</div></p>

<!-- ✓ правильно: закрываете по порядку -->
<div><p>текст</p></div>
⚠️
Такие ошибки браузер часто «прощает», но структура при этом ломается неожиданным образом.

Естественный поток документа

Пока нет CSS, браузер раскладывает элементы по простым правилам: блочные — каждый на своей строке, строчные — подряд, как буквы. Это «естественный поток» (normal flow).

<p>Один абзац — на своей строке

Следующий блочный элемент начнётся с новой строки, а строчные продолжат ту же.

💡
Первые упражнения делайте без CSS — так вы почувствуете, что «под капотом» у любой раскладки.

Отступы и читаемость кода

Браузеру всё равно, как вы отступаете код. Людям — нет. Вложенные теги сдвигайте на два пробела: так читается структура «коробок».

<ul>
  <li>Первый пункт
    <ul>
      <li>Подпункт</li>
    </ul>
  </li>
</ul>
⚠️
Одна «портянка» без переносов строк — главный враг отладки. Не жалейте переносов и отступов.

Автозакрытие тегов в редакторе

VS Code закрывает тег за вас: набрали <p> — появился пустой </p>.

Печатаете:  <p>
Результат:  <p>|</p>   ← курсор уже внутри
💡
Список «самозакрывающихся» тегов (img, br, input) настраивается параметром html.autoClosingTags.

Сниппеты и шаблоны

Не печатайте каркас страницы с нуля каждый раз. В VS Code достаточно набрать восклицательный знак и нажать Tab — появится полный скелет документа.

Вводите:   !
Результат: DOCTYPE + html + head + body и нужные meta.
💡
Свои повторяющиеся блоки можно сохранить как Emmet-сниппеты — кусок из десяти строк вставляется одним ярлыком.

Как браузер парсит HTML

Браузер читает разметку слева направо и строит в памяти дерево элементов — DOM. У каждого тега появляется «узел», который потом можно менять из JavaScript (об этом — урок 9).

HTML:               DOM:
<html>                html
  <body>                └─ body
    <p>текст</p>           └─ p «текст»
ℹ️
Пока не углубляйтесь в DOM — достаточно знать: браузер превращает разметку в структуру, а не в строку.

Пробелы и переносы в исходнике

В обычном тексте несколько пробелов и переводов строк сливаются в один. Поэтому красивые отступы в исходнике на внешний вид не влияют.

<p>Много   пробелов
и перенос
слипнутся в один.</p>
⚠️
Нужно несколько пробелов подряд? Используйте CSS white-space или &nbsp;, а не клавишу Space.

Что браузер делает с опечаткой

Написали тег с ошибкой? Браузер не покажет сообщение — просто не узнает тег и создаст для него «анонимный» узел, чаще всего лишённый стилей.

<p>опечатка>   // название тега сломано
→ текст виден, но семантический смысл потерян
💡
Поэтому проверяйте код валидатором и подсветкой редактора: «оно же работает» скрывает проблемы.

HTML без CSS: вид по умолчанию

Браузер применяет к странице «стили по умолчанию»: заголовки крупные, ссылки синие и подчёркнутые, списки с маркерами. Это user agent styles, и у браузеров они чуть разные.

ℹ️
CSS позже переопределит всё это. Но сначала полезно увидеть «голый» документ.

Что видит поисковик (SEO-вводная)

Поисковик не «видит» страницу глазами — он читает HTML. Хорошие заголовки, title, описание и осмысленный alt помогают людям найти ваш сайт.

💡
SEO начинается не с «продвижения», а с честной и структурированной разметки.

HTML — живой стандарт

HTML5 — не «выпущенная» однажды версия, а постоянно обновляемый стандарт: браузеры добавляют новые возможности ежегодно, без новых «версий языка».

ℹ️
Новые теги до массовой поддержки проверяйте на caniuse.com — там показано, какие браузеры их понимают.

Версии HTML и совместимость

История языковой эволюции: HTML 3.2 → HTML 4.01 → XHTML (слишком строгий) → HTML5 (живой). Современный HTML обратно совместим: страницы 90-х часто открываются до сих пор.

1991  HTML (первый черновик)
1997  HTML 3.2
1999  HTML 4.01
2000  XHTML 1.0 (жёсткая строгость)
2014  HTML5 — современная эпоха
💡
Пишите по актуальному стандарту — и старые браузеры справятся, и новые получат все возможности.

Порядок мета-тегов в head

Внутри <head> важен порядок: charset — первым, затем viewport, потом title, description и подключение стилей.

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">
  <title>Мой сайт</title>
</head>
⚠️
charset должен идти до текста — иначе первые символы могут прочитаться не в той кодировке.

title и h1: разные задачи

<title> — название вкладки и заголовок в поиске. <h1> — видимый заголовок страницы. Они могут быть близки по смыслу, но это два разных элемента.

<title>Купить велосипед в Москве — магазин «Колесо»</title>
<h1>Велосипеды для города и трейла</h1>
💡
В title главные слова ставьте первыми — в выдаче хвост обрезается.

Ссылка или кнопка?

Правило простое: ссылка ведёт на другой адрес, кнопка запускает действие на странице. «Перейти в кабинет» — ссылка, «Отправить форму» — кнопка.

<a href="/cabinet">В кабинет</a>
<button type="submit">Отправить</button>
⚠️
Ссылку нельзя отправить формой, кнопку нельзя «проиндексировать» как адрес. Не подменяйте их.

Эмодзи и шрифты на странице

Эмодзи — обычные Unicode-символы, только цветные. Они работают в любом браузере, если файл сохранён в UTF-8.

<p>Сегодня отличная погода 🚀</p>
⚠️
Вид эмодзи зависит от системы: на Windows они одни, на macOS — другие. Если дизайн критичен — рисуйте иконки SVG.

Инспектор: живое редактирование

В DevTools на панели Elements можно менять HTML прямо на странице: поправили текст — увидели результат мгновенно, без сохранения файла. Идеальная песочница для экспериментов.

💡
Правки в инспекторе не сохраняются в файле. Понравилось — перенесите результат в код вручную.

Live Server: автоперезагрузка

Расширение Live Server для VS Code поднимает локальный сервер и перезагружает страницу при каждом сохранении. Настроили один раз — правки видны сразу.

💡
Alt+L, Alt+O — быстрый запуск. Либо кнопка «Go Live» в нижней панели окна.

Горячие клавиши VS Code

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

💡
Не учите всё сразу — сохранение и отмена дадут 90% пользы на старте.

Кэш и жёсткое обновление

Чтобы не грузить файлы заново, браузер кладёт их в кэш. После правки CSS вы иногда видите старую версию страницы — кэш ещё «не заметил» изменения.

💡
Жёсткое обновление с очисткой кэша — Ctrl+Shift+R. В DevTools удобен флажок «Disable cache».

W3C и WHATWG: стандарты

Стандарты пишут две организации. W3C — консорциум, автор валидаторов и множества спецификаций. WHATWG — группа браузерных компаний, поддерживает «живой» HTML как единый стандарт.

ℹ️
Валидатор W3C (validator.w3.org) — хорошая привычка: ловит ошибки вложенности и атрибутов.

Веб-доступность: вводная

Доступность (a11y) — умение страницы работать для всех: слабовидящих, людей без мыши, пользователей с маленьким экраном. Начинается с честной семантики и текста на кнопках.

💡
Проверьте себя: пройдите по странице клавишей Tab. Если фокус «застрял» — вот он, первый баг доступности.

Как скринридер читает страницу

Скринридер — программа, которая озвучивает интерфейс для незрячих. Она читает не «как выглядит», а «как размечено»: заголовки — как заголовки, кнопки — как кнопки.

Поэтому <div>Оплатить</div> — просто текст, а <button>Оплатить</button> — настоящая кнопка, которую можно нажать с клавиатуры.

⚠️
Семантические теги = доступность «бесплатно». Частые проблемы начинаются там, где всё построено на div-ах.

Типы сайтов: лендинг и портфолио

Понимать, какой сайт вы делаете, полезно — от этого зависит структура. Лендинг — одна длинная страница ради одного действия. Портфолио — витрина работ. Многостраничник — каталог или блог.

💡
На курсе вы соберёте портфолио-страницу — идеальную первую работу, которую можно сразу показать.

Что такое API простыми словами

API — набор готовых команд, которыми одна программа общается с другой. «Покажи погоду», «авторизуй пользователя», «сохрани комментарий» — всё это запросы к API.

Сайт  --«погода в Москве?»-->  api.weather.com
Сайт  <--«+12, снег»----------  api.weather.com
ℹ️
В этом курсе вы познакомитесь с fetch — тем самым способом звать API из браузера.

HTTP и HTTPS: зачем шифрование

http:// передаёт данные открытым текстом — кто угодно «на проводе» может их прочитать. https:// шифрует канал: пароли и письма остаются тайной между браузером и сервером.

⚠️
Если на странице есть формы (вход, оплата) — https обязателен. Браузер помечает такие сайты как «не защищено».

Схема и порт в адресе

Схема говорит, как общаться, а порт — «дверь», через которую это делается. У https адрес по умолчанию на порту 443, у http — на 80, поэтому их почти никогда не пишут.

https://site.ru:443/  порт совпадает с «умолчанием», не пишем
http://site.ru:8080/  нестандартный порт — пишем явно
💡
У Live Server в адресе вида 127.0.0.1:5500 тоже порт — это адрес вашего локального сервера.

Контент важнее декора

Разметка начинается не с «красоты», а со смысла. Сначала контент и структура, потом стили. Так страница остаётся понятной даже без CSS и JavaScript.

💡
Хороший приём: отключите CSS через DevTools и проверьте, понятен ли текст без оформления.

Вёрстка и программирование

Вёрстка — превращение макета (или идеи) в HTML/CSS. Программирование — написание логики поведения. В вебе они связаны, но это разные навыки: один делает «форму», другой — «поведение».

ℹ️
В этом курсе сначала вёрстка (уроки 1–6), затем программирование на JavaScript (уроки 7–9).

Читаемые адреса страниц

Хорошие адреса говорят сами за себя: /blog/cats лучше, чем /page.php?id=55. Это удобно людям и немного помогает поисковикам.

💡
В статических сайтах адрес почти всегда совпадает с путём к файлу: blog/cats.html.

Символы в URL и кириллица

В URL разрешены не все символы. Кириллица и пробелы при отправке «кодируются» (например, %20 — пробел), поэтому адреса могут выглядеть страшно.

пробел      %20
кириллица   %D0%BC... (URL-кодирование)
⚠️
Ссылки на русскоязычные файлы работают, но лучше держать имена файлов латиницей — всем спокойнее.

Иерархия папок проекта

Проект живёт в папке, внутри которой — подпапки: css/, js/, images/. Порядок экономит часы: браузер ищет файлы по относительным путям.

my-site/
├── index.html
├── about.html
├── css/  style.css
├── js/   main.js
└── images/  photo.jpg
💡
Относительные пути — это про «где лежит файл»: css/style.css из корня, ../images/photo.jpg из подпапки.

Первая самостоятельная правка

Быстрый практикум: измените заголовок <h1> на своей странице и посмотрите, как это отразится в DevTools — снова найдите его в инспекторе и поправьте прямо там.

💡
Правки в инспекторе условны: настоящий файл меняйте в редакторе, инспектор — для экспериментов.

Куда ведёт ссылка: осмотр адреса

В любой адрес можно «заглянуть» по частям. Наведите курсор на ссылку — внизу браузера появится статус-бар с адресом. Это бесплатная проверка, куда вы попадёте.

⚠️
Вредные сайты маскируют ссылки под чужие. Всегда смотрите на полный адрес, особенно перед вводом пароля.

HTML — это не скучно, а структурно

HTML часто недооценивают: «ну, теги и теги». Но это язык, на котором компьютеры понимают смысл ваших страниц. Хорошая разметка — сильный навык, а не «простое ремесло».

💡
К концу первого урока вы уже знаете половину того, что понадобится для первого настоящего сайта.

Формы: зачем полям атрибут name

Атрибут name задаёт «ключ», под которым данные поля полетят на сервер. Без имени поле просто отправит пустоту — сервер не поймёт, что это было.

<input name="email" type="email">
<!-- уйдёт так: email=ivan@mail.ru -->
💡
Имена полей — латиницей, без пробелов. Тогда их удобно читать в адресе запроса и в коде обработчика.

Формы: пароль — тип password

type="password" прячет введённое под точками — защита от «гляделки через плечо». Сами данные при этом идут в открытом виде, если нет https.

<label>Пароль<input type="password" name="pass"></label>
⚠️
Поля паролей лучше отправлять только через https и методом post — так пароль не попадёт в историю.

Формы: поиск — тип search

type="search" почти как обычное текстовое поле, но браузер добавляет крестик очистки и учитывает «поисковую» семантику.

<input type="search" name="q" placeholder="Найти на сайте">
💡
Пользователи ждут крестик именно в поле поиска — не изобретайте его вручную, где можно обойтись типом search.

Формы: url и tel

Типы url и tel подсказывают браузеру, что в поле адрес или телефон: на телефонах появится нужная клавиатура, а браузер проверит формат.

<input type="url" name="site">
<input type="tel" name="phone">
ℹ️
Для телефона не задавайте жёсткий формат — в разных странах номера разные. Проверяйте в коде на сервере.

Формы: date и time

Типы date, month, time, week дают браузерный календарь вместо ручного ввода. Пользователю не приходится угадывать формат даты.

<input type="date" name="birthday">
<input type="time" name="meeting">
⚠️
Само значение приходит в стандартном виде (например, 2026-09-20). Формат для показа на странице настраивается отдельно.

Формы: range и его настройка

type="range" — ползунок: удобно для цен, громкости, оценок. Значение уходит как число из min/max.

<input type="range" name="rating" min="0" max="10" value="5">
💡
Пользователю полезно видеть текущее значение ползунка. На чистом HTML это сделать нельзя — пригодится JavaScript из урока 9.

Формы: value — значение по умолчанию

Атрибут value задаёт начальное значение поля. Пользователь может его поменять — это подсказка, а не ограничение.

<input type="text" name="city" value="Москва">
⚠️
Не путайте value с placeholder: первый — реальные данные, второй — временная подсказка, которая исчезает при вводе.

Формы: обязательные поля required

Атрибут required запрещает отправить форму, пока поле пустое. Браузер сам подсветит проблему и объяснит пользователю.

<input type="email" name="email" required>
💡
Обязательные поля обычно помечают звёздочкой * — но помните: проверка на сервере обязательна в любом случае. Браузер не защита.

Формы: novalidate и formnovalidate

Отключить встроенную проверку браузера можно целиком (novalidate на форме) или для одной кнопки (formnovalidate). Полезно, когда поля проверяет свой скрипт.

<form novalidate>
  <button formnovalidate>Черновик</button>
</form>
⚠️
«Черновик» без проверки уместен, но не забудьте защиту от пустых обязательных полей на своей стороне.

Формы: загрузка файлов и enctype

Для передачи файлов форме нужен enctype="multipart/form-data". Без него файл уйдёт текстом — или вовсе потеряется.

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="photo">
</form>
ℹ️
Вспоминайте сразу: файлы — post + enctype. Другой пары для удобной загрузки нет.

Формы: поле вне формы — атрибут form

Атрибут form="id-формы" привязывает поле к форме, даже если оно стоит за её пределами. Выручает при сложных сетках из блоков.

<form id="f"></form>
...
<input name="query" form="f">
⚠️
Хорошая практика — поля держать внутри самой формы. Атрибут form — для редких исключений, а не ежедневный приём.

Формы: подсказки автозаполнения

Браузер запоминает введённое, если атрибут autocomplete совпадает с ожидаемым («email», «name», «tel»). Это экономит пользователям время.

<input type="email" name="email" autocomplete="email">
💡
Для приватных полей (например, кода из СМС) ставьте autocomplete="one-time-code", чтобы браузер не «помогал» не тем значением.

select: список с видимыми строками

У <select> есть атрибут size — он превращает выпадающий список в список с несколькими видимыми строками.

<select name="month" size="3">
  <option>Январь</option>
  <option>Февраль</option>
  <option>Март</option>
</select>
💡
Обычный «выпадайка» с одним выбором в большинстве форм удобнее списка с size — не злоупотребляйте.

option: подпись и длинные списки

У <option> есть атрибут label — короткое название для показа. А длинные списки опций помогают читаться с помощью <optgroup>.

<option value="msk" label="Москва">Москва, Россия</option>
ℹ️
Если label задан, браузер может показывать его вместо текста пункта. Обычно label не нужен — текст опции вполне понятен.

Как разметить анкету: пример

Соберите всё вместе — форма анкеты на семантических тегах:

<form method="post">
  <fieldset>
    <legend>Контактные данные</legend>
    <label>Имя<input name="name" required></label>
    <label>E-mail<input type="email" name="email" required></label>
  </fieldset>
  <button type="submit">Отправить</button>
</form>
💡
Смотрим структуру: fieldset группирует, legend объясняет, label привязывает подписи. Форма сама себя «рассказывает».

Практика: страница «Обо мне»

Задание: сделайте страницу about.html — заголовок, абзац о себе, список увлечений, одна ссылка на ваш любимый сайт. Без CSS: важно почувствовать структуру.

<h1>Обо мне</h1>
<p>Меня зовут Аня, я учусь вёрстке.</p>
<h2>Мои увлечения</h2>
<ul>
  <li>Фотография</li>
  <li>Походы</li>
</ul>
💡
Откройте файл в браузере и посмотрите, как выглядит «голый» HTML. Так начинается понимание вёрстки.

Что попробовать после урока 1

Малые эксперименты закрепляют лучше чтения. Попробуйте три упражнения:

💡
Если что-то сломалось — это тоже результат: найдите и почините, так вы учитесь быстрее всего.

Типовая структура сайта

У большинства сайтов одинаковая анатомия: шапка с навигацией → основной контент → подвал (контакты и ссылки). Эти части в HTML называются header, main, footer.

<header>Логотип и меню</header>
<main>Главное содержание страницы</main>
<footer>Контакты, копирайт</footer>
ℹ️
Та же схема у этого курса: шапка, программы, «почему курс» и подвал.

Как люди читают страницы

Веб-читатели не вчитываются — они сканируют: F-паттерн (текст сверху слева), первые слова заголовков, подчёркнутое и перечисленное. Структурируйте контент под это.

💡
Проверьте свою страницу «сканом»: готовы ли вы найти на ней главное за 5 секунд?

Ошибка 404: что это и куда ведёт

404 — ответ сервера «страница не найдена». Частая причина: опечатка в адресе или переименованный файл. Пользователь попадает сюда, если ссылка где-то устарела.

💡
Хорошая страница 404 объясняет, что случилось, и даёт ссылку на главную. Сделаете её — уже опередите половину сайтов.

Кракозябры и их причины

«Кракозябры» — это текст, прочитанный не в той кодировке. Файл в UTF-8 без тега charset или документ в CP1251 на странице с UTF-8 дадут примерно одинаковую кашу.

⚠️
Лечится на двух фронтах: тег <meta charset="UTF-8"> в документе и сохранение файла редактором в UTF-8.

meta keywords: почему это в прошлом

Раньше мета-тег keywords помогал поиску. Теперь им злоупотребляли (вставляли чужие популярные слова) — и поисковики его игнорируют.

<!-- было, сегодня не работает -->
<meta name="keywords" content="выиграть, лайки">
💡
Тратьте энергию на title, description и понятные заголовки — они видят реальную пользу.

alt для служебных картинок

Если картинка чисто декоративная (иконка, разделитель), пустое alt="" — правильный выбор: скринридер пропустит её.

<img src="decor.png" alt="">
⚠️
Не пишите в alt «картинка» или название файла — из этого скринридер читает бессмыслицу.

Чек-лист «голой» страницы

Перед тем как переходить к CSS, прогоните страницу по маленькому чек-листу:

💡
Страница, читаемая без CSS, — хорошая страница. Дальше стили лишь «оденут» её.

Что такое форма по смыслу

Форма — мостик от пользователя к данным: поля собирают ввод, кнопка отправляет его, сервер отвечает. Даже поиск в Google — это форма, у которой поля спрятаны за красивым интерфейсом.

💡
Размечая форму, думайте о конечной цели: «что я получу на сервере и что с этим будет?».

Тег form: область действия

<form> очерчивает зону «эти поля отправляются вместе». Всё, что попало в тег, отправляется кнопкой внутри него — при условии атрибутов action и method.

<form action="/send" method="post">
  <p>Этот абзац «принадлежит» форме.</p>
</form>
⚠️
Вложенные формы запрещены: одна форма не может быть внутри другой. Если нужно две — размещайте их рядом.

Разница между URL и путём к файлу

URL — полный «почтовый адрес» ресурса (с доменом и протоколом). Путь к файлу — маршрут внутри проекта (css/style.css). Браузер понимает оба, но это разные сущности.

URL:        https://site.ru/css/style.css
Путь:       css/style.css   (относительно текущей папки)
Абсолют:    /css/style.css  (от корня сайта)
ℹ️
Ссылка «от корня» с ведущим / удобна, когда структура сайта стабильна — её не нужно переписывать из подпапок.

Зачем элементы и атрибуты одновременно

Элемент — «что это» (<input>, <a>), атрибут — «как его настроить» (type, href). Одна пара тегов может выглядеть по-разному в зависимости от атрибутов.

<input type="text">     <!-- текст -->
<input type="checkbox"> <!-- галочка -->
<input type="date">    <!-- календарь -->
💡
Запоминайте пары «тег + атрибут», а не отдельные теги — так знания складываются в систему.

Как проверять знание тегов на практике

Зубрить теги бессмысленно — они запоминаются через применение. Откройте любой вопрос: «как сделать список?» — и найдите ответ своим кодом.

💡
Повторение через неделю — лучший «тренажёр» для памяти, чем повторение в тот же день.

План первого сайта-визитки

Визитка — традиционная цель новичка. Продумайте заранее структуру, и уроки лягут на неё естественно:

index.html       главная: имя, чем занимаюсь
about.html       обо мне (структура из урока 1)
projects.html    работы: список или карточки
contacts.html    форма обратной связи
💡
Идею лучше набросать на бумаге: «что на странице» важнее, чем «как это стилизовать».

Экраны и пиксели: основы верстальщику

Размеры на экране живут в CSS-пикселях, а на маленьких экранах плотность выше. Верстальщику важно понимать: «ширина 320px» — это дизайн для телефона, «1200px» — для десктопа.

ℹ️
Вернёмся к размерам подробнее в уроке CSS. Пока достаточно ощущения масштабов.

Адаптивность: одно предложение

Адаптивная страница выглядит удобно на телефоне, планшете и десктопе — контент не ломается и не вылезает за экран. За ингредиенты (fluid-сетки, media queries) возьмёмся в уроках CS.

💡
Уже сейчас сузьте окно браузера: если страница сайта «развалилась» — вы встретили главного врага адаптивности.

DevTools: вкладки для верстальщика

Сюжат четыре вкладки: Elements (HTML+CSS), Console (ошибки JS), Network (что качается), Device toolbar (мобильный вид). Начните с Elements — она нужнее всего.

💡
Открывайте DevTools прямо сейчас: F12. Наведите на любой тег страницы — увидите его «коробку».

Разбор чужой страницы в DevTools

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

⚠️
Смотреть и учиться можно, копировать «под ключ» дизайн и контент — нет. Разбирайте, а не плагиатьте.

Git: версии для одного человека

Git — система контроля версий: сохраняет историю изменений. Даже одному человеку она полезна: «сломали — откатились», «эксперимент не удался — вернулись». Ваш первый проект уже можно положить в репозиторий.

git init
git add .
git commit -m "первая страница"
ℹ️
Git сам по себе — целая тема. Пока достаточно знать: он существует, и он спасёт вас не раз.

Проверка результата в трёх браузерах

Прежде чем считать страницу готовой, откройте её в Chrome, Firefox и Edge (или Safari). Разница в пару пикселей — норма, серьёзные расхождения — сигнал.

💡
Верстка почти всегда проверяется «в трёх браузерах» — это профессиональная привычка, а не паранойя.

Первый сайт: ошибки новичков

Самые частые из них вы уже знаете, но они повторяются у всех:

💡
Составьте свой список частых ошибок — через месяц сверьтесь, сколько ушло.

От одной страницы к многостраничнику

Сайт растёт из одной страницы: добавляете файл — появляется новая страница, связываете их ссылками — получается сайт. Никакой магии, просто папка с файлами HTML.

index.html  ←→  about.html  ←→  contacts.html
💡
Навигация, шапка и подвал повторяются на страницах. Облегчим это копированием, а автоматика придёт позже.

Итог урока 1: что вы уже умеете

После первого урока вы умеете: создавать HTML-файл, размечать текст и списки, делать простые формы, открывать страницу в браузере и смотреть её в DevTools. Это база для всех следующих уроков.

💡
Перечитайте чек-лист из этого урока и проверьте свою первую страницу по нему.

Куда дальше: урок 2 — теги и атрибуты

Дальше вы выучите «алфавит» HTML: семантические теги для текста, списков, цитат и блоков, а также правила их сочетания. Сложность вырастет, но основа уже есть.

ℹ️
Урок 2 — не про новые формы, а про словарь тегов. Ключ к успеху — делать все маленькие примеры на практике.

Практика против теории: как учить HTML

Чтение даёт базу, практика — навык. Правило 20/80: двадцать минут теории, восемьдесят — своих экспериментов. Каждое новое знание тут же проверяйте в коде.

⚠️
Смотреть чужие решения вместо своих — ловушка. Сначала попробуйте сами, потом посмотрите, как сделали другие.

Почему «руки не запоминают» теги

Плохой память на теги — симптом нехватки практики, а не дурной головы. Начните каждый день с короткой разметки (список, форма), и через неделю теги станут «своими».

💡
Профессионалы тоже не помнят всё — они умеют быстро находить нужное в документации.

Место HTML в стеке разработчика

HTML — не единственный «язык» фронтенда, но фундамент: CSS одевает его, JavaScript оживляет. Без прочного HTML знание остальных уровней дрожит.

ℹ️
Порядок курса намеренный: HTML → CSS → JS. Поэтому уроки идут не «перемешкой», а по уровням.

Сколько тегов нужно учить

В HTML порядка ста+ тегов, но активно используются двадцать-тридцать. Начните с самых частых, остальное будет появляться по мере задач.

💡
Скачайте «шпаргалку» тегов или держите под рукой документацию на MDN — это рабочая привычка, а не обман.

Мелочи, которые «роняют» страницу

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

⚠️
Когда страница «сломалась», сначала проверьте самые очевидные места: их мы и разобрали в этом уроке.

Как «починить» испорченную страницу

Страница разъехалась или не открылась? Система поиска должна быть спокойной:

💡
Главное — не паниковать. Ошиблись все: терпеливый поиск причины — базовый навык верстальщика.

Финальное упражнение урока 1

Соберите мини-проект «первая страница»: заголовок, введение, список навыков, форма с одним полем и кнопкой, ссылка «наверх». Откройте в трёх браузерах и проверьте по чек-листу.

🎉
Готово? Вы официально сделали первый шаг. На следующем уроке выучим словарь тегов — и страницы станут осмысленными.

Самый первый файл: страница «Привет»

Любой сайт начинается с одного файла: создайте index.html, впишите каркас и откройте в браузере. Уже в первой строке видно, что HTML — это текст с правилами.

<!DOCTYPE html>
<meta charset="UTF-8">
<title>Привет</title>
<h1>Привет, мир!</h1>
💡
Правило «одного файла»: маленький шаг, который превращает «теорию» в «я работаю с вебом».

Слэши в путях: косые правила

В путях HTML-файлов разделитель — косая черта «/». В адресах страниц она же отделяет «папки» сайта. Это универсальная «дорога»: от имени файла до URL.

<img src="images/photo.jpg">
<a href="about.html">О нас</a>
⚠️
Обратный слэш «\» из Windows в HTML-путях — почти всегда ошибка: браузер его не понимает.

Пробелы и табы: только для читаемости

Множество пробелов подряд браузер схлопывает в один. Отступы нужны не машине, а вам: правильная вложенность — половина «читаемости» разметки.

<ul>
  <li>один</li>
  <li>два</li>
</ul>
💡
Отступ = «уровень вложенности»: чем глубже элемент, тем дальше он от левого края.

Редактор кода: что выбрать новичку

Блокнот хватит, но редактор «заряжает»: подсветка синтаксиса, автозакрытие тегов, живой предпросмотр. VS Code — бесплатно, по-русски, с множеством дополнений.

💡
Расширение Live Server показывает изменения без перезагрузки вручную — попробуйте с первого урока.

Как браузер строит страницу из кода

Маршрут: HTML-текст → разбор в дерево DOM → стили → рисование на экране. Понимание «пайплайна» объясняет, почему страница иногда «скачет» при загрузке.

💡
Если картинки «прыгают», браузер ещё не знал их размер: задайте ширину и высоту заранее.

«Прощаемые» ошибки браузера

Браузер пытается «достроить» пропущенный закрывающий тег — но не всегда так, как вы хотели. Не полагайтесь на снисходительность: закрывайте теги.

<p>Текст без закрытия
<p>Второй абзац
⚠️
«Прощённая» ошибка сейчас — «непонятная» вёрстка потом. Пишите строго.

Кодировка против «кракозябр»: детали

Кракозябры — это байты, прочитанные не той кодировкой. Мета-тег charset=UTF-8 в head сообщает браузеру, как «прочитать» файл. Отсюда всё начинается.

<meta charset="UTF-8">
💡
Файл должен реально сохраняться в UTF-8, а не только сообщать об этом: это разные вещи.

head против body: что где живёт

head — «служебный отдел»: мета, стили, скрипты, заголовок вкладки. body — видимое содержимое страницы. Пока они не спутаны — порядок в документе.

<head>
  <title>Заголовок вкладки</title>
</head>
<body>видимый контент</body>
💡
Простая проверка: то, что видно на странице, — body; всё остальное — head.

Валидатор W3C: как проверить страницу

Официальный валидатор (validator.w3.org) «прочитает» ваш HTML и перечислит ошибки и предупреждения по стандарту. Отличная «вторая пара глаз» для новичка.

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

Описание и ключевые слова: meta на деле

Один «служебный» тег отвечает за текст под результатом поиска. Описание пишет человеку, заголовок — и человеку, и поиску. Слова — ваша «витрина».

<meta name="description"
      content="Уроки веб-разработки для новичков">
💡
Длиной в 150–160 символов, с главным смыслом в начале — так показывают в поиске.

Папки assets, css, js: порядок всему

Маленький сайт живёт без папок, но привычка окупится: стили в css/, скрипты в js/, картинки в images/. Через месяц вы легко найдёте любой файл.

site/
  index.html
  css/style.css
  js/main.js
  images/photo.jpg
💡
Имена папок — строчными буквами, без пробелов: так безопаснее для хостинга.

Навигация по файлам в редакторе

В VS Code переключайтесь между файлами мышью или Ctrl+P (быстрый поиск). Когда уроков много, «перепрыгивание» между HTML и CSS — основной темп работы.

💡
Клавиша Ctrl+P: печатаете имя файла — Enter, и вы уже там. Пробуйте сразу.

TODO-заметки прямо в HTML

Комментарий <!-- TODO: добавить цены --> — «личная записка» для будущего вас. Так недостроенное не теряется, пока страница «дозревает».

<!-- TODO: переписать текст под бриф -->
💡
Слово TODO отображают в списке задач многие редакторы — пишите его единообразно.

lang: язык страницы и его код

Атрибут lang на html — «язык документа»: скринридеры читают с нужными интонациями, поиск понимает аудиторию. Для русского — lang="ru".

<html lang="ru">
💡
Если цитата на английском — пометьте только её: lang="en" на фрагменте.

Почему полезно печатать код вручную

Сниппеты и автозакрытие экономят секунды, но «печатать руками» учит: вы запоминаете теги, чувствуете структуру и не теряетесь при чтении чужого кода.

💡
Правило «20 раз»: один и тот же тег набран руками двадцать раз — он остаётся в памяти навсегда.

Публикация на GitHub Pages

Готово — и хочется показать? GitHub Pages хостит статические страницы бесплатно: закоммитили файлы в репозиторий, включили Pages — и у вас есть адрес вида username.github.io.

<a href="https://username.github.io/">
  Мой первый сайт</a>
💡
Файл должен называться index.html и лежать в корне репозитория — так его отдадут по адресу самого репозитория.

Частые опечатки в HTML

Лишняя кавычка, закрытый не тот тег, имена файлов с пробелом, два «=» в атрибуте — классика опечаток. Спокойствие и валидатор разбирают их за минуту.

<img src="images/photo.jpg" class="photo">  // src без кавычки — «тихая» ошибка
💡
Описка видна не глазами, а поведением страницы. Нашли «не так» — проверьте атрибуты первыми.

Стратегия чтения чужого кода

Чужие страницы — лучший учебник: откройте в инспекторе, «прочитайте» структуру от корня к тегам, отметьте для себя приёмы. Так вы учитесь «сверху вниз», как браузер.

💡
Порядок чтения: head → body → h1 → структура блоков → детали. Сначала общий смысл, потом мелочи.

Контраст текста: читаемость всем

Цвет фона и текста должны различаться достаточно, чтобы читал и «плохой» экран, и человек со зрением послабее. Контраст 4.5:1 — рабочая норма для обычного текста.

💡
Светло-серый текст на белом — «красиво» в макете и нечитаемо в жизни. Проверяйте на экране телефона.

Как измерять прогресс в разметке

Прогресс — не «прочитал главу», а «сделал страницу». Поняли таблицу — сверстайте расписание; поняли формы — соберите анкету. Один проект на одну тему.

💡
Заведите «портфолио-папку» из пяти маленьких страниц: через месяц увидите, насколько выросли.

Поля и их типы: как устроена форма

Каждое поле формы — это input с типом: text, email, number... Тип решает, какую клавиатуру покажет телефон и как браузер проверит ввод. «Правильный» тип — половина валидации.

<input type="text" name="city">
<input type="email" name="mail">
💡
Список типов в DevTools не нужен: просто вспоминайте задачу — «набор текста», «почта», «номер».

Группа радиокнопок: один выбор из списка

Радиокнопки объединяются одинаковым атрибутом name: выбрать можно ровно один вариант из группы. Редко, но полезно: переключение «темы», «тарифа», «пола».

<input type="radio" name="theme" value="light"> Светлая
<input type="radio" name="theme" value="dark"> Тёмная
💡
Если name разные — это две независимые группы, а не «или-или». Держите name одним.

Отмеченный по умолчанию: checked

Атрибут checked делает радиокнопку или чекбокс выбранными сразу при загрузке. Удобно для «согласен с правилами», для варианта «по умолчанию» в группе.

<input type="checkbox" checked> Присылать новости
💡
Для каждой группы из радиокнопок выделяйте «запасной» вариант — так на форме не «висит» пустой выбор.

Связка label и элемента: бонус клика

label привязанный к полю атрибутом for (или оборачивающий поле целиком) расширяет зону клика: можно «ткнуть» в подпись, и фокус уйдёт в поле. Доступно и удобно.

<label for="city">Город</label>
<input id="city">
💡
Чем крупнее «мишень», тем меньше промахов на телефоне — label решает не только доступность.

Подсказка-плейсхолдер и его границы

placeholder рисует серый пример внутри поля. Это не замена label: подсказка исчезает при вводе, а подпись остаётся. Используйте оба — напоминание и пример вместе.

<input type="tel"
       placeholder="+7 900 000-00-00">
⚠️
Плейсхолдер «съедает» контекст: для сложных полей он лучше, но подпись всё равно обязательна.

Выпадающий список: size строк

Атрибут size делает select «раскрытым»: видно сразу несколько строк, а не один выбранный пункт. Когда вариантов мало и выбор «на виду» — выглядит естественно.

<select size="3">
  <option>Эконом</option>
  <option>Стандарт</option>
  <option>Люкс</option>
</select>
💡
size — «витрина» выбора: с ним не нужно открывать выпадающее меню, всё на виду.

Ползунок range: значение подписью

input range — ползунок с «дорогой» от min до max и шагом step. Сам ползунок не показывает число: поставьте рядом output, куда скрипт пишет текущее значение.

<input type="range" min="0"
       max="100" value="50">
💡
Ползунок хорош для «настроек»: громкость, яркость, размер — интуитивный вид выбора.

Ввод даты: календарь вместо строки

input type="date" отдаёт калибрированный календарь — удобно с телефона и без ошибок формата. Парой идут time (время) и datetime-local (дата+время).

<label>Дата поездки
  <input type="date" name="when">
</label>
💡
Выбор даты «календарём» исключает опечатки вроде 32.06 — браузер всё делает сам.

Длина поля: minlength и maxlength

maxlength ограничивает, сколько символов разрешено ввести; minlength задаёт минимум, который браузер проверит при отправке. Пароль и комментарий — любимые поля правил длины.

<input type="password"
       minlength="8" maxlength="20">
💡
Ограничение делайте «по-доброму»: короткое предупреждение о правиле рядом с полем экономит нервы.

Шаблон номера телефона: pattern

pattern принимает регулярное выражение — «маску» ввода. Например, телефон в формате +7(900)000-00-00. Если ввод не подходит — браузер не даст отправить форму.

<input type="tel" name="phone"
       pattern="\+7\([0-9]{3}\)[0-9]{3}-[0-9]{2}-[0-9]{2}">
💡
Начать можно с простого: [0-9]{10} — десять цифр. Маски сложных форматов смотрите в справочниках.

Неактивные поля: disabled и его цена

disabled выключает поле: оно не принимает ввод и не отправляется. Его «двоюродный брат» readonly только запрещает изменение, но значение уходит на сервер.

<input type="text" value="Только чтение" readonly>
<input type="text" disabled>
💡
Правило: «нельзя менять» — readonly; «совсем не участвует в форме» — disabled.

Числовое поле: number и стрелки

input type="number" даёт числовую клавиатуру и стрелки-шаги, проверяет min/max/step. Осторожно: «число» здесь — строка с цифрами, к серверу обычно приходит именно строка.

<input type="number" min="1" max="10" step="1">
💡
Для количества в корзине, возраста, рейтинга — number; для «произвольного числа» — чаще text.

Телефонная клавиатура: inputmode

inputmode подсказывает, какую клавиатуру показать на телефоне: decimal — цифры, numeric — числа, email — «@» и «.», tel — цифры и символы номера. Поле остаётся text — меняется только клавиатура.

<input type="text" inputmode="numeric"
       placeholder="Код из SMS">
💡
Классика: почта — type=email, номер — type=tel. Когда нужно «и то и то» — inputmode делает своё дело.

Список вариантов: datalist подсказки

datalist подключается к input через атрибут list и «приносит» подсказки при вводе: пользователь выбирает из них или пишет своё. Гибче select — можно своё значение.

<input list="cities">
<datalist id="cities">
  <option value="Москва">
  <option value="Казань">
</datalist>
💡
Для «фиксированных вариантов» — select; для «подсказок при свободном вводе» — datalist.

Скрытые данные: input hidden

input type="hidden" уносит с формой значение, которое пользователь не видит: id записи, версию формы, токен от бота. Оно участвует в отправке, но не занимает места.

<input type="hidden" name="post_id"
       value="42">
💡
Не кладите в hidden ничего секретного: пользователь легко увидит его через инструменты разработчика.

Горячие клавиши формы: accesskey

Атрибут accesskey назначает элементу «горячую» клавишу: Alt+буква переводит фокус или активирует. Удобно для форм «по клавиатуре», но комбинации меняются браузерами и раскладками.

<a accesskey="s" href="#search">Поиск</a>
💡
Совет: выбирайте «невинные» клавиши (s, f, h), чтобы не конфликтовать с браузерными.

Отправка Enter: поведение по умолчанию

В форме Enter в любом поле обычно «нажимает» первую кнопку submit/button. Это ожидание людей: не путайте его и не вешайте «случайных» обработчиков без причины.

<form>
  <input type="text">
  <button type="submit">Искать</button>
</form>
💡
Если Enter отправляет форму не туда — пересмотрите, какая кнопка первой в DOM.

Автозаполнение: доверие и настройка

Браузеры запоминают введённое и подставляют заново: имя, почта, пароль. Атрибут autocomplete направляет это «досье» в нужные поля: email, name, current-password.

<input type="email"
       autocomplete="email">
💡
Правильные значения autocomplete спасают от «подставил почту в телефон» и злят меньше людей.

Кнопка вне формы: атрибут form

Кнопка связана с формой не вложенностью, а атрибутом form: атрибут задаёт id формы. Так можно расположить кнопку где угодно на странице — даже за пределами тега form.

<form id="reg">...</form>
<button type="submit" form="reg">Сохранить</button>
💡
Приём для «шапки»: поиск сверху страницы, но форма поиска поддерживается кнопкой из другого блока.

Итоги форм: чек-лист «живой» формы

Форма готова, когда: тип у каждого поля «правильный», label связаны, есть placeholder примеры, minlength/maxlength заданы, required проставлены, кнопка с type=submit. Проверьте по списку — и отправьте тестовые данные.

💡
Раз в месяц перечитайте свою старую форму: увидите, как много вы уже умеете.

Меню из вложенных списков

Иерархическое меню — это список внутри элемента списка: li хранит ul с подпунктами. Глубина «веток» читается по вложенности, а не по классам.

<ul>
  <li>Курсы
    <ul>
      <li>HTML</li>
      <li>CSS</li>
    </ul>
  </li>
</ul>
💡
Вложенный ul живёт строго внутри li, а не «после» него — иначе вложенность сломается.

Нумерация с продолжением: start

Атрибут start задаёт стартовое число нумерованного списка. Удобно, когда статья продолжает нумерацию «с 41-го пункта» или список начинается не с единицы.

<ol start="3">
  <li>третий пункт</li>
  <li>четвёртый</li>
</ol>
💡
Обратный порядок сделает reversed; счёт «с пятёрки» — start="5". Семантика «порядок важен» сохраняется.

Маркеры списков: circle, square, disc

У маркированного списка три «родных» маркера: disc (точка), circle (кольцо), square (квадрат). Выбор — через CSS list-style-type. Это про вид, смысл остаётся «перечисление».

<li style="list-style-type: square">пункт</li>
💡
Декоративные «галочки» и «стрелки» рисуют обычно ::before — это уже вопрос стилей, а не списка.

Один h1 на страницу

На странице обычно один h1 — «заголовок документа». Дальше идут h2 для разделов, h3 для подразделов. Иерархию читают люди, поисковики и скринридеры.

<h1>Учебный курс по HTML</h1>
  <h2>Основы тегов</h2>
    <h3>Как устроен тег</h3>
💡
Слово «h1=главное, h2=разделы» — краткая памятка иерархии заголовков.

Структура страницы: header, main, footer

Три «зоны» есть у каждой страницы: header (шапка), main (содержимое), footer (подвал). Добавьте nav для навигации и aside для допов — и каркас почти готов.

<header>шапка</header>
<nav>меню</nav>
<main>основное</main>
<footer>подвал</footer>
💡
main в документе один; header и footer могут повторяться внутри статей и секций.

Декоративная картинка: пустой alt

Если картинка ничего не сообщает — пусть alt будет пустым (alt=""). Скринридер пропустит её молча. Текст «фото» или «картинка» лишь шумит для читающего вслух.

<img src="divider.svg" alt="">
💡
Правило: пустой alt для «украшений», содержательный — для информативных изображений.

SEO-связка: title, description, alt

Три «полки» поисковика: title (заголовок результата), description (анонс), alt у информативных картинок. Заполнены осмысленно — страница понятнее и человеку, и поиску.

💡
Проверяйте себя так: «прочитаю одну строку — пойму ли, о чём страница?».

Карта якорей: навигация по длинной странице

Для длинной страницы удобно «оглавление»: список ссылок на якоря через href="#id". Имя якоря — id любого элемента, не обязательно в начале страницы.

<a href="#chapter2">Глава 2</a>
<h2 id="chapter2">Глава вторая</h2>
💡
Ссылка точно «вниз» к разделу работает и на телефоне: окно само прокрутится к якорю.

Браузерные отступы текста

До CSS браузер уже рисует «что-то читаемое»: абзацы с отступами, списки с маркерами, заголовки жирные. Знание «по умолчанию» помогает предсказать, как ляжет вёрстка.

💡
Когда стили «не применились» — посмотрите, что показал браузер без них: часто это и есть источник путаницы.

Инлайн-код в абзаце: тег code

Внутри предложения фрагмент кода оборачивают code: <div>. Так пометка «это код» видна и человеку, и техническим инструментам. Для блока строк — pre + code.

<p>Тег <code><a></code>
делает ссылку.</p>
💡
Скобки < и > внутри code пишите как сущности < и >, иначе браузер их «съест».

Сущности на практике: ©, &, <

Знак «&» откроет символ, «<» и «>» спрячут HTML. Строки вроде & и © — «сущности»: безопасный способ вписать спецсимвол в текст.

&   // амперсанд
<   // знак «меньше»
© // копирайт ©
💡
Запомните три рабочих: <, >, &. Остальные «сущности» удобнее искать по таблицам.

Практика: страница-«меню» ресторана

Сверстайте меню без стилей: заголовок ресторана, список блюд с ценами, подсказку «готовят 15 минут». Это упражнение тренирует структуру: h1, h2, ul, dl.

<h1>Кафе «Уют»</h1>
<h2>Завтраки</h2>
<ul>
  <li>Омлет — 150 ₽</li>
</ul>
💡
Попробуйте добавить «рекомендует шеф» рядом с блюдом — и придумайте тег для этого.

Разметка новостей: список статей

Лента новостей — это список: каждый «анонс» — article с заголовком, датой и коротким текстом. Снаружи секция или список, внутри — самостоятельная статья.

<section>
  <article>
    <h2>Открытие сезона</h2>
    <p>Сегодня стартуют соревнования.</p>
  </article>
</section>
💡
article «живёт сам по себе»: его можно перенести на другую страницу целиком.

Аудио на странице: тег audio

audio вставляет аудиофайл: controls показывает плеер, autoplay включает сам, loop повторяет. Для «подкаста», «голоса» и «фона» — это базовый тег мультимедиа.

<audio controls src="voice.mp3">
  Ваш браузер не поддерживает аудио.
</audio>
💡
Звук «сам по себе» не включают без нужды: человек сам решает, когда слушать.

Проверка на сервере: localhost

Локальный сервер (напр. Live Server) притворяется хостингом: адрес вида http://localhost:5500/ — как «настоящий» сайт, только ваш. Так проверяют пути и поведение точно-по-HTTP.

💡
Открытие файла дважды кликом и открытие «через localhost» — разные способы: второй «честнее» к браузеру.

Практика: страница «Свяжитесь с нами»

Соберите «контактную» страницу: заголовок, форма (имя, почта, сообщение), данные связи (телефон, адрес) и карту-ссылку. Все изученные элементы — в одном проекте.

<h1>Свяжитесь с нами</h1>
<p>
  <a href="tel:+79000000000">
    +7 900 000-00-00</a>
</p>
💡
Телефон со «звонительным» тегом tel: на телефоне эта ссылка открывает набор номера.

Чек-лист страницы с формой

Перед отправкой проверьте: каждый input имеет label и name; есть submit; у полей правильные типы; placeholder и required на месте; данные не «секретные» в hidden. Быстрая «перекрёстная» проверка экономит часы после запуска.

💡
Отправьте форму с пустыми полями — браузер сам скажет, где забыли required.

Изоляция фрагмента: span и вложение

span — «бессмысленный» строчный тег: нужен, чтобы подчеркнуть кусок текста (стилем или смыслом), не ломая поток. Внутри абзаца — главное применение.

<p>Цвет <span class="hot">красный</span> в моде.</p>
💡
span — «точечный инструмент»: в него кладут ровно то, что нужно пометить, не больше.

Пустые теги: зачем они нужны

Теги без закрывающего — это элементы, у которых нет содержимого: img, br, input, hr. Они «самодостаточны»: картинка показывает себя, перенос строки разрывает поток.

<img src="logo.png">
<br>
<hr>
💡
«Пустой» не значит «лишний»: каждый из них делает строго своё действие.

Контрольная: всё ли собрано с урока 1

Быстрая самопроверка: страница с DOCTYPE, UTF-8, языком ru; уникальным title и описанием; структура body из заголовков, абзацев, списков; одна форма с полями и кнопкой. Собрали — открывайте следующий урок.

💡
Главный критерий: страница «читается», даже если стилей ещё нет.

Визитка: одна страница про вас

Сайт-визитка вмещает всё важное на одной странице: кто вы, чем занимаетесь, как связаться. Для практики лучше всего: мало контента — много решений о структуре.

💡
Разложите «о себе» на блоки: приветствие, навыки, опыт, контакты — и назовите h2-ами.

Структура «Обо мне»: блоки и порядок

Типичный порядок блока «обо мне»: кем работаете, что умеете, чем гордитесь. Абзацы короткие, важное — отдельными тегами: strong, ul, ссылки на проекты.

<section>
  <h2>Обо мне</h2>
  <p>Меня зовут Костя, я учусь вёрстке.</p>
</section>
💡
Пишите «для человека»: вместо «я освоил многие технологии» — список конкретных тегов.

Портфолио: мини-галерея своими руками

Портфолио из 3–4 работ располагают сеткой или списком: «карточка» — миниатюра, название, ссылка. Всё руками, без фреймворков: вы уже умеете достаточно.

<h2>Мои работы</h2>
<ul>
  <li><a href="work1.html">Первая работа</a></li>
</ul>
💡
Не «копилка всего»: три хороших примера сильнее тридцати сырых.

Блог: страница со статьями

Блог — записи в обратном порядке: свежие сверху. Каждый пост — article с заголовком, датой и кратким вступлением, ссылкой «читать дальше».

<article>
  <time datetime="2026-09-01">1 сентября</time>
  <h2>Как я учил HTML</h2>
</article>
💡
Дата в машиночитаемом виде (datetime) помогает и людям, и поисковикам понять «свежесть».

Лендинг: одна цель на страницу

Лендинг продаёт одно действие: «оставить заявку», «скачать», «записаться». Вся страница ведёт к этому: заголовок → выгода → форма. Структура простая — тренировка смысла.

💡
Задайте себе вопрос «зачем эта страница?» — и выньте из макета всё, что не ведёт к цели.

Многостраничник: навигация между файлами

Три страницы складываются в «сайт» через навигацию: index.html, about.html, contacts.html. Ссылки ведут на относительные пути — и сайт «ездит», если папку перенести.

<nav>
  <a href="index.html">Главная</a>
  <a href="about.html">О нас</a>
</nav>
💡
Повторять меню на каждой странице неприятно, но для первых проектов — нормально.

Хостинг: как файл становится сайтом

Хостинг — компьютер, который 24/7 «раздаёт» ваши файлы по адресу. Вы кладёте папку на сервер, люди открывают URL — и видят страницу. Локальный «двойник» этого — localhost.

💡
Для статики хватит бесплатного хостинга: никаких баз данных, просто папка с HTML.

Домен: адрес, который запоминают

Домен (golld.ru) — имя вместо IP-адреса. Его покупают у регистратора и «привязывают» к хостингу через DNS: специальные серверы переводят имя в адрес.

💡
DNS — «телефонный справочник интернета»: быстро объясняет, куда вести запрос по имени.

HTTPS: замок в браузере

HTTPS шифрует трафик между браузером и сайтом. Замок в адресной строке — признак «зашифровано». Без него данные формы могут «услышать» по пути. С 2021 года почти все сайты перешли на HTTPS.

💡
Локальная разработка обычно «http» — это нормально; публичный сайт — обязательно https.

Кэш браузера: почему «старая» страница

Браузер запоминает файлы, чтобы не качать их снова. После правки CSS «старый» стиль может остаться в кэше — и страница выглядит «не обновившейся». Это не баг, а экономия.

💡
Не видите правок — сделайте «жёсткое» обновление (Ctrl+F5) или откройте страницу в инкогнито.

Мобильные экраны: как проверить самому

Половина посетителей — с телефонов. В DevTools есть «режим устройства»: эмуляция экранов iPhone/Android и «переключение» ширины вручную. Загляните туда перед выпуском.

💡
Жмите Ctrl+Shift+M в DevTools и «растягивайте» окно: так вы увидите, где ломается макет.

Жёсткое обновление: ctrl+F5

Обычный F5 — «перезагрузить», но кэш иногда «застревает». Ctrl+F5 (жёсткое) — очистить и загрузить заново. Лекарство от «я же поменял, а оно не работает».

💡
Помогло? Дело было в кэше. Не помогло — значит, «не то» файл или правка, ищите дальше.

Инспектор кода: осмотр чужого сайта

Правый клик — «Исследовать элемент»: открывается DOM и стили любой страницы. Учитесь «читать» вёрстку именитых сайтов: разбирайте, как устроены их блоки.

💡
Это чтение, а не кража: выучите приём — но не «срисовывайте» сайт целиком.

Копирование вёрстки: этично ли

Перенимать приёмы (структуру, подход) — нормально; копировать чужие тексты и шрифты целиком — нет. В сетях и вёрстки «фишки» общие, но результат должен быть ваш.

💡
Хорошая практика: «сделай по мотивам», а потом «перепиши своими словами» — в два подхода.

Веб-стандарты: почему «сверху вниз»

HTML описывают стандарты W3C и WHATWG: браузеры обязаны «читать» одинаково. Поэтому одна страница открывается везде. Стандарты — это «общий язык» интернета.

💡
Новый тег встречает незнакомый браузер? Пишите «по стандарту», а не «по любви» к одному браузеру.

Доступность: инклюзивный сайт

Сайт «для всех» — с alt у картинок, подписями у форм, читаемым контрастом. Слабовидящие, глухие, люди с ограничениями моторики пользуются теми же страницами, что и вы.

💡
Начните с «малого зоопарка»: alt, lang, label, логичный порядок фокуса.

Цифровой след: что видно в поиске

Title, description, структура заголовков — то, что покажет поиск вашей странице. Вы формируете «визитку» ещё до того, как кто-то нажал ссылку.

💡
Проверьте себя: введите свою страницу в поиск — что подскажет текст под ссылкой?

Профессия «верстальщик»: что сейчас

«Верстальщик HTML/CSS» — часть «frontend-разработчика». Сейчас востребованы навыки: семантика, адаптивность, доступность, аккуратность. Это отличная точка входа в веб-разработку.

💡
Портфолио из 3–5 аккуратных работ важнее диплома о курсах.

Пути развития: верстальщик или разработчик

Дальше развилки: углубляться в интерфейсы (анимации, доступность, дизайн-системы) или идти в код (JavaScript, затем фреймворки). Обе ветки растут из базы HTML/CSS.

💡
Попробуйте обе: месяц «вёрстки красиво» и месяц «логики на JS» — и станет понятнее, что ваше.

Итоги урока 1: план роста на месяц

Вы владеете базой: структура документа, теги, формы, пути, публикация, DevTools. План на месяц: сверстайте визитку → «меню» → блог → портфолио; выложите одну страницу на GitHub Pages.

💡
Один проект в неделю — и к концу месяца у вас мини-портфолио «сам сделал».

Вложение короткое: тег внутри тега

Один тег может жить внутри другого: в абзаце, в li. «Внутренний» тег закрывается раньше «внешнего» — строго «по-матрёшечному».

<p>Краткое <strong>описание</strong>.</p>
💡
Открыли A, потом B — закрывайте B раньше A. «Непересекающиеся» вложения — правило валидного HTML.

Атрибут всегда с именем и значением

Атрибут — пара «имя=значение» внутри открывающего тега: href="page.html". У одних атрибут значение обязательно, у других его можно опустить (boolean-атрибуты). Имя — латиницей, без пробелов.

💡
Пробел в значении — «закрывает» атрибут: поэтому значения берут в кавычки.

Кавычки внешние и внутренние в атрибуте

Значение можно оборачивать в «двойные» или «одиночные» кавычки. Если внутри есть кавычка одного вида — используйте другой: title='Он сказал "да"'.

💡
«Наружная» пара и «внутренняя» не должны совпадать: одинарные снаружи — двойные внутри, и наоборот.

Строки и пробелы: браузер «склеивает»

Несколько пробелов, табов и переносов строк браузер «схлопывает» в один пробел. Раскладка кода «в столбик» не «ломает» текст — наоборот, делает его читаемым.

<p>Тайные
пробелы
схлопнуты</p>
💡
Хотите «настоящие» переносы — используйте <br> или <pre>, а не «свои» пробелы.

Комментарии: заметки не для показа

Комментарий в HTML пишется так: <!-- текст -->. Его не показывают браузер, но видят разработчики в исходном коде. Комментарии поясняют «сложные места» и «отключают» блоки на время.

<!-- шапка страницы -->
<header>...</header>
💡
Комментируйте «почему так», а не «что делает»: по коду и так видно «что».

Верхний и нижний регистр тегов

HTML не различает регистр тегов: <P> и <p> — одно и то же. Но «нижний» регистр — общепринятая норма: легче читать и согласовано с XHTML-наследием.

💡
Валидатор «прощает» и «CSS-имена» тоже строчными: привыкайте писать всё строчными буквами.

Заброшенные теги: что «устарело»

Теги-«реликвии» (<font>, <center>, <marquee>) устарели: их заменил CSS. Современный HTML их «терпит», но не рекомендует. Не вводите «старинный» код в новые страницы.

💡
Встретили <center> в старом коде — замените на CSS text-align/flex-центр.

Источники HTML: файлы и генераторы

HTML пишут руками в редакторе, но страницы часто «собирают» генераторы (CMS, конструкторы, фреймворки). Начинающему важнее понимать «простые» куски, чем «говорить» генератору вслепую.

💡
Умение «читать» сгенерированный HTML — защита: вы понимаете, что публикуете.

Структура документа: два «больших» блока

Каждый HTML-документ делится на head (служебное) и body (видимое). В head — метаданные и подключения, в body — контент страницы. «Скелет» так читается всегда.

💡
Вспомните «голова-тело»: всё «служебное» в head, всё «видимое» в body.

Порядок подключений в head

Раньше грузятся мета-теги и «критические» стили; скрипты — «после» или с отложенной загрузкой. Порядок влияет на скорость отображения. «Тяжёлые» ресурсы — «ниже», «быстрые» — «выше».

💡
Стили в head, скрипты в конце body — классический «быстрый» расклад.

Заголовок вкладки: title как «строка окна»

title — текст во вкладке браузера и в выдаче поиска. Он должен «рассказывать» страницу: коротко, информативно, с «брендом». Честный title — «визитка» вкладки.

<title>Урок 1 — Основы HTML</title>
💡
Длина title — «50–60 символов»: поиск «обрезает», вкладки «ужимают».

Язык страницы: атрибут lang

<html lang="ru"> говорит браузеру и скринридерам, на каком языке текст. От кодировки зависит «подсказки правописания», «перевод», «озвучка». Правило: lang — всегда.

💡
Раздел на другом языке («quoted») — уточните lang на «блоке», иначе озвучка «помучает».

Кодировка файла: одинаково на всех экранах

DOCTYPE и charset="UTF-8" «договариваются», как читать символы. Без объявления кодировки кириллица может «рассыпаться». Текстовый файл должен быть сохранён «в той же кодировке».

<meta charset="UTF-8">
💡
«Кракозябры» — почти всегда «кодировка файла ≠ кодировка в мета-теге».

Читать страницу: источник и инспектор

«Просмотр кода страницы» (Ctrl+U) показывает исходный HTML; «Инспектор» (F12) — «живое» DOM-дерево. Исходник — «то, что прислали»; инспектор — «то, что построил браузер».

💡
Скрипты «меняют» страницу: в инспекторе видно «после», в источнике — «до».

Валидатор: формальная проверка

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

💡
«Предупреждения» валидатора читайте: некоторые «советы» улучшают доступность.

«Обновить» страницу: жёсткий и мягкий

F5 — «взять заново», Ctrl+F5 — «забудь кэш, возьми всё заново». После правки CSS «старый» кэш может «держать» старое. Ctrl+F5 — «железный» способ проверить себя.

💡
«Ничего не поменялось» после правок — Ctrl+F5: чаще всего виноват кэш.

Сколько страниц: многостраничность

Сайт часто состоит из нескольких файлов: index.html, about.html, contacts.html. Ссылки между ними — относительные пути. «Структура папок» = «структура сайта».

<a href="about.html">О нас</a>
💡
Главная «index.html» открывается по адресу папки «как есть» — «точка входа» сайта.

Относительные пути: «отсюда и вниз»

Путь «cat.jpg» — файл рядом; «img/cat.jpg» — в подпапке; «../cat.jpg» — на уровень выше. Относительные пути переносимы: «переезжает» сайт — путь «живёт».

💡
Проверяйте пути «кликами»: битая картинка — почти всегda «вру к пути».

«Корень» сайта: абсолютные адреса

Путь «/assets/style.css» начинается «от каталога сайта» (не от файла). На «локальных» техниках и «в продакшене» работает по-разному. Ставьте «корневые» — когда точно знаете «серверную» структуру.

💡
Локально «/…» может указать на «диск», а не на проект: осторожно с «корнем» на практике.

Файлы-страницы: расширения и пробелы

Страницы — файлы .html; избегайте пробелов и кириллицы в именах: page-2.html вместо «страница два.html». Пробел в URL кодируется «плохо» и путается. «Простые» имена — «спокойные» ссылки.

💡
Имена строчными, с дефисами: «kurs-html.html» читается и «переезжает» без сюрпризов.

Заголовки внутри: h3 и h4 на практике

Кроме h1–h2 в разметке живут h3 и h4: подразделы внутри разделов. Иерархия «сложна», но «правильна»: не пропускайте уровни. Скринридер строит «карту» страницы по всем заголовкам.

<h2>Раздел</h2>
<h3>Подраздел</h3>
💡
«Прыгать» c h2 на h4 — «дырка» в оглавлении: читатели «на карте» споткнутся.

Абзацы и переносы: p и br

<p> — абзац (блок), <br> — перенос строки «внутри». Абзац разделяет «мысли», br переносит «строку». Не «штампуйте» br ради отступов — там место margin у p.

💡
Адрес или стихотворение — «br» уместен; «просто отступ» — margin.

Маркированные списки: ul и li

<ul> — «набор» пунктов (ul>li). Маркер по умолчанию — «точка». Списки «разбивают» перечисления на «опоры» чтения. Вложенность списков допустима — «двухуровневое» меню.

<ul>
  <li>Первый</li>
  <li>Второй</li>
</ul>
💡
«Прямые дети» ul — только li: «напрямую» текст в ul — «ошибка» структуры.

Нумерованные списки: ol и порядок

<ol> — «последовательность»: шаги, рейтинг, хронология. Нумерацию «ставит» браузер, а не «вручную» текст. Серийность «сама» пересчитывается — удобно при правках.

💡
«Шаги приготовления» — ol; «перечень цветов» — ul. Смысл решает, а не «вид».

Списки определений: dl, dt, dd

Словарь-список: dl содержит пары dt (термин) и dd (определение). Характеристики товара, глоссарий, «пара-значение» — «смысловая» пара. Читается «машиной» и «человеком».

<dl>
  <dt>Монитор</dt>
  <dd>27 дюймов</dd>
</dl>
💡
Один dt — один dd (или несколько переносов). «Словарь» = «dl»: не «переинаковка» в table.

Цитаты в тексте: q и blockquote

Строчная цитата — <q> (« » добавляют «по ситуации»); большая — <blockquote>. Атрибут cite у q «свешивает» источник. Цитата «внутри» текста — «кавычки», отдельная — «блок».

💡
«Кавычки» к q «подставляет» браузер: не дублируйте «ёлочки» вручную в тексте.

Изображения: img с alt и без

<img src="foto.jpg" alt="описание"> — картинка. alt — «текст» при её отсутствии и для доступности. Декоративную картинку «обозначают» пустым alt=" ". Не «грузите» картинки «для красоты» без alt.

💡
alt «не работает» при «слушанье» — но «читается» скринридером: пишите «что на фото».

Ссылки на скачивание: атрибут download

<a href="file.zip" download> — «начать скачивание» вместо «открыть». download «говорят» браузеру «качай». Для PDF и ZIP — «прямое» действие по имени ссылки.

💡
«Скачать» без download откроет файл «в браузере»: назвал «скачай» — добавь download.

Горизонтальная линия: hr

<hr> — смысловой «разделитель» между частями содержания. «Эра», «акт», «смена темы» — его стихия. «Толстую линию для красоты» лучше рисовать CSS-границей, а «смысл» — hr.

💡
hr «без текста» — «разделитель»; если нужен «вещающий» разрыв — section + заголовок.

Средства для текста: em и i

<em> — смысловой акцент (интонация); <i> — «начертание» (термин, название, иноязычное слово). Не путайте: «эмоциональное» — em, «типографское» — i.

💡
Курсив «во имя» терминов — i; «во имя» ударения — em. Различие читают машины и «дикторы».

Код в тексте: code и pre

<code> — «строчный» фрагмент кода; <pre> — блок с сохранёнными переносами и пробелами. Для «разметки в разметке» символы «<» и «>» экранируют. Код «в статье» — «мелким моноширинным».

<p>Пишем <code>&lt;h1&gt;</code>.</p>
💡
Чтобы «показать» тег, а не «создать» его — «&lt;» и «&gt;» вместо «<» и «>».

Даты и время: тег time

<time datetime="2026-09-20">20 сентября</time> — «машиночитаемая» дата. Осень «правильная» у поиска и календарей. Текст для «людей», datetime — «для машин».

💡
datetime в формате ISO 8601 (ГГГГ-ММ-ДД): «парсится» без «ручных» догадок.

Выделение «для роботов»: тег mark

<mark> подсвечивает «важное для справки»: совпадения поиска, ключевые слова. По умолчанию — жёлтая «подсветка». Смысл — «полезная» метка, а не «любая» краска.

💡
mark уместен на «выделенном в выдаче»: «слово, которое искали» — его родной дом.

Переносы слов: тег wbr в помощь

<wbr> — «место возможного переноса» длинного слова. Длинные URL и «термины» «в тесноте» переносятся «по-доброму». Браузер переносит «только в нужную минуту».

💡
«Суперкалькулятор» без wbr «выедет» из карточки; с wbr — «перенесётся» аккуратно.

Если символ не «на клавиатуре»: сущности

«©», ««», «—», « » — HTML-сущности: «кодовые» символы. Нужны для «неудобных» знаков и «надёжной» вёрстки кавычек/тире. «&» — сам «символ амперсанда» как сущность.

💡
«Ёлочки» через « » — «уроки» и «цены» в кавычках «читать» приятно.

Пробел «недробищийся»:  

&nbsp; — «неразрывный» пробел: слова не «разрывают» на переносе. «и 500 ₽» — «единое» целое. Цифры с «единицами» живут «вместе», когда « » между ними.

💡
«3 кг» и «№ 7» — «не разрываются»; в юникоде « » тоже «не липнет» к концу строки.

Подстрочные и надстрочные: sub и sup

<sub> — «индекс» (H₂O), <sup> — «степень» (м²). Формулы и единицы — «их» стихия. Смысл «ниже/выше» строки — «начертание», но «математический» ввод — «в типографике».

💡
«H<sub>2</sub>O» и «10<sup>2</sup>» — формула «читается» с «настоящими» индексами.

Термин и его расшифровка: abbr

<abbr title="HyperText">HTML</abbr> — сокращение с расшифровкой. Наведение «показывает» title; скринридер «читает» текст. Акронимы «объясняются» при первом вхождении.

💡
«расшифровка» в title = «пояснение над инструментом»: первый раз — обязательно, дальше — «по вкусу».

Ссылка на телефон и почту: tel и mailto

href="tel:+7..." и href="mailto:hi@site.ru" — «живые» контакты: звонок и письмо «по клику». На телефоне «набирает», на десктопе — «почтовик». «Международный» формат — без пробелов.

💡
«Звонок» одним кликом — конверсия «мобильных»; пишите href с «+» и кодом страны.

Скачивание с именем: download="имя"

Значение атрибута download задаёт «имя» скачиваемого файла: download="program.pdf". Пользователь «сохраняет» с «вашим» именем. Удобно для «шаблонов» и «программ» из «безликих» ссылок.

💡
«Без download» — «откроется»; «с именем» — «сохранится как»: осмысленно для «скачиваемого» контента.

Формы: что «собирается»

Форма «собирает» данные пользователя: form содержит поля input, textarea, кнопки. Атрибут name у поля — «имя» данных. После отправки данные «уходят» на сервер (или «ловятся» скриптом).

💡
Каждое «поле» — name: без него «уехавшая» пара «имя-значение» не соберётся.

Поле ввода: input с типом text

<input type="text" name="имя"> — «строка» для текста. type задаёт «вид»: text, email, number, date... name — «адрес» данных, placeholder — «подсказка внутри».

💡
placeholder «исчезает» при вводе: не заменяйте им label — «постоянную» подпись поля.

Подпись к полю: label

<label for="имя"> привязан к полю: клик по тексту «фокусирует» поле. Скринридер «читает» label как имя поля. Пара «label+input» — «минимальная» доступная форма.

<label for="email">Почта</label>
<input id="email" type="email">
💡
id поля ↔ for у label: «одинаковый» код — «связка» работает и на телефоне.

Большой текст: textarea

<textarea></textarea> — «многолинейное» поле: комментарии, отзывы. «Переносы» и «строки» работают «как в блокноте». Размер задаётся CSS (не «атрибутами» ширины-строк).

💡
textarea «не самозакрывающийся»: текст «по умолчанию» — между открывающим и закрывающим тегом.

Выбор из списка: select и option

select — «раскрывающийся» список вариантов (option). value у option — «значение» пункта, текст — «показываемый» вариант. «Выбираемое множество» — его родная задача.

<select name="city">
  <option value="msk">Москва</option>
  <option value="spb">Санкт-Петербург</option>
</select>
💡
Значение «отправляется» из value, а не из «показанного» текста: «код-значение» — раздельно.

Чекбокс: галочка да/нет

<input type="checkbox"> — «флажок» из «независимых» пунктов. Согласие с правилами, «выбор нескольких». «Меченый» (checked) — «включён по умолчанию». value «согласия» — на «отправку».

💡
«Несколько галочек» — каждый сам по себе; switch-«выбор одного» — радио.

Радио-кнопки: один из группы

<input type="radio"> — «селекция одного» в группе: одинаковый name у всех вариантов. Выбрать можно только один. «Число для 1» — «по выбранному радиокоду»: value разное, имя — общее.

💡
Имя группы — «то же самое»: иначе поле «считается» другим и «выбрать одно» не получится.

Кнопка отправки: input submit

<input type="submit" value="Отправить"> — «отправляет» форму. Без submit форма «отправки» не имеет. Кнопку «нажимают» и Enter в поле «запускает» её.

💡
Текст кнопки «на кликабельном» — value; «картинка-отправить» — type="image".

Кнопка сброса: reset осторожно

<input type="reset"> «сбрасывает» форму к начальному виду. Пользователь «потерял» ввод — страшно. В «простых» формах reset обычно «лишний»: разочаровывает «случайными» кликами.

💡
«Сбросить» — по запросу (пользователь «сам»), а не «кнопка рядом с отправкой».

Скрытое поле: hidden-значение

<input type="hidden" name="session" value="abc"> — «невидимое» поле для «служебных» данных формы. «Не показывается», но «отправляется». Токены, id записи, «состояния» — его работа.

💡
hidden «видно» в DevTools: не кладите туда «секреты», это «прозрачный» конверт.

Обязательное поле: required

Атрибут required «не отпускает» форму без заполнения: браузер «подскажет» и «покажет» ошибку. «Логическая» обязательность — на server-стороне; required — «первый уровень» UX.

<input name="email" required>
💡
required «без» «ручных» проверок; но «проверьте» и «сервер»: браузер «не панацея».

Ограничение длины: maxlength

maxlength="30" «ограничивает» символы в поле: «счётчик» ввода. Полезно для «публикаций», «био», «кода». «Сервер» тоже «должен верить» maxlength — вдруг обойдут.

💡
«Перебор» не «слезет» в базу; maxlength защищает «от себя», len на сервере — «от всех».

Числовое поле: input type="number"

type="number" — «цифровое» поле со стрелками «вверх/вниз». min/max/step «рамки» и «шаг» числа. На телефоне «цифровая» клавиатура. Для «чисел, а не «страниц» — number.

💡
«Число с «плавающей точкой» — не лепите в text; number «понимает» формат «0.5».

Дата в форме: input type="date"

type="date" — «календарь» в поле: выбор даты без «ручного» формата. Браузер «ставит» свой виджет. «Событие», «бронирование», «доставка» — «календарные» поля его область.

💡
Формат значения date — ISO «2026-09-20»; «эстетика» показа по «локали» пользователя.

Пароль: input type="password"

type="password" — «замаскированные» символы. «Точки или звёздочки» скрывают ввод. «Безопасность» — это «шифрование» на сервере, а маска — «от глаз». «Вспышка» пароля — отдельная кнопка-«глаз».

💡
«Глаз-переключатель» маски — фича многих форм: пользователь «видит» опечатку.

Почта и URL: валидность типов

type="email" и type="url" дают «встроенную» проверку формата: браузер «ругается» на «непохожее». На телефоне — «нужная» клавиатура (@, «точки»). «Мягкая» валидация «первого» уровня.

💡
type=email «не идеален» (пропускает «странности») — но «отсекает» основное «мусорное».

Диапазон: input type="range"

type="range" — «ползунок» для выбора из диапазона: громкость, объём. min/max/step — «границы» и «шаг». «Значение» — в value, «глаз» — свой UI. «Грубая» настройка «ёлочкой» — его место.

💡
«Ползунок» интуитивно «удобен», но «точное» число «показывайте» рядом: value «не видно».

Цвет: input type="color"

type="color" — «выбор цвета» со «своей» палитрой браузера. Значение — HEX: #ff4400. Настройки темы, «палитра» редактора — «цветные» поля. «Точная» копия — для «дизайнеров».

💡
color «возвращает» ровно HEX; «предустановленных» палитр «своими» руками — на JS.

Фокус по порядку: tabindex

Нажимая Tab, пользователь «ходит» по интерактивным элементам. tabindex="0" — элемент «в» порядке «обычных»; «положительный» — «первее»; «-1» — «нет в Tab-цепочке» (фокусируется скриптом).

💡
«Порядок» по умолчанию — «по разметке»: не «ломайте» его без причины «ручными» номерами.

Выключенное поле: disabled

disabled «блокирует» поле: нельзя вводить, «передано» не будет. «Отключено», «недоступно», «ждать» — его слово. Доступность: «не работает» читается ролью «недоступно».

💡
disabled «убирает» из отправки: «выбранное-но-не-доступное» — «не слетит» в данные.

Группа полей: fieldset и legend

Поля «по смыслу» группирует fieldset; название группы — legend. «Контакты», «адрес доставки», «платёж» — «разделы» формы с «заголовком». Скринридер «читает» legend «группе» полей.

<fieldset>
  <legend>Контакты</legend>
  <label>Почта <input type="email"></label>
</fieldset>
💡
«Радио-группа» с legend: «вопрос» — legend, «варианты» — радио. Чисто и доступно.

Место для «наведения»: placeholder

placeholder — «пример» или «подсказка» внутри пустого поля. Он «не label»: исчезает при вводе. Уместен «+ подпись», а не «вместо». «Что и как писать» — «подсказка не постоянная».

💡
Если «пустое» поле с placeholder «смотрится» как «без имени» — добавьте «настоящий» label.

Направление вращения: autofocus

autofocus «ставит» курсор в поле «при загрузке»: поиск, первый шаг формы. «Экономия клика», но «скролл» может «прыгнуть». Один autofocus на страницу: не «все» поля сразу.

💡
autofocus в «диалогах» — удобно; на «обычных» страницах «не навязывайте» фокус.

Отправка без кнопки: Enter

Enter в поле «отправляет» форму, если есть submit-кнопка. «Только поле + Enter» — быстрый поиск. Для многострочных textarea Enter «делает» перенос. «Логика Enter» — «свойство формы», не «магия».

💡
Держите submit «в форме» — и Enter «сработает». Убрали кнопку — Enter «молчит».

Предзаполнение: атрибут value

value="Предзаполнено" — текст в поле «до ввода». Для «fixed» значений; пользователь «меняет». Для «запоминания ввода» — атрибут autocomplete. value «не заменяет» placeholder — это «данные», не «подсказка».

💡
«Редактируемое» поле с value «отправляет» предзаполненное: «изменить» — по желанию.

Автозаполнение форм: autocomplete

Атрибут autocomplete="email" говорит браузеру «что это»: имя, почта, телефон. Согласие «дать» из «сохранённого» — браузер «подставляет». «Логичные» типы = «меньше» ввода руками.

💡
«Код-подтверждение» — autocomplete="one-time-code": браузер «подтянет» SMS-код.

Список в подсказках: datalist

datalist — «предложить», но «свободный ввод»: list у input «соединяет». «Город», «валюта», «браузер» — «подсказывает», но «не ограничивает». Список + «свободная строка» — его суть.

<input list="city">
<datalist id="city">
  <option value="Москва">
</datalist>
💡
datalist «не» «строгий выбор»: пользователь пишет «своё», браузер «лишь» подсказывает.

Поиск с очисткой: input type="search"

type="search" — «поисковое» поле: браузер даёт «крестик»-очистку. На телефоне — «поисковая» клавиатура. От chapter-«текст» отличает «ролью» и «кнопкой». Поиск «слушал» — «уважайте» знак х.

💡
«Поиск» — search: «согласие» бразера «очистить» «значком» бесплатно вам.

Дня и месяца: месяц и неделя

type="month" и type="week" — «выбор» месяца и «недели». Бронирование, отчёты, расписание — «периоды», а не «даты». Формат «значений»: YYYY-MM и «неделя-номер».

💡
«Период»-поля «экономят» пользователя: «неделя с… по…» — один клик вместо двух.

Время: input type="time"

type="time" — «часы:минуты» без даты: начало встречи, «занятие». «Полночь» и «24:00» — пограничные значения. Удобен «в паре» с date: «дата+время» — два поля.

💡
«Границы» time (min/max) «работают» не везде одинаково; «важное» время «проверьте» на сервере.

Форма и семантика: «правильный» каркас

Форма «в» структуры: главная «несколько» форм — каждая «своя» (поиск vs заявка). «Вложенных» форм «не бывает» — HTML «запрещает». «Правильная» иерархия форм — «спокойная» отправка.

💡
Две «независимые» кнопки в одной форме «отправят» всё: разделите «по-задачам».

Ссылки и формы: когда что

Ссылка — «переход»: на страницу, к записи. Форма — «отправка»: собрать данные. «Важно»: поиск — форма, «назад к списку» — ссылка. «Гиперссылка на действие» — «scene» «запутывает» систему.

💡
«Звонок/почта» кликом — ссылка; «данные пользователя» — форма. Разделяйте «тип действия».

Стилизация без CSS: атрибут выравнивания

align="center", bgcolor — «старые» атрибуты выравнивания и цвета. Они «работают», но «вытеснены» CSS. «Новый» код: стили — в CSS, а «атрибут» — «реликт» хранения.

💡
Валидатор «помечает» устаревшие атрибуты «предупреждением»: замените их на CSS.

Универсальный контейнер: div

<div> — «блочный» контейнер без смысла «сам по себе». Его «наполняют» классом: div class="card". Когда «своего» семантического тега нет — div «честный» выбор.

💡
«Див ради дива» — не копите; семантический тег (section, article) там, где «смысл» есть.

Строчный контейнер: span

<span> — «строчная» обёртка внутри текста: подсветить «слово» стилем. Не создаёт строк, «течёт» в тексте. «Кусочек» с классом — его работа.

<p>Жирное <span class="accent">слово</span>.</p>
💡
«Смыслу» нет — span; «смыслу» есть — strong, em, mark. Не «переодевайте» смысл в span.

Практика: мини-страница «визитка кода»

Соберите страницу со всем из урока: заголовки, абзацы, список, картинка, ссылка, форма с полями. Плюс «иерархию» заголовков и «списки по смыслу». Это ваш «сверхкомпактный» справочник-визитка.

💡
«Визитка» за 20 минут повторяет «прочитанное» и «запирает» в навык.

Практика: опросник из полярных типов

Соберите «опрос»: text, radio-группу, checkbox, select, textarea, «обязательные» поля. Отправьте «в никуда» action="#" — и «потеряйте» данные с удовольствием. Формы «в рукаве» готовы.

💡
action="#" «не отправляет» по-настоящему — просто «тренировочная» мишень.

Практика: меню из вложенного списка

Двухуровневое меню: ul с вложенным ul. «Смысл» — список; «красота» — выпадающее. Скринридер «прочтёт» структуру. На пустом пути «важные» пункты «наверху».

💡
Вложенный ul «афиширует» иерархию пунктов: «главное>под-пункт» — честная структура.

Оценка своей страницы: 5 проверок

Проверьте «пятерку»: 1) h1 один; 2) alt у картинок; 3) label у полей; 4) ссылки «со смыслом»; 5) валидатор «без критического». «Пятёрка» — «двадцатка» страниц «здоровых».

💡
«Пятёрка» — это «чек-лист перед публикацией»: «гоняйте» её на каждой странице.

Контрольная работа по уроку 1

Соберите «страницу-конференцию»: тема (h1), описание (p), программы (ol), спикеры (ul с figure), форма заявки. Всё «по семантике» урока. Покажите «решение» — и урок 1 «закрыт».

💡
Контрольная «домашняя» — лучший «перевод» теории в «навык»: верстайте без шаблонов.

Атрибуты данных: data-* для своих меток

data-любое-имя — «свой» парный атрибут-метка: data-id="42". JS «читает» их без классов-«закоулков». «Метаданные» элемента: id записи, состояние, конфиг — их дом.

<div class="card" data-id="42">...</div>
💡
«Свои» атрибуты (не data-) невалидны; «data-» — «официальная» песочница метаданных.

Семантические поля: role-атрибут ARIA

role «объясняет» элементу его «роль»: role="button" на div. «Свою» роль сохраняют «нативных» тегов (kbd