Глобальные атрибуты HTML

Глобальные атрибуты -- атрибуты, которые можно использовать на любом HTML-элементе. Они управляют идентификацией, стилизацией, видимостью, доступностью и интерактивностью.

Зачем нужно

Глобальные атрибуты -- фундамент работы с HTML. class и id связывают разметку с CSS и JavaScript. data-* позволяют хранить данные в DOM. hidden, inert, tabindex управляют видимостью и доступностью. Без них невозможно стилизовать, скриптовать и делать доступный интерфейс.

Где используется

  • Каждый HTML-элемент на каждой странице
  • CSS-селекторы (class, id)
  • JavaScript DOM-доступ (id, data-*)
  • Доступность (tabindex, title, lang)
  • Drag-and-drop (draggable)
  • Интерактивный контент (contenteditable)

class

<!-- Один класс -->
<div class="container">...</div>

<!-- Несколько классов (через пробел) -->
<p class="text text--bold text--red">Жирный красный текст</p>

<!-- BEM-именование -->
<div class="card">
  <h2 class="card__title">Заголовок</h2>
  <p class="card__text card__text--muted">Текст</p>
</div>
// JavaScript: работа с классами
const el = document.querySelector('.card');

el.classList.add('card--active');
el.classList.remove('card--active');
el.classList.toggle('card--active');
el.classList.contains('card--active'); // true/false
el.classList.replace('card--old', 'card--new');

id

<!-- Уникальный идентификатор (один на страницу!) -->
<header id="site-header">...</header>
<main id="main-content">...</main>

<!-- Якорная ссылка -->
<a href="#section-2">К разделу 2</a>
<section id="section-2">...</section>

<!-- Связь label и input -->
<label for="email">Email:</label>
<input type="email" id="email">
// Быстрый доступ
const header = document.getElementById('site-header');
// Или через CSS-селектор
const header = document.querySelector('#site-header');

Правило: id должен быть уникальным на всей странице. Для повторяющихся элементов используй class.

hidden

<!-- Полностью скрывает элемент (display: none) -->
<div hidden>Скрытый контент</div>

<!-- Скрыть до востребования через JS -->
<div id="error-msg" hidden>Произошла ошибка!</div>

<script>
  document.getElementById('error-msg').hidden = false; // Показать
</script>

<!-- hidden="until-found": скрыт, но доступен для поиска (Ctrl+F) -->
<div hidden="until-found" id="answer">
  Ответ на вопрос
</div>
<!-- Браузер раскроет элемент, если пользователь найдёт текст через поиск -->

inert

<!-- inert отключает ВСЁ взаимодействие с поддеревом -->
<main inert>
  <button>Неактивная кнопка</button>  <!-- Не кликается -->
  <input type="text">                 <!-- Не фокусируется -->
  <a href="#">Ссылка</a>              <!-- Не кликается -->
  <!-- Также скрыто от screen reader -->
</main>

<!-- Типичное использование: фон за модалкой -->
<script>
  function openModal() {
    document.querySelector('main').inert = true;
    document.querySelector('dialog').showModal;
  }

  function closeModal() {
    document.querySelector('main').inert = false;
    document.querySelector('dialog').close();
  }
</script>

data-* (пользовательские данные)

<!-- Хранение данных в HTML-элементах -->
<div class="user-card"
     data-user-id="42"
     data-role="admin"
     data-created="2025-01-15">
  <h3>Alice</h3>
</div>

<ul>
  <li data-price="1500" data-category="electronics">Наушники</li>
  <li data-price="3000" data-category="electronics">Клавиатура</li>
  <li data-price="500"  data-category="accessories">Чехол</li>
</ul>
// JavaScript: dataset API
const card = document.querySelector('.user-card');

// Чтение (data-user-id → dataset.userId)
console.log(card.dataset.userId);   // "42"
console.log(card.dataset.role);     // "admin"
console.log(card.dataset.created);  // "2025-01-15"

// Запись
card.dataset.status = 'active';
// → <div data-status="active">

