Plumeria logoPLUMERIA

CSS Specificity

:not(#\#) for priority

Plumeria adds :not(#\#) to longhand property atomic class, increasing priority.

Override only that value

This ensures longhand properties always addtion to shorthand properties, regardless of merge order:

const styles = css.create({
  base: { margin: 10 },
  custom: { marginTop: 20 },
});
 
// Both produce the same result
css.props(styles.base, styles.custom);
css.props(styles.custom, styles.base);
 
// Result: margin 10px on all sides, except top is 20px

Normally, if a shorthand is below a longhand, it will override the all longhand, but if you raise its priority, the following CSS will return the same result:

atom1 {
  padding: 20px
}
 
atom2:not(#\#) {
  padding-top: 10px;
}

And this too

atom2:not(#\#) {
  padding-top: 10px;
}
 
atom1 {
  padding: 20px
}

This slightly increases bundle size, but is necessary to maintain for strict behavior.

Override all

Also, if a shorthand is written after a longhand in the same key, the previous longhand will be filtered and overridden.

const styles = css.create({
  base: {
    paddingTop: '20px', // filtered out
    padding: '10px' // override all padding-long-hand
  },
 });

As follows:

atom1 {
  padding: 10px
}

Enforcing with ESLint

These behaviors are complex even in normal CSS, so ESLint is effective for enforcing consistent behavior through rules. When the ESLint rule is enabled, in the key longhand properties will always after shorthand properties.

css.props() merge styles

Also, when css.props() has duplicate properties on its arguments, the style properties on the right always take precedence and duplicate properties on the left are filtered. In that case no filtered hash is generated.

const styles = css.create({
  base: { fontSize: 10 },
  custom: { fontSize: 16 },
});
 
// The right always wins
css.props(styles.base, styles.custom); // 16px
css.props(styles.custom, styles.base); // 10px

Generated as follows:

atom1 {
  font-size: 16px
}

Or:

atom2 {
  font-size: 10px
}

On this page