data-*. Это — атрибуты, которые можно применять для удобного хранения в стандартных HTML-элементах различной полезной информации. Эта информация, в частности, может применяться в JavaScript и CSS.
Общие сведения
HTML-элементы могут иметь атрибуты, которые используются для решения самых разных задач — от предоставления данных ассистивным технологиям, до стилизации элементов.
<!-- Атрибут `class` можно использовать для стилизации в CSS, атрибут `role` используется ассистивными технологиями --> <div class="names" role="region" aria-label="Names"></div>
При этом не рекомендуется создавать собственные атрибуты, или применять существующие атрибуты такими способами, на которые они не рассчитаны.
<!-- `highlight` не является HTML-атрибутом--> <div highlight="true"></div> <!-- `large` не является допустимым значением для `width` --> <div width="large">
Это плохо по многим причинам. HTML-код оказывается неправильно сформированным. И хотя подобное может и не иметь реальных негативных последствий, это лишает разработчика тёплого чувства вызываемого тем, что он создаёт валидный HTML-код. Но главная причина того, что так поступать не следует, заключается в том, что HTML — это язык, который постоянно развивается. В результате, если некий атрибут сегодня в языке не применяется, это не значит, что в будущем ничего не изменится.
Правда, если кому-то нужно использовать подобные атрибуты, у него есть совершенно нормальный способ это делать. Речь идёт о создании собственных атрибутов, названия которых начинаются с префикса data-. С этими атрибутами можно совершенно спокойно работать, применяя их так, как нужно программисту.
Синтаксис
Возможность создавать собственные HTML-атрибуты и записывать в них данные может оказаться крайне полезной. Это, как вы понимаете, возможно благодаря атрибутам data-*. Именно для этого такие атрибуты и предназначены. Выглядит это так:
<!-- Этим атрибутам необязательно назначать значения --> <div data-foo></div> <!-- ...но они могут содержать значения --> <div data-size="large"></div> <!-- Тут мы имеем дело с HTML, поэтому надо экранировать HTML-код, который, возможно, решено будет записать в атрибут --> <li data-prefix="Careful with HTML in here."><li> <!-- Если надо - можно создавать длинные имена атрибутов --> <aside data-some-long-attribute-name><aside>
Эти атрибуты, именно из-за того, что они всегда начинаются с префикса data-, часто называют атрибутами data-* или data-атрибутами. При формировании имён этих атрибутов сначала идёт слово data, потом — тире (-), а потом — оставшаяся часть имени, устроенная так, как нужно разработчику.
Можно ли использовать атрибут, имеющий имя data?
Вот пример кода, в котором используется атрибут с именем data:
<div data=""></div>
Атрибут с таким именем, вероятно, никому не повредит, но его применение не позволит пользоваться JavaScript-инструментами, которые мы рассмотрим ниже. В этом примере разработчик, фактически, создаёт некий собственный атрибут, что, как уже было сказано, делать не рекомендуется.
Чего не стоит делать с атрибутами data-*
В таких атрибутах не стоит хранить содержимое, которое должно быть доступно ассистивным технологиям. Если некие данные должны быть видимы на странице, или должны быть доступны средствам для чтения с экрана, их недостаточно просто поместить в атрибут data-*. Такие данные должны появиться и в обычной HTML-разметке.
<!-- Эти данные не выводятся на странице, они недоступны ассистивным технологиям --> <div data-name="Chris Coyier"></div> <!-- Если нужен программный доступ к данным, но они не должны выводиться на странице, есть и другие способы... --> <div> <span class="visually-hidden">Chris Coyier</span> </div>
Вот материал о том, как скрывать элементы веб-страниц.
Стилизация элементов с использованием атрибутов data-*
В CSS можно выбирать HTML-элементы, основываясь на атрибутах и их значениях.
/* Выбрать элемент с таким именем атрибута, имеющим такое значение */ [data-size="large"] { padding: 2rem; font-size: 125%; } /* Выбор можно ограничить элементом, классом, или чем-то другим */ button[data-type="download"] { } .card[data-pad="extra"] { }
Это может показаться интересным. Для стилизации в HTML/CSS используются, в основном, классы. И хотя классы — это замечательный инструмент (они отличаются средним уровнем специфичности, с ними можно работать с помощью удобных JavaScript-методов через свойство элементов classList), элемент может либо иметь, либо не иметь некоего класса (то есть, класс в элементе либо «включен», либо «выключен»). При использовании атрибутов data-* в распоряжении разработчика оказываются и возможности классов («включено/выключено»), и возможность выбора элементов, основываясь на значении атрибута, которое он имеет на том же уровне специфичности.
/* Выбор элементов, у которых имеется указанный атрибут */ [data-size] { } /* Выбор элемента, атрибут которого имеет заданное значение */ [data-state="open"], [aria-expanded="true"] { } /* Селектор "начинается с", использование которого приведёт к выбору элементов, атрибут которых содержит "3", а так же - что угодно другое, начинающееся с 3 - вроде "3.14" */ [data-version^="3"] { } /* Селектор "содержит" указывает на то, что заданная строка должна содержаться где-то в значении свойства */ [data-company*="google"] { }
Специфичность селекторов атрибутов
Специфичность селекторов атрибутов такая же, как у классов. Специфичность часто рассматривают как значение, состоящее из 4 частей:
- Встроенный стиль
- ID
- Классы и атрибуты
- Теги
В результате, если представить себе значение специфичности для элемента, который стилизуется только с использованием селектора атрибута, то оно будет выглядеть так: 0, 0, 1, 0.
А вот ещё один селектор:
div.card[data-foo="bar"] { }
Он уже будет описываться значением 0, 0, 2, 1. Число 2 здесь появляется из-за того, что тут имеется и класс (.card), и атрибут ([data-foo="bar"]). А 1 здесь из-за того, что тут присутствует лишь один тег (div).
Вот, чтобы было понятнее, иллюстрированная версия этих рассуждений.

