digdir / designsystemet

Designsystemet
https://designsystemet.no
MIT License
68 stars 34 forks source link

Use data attributes for css #2065

Open Barsnes opened 1 month ago

Barsnes commented 1 month ago

This is a suggestion, and needs to be investigated

Today we have explicit classes for sizes, etc. - but it would be nice if we can have a good developer API for this, even if our users use just CSS classes.

A proposal is to use data attributes like we use props in react, so things like size and variant are the same across all components. This is also how we will do theming, so it plays nicely with that,

Given a button we want to be small. secondary variant and danger color, we would do this:

<button class="fds-btn" data-size="sm" data-variant="secondary" data-color="danger">
button
</button>

Our css would look like this:

.fds-btn { ... }
.fds-btn[data-size="sm"] { ... }
.fds-btn[data-variant="secondary"] { ... }
.fds-btn[data-color="danger"] { ... }

A big plus for doing this is that our users only need to set one class to define the component. It is easy to select, and change a data attribute with javascript, easier than classes:

let value = el.getAttribute("data-size");
el.setAttribute("data-state", "sm");

CSS Trick has a great article about this

Barsnes commented 1 month ago

This might be related to #1952

mimarz commented 1 month ago

Do we have an example of other css frameworks that have done this approach?

Barsnes commented 1 month ago

Do we have an example of other css frameworks that have done this approach?

I don't know of any framework that does this currently, I did a quick look and did not find any. Another small plus I thought of, is also the lowered risk of adding multiple classes of the same type, ex.: two variant classes

poi33 commented 1 month ago

If the project wants to eventually move to web components I think this could be done. The attributes would not have to be data attributes, they could simply be any self defined ones in a web component.

I guess most systems like to separate code and styling. Dom attributes deal with everything except styling while the classes are used for styling.

poi33 commented 1 month ago

Most web component + design systems don't use this after some searching. But I found some that do:

They all attach it to the root of the web component with a attribute selector :host([variant="secondary"]) button type selectors

Microsoft fluentUI also does this: https://github.com/microsoft/fluentui/blob/master/packages/web-components/src/button/button.styles.ts#L311C5-L311C46 But they have a different solution to generate a stylesheet for each component 🤯

Barsnes commented 1 month ago

It seems like React Aria quite a bit image ref