// Удаление
delete card.dataset.role;
/* CSS: использование data-* атрибутов */
[data-role="admin"] {
  border-left: 3px solid red;
}

[data-category="electronics"] {
  background: #e3f2fd;
}

/* Отображение data-* через content */
[data-price]::after {
  content: ' — ' attr(data-price) ' руб.';
}

tabindex

<!-- tabindex="0": включить в Tab-порядок -->
<div role="button" tabindex="0">Кастомная кнопка</div>

<!-- tabindex="-1": фокус программно, не через Tab -->
<h2 id="section-title" tabindex="-1">Раздел</h2>

<!-- tabindex > 0: кастомный порядок (ИЗБЕГАТЬ!) -->

Подробнее: Фокус и клавиатурная навигация

title

<!-- Tooltip при наведении мыши -->
<abbr title="Hypertext Markup Language">HTML</abbr>

<button title="Удалить этот элемент">
  <svg><!-- иконка крестика --></svg>
</button>

<!-- НЕ используй title как замену aria-label -->
<!-- title не читается всеми screen reader-ами -->

Важно: title ненадёжен для доступности. Используй aria-label для screen reader.

draggable

<!-- Элемент можно перетаскивать -->
<div draggable="true" id="drag-item">Перетащи меня</div>

<div id="drop-zone" class="drop-zone">Зона для сброса</div>

<script>
  const item = document.getElementById('drag-item');
  const zone = document.getElementById('drop-zone');

  item.addEventListener('dragstart', (e) => {
    e.dataTransfer.setData('text/plain', item.id);
  });

  zone.addEventListener('dragover', (e) => {
    e.preventDefault(); // Разрешить drop
  });

  zone.addEventListener('drop', (e) => {
    e.preventDefault();
    const id = e.dataTransfer.getData('text/plain');
    zone.appendChild(document.getElementById(id));
  });
</script>

contenteditable

<!-- Элемент можно редактировать прямо на странице -->
<div contenteditable="true" id="editor">
  Этот текст можно редактировать прямо в браузере.
</div>

<script>
  const editor = document.getElementById('editor');
  editor.addEventListener('input', () => {
    console.log(editor.innerHTML); // Получить содержимое
  });
</script>

lang

<!-- Язык документа -->
<html lang="ru">

<!-- Язык отдельного элемента -->
<p>Привет! <span lang="en">Hello!</span></p>
<blockquote lang="de">Guten Tag!</blockquote>

lang влияет на:

  • Произношение screen reader
  • Автоматическую расстановку переносов
  • Выбор шрифта
  • Проверку орфографии

Другие глобальные атрибуты

<!-- style: инлайн-стили (избегать) -->
<p style="color: red;">Красный текст</p>

<!-- dir: направление текста -->
<p dir="rtl">مرحبا</p>  <!-- Арабский: справа налево -->

<!-- spellcheck: проверка орфографии -->
<textarea spellcheck="true"></textarea>

<!-- translate: разрешить автоперевод -->
<span translate="no">Brand Name</span>

<!-- autofocus: автоматический фокус при загрузке -->
<input type="search" autofocus>

<!-- popover: Popover API (новый) -->
<button popovertarget="menu">Меню</button>
<div id="menu" popover>Содержимое меню</div>

Частые ошибки

Ошибка Проблема Решение
Дублирование id getElementById вернёт только первый Уникальные id
title вместо aria-label SR может не прочитать aria-label для доступности
tabindex > 0 Ломает естественный порядок Tab Только 0 или -1
style вместо class Нет переиспользования, тяжело менять CSS-классы
hidden на видимом элементе Элемент скрыт, CSS не поможет hidden перезаписывает CSS display

Практика

  1. Создай карточки товаров с data-price, data-category и отфильтруй через JS
  2. Реализуй drag-and-drop с draggable
  3. Создай редактируемый блок с contenteditable
  4. Используй hidden и inert для модального окна
  5. Проверь lang атрибут на своей странице

Связанные темы

Ресурсы