question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Incorrect selector splitting & broken styles

See original GitHub issue

Description

When a selector (in selectors css prop) contains a , (COMMA), it may be split incorrectly.

Reproduction & Expected behavior

For instance:

  1. within attribute selector & quoted
css({
  selectors: {
    '&:[data-list="a,b"]': { color: "green" },
  },
})

It generates:

._cd2tw1:[data-list="a{color:green}
._1xk4x6tb"]{color:green}
  1. With escaped COMMA (,) in attribute selector:
css({
  selectors: {
    '&:[data-list=a\\,b]': { color: "green" },
  },
})

It generates:

._5g05z7:[data-list=a\{color:green}
._7eu5q1b]{color:green}._3sn2xs{color:hotpink}

Expected behavior

A selector group should be split correctly. Escaped values are valid in selectors, so a COMMA (,) may appear outside of a quoted value, e.g:

.c[data-value=a\,b] {
  color: red;
}

In:

<h1 class="c" data-value="a,b">
  This is an example
</h1>

Actual behavior

It is split as rule.split(',') which incorrectly splits valid group selectors

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
eddywcommented, Jul 29, 2020

@kripod I’m not quite sure how to achieve this with a single RegExp 🤔 In any case, Otion doesn’t need to validate if a selector is valid or not, it just needs to know when to split a string.

From CSS syntax, these 👇 are known to create groups, so anything within a group shouldn’t be split (regardless if it’s valid or not) + escaped \, shouldn’t be used as split index:

const MATCHES = [
  /\"([^\"]*)\"?/g, // R_STR_DBL
  /\'([^\']*)\'?/g, // R_STR_SGL
  /\[([^\]]*)\]?/g, // R_SQUARE
  /\(([^\)]*)\)?/g, // R_PARENT
  /\{([^\}]*)\}?/g, // R_CURLY
  /\\,/, // R_ESCAPED_COMMA
];
function toPlaceholder(m) {
  return "_".repeat(m.length);
}
function getSelectors(rawInput) {
  let input = rawInput;

  MATCHES.forEach((r) => (input = input.replace(r, toPlaceholder)));

  const selectors = input.split(',')

  for (let i = 0, lastIndex = 0; i < selectors.length; i++) {
    const current = selectors[i]
    selectors[i] = rawInput.substr(lastIndex, current.length).trim()
    // Here you can validate selectors[i][0] === '&' or not
    lastIndex = lastIndex + current.length + 1;
  }

  return selectors
}

I know it’s ugly lol but it works and maybe it could be improved somehow 🤷‍♂️ Since it doesn’t validate, there are many ways of breaking this. For example, a CSS comment could be used as selector &:hover /* and it’d break everything. From w3c CSS syntax, the first thing the tokenizer does is consume comments and return nothing. It’s fairly simple to remove CSS comments with RegExp. Besides that, some selectors may be valid in some browsers but invalid in others (e.g: IE11), so this just assumes you know how to define selectors and you just want to split them separating them by COMMA (,).

If a selectors parser and validator is within the scope of otion to implement, then I’d suggest to have a look at:

  1. https://github.com/css-modules/css-selector-tokenizer
  2. https://github.com/fb55/css-what

Those are the only 2 projects I know that are up to date and seem to follow w3c specs (CSS syntax tokenizer & parser). However, I don’t know of any CSS-in-JS lib … or any library that actually does validation of CSS selectors 🤷‍♀️ . All assume you know what you’re doing 😅

0reactions
kripodcommented, Aug 2, 2020

Parsing is out of this project’s scope, so we should consider this to be mostly resolved with RegExp. I’ve expanded the docs, linking to this issue as a reference.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Invalid CSS selector causes rule to be dropped - Stack Overflow
Instead of trying to guess, risk guessing wrongly and breaking the rule in some way (e.g. by matching and styling all the wrong...
Read more >
CSS Code Splitting | Tan Li Hau
The motivation of CSS splitting arises when we try to split our CSS styles and lazily load the styles only when we actually...
Read more >
Selectors Level 4 - W3C
They are a core component of CSS (Cascading Style Sheets), which uses Selectors to bind style properties to elements in the document.
Read more >
invalid - CSS: Cascading Style Sheets - MDN Web Docs
The :invalid CSS pseudo-class represents any , , or other element whose contents fail to validate.
Read more >
How Do You Remove Unused CSS From a Site?
Here's what I'd like you to know upfront: this is a hard problem. ... I think the future of styling is an intentional...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found