Jss: [jss-nested] before/after pseudo elements do not seem to support functions as rule values

Created on 8 May 2018  路  10Comments  路  Source: cssinjs/jss

I'm running into an issue where assigning a function value to a property inside a pseudo element causes the following error:

Warning: Rule is not linked. Missing sheet option "link: true".

Strangely, it does not seem to repro with pseudo classes.

I've isolated a repo here: https://codesandbox.io/s/kor8kkzjzv

bug high plugin

Most helpful comment

When you use &:after it doesn't work an throws an error, but if you use &::after it works correctly.

All 10 comments

Looks like a bug related to jss-nested plugin.

Any chance you could look into it?

When you use &:after it doesn't work an throws an error, but if you use &::after it works correctly.

Interesting, that might be even a bug in the core, potentially CSSOM related, because of rule linking.

@kof Yea I'm digging into it. I also noticed that non-standard media queries also throw the same warning when assigned a function value:

"@media screen and (-ms-high-contrast: active)": {
    foo: {
        background: config => config.background
    }
}

My hunch is the two are related, unless its known that browser-specific media queries wont work. But the fact that the above repros without jss-nested makes me think both are related to core.

Good call @HenriBeck - I didn't try the correct syntax (bad habit on on my part)

Okay I tracked the issue down:

  • StyleSheet.link() retrieves the CSSRuleList from the renderer (and subsequently from the DOM) and passes it to RuleList.link.
  • RuleList.link() iterates over the CSSRuleList and tries to match them to StyleRules stored in the RuleList. If a match is found, the rule is linked, otherwise it is ignored.

The last part is where the issue is originating from. It seems that the CSSStyleRule and CSSMediaRule selectorText properties are getting mutated by the browser:

  • .foo-0-0-1:after becomes .foo-0-0-1::after
  • @media screen and (-ms-high-contrast: active) becomes @media not all

So RuleList.map is storing rules by one string (.foo-0-0-1:after) and the selectorText of the CSSStyleRule that is created from that StyleRule is mutated (.foo-0-0-1::after). This means JSS is not able to match the JSS rule with the CSS rule, which results in the error that the rule has not been linked whenever the stylesheet is updated.

I'm trying to think of a more bullet-proof way to associate JSS rules with CSS rules but I don't have any stellar ideas yet - let me know if you have any thoughts on it.

Yeah, thats what I assumed already, I think we should simply log warning in development mode when user uses single colon for pseudo elements. WDYT?

We can make the check in dev, so that we don't pay performance hit in production and we can make sure in production version this check is not even part of the bundle.

Luckily the list of pseudo elements is very small: https://developer.mozilla.org/de/docs/Web/CSS/Pseudo-elements

I've noticed it repros in the following cases:

  • pseudo elements defined with a single colon - :after
  • attribute selectors defined with a single quote - [aria-disabled='true']
  • un-recognizable media queries - @media screen and (-ms-high-contrast:active)

And maybe more? Since it isn't specific to pseudo elements and instead related to incorrect syntaxes in general, I want to propose updating the warning message to something more useful for tracking down which rules are not getting linked:

Rule is not linked: ".example-selector:after" - ensure CSS is properly formatted and sheet option "link: true".

We can then update all the documentation using pseudo-elements to use double colons so the documentation examples are correct.

Hows that sound to you? I'm happy to put up the PR.

Fixed in #857

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Telokis picture Telokis  路  3Comments

synchronos-t picture synchronos-t  路  4Comments

HenriBeck picture HenriBeck  路  4Comments

kof picture kof  路  4Comments

AleshaOleg picture AleshaOleg  路  3Comments