Глобальные атрибуты 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 |
Практика
- Создай карточки товаров с
data-price,data-categoryи отфильтруй через JS - Реализуй drag-and-drop с
draggable - Создай редактируемый блок с
contenteditable - Используй
hiddenиinertдля модального окна - Проверь
langатрибут на своей странице
Связанные темы
- Теги и атрибуты -- основы HTML-атрибутов
- Фокус и клавиатурная навигация -- tabindex подробнее
- ARIA атрибуты -- атрибуты доступности
- Семантическая разметка -- семантические элементы