I have a question regarding how it's possible to access CSS variables that are not inline/exist on the same page. I.e. the CSS variables are defined in a custom CSS file.
I have a page that has an image with 3 inputs. One for controlling a background color, blur, and padding. As the sliders/colors is picked, the image and background color are adjusted accordingly. I have already written the javascript and it works but I am unsure on the exact reason why. I am trying to read through the documentation on mozilla developer documentation but my question was not answered: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables
My question is as follows:
:root
pseudo class in my custom CSS filedocument.documentElement.style.setProperty
function in javascriptI understand that the documentElement
by default returns the HTML element and you can find all children elements using this. And CSS variables are modified using the .style.setProperty
function. So how is it that I can simply change the CSS variables I defined by selecting the global HTML element?
Is it because the :root
pseudo class makes these variables available to be modified at the HTML element level? I am trying to wrap my head around how these CSS variables can be accessed and modified at a more concrete level. If the answer is as simple as css variables defined at the root pseudo class levels are able to be modified by accessing the HTML element, that would confirm my suspicions.Otherwise if you can dig into a little more detail, that would be helpful.
Link to Plunker: http://plnkr.co/edit/FdlCW7Ym5m8odaK05u4g?p=preview
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Scoped CSS Variables and JS</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h2>Update CSS Variables with <span class='hl'>JS</span></h2>
<div class="controls">
<label for="spacing">Spacing:</label>
<input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px">
<label for="blur">Blur:</label>
<input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">
<label for="base">Base Color</label>
<input id="base" type="color" name="base" value="#ffc600">
</div>
<img src="https://source.unsplash.com/7bwQXzbF6KE/800x500">
<script>
const inputs = document.querySelectorAll('.controls input');
function handleUpdate() {
const val = this.dataset.sizing || '';
document.documentElement.style.setProperty(`--${this.name}`,this.value + val);
}
inputs.forEach(currentItem => {
currentItem.addEventListener('change', handleUpdate);
currentItem.addEventListener('mousemove', handleUpdate)
});
</script>
CSS:
/* Styles go here */
:root {
--base: #ffc600;
--spacing: 10px;
--blur: 10px;
}
/*
misc styles, nothing to do with CSS variables
*/
img {
padding: var(--spacing);
background: var(--base);
filter: blur(var(--blur));
}
.hl {
color: var(--base);
}
body {
text-align: center;
background: #193549;
color: white;
font-family: 'helvetica neue', sans-serif;
font-weight: 100;
font-size: 50px;
}
.controls {
margin-bottom: 50px;
}
input {
width:100px;
}
Your hypothesis is correct: CSS custom properties specified with the :root
-selector, are assigned to the html
-element. And because of the inheritance, they are available for all the children of <html>
.
From https://developer.mozilla.org/en-US/docs/Web/CSS/:root
The :root CSS pseudo-class matches the root element of a tree representing the document. In HTML, :root represents the
<html>
element and is identical to the selector html, except that its specificity is higher.
From https://developer.mozilla.org/en-US/docs/Web/API/Document/documentElement
Document.documentElement returns the Element that is the root element of the document (for example, the
<html>
element for HTML documents).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With