Главная » Статьи » JavaScript для общения с CSS и Sass

JavaScript для общения с CSS и Sass

JavaScript для общения с CSS и Sass

От автора: JavaScript и CSS живут вместе более 20 лет. И все же было невероятно сложно обмениваться между ними данными. Конечно, были хорошие попытки. Но я имею в виду что-то простое и интуитивно понятное — что-то, что не связано со структурными изменениями, а скорее включает использование пользовательских свойств CSS и даже переменных Sass.

Пользовательские свойства CSS и JavaScript

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

В частности, мы можем использовать JavaScript с пользовательскими свойствами несколькими способами. Мы можем установить значение пользовательского свойства, используя setProperty:

document.documentElement.style.setProperty("--padding", 124 + "px"); // 124px

Мы также можем получить переменные CSS, используя в JavaScript getComputedStyle. Логика довольно проста: пользовательские свойства являются частью стиля, поэтому они являются частью вычисляемого стиля.

getComputedStyle(document.documentElement).getPropertyValue('--padding') // 124px

Что-то наподобие работы с getPropertyValue. Это позволило нам получить значение пользовательского свойства из встроенного стиля HTML разметки.

document.documentElement.style.getPropertyValue("--padding'"); // 124px

Обратите внимание, что пользовательские свойства ограничены. Это означает, что нам нужно получить вычисляемые стили из определенного элемента. Так как мы ранее определили переменную для :root, мы получаем их для элемента HTML.

Переменные Sass и JavaScript

Sass — это язык предварительной обработки, то есть он превращается в CSS еще до того, как становится частью веб-сайта. По этой причине доступ к ним из JavaScript так же, как и к пользовательским свойствам CSS, которые доступны в DOM в виде вычисляемых стилей, невозможен.

Нам нужно изменить процесс сборки, чтобы сделать это. Я думаю, что в большинстве случаев в этом нет особой необходимости, поскольку загрузчики часто уже являются частью процесса сборки. Но если это не так в вашем проекте, нам нужны три модуля, которые способны импортировать и переводить модули Sass.

Вот как это выглядит в конфигурации webpack:

module.exports = { // ... module: { rules: [ { test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"] }, // ... ] }
};

Чтобы сделать переменные Sass (или, в частности, в данном случае SCSS) доступными для JavaScript, нам нужно их «экспортировать».

// variables.scss
$primary-color: #fe4e5e;
$background-color: #fefefe;
$padding: 124px; :export { primaryColor: $primary-color; backgroundColor: $background-color; padding: $padding;
}

Блок :export – это магия WebPack, которая используется, чтобы импортировать переменные. Что хорошо в данном подходе, так как мы можем переименовать переменные, используя синтаксис camelCase, и выбрать то, что мы извлекаем.

Затем мы импортируем файл Sass (variables.scss) в JavaScript, предоставляя доступ к переменным, определенным в файле.

import variables from './variables.scss'; /* { primaryColor: "#fe4e5e" backgroundColor: "#fefefe" padding: "124px" }
*/ document.getElementById("app").style.padding = variables.padding;

Есть некоторые ограничения для синтаксиса :export, о которых стоит упомянуть:

Он должен быть на верхнем уровне, но может находиться в любом месте файла.

Если в файле он встречается более одного раза, ключи и значения объединяются и экспортируются вместе.

Если конкретный exportedKey дублируется, последний (по порядку в источнике) имеет приоритет.

exportedValue может содержать любой символ, который действителен в объявлении значений CSS (включая пробелы).

exportedValue не нужно заключать в кавычки, потому что он уже рассматривается как литеральная строка.

Есть много способов получить доступ к переменным Sass в JavaScript, которые могут вам пригодиться. Я склонен использовать этот подход для разделения контрольных точек. Вот мой файл breakpoints.scs, который я позже импортирую в JavaScript, чтобы иметь возможность использовать метод matchMedia() для создания согласованных контрольных точек.

// Sass variables that define breakpoint values
$breakpoints: ( mobile: 375px, tablet: 768px, // etc.
); // Sass variables for writing out media queries
$media: ( mobile: '(max-width: #{map-get($breakpoints, mobile)})', tablet: '(max-width: #{map-get($breakpoints, tablet)})', // etc.
); // The export module that makes Sass variables accessible in JavaScript
:export { breakpointMobile: unquote(map-get($media, mobile)); breakpointTablet: unquote(map-get($media, tablet)); // etc.
}

Анимация является еще одним вариантом использования. Длительность анимации обычно хранится в CSS, но более сложные анимации необходимо выполнять с помощью JavaScript.

// animation.scss
$global-animation-duration: 300ms;
$global-animation-easing: ease-in-out; :export { animationDuration: strip-unit($global-animation-duration); animationEasing: $global-animation-easing;
}

Обратите внимание, что я использую при экспорте переменной пользовательскую функцию strip-unit. Это позволяет мне легко парсировать вещи на стороне JavaScript.

// main.js
document.getElementById('image').animate([ { transform: 'scale(1)', opacity: 1, offset: 0 }, { transform: 'scale(.6)', opacity: .6, offset: 1 }
], { duration: Number(variables.animationDuration), easing: variables.animationEasing,
});

Я рад, что могу легко обмениваться данными между CSS, Sass и JavaScript. Совместное использование таких переменных делает код простым и чистым.

Конечно, есть несколько способов достичь одного и того же. В 2017 году Лес Джеймс поделился интересным подходом, который позволяет Sass и JavaScript взаимодействовать через JSON. Я могу быть предвзятым, но думаю, что подход, который мы рассмотрели здесь, является самым простым и наиболее интуитивным. Это не требует сумасшедших изменений в том, как вы уже используете и пишете CSS и JavaScript.

Автор: Marko Ilic

Источник: https://css-tricks.com

Редакция: Команда webformyself.