Атрибут data-*
В HTML 4 крайне не хватало возможности создавать свои собственные атрибуты для хранения значений. Зачем это надо? Вот несколько задач, где это может потребоваться.
- Создание всплывающих подсказок без применения скриптов.
- Определение стиля элемента на основе значения атрибута.
- Получение и изменение значений через скрипты.
В HTML5 появился новый универсальный атрибут, который можно добавлять к любому тегу. Правила написания атрибута простые:
- всегда начинаем с data-;
-     используем только латинские буквы, дефис (-), двоеточие (:) и подчёркивание (_).
 
CSS и JavaScript немного по разному обращаются к таким атрибутам, так что разберём примеры для них отдельно.
CSS
В CSS есть атрибуты тегов, при наличии какого-либо атрибута или заданного значения мы задаём необходимый стиль.
<div data-fluid>Содержимое</div>Теперь можем в стилях обратиться к этому элементу как div[data-fluid] и установить для него нужное оформление. В общем, это напоминает работу классов, поэтому не является какой-то уникальной или необходимой фичей. Так что полезнее задавать значения.
<div data-columns="3">Содержимое</div>В CSS после этого можем задавать разный стиль при различных значениях нашего атрибута data-columns.
div[data-columns=2] { width: 480px; }
div[data-columns=3] { width: 720px; }Опять же, это в какой-то мере является заменой классам, ничего ведь не мешает сделать классы с именами column-2, column-3 и добавлять их при необходимости.
Более изящной областью применения выступает включение функции attr(). Она получает значение заданного атрибута и вставляет его в стиль. Удобно это использовать для создания всплывающих подсказок. Текст пишем прямо внутри элемента, а вывод и оформление подсказки реализуем с помощью CSS.
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Всплывающая подсказка</title>
  <style>
   meter {
    position: relative;
   }
   meter:hover::after {
    content: attr(data-description);
    background: #ffe;
    padding: 5px;
    border: 1px solid #666;
    position: absolute;
    top: 20px;
   }
  </style>
 </head>
 <body>
  <p>Температура воды</p>
  <meter value="0" max="100" low="10" high="60" data-description="Низкая"></meter>
  <meter value="30" max="100" low="10" high="60" data-description="Нормальная"></meter>
  <meter value="80" max="100" low="10" high="60" data-description="Горячая"></meter>
  <meter value="100" max="100"  data-description="Кипяток"></meter>
 </body>
</html>В данном примере к элементу <meter> добавляется атрибут data-description содержащий необходимый текст для вывода. Само отображение происходит с помощью псевдоэлемента ::after и свойства content, значением которого как раз и выступает функция attr().
JavaScript
Если в CSS мы обращаемся к имени атрибута напрямую, указывая его полностью, то в JavaScript это делается через метод dataset. Само имя атрибута преобразовывается в переменную по следующим правилам:
- data- отбрасывается;
- любой дефис идущий перед буквой отбрасывается, а буква за ним становится заглавной.
На практике это выглядит так.
  data-description превращается в description.
  data-full-description превращается fullDescription.
  data-description-of-tag превращается descriptionOfTag.
Традиционный способ получить доступ к элементу и его атрибутам — задать идентификатор и обратиться к элементу через getElementById, как показано в примере ниже.
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>dataset</title>
 </head>
 <body>
  <div id="user" data-id="1234567890" 
       data-user="Вася Пупкин" 
       data-date-of-birth="01.04.1990">Пользователь</div>
  <script>
   var el = document.getElementById('user');
   id = el.dataset.id; // Получаем значение атрибута data-id
   user = el.dataset.user;
   dob = el.dataset.dateOfBirth; // Получаем значение атрибута data-date-of-birth
   el.dataset.ban = 'Нет'; // Назначаем новый атрибут data-ban и его значение
   console.log(user); // Выводим в консоль значение переменной user
   console.log(dob); // Выводим в консоль значение переменной dob
  </script>
 </body>
</html>Вначале добавляем к элементу идентификатор с уникальным значением. Затем получаем доступ к элементу через getElementById. Теперь мы можем обращаться к любым атрибутам data через метод dataset, причём не только получать, но и устанавливать значения. Храниться они будут до перезагрузки страницы или до установки нового значения.