Let’s say I want to implement a text switch with CSS as outlined in https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way:
:root {
--release-version: "R0.0.0";
--build-version: "v0.0.0";
}
/* https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way */
#app-version {
position: relative;
}
#app-version-checkbox {
display: none;
}
#app-version-checkbox:checked + #app-version::after {
content: var(--build-version);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
}
<input id="app-version-checkbox" type="checkbox">
<label for="app-version-checkbox" id="app-version">R0.0.0</label>
which as you can see, is working.
But what I really want is to be able to update the versions:
//TODO: get versions from a config file or something
let releaseVersion = "R1.1.0"
let buildVersion = "v1.32.0"
window.onload = () => {
const root = document.querySelector(":root");
root.style.setProperty("--release-version", releaseVersion)
root.style.setProperty("--build-version", buildVersion)
//cannot change label text with CSS
document.querySelector("#app-version").innerHTML = releaseVersion
}
:root {
--release-version: "R0.0.0";
--build-version: "v0.0.0";
}
/* https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way */
#app-version {
position: relative;
}
#app-version-checkbox {
display: none;
}
#app-version-checkbox:checked + #app-version::after {
content: var(--build-version);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
}
<input id="app-version-checkbox" type="checkbox">
<label for="app-version-checkbox" id="app-version"></label>
and that doesn’t work.
So at first, I thought I’m just stupid and I’m not supposed to use innerHTML and that broke something, but even if I don’t do that:
//TODO: get versions from a config file or something
let releaseVersion = "R1.1.0"
let buildVersion = "v1.32.0"
window.onload = () => {
const root = document.querySelector(":root");
root.style.setProperty("--release-version", releaseVersion)
root.style.setProperty("--build-version", buildVersion)
}
:root {
--release-version: "R0.0.0";
--build-version: "v0.0.0";
}
/* https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way */
#app-version {
position: relative;
}
#app-version-checkbox {
display: none;
}
#app-version-checkbox:checked + #app-version::after {
content: var(--build-version);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
}
<input id="app-version-checkbox" type="checkbox">
<label for="app-version-checkbox" id="app-version">R0.0.0</label>
That still doesn’t work.
It’s the act of setting the variables that breaks the app, and if I inspect the snippet, I also notice that the override is weird, too:
I feel like I’m missing something obvious, but I just don’t see it.
What is going on, here?
(And yes, I do realise that since I’m now using JS anyway, I could just use a button, but I want to understand why this is happening.)
EDIT: doing it with CSS variables would also allow me to do things like
.release-version::after {
content: var(--release-version);
}
which would be nice.
>Solution :
CSS variables are copied as they are from where they are defined to the place where they are use var(--build-version).
When you do:
root.style.setProperty("--release-version", releaseVersion)
root.style.setProperty("--build-version", buildVersion)
It would result into this:
:root {
--release-version: R1.1.0;
--build-version: v1.32.0;
}
I mean you would expect that root.style.setProperty("--color", "red") results into --release-version: red; and not into --release-version: "red";. But the text has to be quoted, so you somehow need to add the quotes around the text.
You could utilize JSON.stringify to convert the string a textual representation with those quotes that are required, which would also allow to " in the contents of the value:
//TODO: get versions from a config file or something
let releaseVersion = 'R1.1.0"'
let buildVersion = 'v1.32.0"'
window.onload = () => {
const root = document.querySelector(":root");
root.style.setProperty("--release-version", JSON.stringify(releaseVersion))
root.style.setProperty("--build-version", JSON.stringify(buildVersion))
//cannot change label text with CSS
document.querySelector("#app-version").innerHTML = releaseVersion
}
:root {
--release-version: "R0.0.0";
--build-version: "v0.0.0";
}
/* https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way */
#app-version {
position: relative;
}
#app-version-checkbox {
display: none;
}
#app-version-checkbox:checked + #app-version::after {
content: var(--build-version);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
}
<input id="app-version-checkbox" type="checkbox">
<label for="app-version-checkbox" id="app-version"></label>
