CSS позволяет хранить в переменных код javascript. И хотя такие переменные и вообще хранение js-кода могут показаться бессмысленными, но но тем не менее такой код может выполняться браузером как любой стандартный код JavaScript. Рассмотрим простейший пример:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
<style>
:root {
--script: console.log("Hello from CSS");
}
</style>
</head>
<body>
<script>
// получаем стили документа
const style = getComputedStyle(document.documentElement);
// получаем значение свойства --script
const script = style.getPropertyValue("--script");
// Выполняем код в свойстве --script
new Function(script)();
// альтернативный вариант выполнения
// eval(script);
</script>
</body>
</html>
Здесь свойство или переменная CSS --script хранит js-код, который выводит на консоль браузера сообщение.
Чтобы выполнить этот код, сначала получаем стили документа:
const style = getComputedStyle(document.documentElement);
Затем получаем среди этих стилей определение свойства --script:
const script = style.getPropertyValue("--script");
Далее выполняем код:
new Function(script)();
В качестве альтернативы для выполнения кода можно вызвать функцию eval():
eval(script);
В итоге на консоль браузера будет выведено соответствующее сообщение:
В качестве хранимого кода могут применяться более сложные выражения JavaScript. Например, используем конструкцию if:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
<style>
:root {
--script: if (x > 5) document.body.style.background = "blue";
}
</style>
</head>
<body>
<script>
let x = 10;
const style = getComputedStyle(document.documentElement);
const script = style.getPropertyValue("--script");
eval(script);
</script>
</body>
</html>
Здесь если значение переменной x больше 5, то окрашиваем пространство элемента body в синий цвет.
В каких ситуациях подобные возможности могут иметь практическую пользу? На первый взгляд таких ситуаций не так много. И навскидку единственное, что приходит в голову, это какое-то логгирование, которое так или иначе связано с настройками в CSS. Например, мы хотим логгировать минимальную ширину окна браузера, который используется пользователем. В этом случае мы могли написать что-то вроде следующего:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
<style>
:root{
--log: localStorage["minwidth"] = 0;
}
@media (min-width:500px) {
:root{
--log: localStorage["minwidth"] = 500;
}
}
@media (min-width:800px) {
:root{
--log: localStorage["minwidth"] = 800;
}
}
@media (min-width:1200px) {
:root{
--log: localStorage["minwidth"] = 1200;
}
}
</style>
</head>
<body>
<script>
window.onload = window.onresize =()=>{
const log = getComputedStyle(document.documentElement).getPropertyValue("--log");
eval(log);
};
</script>
</body>
</html>
Здесь в localStorage записываем элемент с ключом "minwidth", значение которого зависит от значений media-query. А в коде javascript
определяем обработчик событий window.onresize и window.onload, чтобы при загрузке страницы, а также при изменении ширины окна браузера значение в localStorage перезаписывалось.