Replies: 1 comment
-
I agree with @janhassel As mentioned in #15926 I am very much suffering from modifier overload and this only became apparent when working on So I would not stick to Swapping the BEM modifier for non-global utility classes also works e.g. With regards to your second suggestion, I think it moves closer to having SCSS that can be shared between Web Components and React. Currently Web Components uses the not much loved |
Beta Was this translation helpful? Give feedback.
-
This write-up is based on various discussions with @joshblack @rodet @daphoenix @lee-chase
Motivation
Carbon's CSS classes are not advertised as part of the public API and therefore can change between minor and patch releases. In reality though, development teams find themselves in situations where overwriting a certain style is necessary; whether it is temporary or intended to be permanent. When the CSS classes are addressed, the visual state of an application becomes volatile and may break with any update.
Some of Carbon's selectors are extremely specific and the only realistic option to overwrite them is by using
!important
.The naming of Carbon's CSS classes is currently inconsistent in many components which make them hard to predict.
A lot of BEM modifiers are applied to class names for basic states, like
--disabled
,--readonly
, or--selected
.Approach
An approach to address above stated problems could be to design selectors from
@carbon/styles
to be more attribute-focused.For example
.cds--btn:disabled
instead of.cds--btn--disabled
.To circumvent existing specificity issues as well as ones that might arise from this change in selector convention,
:where
could be used to reduce the specificity to 0.Examples
.cds--btn--disabled
.cds--btn:where(:disabled)
.cds--dropdown .cds--list-box__menu-item--active
.cds--dropdown :where([role="option"][aria-selected="true"])
.cds--text-input-wrapper--readonly .cds--text-input
.cds--text-input :where(input:read-only)
This would bring in the following advantages:
.my-coponent--selected
.my-component [role="option"][aria-selected="true"]
getByRole
philosophy but for style selectorsThinking one step further
We recently had a discussion whether or not Carbon should provide styles for standard HTML elements (like
<strong>
,<ins>
/<del>
,<q>
).On the one side this would reduce the overhead of having extremely simple components like
<UnorderedList>
and<ListItem>
which essentially just forward the native<ul>
and<li>
elements and add classes to it.The big issue with that would be that Carbon would start influencing the global scope and potentially interfere with other custom components or non-carbon contexts that build upon these native elements.
With a more attribute-focused approach like above, an opportunity for lower-level style mixins opens up. Currently each component's style is available as a mixin from
@carbon/styles
. The mixin includes all classes though:What if instead the top-level class is used to scope all selectors and the mixin only includes these inner ones:
This would allow developers to utilize Carbon's styles in three ways:
<UnorderedList><ListItem>One</ListItem></UnorderedList>
<ul class="cds--list"><li>Two</li></ul>
ul { @include carbon.list; }
<ul><li>Three</li></ul>
Challenges
Above example for a list is very simple and while similar components already exist and more might be added in the future, some of Carbon's components are also a lot more complex. To claim every single component can be styled purely by attributes and without classes would be naive and if tried would probably result in unmaintainable styles.
In that case, does it still make sense to move the top-level class of a component outside of its mixin or only do that for a specific set of components (would create inconsistency) or provide an optional argument for the mixin to override the top-level selector?
These might be two different topics but go hand-in-hand which is why I opted to combine them in this proposal.
I'm curious what everyone’s take on this is?
Beta Was this translation helpful? Give feedback.
All reactions