CSS `content` property no longer renders encoded characters
Do you want to request a feature or report a bug?
bug
What is the current behavior?
Old behavior now must be done through string-literal instead of standard string.
If the current behavior is a bug, please provide the steps to reproduce and possibly a minimal demo or testcase in the form of a Next.js app, CodeSandbox URL or similar
The following no longer works in NextJS 9.1.1 to render a encoded character:
<style jsx>{`
.whatever-class:after { content: "\\0025B6"; };
</style>
We now have to do:
.whatever-class:after { content: ${`"\\0025B6"`}; }
What is the expected behavior?
Standard way of rendering content should still work.
Environment (include versions)
- OS: macOS Catalina
- Browser: Chrome 77
- styled-jsx (version): NextJS 9.1 bundled ([email protected])
Did this work in previous versions?
Yes
@HDTran have you tried with \\\\0025B6?
@giuseppeg i have the same issue; upgraded from 9.0.3 to 9.1.3 9.0.3 code that worked:
ul li::before {
content: "\\2022";
}

with 9.1.3

i have tried \\\\2022 and many other unicode options but nothing is working.
please advice ... until then rolling back
Sorry for the troubles folks! Can you create a testcase in codesandbox or repository? This seems to be working https://codesandbox.io/s/hello-world-n1y2y
@giuseppeg this is crazy ... i see your sandbox works however I forked it at https://codesandbox.io/s/hello-world-bpwbp and did nothing and it does not work:

is there a bad cdn version of 9.1.3?
I think the regression is due to https://github.com/zeit/styled-jsx/pull/577.
The following escape sequence is invalid and the code won't parse.
`
div:after {
content: '\0025B6';
}
`
The raw version of the string works of course:
String.raw`
div:after {
content: '\0025B6';
}
`
parses just fine.
To avoid using String.raw then you'd escape the \:
`
div:after {
content: '\\0025B6';
}
`
At this point the problem is that with https://github.com/zeit/styled-jsx/pull/577 we use the raw version of this string instead of the "cooked" one, hence the final styles string has \\0025B6 with double \\.
Initially I made this change because @lfades reported that
`content: '\`'`
didn't work. Honestly I don't remember why.
@lfades / @Timer shall we revert https://github.com/zeit/styled-jsx/pull/577 ?
@giuseppeg https://github.com/zeit/styled-jsx/pull/577 was a fix for a component like this one:
const InlineCode = ({ color, children }) => (
<code>
{children}
<style jsx>
{`
code {
color: ${color ? color : '#bd10e0'};
}
code::before {
content: '\`';
}
code::after {
content: '\`';
}
`}
</style>
</code>
)
That component was broken because of this line:
content: '\`';
@HDTran @jschimmoeller I think I found the answer to this issue: https://github.com/babel/babel/issues/1198#issuecomment-90905690
Basically you should use hex-based escapes otherwise the code won't parse and throw a syntax error when you use the octal format \0025B6. With \u25B6 it works just fine.
Maybe we can add this to the README? Not sure if it is worth trying to do the conversion ourselves i.e. allow you to use \\00 and we replace it with \u.
@giuseppeg i tried \\u25B6 with the same results

try with one backslash
@giuseppeg i sent over an hour trying many different backslash options but nothing is working; one, two, and even 4. I even went over to the babel link and tried some of their options but nothing works
@jschimmoeller you're right sorry I replied from my phone and didn't get a chance to test it. I guess then \\0025B6 is the right way to go, we just need to figure out what is the best fix for it.
I have got the same issue too, initially thought that it was an issue with the sass-parser, So does anyone have a workaround to this other than rolling back the nextjs version? I upgraded to 9.2 only last week.
I am using font awesome 5
code in next v7 which rendered the font right
content: "\f107";
code in next v9.2.0
content: "\f107"; --> output --> content: "\\f107";
tried the following combinations
content: "\\f107"; --> output --> content: "\\\\f107";
content: "\\00f107"; --> output --> content: ""\\\\00f107";
content: "\uf105"; --> output --> content: "\\f107";
Hi @jschimmoeller, Are you sure this worked in v9.0,3? I downgraded to even v9.0.0, but its still not fixed.

This doesnt work locally, but works fine on codesandbox.io https://codesandbox.io/s/next-js-font-issue-m0ncx
I have found a quick workaround for this until the issue is properly fixed, This will require the styles to be defined in SCSS.
I your SCSS file need to replace all occurrences of
content:'\XXX'; with --> content: unquote("'\XXX'");
Note the use of the SCSS function unquote() and the special way the quotes are defined.
You will also need to have a sass-loader imported on your package.json and next.config.js
I'm experiencing the same issues with encoded chars in pseudo content, as with the OP i'm using Next (all the way up to 9.4.5-canary.10, using styled-jsx 3.3.0), and the only way I can get consistent behaviour across SSR/CSR/SSG is the OP's string-literal solution of
.whatever-class:after { content: ${`"\ue815"`}; }
have tried all the other solutions and no matter how many slashes i add, there are bugs in at least one rendering approach.
Things I've tried are:
content: '\e815' - original approach, works for CSR but SSR/SSG (using flush()) the slash gets removed. Also if the char code starts \f the slash remains but then is treated as a line break in the returned string (in flush() when the string is extracted from the array)
content: '\ue815' - approach suggested on here, fixes SSR but breaks CSR
content: '\\e815' - approach suggested on here, fixes SSR but breaks CSR