1 тег, 1 класс и 1 атрибут
У селекторов атрибутов специфичность ниже, чем у идентификаторов (ID), но выше, чем у тегов (элементов). Их специфичность равна специфичности классов.
Значения атрибутов, нечувствительные к регистру
Если нужно, чтобы селекторы выбирали бы атрибуты, значения которых могут содержать строки, записанные с использованием разных комбинаций строчных и прописных букв, можно воспользоваться вариантом селектора, нечувствительным к регистру.
/* Всё это соответствует следующему селектору <div data-state="open"></div> <div data-state="Open"></div> <div data-state="OPEN"></div> <div data-state="oPeN"></div> */ [data-state="open" i] { }
Такое поведение обеспечивает использование в селекторе символа i.
Вывод данных, хранящихся в атрибутах data-*
CSS позволяет извлекать значения атрибутов data-* и выводить их на странице.
/* <div data-emoji=":-)"> */ [data-emoji]::before { content: attr(data-emoji); /* Возвращает ':-)' */ margin-right: 5px; }
Примеры использования атрибутов data-* для стилизации элементов
Атрибуты data-* можно использовать для указания того, сколько столбцов должно быть у grid-контейнера. Вот HTML-код:
<div data-columns="2"> <div></div> <div></div> <div></div> <div></div> </div> <div data-columns="3"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div> <div data-columns="4"> <div></div> <div></div> <div></div> <div></div> </div>
Вот соответствующий CSS-код:
[data-columns] { display: grid; grid-gap: 1rem; padding: 1rem; margin: 0 0 1rem 0; } [data-columns] > div { height: 100px; background: white; } [data-columns="2"] { background: #64B5F6; grid-template-columns: repeat(2, 1fr); } [data-columns="3"] { background: #9CCC65; grid-template-columns: repeat(3, 1fr); } [data-columns="4"] { background: #FFB74D; grid-template-columns: repeat(4, 1fr); }
А вот — фрагмент результирующей страницы.

Grid-контейнеры, настройка которых производится с помощью атрибутов data-*
Поэкспериментировать с этим примером можно на CodePen.
Работа с атрибутами data-* в JavaScript
К значениям атрибутов data-* можно обращаться, как и к значениям других атрибутов, пользуясь методом getAtribute для чтения данных, и методом setAttribute для записи.
// Чтение значения атрибута let value = el.getAttribute("data-state"); // Запись значения атрибута. // В data-state записывается значение "collapsed" el.setAttribute("data-state", "collapsed");
Однако атрибуты data-* имеют и собственный особый API. Предположим, у нас есть элемент с несколькими атрибутами data-* (что совершенно нормально):
<span data-info="123" data-index="2" data-prefix="Dr. " data-emoji-icon=":-)" ></span>
Если имеется ссылка на этот элемент, то читать и записывать значения его атрибутов можно так:
// Чтение span.dataset.info; // 123 span.dataset.index; // 2 // Запись span.dataset.prefix = "Mr. "; span.dataset.emojiIcon = ";-)";
Обратите внимание на то, что в последней строке JS-кода используется запись имени атрибута в верблюжьем стиле. Система автоматически преобразует имена HTML-атрибутов, записанные в кебаб-стиле, в имена, записанные в верблюжьем стиле. То есть — data-this-little-piggy превращается в dataThisLittlePiggy.
Этот API, конечно, не такой удобный, как API classList, поддерживающий понятные методы вроде add, remove, toggle и replace, но это, всё же, лучше чем ничего.
В JavaScript можно работать и со встроенными в элементы наборами данных:
<img align="center" src="spaceship.png" data-ship-id="324" data-shields="72%" onclick="pewpew(this.dataset.shipId)"> </img> <h2><font color="#3AC1EF">JSON-данные в атрибутах data-*</font></h2> <ul> <li data-person=' { "name": "Chris Coyier", "job": "Web Person" } '></li> </ul>
А почему бы не записать в атрибут data-* JSON-данные? Ведь это всего лишь строки, которые можно отформатировать как валидные JSON-данные (учитывая кавычки и прочее). При необходимости эти данные можно извлечь из атрибута и распарсить.
const el = document.querySelector("li"); let json = el.dataset.person; let data = JSON.parse(json); console.log(data.name); // Chris Coyier console.log(data.job); // Web Person
Об использовании атрибутов data-* в JavaScript
Идея тут заключается в том, чтобы, пользуясь атрибутами data-*, размещать в HTML-коде данные, к которым можно обращаться из JavaScript для выполнения неких действий.
Распространённый вариант реализации этого сценария направлен на организацию работы с базами данных. Предположим, у нас имеется кнопка Like:
<button data-id="435432343">Like</button>
У этой кнопки может быть обработчик нажатия, выполняющий AJAX-запрос к серверу. Обработчик, если пользователь лайкнет что-то с помощью кнопки, увеличивает количество лайков в серверной базе данных. Обработчик знает о том, какую именно запись надо обновить, так как берёт сведения об этом из атрибута data-*.
Итоги
Вот, вот и вот — стандарты, связанные с селекторами атрибутов data-*. Здесь, на сайте Caniuse, можно узнать о поддержке атрибутов data-* браузерами. Если вы раньше не пользовались этими атрибутами, надеемся, этот материал дал вам пищу для размышлений.
Уважаемые читатели! Как вы применяете HTML-атрибуты data-*?
ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/490626/


Добавить комментарий