Using :not pseudo-class across components

54 views Asked by At

I have a <Section> component:

const styles = theme => ({
  section: {
    backgroundColor: theme.colors.primary,
    color: theme.colors.white,

    '& a:not(.button)': {
      color: 'currentColor',
      textDecoration: 'underline',
    },
  },
});

And a <Button> component:

const styles = theme => ({
  button: {
    backgroundColor: theme.colors.light,
    color: theme.colors.dark,
    padding: theme.spacing.default,
  },
});

Basically, I'd like to use <Button> inside of <Section> and not have its color overridden.

I can't use & a:not($button) because it's in a different component.

3

There are 3 answers

0
Mike On

One possible solution I just tested is simply adding !important to the <Button> styles. It feels dirty...

0
Mike On

A better solution was to modify the selector to: a:not([class^="button"]), which will target JSS generated classes.

3
Oleg Isonen On

Don't override components styles implicitly using selectors. It is a very fragile approach, because it is breaking encapsulation and at some point it will break your styles.

You should either use color: inherit in the button component and let parent always define the color or use explicit overrides:

  1. Accept a class name in the child, define in parent a css rule with your color. (Good when static)
  2. Using theming (Good when static and predefined)
  3. Use function values and props http://cssinjs.org/json-api#function-values (Good if highly dynamic)