Перейти к основному содержимому
Блокчейн38ГЛАВА 38HTML: из чего состоит страницаheadernavmainfooter<!doctype html>

HTML: из чего состоит страница

Прочитано0%
Квизы0/4
Тренажёрыне пройден0/1
Уровень 1 · Новичок

Зачем это нужно​

Контракт развёрнут, адрес есть, транзакции проходят. Но пользоваться этим пока может только тот, кто умеет писать скрипты.

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

Начинается интерфейс с языка разметки. Он не программирует — он описывает, что на странице есть: заголовок, поле ввода, кнопка, таблица операций. Всё остальное — оформление и поведение — прикладывается к этому описанию.

Три языка, три разных вопроса​

ТРИ ЯЗЫКА СТРАНИЦЫ, ТРИ РАЗНЫХ ВОПРОСАHTMLчто здесь естьзаголовок, абзац, поле, кнопкасмысл и структураCSSкак это выглядитразмер, цвет, расположениеоформлениеJavaScriptчто происходитнажали — отправили запросповедениестраница живёт и без второго, и без третьего: без оформления — некрасиво, без поведения — статичнобез первого не живёт вовсе: оформлять и оживлять нечеговаш интерфейс к контракту — это те же три языка плюс библиотека работы с сетью
Разметка отвечает «что здесь есть», оформление — «как выглядит», сценарий — «что происходит»

Язык разметки отвечает на вопрос «что здесь есть». Это заголовок. Это поле для суммы. Это кнопка отправки. Это таблица.

Язык оформления отвечает «как это выглядит»: размеры, цвета, расположение.

Язык сценариев отвечает «что происходит»: нажали кнопку — собрали транзакцию, отправили в сеть, показали результат. Это уже знакомый нам TypeScript, только выполняется он не в Node, а в браузере.

Порядок не случаен. Страница живёт без оформления (некрасиво, но работает) и без сценариев (статично, но читается). Без разметки не живёт вовсе: оформлять и оживлять нечего.

Элемент: тег, атрибуты, содержимое​

<input id="amount" type="number" min="1" placeholder="Сумма в ETH">
Нажми на часть выражения

Большинство элементов устроены иначе — с содержимым и закрывающим тегом:

<button type="submit">Отправить</button>

Здесь Отправить — содержимое, а </button> — закрывающий тег. Элементы вкладывают друг в друга, и получается дерево: страница — это не текст сверху вниз, а дерево элементов.

Скелет документа​

<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Хранилище</title>
</head>
<body>
<h1>Хранилище</h1>
</body>
</html>
Нажми на часть выражения

Проверка на живой странице показывает, что из этого куда попадает:

заголовок вкладки: "Хранилище"
язык страницы : ru

Браузер не отказывается — он достраивает​

Компилятор Solidity на ошибку отвечает отказом. Браузер устроен ровно наоборот: он всегда что-нибудь покажет, даже если разметка сломана. Это удобно и опасно одновременно.

Первый прогон: ни один тег не закрыт.

написали: <p>первый<p>второй<div>третий</div> — ни один тег не закрыт
получилось: p, p, div
внутри первого p: "первый"

Браузер сам закрыл первый абзац, когда начался второй. Результат оказался тем, что мы имели в виду.

Второй прогон выглядит так же безобидно, но заканчивается иначе:

написали: <p>снаружи<div>внутри</div>хвост</p>

── что получилось ──
<p>
текст: "снаружи"
<div>
текст: "внутри"
текст: "хвост"
<p>
БРАУЗЕР НЕ ОТКАЗЫВАЕТСЯ, А ДОСТРАИВАЕТнаписали<p>снаружи <div>внутри</div> хвост</p>получилось<p> «снаружи»<div> «внутри»текст «хвост» — сам по себе<p> пустойчетыре узла вместо двухблочный элемент внутри абзаца закрывает абзац: так устроены правила разбора, и ошибки не будетни одного сообщения браузер при этом не выведет — расхождение видно только в деревепоэтому разметку проверяют инструментом, а не глазами: глазами она выглядит правильной
Четыре узла вместо двух: блочный элемент внутри абзаца закрывает абзац, а слово «хвост» остаётся без родителя

Разберём по шагам. Абзац открылся. Встретился блочный элемент — по правилам разбора он закрывает абзац, потому что абзац не может содержать блочные элементы. Слово «хвост» оказалось уже вне абзаца — прямо в теле документа. А закрывающий </p> без открывающего создал пустой абзац.

