Setting text of pseudo element from JavaScript

I'm trying to set the text of a pseudo element (::before or ::after) through JavaScript.
h1 {
--text: "Hello World!";
--color: black;
}

h1::before {
content: var(--text);
color: var(--color);
}
h1 {
--text: "Hello World!";
--color: black;
}

h1::before {
content: var(--text);
color: var(--color);
}
Setting the color works as expected:
document.querySelector('h1').style.setProperty('--color', 'hotpink')
document.querySelector('h1').style.setProperty('--color', 'hotpink')
While trying to set the text makes the pseudo element disappear
document.querySelector('h1').style.setProperty('--text', 'Hello World from JS'))
document.querySelector('h1').style.setProperty('--text', 'Hello World from JS'))
js I know there are other ways I can solve this, but I'd like to understand why this does not work. Here is a codesanbox that reproduces the issue: https://codesandbox.io/s/clever-wind-q4r2vh
CodeSandbox
clever-wind-q4r2vh - CodeSandbox
clever-wind-q4r2vh
7 Replies
ἔρως
ἔρως14mo ago
it doesnt work because you are no longer setting the value to a string you are setting it to a list of properties separared by space you have to wrap it in quotes inside the string to make it easier for you to deal with escaping and other bs, you can just do this:
document.querySelector('h1').style.setProperty('--text', JSON.stringify('Hello World from JS')))
document.querySelector('h1').style.setProperty('--text', JSON.stringify('Hello World from JS')))
it is an horrible solution that works 99.9% of the time
Santiago García
Santiago GarcíaOP14mo ago
That did the trick. Thanks!
ἔρως
ἔρως14mo ago
you're welcome by the way, another solution to change the text is to use a data attribute that had the value you need, then you can change it by changing the attribute for example, your h1 could have a data-text="hi"
Santiago García
Santiago GarcíaOP14mo ago
Yes, that's what I ultimately went with. Was just frustated that the custom properties way didn't work.
ἔρως
ἔρως14mo ago
it works, but not the way you expected you can pass it a list of values like 1px 9px red the browser takes it and throws it into the value, without knowing what you are exactly wanting to do to pass it a string, you need to tell the browser to tell the css that it is a string, so, you need to wrap it in quotes to be a string
Santiago García
Santiago GarcíaOP14mo ago
Yeah, that makes sense.
ἔρως
ἔρως14mo ago
and be careful, because you can send multiple quoted strings separated by spaces for example, the content property just gobbles them together but the grid-template-areas (or whatever the name is) will interpret it as multiple values the easiest is the time consuming one you've done or, you can use sass with a map of values, that spits out the list of strings for you
Want results from more Discord servers?
Add your server