Одно из самых серьёзных противостояний в мире веб-разработки – CSS против JavaScript. У обоих есть свои достоинства, собственный синтаксис и идеи, иногда понять их может быть непросто. Но есть способы заставить их общаться и использовать достоинства каждого.
С позиции JavaScript для установки различных CSS-свойств HTML-элементу, требуется найти его в DOM и получить доступ к нему. После добавления стилей, у этого элемента появляется атрибут style
, который вы не стали бы, наверное, писать вручную.
Ещё один способ доступа к CSS-свойствам из JavaScript – использовать настраиваемые CSS-свойства, они также известны, как «CSS-переменные» (CSS variables), которые можно определять с помощью синтаксиса --
. Так:
:root {
--pagebackground: powderblue;
}
body {
background: var(--pagebackground);
}
Это «переменные», поэтому их можно неоднократно использовать в таблице стилей.
Получить к ним доступ и управлять значениями этих переменных можно с помощью JavaScript. В этом примере настраиваемое CSS-свойство устанавливается для корневого элемента документа. Его можно прочитать так:
let bg = getComputedStyle(document.documentElement).
getPropertyValue('--pagebackground');
И его можно установить с помощью JavaScript, получив доступ к стилю корневого элемента (или вообще любого другого элемента с настраиваемыми свойствами), так:
document.documentElement.style.setProperty('--pagebackground', 'firebrick');
Но самое выдающееся во всей этой истории то, что используя возможности JavaScript, можно предоставить CSS то, к чему он не может получить доступ. Например, CSS не может прочитать координаты курсора мыши, а JavaScript может.
Для начала, в CSS надо определить пару свойств --mouse-x
и --mouse-y
, а также установить им начальные значения – 0
:
:root {
--mouse-x: 0;
--mouse-y: 0;
}
Затем, в JavaScript следует добавить документу обработчик mousemove
. Тогда при движении курсора можно получать его координаты и управлять этими двумя CSS-свойствами с помощью JavaScript:
let root = document.documentElement
document.addEventListener('mousemove', e => {
root.style.setProperty('--mouse-x', e.x);
root.style.setProperty('--mouse-y', e.y);
});
В-общем, дело нехитрое. Поскольку настраиваемые CSS-свойства реагируют на движение мыши и изменяют свое значение, теперь можно, например, показать кружок и заставить его двигаться вслед за курсором, так:
HTML:
<div id="ball"></div>
CSS
:root {
--mouse-x: 0;
--mouse-y: 0;
}
#ball {
width: 20px;
height: 20px;
background: white;
border-radius: 100%;
transform: translate(
calc(calc(var(--mouse-x) - 10) * 1px),
calc(calc(var(--mouse-y) - 10) * 1px)
);
}
Здесь некоторые пояснения к CSS:
- ширина и высота
DIV
установлены равными 20 пикселей, а фон – белый - добавление
border-radius: 100%
гарантирует, что из квадрата получится круг. - затем используется
transform: translate
, чтобы позиционировать круг на экране. Это может быть что-то вродеtransform: translate (200px, 300px)
, чтобы расположить наш шар на 200 пикселей по горизонтали и 300 пикселей по вертикали относительно левого верхнего угла. - поскольку JavaScript возвращает для настраиваемого CSS-свойства числовое значение, его необходимо преобразовать в пиксели, умножив на
1px
. - так как размер шара составляет 20 пикселей, то чтобы поместить его центр в точки
--mouse-x
и--mouse-y
, нужно вычесть из координат 10.
Этот трюк позволяет выполнять сложные вычисления, считывать состояние браузера и внешнее взаимодействие с ним в JavaScript, затем передавать результат в CSS и изменять его.
Sharing data between CSS and JavaScript using custom properties.