Что за объект CSSStyleDeclaration и откуда он берется

Liudmila Mzhachikh
3 min readMay 11, 2018

Даже если вы совсем не новичок во фронтенде, вы могли ничего не слышать об этом объекте. А между тем вы постоянно с ним взаимодействуете.

Объект CSSStyleDeclaration — это объект, который возвращается, когда мы хотим получить значение стиля из JS:

el.style.opacity;
window.getComputedStyle(el).opacity;

Давайте рассмотрим подробнее, откуда он берется и что из себя представляет.

Любой язык состоит из синтаксических правил (грамматики) и лексики (словаря). Вспомните, как в школе вы делали синтаксический разбор предложения, определяли в нем подлежащее, сказуемое и т. д. Синтаксис определяет структуру предложения, чтобы оно не было бессмыслицей. Лексика — это слова языка, те самые, которые можно найти в толковом словаре.

И язык CSS не исключение. У него тоже есть синтаксис и лексика. Лексические и синтаксические правила описаны в его спецификации.

Лексический и синтаксический анализ производится браузером на этапе построения объектной модели.

Лексический анализ представляет собой разделение информации на токены, или лексемы. В обычном человеческом языке токенами бы были все слова. Лексическая грамматика (словарь) определяется регулярными выражениями для каждого токена. Эти выражения перечислены в спецификации. Вот некоторые из них:

comment                 \/\*[^*]*\*+([^/*][^*]*\*+)*\/
num [0-9]+|[0-9]*"."[0-9]+
nonascii [\200-\377]
nmstart [_a-z]|{nonascii}|{escape}
nmchar [_a-z0-9-]|{nonascii}|{escape}
name {nmchar}+
ident {nmstart}{nmchar}*
{num}{E}{M} {return EMS;}
{num}{E}{X} {return EXS;}
{num}{P}{X} {return LENGTH;}
{num}{D}{E}{G} {return ANGLE;}
{num}{R}{A}{D} {return ANGLE;}
{num}{M}{S} {return TIME;}
{num}{ident} {return DIMENSION;}
{num}% {return PERCENTAGE;}
{num} {return NUMBER;}

То есть проверяется, подходит ли значение CSS-свойства под ту или иную регулярку и в зависимости от этого относится к тому или иному типу.

Синтаксический анализ представляет преобразование куска CSS в такую древовидную структуру:

Здесь color: red — это CSS Declaration. Он включает свойство и значение.

А CSS Declaration Block — это совокупность всех свойств-значений у данного элемента.

Взаимодействие с этими блоками как раз и осуществляется с помощью объекта CSSStyleDeclaration. Вот как он определяется в спецификации:

The CSSStyleDeclaration interface represents a CSS declaration block, including its underlying state, where this underlying state depends upon the source of the CSSStyleDeclaration instance.

Он содержит CSS Declaration Block и методы взаимодействия с ним.

Точнее, он включает индексированный список всех поддерживаемых свойств + все пары ключ-значение. Попробуем вывести его в консоль:

const el = document.getElementsByTagName('div')[0];
const styles = window.getComputedStyle(el);
console.log(styles);

Получим такую структуру:

0:"animation-delay"
...
marginRight:"0px"
opacity:"0.5"

Ключ — это (почти всегда) имя CSS-свойства, записанное в CamelCase, значение строка, а точнее, объект DOMString. Поэтому при получении значения свойства возвращается строка

el.style.opacity = 0.3; // Это число
typeof el.style.opacity === 'string' // Да, это строка

Объект CSSStyleDeclaration предоставляет следующие методы:

CSSStyleDeclaration.getPropertyPriority() - возвращает значение флага importantCSSStyleDeclaration.getPropertyValue() - возвращает значение свойстваCSSStyleDeclaration.item() - возвращает имя свойстваCSSStyleDeclaration.removeProperty() - удаляет свойство из CSS Declaration BlockCSSStyleDeclaration.setProperty() - меняет существующее или создает новое свойство

Таким образом, CSSStyleDeclaration — это объект содержащий коллекцию пар CSS-свойств вида ключ-значения. Значения свойств в нем представлены в виде строк (DOMString). Он предоставляет методы работы со свойствами. В современных браузерах появился аналог объекту CSSStyleDeclaration — StylePropertyMap. Подробнее о нем можно прочитать здесь.

Материалы

Подписывайтесь на блоги:

Телеграм: frontend_thoughts

Instagram: lucy_frontend

--

--

Liudmila Mzhachikh

Frontend developer at Mail.Ru Group 👩‍💻, leader of moscowcss community, conference speaker 🎤, write about IT, channel: t.me/frontend_thoughts