Вместо двух элементов получилось четыре узла, и один из них пуст. При этом:

  • ошибки не было;
  • предупреждения не было;
  • на экране всё выглядит примерно как задумано.

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

Важно

Отсюда правило: разметку проверяют инструментом, а не глазами. Глазами она выглядит правильной ровно до того момента, когда что-то перестаёт работать без объяснений.

Отвечено вопросов: 0 из 2
Что сделает браузер с некорректной разметкой?
Почему <p>снаружи<div>внутри</div>хвост</p> даёт четыре узла?
Отвечено верно: 0 из 2

У каждого тега уже есть оформление​

Файл без единой строки оформления выглядит не как голый текст. Браузер применяет к тегам собственные стили. Прогон снимает их с живой страницы:

тег размер жирность отступы св/сн поток
h1 32px 700 21.44px / 21.44px блочный
h2 24px 700 19.92px / 19.92px блочный
h3 18.72px 700 18.72px / 18.72px блочный
p 16px 400 16px / 16px блочный
ul 16px 400 16px / 16px блочный
li 16px 400 0 / 0 элемент списка
a 16px 400 0 / 0 строчный
strong 16px 700 0 / 0 строчный
code 13px 400 0 / 0 строчный
button 13.3333px 400 0 / 0 строчно-блочный
input 13.3333px 400 0 / 0 строчно-блочный
span 16px 400 0 / 0 строчный
div 16px 400 0 / 0 блочный

body: margin 8px, шрифт Times
У КАЖДОГО ТЕГА УЖЕ ЕСТЬ ОФОРМЛЕНИЕтегразмержирностьотступыпотокh132px70021.44pxблочныйh224px70019.92pxблочныйp16px40016pxблочныйa16px4000строчныйcode13px4000строчныйbutton13.33px4000строчно-блочныйблочный занимает всю ширину и начинается с новой строки; строчный — только своё место в строкеотступы у заголовков и абзацев не ваши — их даёт браузер; поэтому оформление часто начинают со сброса
Размеры, жирность и отступы даёт браузер; поэтому оформление часто начинают со сброса

Три вывода.

Блочные и строчные — разные по поведению. Блочный занимает всю доступную ширину и начинается с новой строки: заголовки, абзацы, списки, div. Строчный занимает только своё место в строке и переносится вместе с текстом: ссылка, strong, code, span.

Отступы у заголовков и абзацев — не ваши. Их дал браузер. Отсюда вечное «между блоками откуда-то взялся зазор»: он был там с самого начала.

У тела документа поля 8 точек, а шрифт — Times. Это и есть причина, по которой оформление почти всегда начинают со сброса: обнуляют поля и задают нормальный шрифт.

Интересный факт

Размер 13.3333px у кнопки и поля ввода — не опечатка. Это наследие давних договорённостей об элементах управления, и в разных браузерах числа чуть расходятся. Ещё одна причина задавать размеры самому.

Смысловые теги: не всё есть div​

Технически всю страницу можно собрать из div и span. Работать будет. Но теги выбирают не за внешний вид, а за смысл — по нему страницу понимают те, кто её не видит.

<header><h1>Хранилище</h1></header>
<nav><a href="/">Главная</a> <a href="/about">О проекте</a></nav>
<main>
<article>
<h2>Ваш вклад</h2>
<p>0 ETH</p>
</article>
</main>
<footer><p>2026</p></footer>
тегчто означает
<header>шапка страницы или раздела
<nav>набор ссылок для перехода
<main>основное содержимое; на странице ровно один
<article>самостоятельный кусок, который имеет смысл отдельно
<section>раздел со своим заголовком
<footer>подвал
<h1>…<h6>заголовки по уровням, без пропусков

Программа чтения с экрана строит по этим тегам оглавление и позволяет перейти сразу к основному содержимому. Из сплошных div оглавления не получится: все они для неё одинаковы.

Совет

Практический признак: если для элемента есть подходящий смысловой тег — берите его. div и span остаются для случаев, когда элемент нужен только ради оформления и ничего не значит сам по себе.

Формы: браузер проверяет за вас​

Форма — это то, через что пользователь вводит данные: сумму вклада, адрес получателя, согласие.

<form>
<label for="a">Сумма</label>
<input id="a" name="amount" type="number" required min="1">
<input name="to" type="text" placeholder="адрес">
<input name="agree" type="checkbox" checked>
<button type="submit">Отправить</button>
</form>

Прогон показывает, что из этого умеет сам браузер:

полей в форме : 4
поле amount : type=number, required=true
подпись через for/id : "Сумма" → amount
проверка до отправки : форма верна? false
после ввода 5 : форма верна? true
что уйдёт на сервер : amount=5&to=&agree=on
Нажми на часть выражения

