Today I realised that inline JavaScript inside the <head> can change the state of whatever comes in the <body> — even before the HTML is parsed, and without blocking it!
Instead of deferring the execution of JavaScript after the <body> is parsed (by using defer/type="module", waiting for the DOMContentLoaded event or by moving the JS before the closing </body> tag), one can instead use CSS variables to represent different state possibilities in the HTML. For example showing/hiding certain elements based on the state of a CSS variable.
<span style="display: var(--show-message, none)">
Should I be displayed?
</span>
An inline <script> in the <head> then configures the CSS variables according to some state by setting them on the <html> element. This script happens before the <body> is parsed, but once the parser reaches it, the variables already have the proper state and will therefore display the HTML accordingly.
<script>
if (localStorage.getItem('showHiddenMessage')) {
document.documentElement.style.setProperty("--show-message", 'inline');
}
</script>
I had two use cases for this today. One was to add dynamic behaviour to cached pages from the server without layout shifts or flash of out-of-sync HTML. The other was a client-side A/B testing setup without showing the wrong version to the user and without delaying first paint.
Modern browsers have two different runtimes (JS and CSS) that can talk to each other via CSS custom properties in HTML. The state transfer can happen before the HTML is fully parsed.
Very cool! 🤯