Иногда для работы скрипта или стилей нужно прикрепить к элементу какие-то дополнительные данные, которые не относятся ни к одному из стандартных атрибутов HTML. Именно для такого случая существуют пользовательские атрибуты data-.
Формат простой: пишется data-, затем произвольное имя, например data-user-id или data-status. Значение такого атрибута можно прочитать из JavaScript или использовать в CSS-селекторах для стилизации по определённому условию — скажем, показать элемент по-другому, если у него data-status равен "active".
Плюс такого подхода в том, что разметка остаётся валидной — браузер не ругается на непонятные атрибуты, в отличие от попытки придумать собственный несуществующий тег. При этом данные хранятся прямо в HTML, рядом с элементом, которого касаются, а не где-то в отдельном JS-файле, что упрощает чтение кода.
Злоупотреблять data-атрибутами всё же не стоит — если данных много и они сложные, разумнее хранить их в JSON и подгружать отдельно. Но для несложных пометок, флагов и идентификаторов, которые нужны скрипту, это удобный и предсказуемый инструмент.
Подробнее про синтаксис и работу с такими атрибутами через JavaScript рассказано в статье про data-атрибуты на MDN.
В JavaScript такие атрибуты доступны через специальный объект dataset прямо на элементе, причём дефисное имя автоматически превращается в camelCase — data-user-id становится dataset.userId. Небольшая деталь синтаксиса, но она объясняет, почему в проектах принято придерживаться единого стиля именования таких атрибутов с самого начала.
В CSS такие атрибуты пригождаются для стилизации без лишних классов — селектор вида элемент с определённым значением data-атрибута позволяет менять внешний вид блока в зависимости от его состояния, не добавляя и не убирая классы через скрипт при каждом изменении.