Строка amount=5&to=&agree=on — то, как данные формы выглядят при отправке. Пустое поле уходит с пустым значением, галочка — словом on.

Отвечено вопросов: 0 из 2
У поля есть id, но нет name. Что произойдёт при отправке формы?
Зачем у кнопки внутри формы пишут type="button"?
Отвечено верно: 0 из 2

Ссылки, картинки и то, что к ним прилагается​

<a href="https://etherscan.io/address/0x8464…" target="_blank" rel="noopener noreferrer">
Посмотреть в обозревателе
</a>

<img src="logo.svg" alt="Логотип хранилища" width="120" height="40">
Нажми на часть выражения

Типичные ошибки​

Забыли кодировку. Кириллица превращается в «Ð¥Ñанилище». Строка с кодировкой ставится первой в служебной части.

Забыли строку про ширину экрана. На телефоне страница показывается уменьшенной целиком, буквы нечитаемы. На компьютере при этом всё в порядке — и ошибку не видно.

Поле без имени. Данные не уходят. Никаких сообщений при этом нет.

Кнопка в форме без указания вида. Нажатие перезагружает страницу, и всё, что было введено, теряется.

Блочный элемент внутри абзаца. Дерево получается не тем, что задумано, — молча.

Пропущенный уровень заголовка: после h1 сразу h3. Оглавление для незрячих ломается, хотя на экране разницы нет.

div вместо кнопки. Выглядит как кнопка, но на неё не перейти с клавиатуры и не нажать пробелом. Если это кнопка — пишите кнопку.

Отвечено вопросов: 0 из 2
Зачем выбирать смысловой тег вместо div, если выглядят они одинаково?
Зачем к картинке пишут width и height, если размеры задаются оформлением?
Отвечено верно: 0 из 2

Слова главы​

  • Элемент — тег, его атрибуты и содержимое; элементы вкладываются и образуют дерево.
  • Атрибут — имя и значение внутри открывающего тега; бывают и без значения.
  • Служебная часть — кодировка, заголовок вкладки, ширина экрана; на странице не видна.
  • Кодировка — первой строкой, иначе кириллица ломается.
  • Блочный и строчный — занимает всю ширину с новой строки или только место в строке.
  • Стили браузера — размеры и отступы, которые есть у тегов до всякого оформления.
  • Смысловые теги — шапка, навигация, основное, подвал; по ним страницу понимают программы чтения.
  • Форма — поля с именами; браузер проверяет обязательность и ограничения сам.

Тренажёр: набрать вслепую​

Цель: скорость ≥ 100 зн/мин, точность ≥ 88%

<!doctype html>

На чемпионате​

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

Смысловые теги — это баллы. Доступность интерфейса проверяют, и разница между div и правильным тегом видна сразу — по оглавлению и по переходу с клавиатуры.

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

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

Куда углубиться​

  • Таблицы — заголовки строк и столбцов, подписи; понадобятся для списка операций.
  • Диалоговые окна — встроенный элемент вместо самодельного всплывающего окна.
  • Атрибуты доступности — когда смысловых тегов не хватает.
  • Порядок обхода с клавиатуры — что попадает в него само, а что нет.
  • Проверка разметки — официальная служба, которая находит именно те расхождения, что не видны глазами.

Сводная проверка по всей главе: 8 вопросов, 5:00 на всё, без подсказок по ходу. Вопросы показываются по одному, ответ изменить нельзя. Если время выйдет — экзамен завершится с тем, что успел ответить. Пересдавать можно сколько угодно раз.

Куда дальше: проверенные ресурсы​

Видео по теме

ВидеоОсновы HTML для Начинающих (актуально в 2026)Сергей Дмитриевский
Видео3. Блочные и строчные теги в HTML. Теги div, spanАлександр Ламков — Friendly Frontend
Видео15. Семантические теги HTML: header, main, footer, section, aside, nav и остальные. Семантика HTML5Александр Ламков — Friendly Frontend
Видео11. HTML формы. Теги form, fieldset, legend, label и поле ввода inputАлександр Ламков — Friendly Frontend
ВидеоЯЗЫК РАЗМЕТКИ HTML ЗА 40 МИНУТ ДЛЯ НАЧИНАЮЩИХ. ВСЕ ТЕГИ ВКЛЮЧЕНЫ.wise.js 

Комментарии

Обсуждение живёт в GitHub Discussions и грузится с чужого домена — поэтому только по нажатию.