Учебник веб-разработки
Разделы учебника
На этой странице

V. Интерфейс и UIKit

HTML, DOM и CSS: платформа под React

Оглавление · Компоненты React

HTML описывает структуру и смысл документа. DOM — дерево объектов, которое браузер построил после разбора HTML; JavaScript может менять это дерево. CSS задаёт представление. React вычисляет описание интерфейса и согласует его с DOM, но доступность и правила layout остаются правилами браузера.

Исходник схемы
flowchart LR
  HTML[HTML] --> DOM[DOM]
  CSS[CSS] --> Layout[Стили и layout]
  DOM --> Layout
  Layout --> Paint[Отрисовка]
  DOM --> Accessibility[Дерево доступности]

Семантика прежде внешнего вида

Ссылка переводит на адрес, кнопка выполняет действие. Заголовок обозначает уровень структуры, а не размер шрифта. main выделяет главное содержимое, nav — навигацию, список — связанные пункты. Нативная кнопка уже поддерживает клавиатуру и disabled; у div с обработчиком клика этих свойств нет.

Сохраните пример как отдельный временный index.html, откройте в браузере:

<!doctype html>
<html lang="ru">
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Учебное расписание</title>
  <main>
    <h1>Расписание</h1>
    <form>
      <label for="query">Название события</label>
      <input id="query" name="query" type="search" />
      <button type="submit">Найти</button>
    </form>
    <ul class="events">
      <li><a href="#first">Тренировка</a></li>
      <li><a href="#second">Открытый урок</a></li>
    </ul>
  </main>
</html>

Без JavaScript отправка формы меняет адрес с query string. У кнопки внутри формы по умолчанию тип submit; для локального действия нужен type="button". Связь for/id даёт полю доступное имя. Placeholder не заменяет label. Для содержательной фотографии нужен осмысленный alt; для декоративной — пустой.

DOM может отличаться от исходной строки: браузер исправляет некорректную вложенность. Это одна из причин ошибки гидратации. Проверяйте Elements и исходный HTML, а не только JSX. Внешний HTML нельзя без проверки считать безопасным: React экранирует обычные текстовые значения, но вставка HTML отдельным API требует отдельной модели доверия.

Каскад и геометрия

Каскад выбирает объявление с учётом происхождения, важности, слоя, специфичности и порядка. «Последнее правило выигрывает» верно только после сравнения предыдущих факторов. Наследование передаёт некоторые свойства от родителя; размеры блока обычно не наследуются. В DevTools смотрите Computed и источник победившего объявления. В проекте порядок Mantine layer и UIKit разобран отдельно.

Добавьте в пример CSS:

* {
  box-sizing: border-box;
}
body {
  margin: 0;
  font-family: system-ui, sans-serif;
}
main {
  max-width: 60rem;
  margin-inline: auto;
  padding: 1rem;
}
form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}
input {
  min-width: 0;
  max-width: 100%;
}
.events {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 1rem;
  padding: 0;
  list-style: none;
}
.events li {
  padding: 1rem;
  border: 1px solid currentColor;
}
a:focus-visible,
button:focus-visible,
input:focus-visible {
  outline: 3px solid #2166d1;
  outline-offset: 3px;
}

В box model содержимое окружено padding, border и margin. При border-box заданная ширина включает padding и border. Flex удобен для одной оси, Grid — для сетки. min-width: 0 разрешает flex-элементу сжиматься; фиксированная ширина не гарантирует адаптивность. rem зависит от корневого размера шрифта. Не переставляйте Grid/Flex элементы ради красоты, если это делает порядок клавиатурного фокуса непонятным: DOM остаётся источником порядка чтения.

Лаборатория браузера

  1. Отключите CSS. Смысл документа и подписи должны сохраниться.
  2. Пройдите Tab и Shift+Tab, активируйте кнопку клавиатурой. Фокус должен быть виден.
  3. Проверьте 320 px, широкий экран и увеличенный текст: без горизонтального переполнения формы, с сохранённым порядком событий.
  4. В Elements временно измените padding; найдите источник в Computed. Изменение DevTools не сохраняется в файле.
  5. В Network отправьте форму и найдите URL с query. Различите запрос документа и запрос данных; Console покажет ошибки JavaScript, а не все ошибки сети.
  6. В дереве доступности проверьте имя поля и роль кнопки. Это полезная проверка, но она не заменяет использование экранного диктора.

Результат: объясняете одну проблему на каждом уровне: семантика, layout, фокус и загрузка. Браузерные проверки в этой лаборатории выполняет читатель; разбор HTML в happy-dom не подтверждает layout и доступность в настоящем браузере. В проекте CSS Modules ограничивают область имён классов, а не отменяют каскад.

Источники: HTML, каскад, Grid и доступность.