styled-jsx icon indicating copy to clipboard operation
styled-jsx copied to clipboard

:global rules style elements outside of subtree

Open ivan-kleshnin opened this issue 3 years ago • 1 comments

Bug Report or Question (not sure)

What is the expected behavior?

According to docs :global rules affect elements INSIDE given subtree.

Please keep in mind that :global() styles will affect the entire subtree, so in many cases you may want to be careful and use the children (direct descendant) selector.

☝️ subtree is mentioned, so I don't expect it to style EVERY .test element in the app.

What is the expected behavior?

:global rules affect elements OUTSIDE given subtree at least in some cases.

How to reproduce

import * as React from "react"

export default function() : JSX.Element {
  return <>
    <div className="test">
      test1
    </div>
    <Component/>
    <div className="test">
      test3
    </div>
  </>
}

function Component() {
  return <>
    <div className="test">
      test2
    </div>
    <style jsx>{`
      :global(.test) {
        color: red
      }
    `}</style>
  </>
  // ^ expecting this style to affect a single .test element
  // I know that :global is unnecessary here, could be just `.test { ... }` 
  // Coded like that for demo purpose
}

Screenshot 2021-06-16 at 19 34 19

I'm not sure whether it's a bug or an unfortunate doc paragraph and hence my misunderstanding.

ivan-kleshnin avatar Jun 16 '21 16:06 ivan-kleshnin

The docs are pointing out that a rule like .foo :global(.test) would affect any .test element inside .foo, even if it's nested deep inside some other component, therefore you probably want to use .foo > :global(.test) instead.

SystemParadox avatar Aug 03 '21 10:08 SystemParadox

I think it's not a bug.

The style below:

:global(.test) {
      color: red
    }

will be transpiled to :

.test {
      color: red
    }

which means .test becomes a truly global selector. It will affect all tag or component with.test className in the whole app.

The doc says :global() styles will affect the entire subtree. It actually means div :global() will affect the entire subtree, because div :global(.test) will be transpiled to:

.div.jsx-12345 .test {
   color: red
}

so the doc suggests using div > :global() instead of div :global().

kejiweixun avatar Oct 28 '22 02:10 kejiweixun

I dunno. I've switched to TailwindCSS and I'm longer interested in CSS-in-JS approach in general. So closing the issue.

ivan-kleshnin avatar Oct 28 '22 06:10 ivan-kleshnin