Что такое атрибуты HTML и какие они бывают?

JuniorHTML #html #attributes

Вопрос

Что такое HTML-атрибуты, чем глобальные атрибуты отличаются от специфичных для конкретного тега, и как работают булевы атрибуты?

Короткий ответ

Атрибуты — это пары имя="значение" внутри открывающего тега, задающие дополнительные свойства элемента. Глобальные атрибуты (id, class, data-*, tabindex, style, title) применимы к любому тегу; специфичные валидны только для определённых элементов (href только у <a>/<link>, src только у медиа-тегов). Булевы атрибуты (disabled, checked, required) включаются самим фактом присутствия в разметке, а не значением.

Подробный ответ

Глобальные атрибуты доступны на любом HTML-элементе:

  • id — уникальный идентификатор в пределах документа, используется для якорей, label[for], CSS/JS-селекторов.
  • class — список классов для CSS и JS, может повторяться на многих элементах.
  • data-* — произвольные data-атрибуты для хранения кастомных данных, доступны в JS через element.dataset.someName (camelCase из data-some-name). Не влияют на рендеринг и валидны в HTML5 стандарте.
  • tabindex — управляет порядком и возможностью фокусировки клавиатурой: 0 — элемент встраивается в естественный порядок табуляции, -1 — фокусируется программно (el.focus()), но выпадает из Tab-обхода, положительное число — задаёт явный (и обычно нежелательный, ломающий естественный порядок) приоритет.
  • title, style, hidden, contenteditable, draggable, lang, aria-* — тоже глобальные.

Специфичные атрибуты валидны только для своих тегов: href/target/rel у <a>, src/alt/srcset у <img>, type/value/placeholder у <input>. Использование их вне контекста невалидно и не имеет эффекта.

Булевы атрибуты — особая категория: их наличие само по себе означает true, а значение (если указано) не имеет значения по спецификации.

  • <input disabled> — поле отключено.
  • <input disabled="disabled">, <input disabled="">, <input disabled="false"> — все три варианта тоже означают "отключено", потому что HTML-парсер смотрит на присутствие атрибута, а не на его строковое значение.
  • Чтобы включить/выключить такой атрибут через JS правильно, используют el.disabled = true/false или el.toggleAttribute('disabled'), а не setAttribute('disabled', 'false').

Пример

<button
  id="submit-btn"
  class="btn btn-primary"
  data-testid="submit"
  data-user-id="42"
  tabindex="0"
  disabled
>
  Отправить
</button>

<script>
  const btn = document.getElementById('submit-btn');
  console.log(btn.dataset.userId); // "42"
  btn.disabled = false; // корректный способ снять булев атрибут
</script>

Дополнительные вопросы

  • Чем dataset отличается от произвольных JS-свойств объекта элемента?
  • Почему setAttribute('disabled', 'false') не включит поле обратно?
  • Как tabindex="-1" используется в связке с управлением фокусом в SPA?