microsoft / fluentui-blazor

Microsoft Fluent UI Blazor components library. For use with ASP.NET Core Blazor applications
https://www.fluentui-blazor.net
MIT License
3.87k stars 376 forks source link

docs: explain design tokens and styling #1731

Closed tbasallo closed 7 months ago

tbasallo commented 8 months ago

I think one of the biggest hurdles people face using this library is design and customization. I also understand that that is not a complete accident. But hopefully it's also understood that there are other requirements that apps have that do not make this library unusable, because I think it's great.

It's unclear from the docs how does one add some custom colors outside of the main design system styling. Or what's the best practice in this component library.

I also realize that maybe I (and others) are coming from a less strict design environment that this completely opposed to. Which I can understand...

For example, I have a button/anchor that MUST BE green. There's a reason and it has to happen. But I can't seem to know what the best way to that us, so I ended up doing this:

<FluentAnchor Href="@Url" Class="bg-green">GOOD JOB</FluentAnchor>
//CSS
fluent-anchor.bg-green::part(control) {    
    color: #fff;
    --neutral-fill-rest: green;
}

But is the best way> It works, but I rather do something that the system supports and falls into its design language.

As a side not, I was able to use Fill with fluent-badge in a more intuitive way, though very similar to the above:

<FluentBadge Fill="success">val23</FluentBadge>
//CSS
fluent-badge {
    --badge-fill-success: green;
    --badge-color-success: #fff;
}

The badge seems like it wants to support my various badge colors (makes sense I think) whereas anchor/button, maybe not.

While I love the library and want to use it for Blazor projects going forward, I am concerned with how stuck I will be with the minimal amount of styling possible.

vnbaaij commented 7 months ago

I think one of the biggest hurdles people face using this library is design and customization. I also understand that that is not a complete accident. But hopefully it's also understood that there are other requirements that apps have that do not make this library unusable, because I think it's great.

It's unclear from the docs how does one add some custom colors outside of the main design system styling. Or what's the best practice in this component library.

I also realize that maybe I (and others) are coming from a less strict design environment that this completely opposed to. Which I can understand...

The design system we use (Fluent) does not really offer a lot of guidance or options to 'color outside of the lines'. That is the main reason we don't give (and have) much docs on how to do that. Doing and/or enabling that is also not a goal of this library, so we don't give much focus or attention to that (we are just a very small team with limited capacity). We (as a Microsoft library) try to follow our own (as Microsoft developed) design system as good as possible.

I fully understand that you might sometimes need to break out of that because of your company's rules, designer demands or whatever.

For example, I have a button/anchor that MUST BE green. There's a reason and it has to happen. But I can't seem to know what the best way to that us, so I ended up doing this:

<FluentAnchor Href="@Url" Class="bg-green">GOOD JOB</FluentAnchor>
//CSS
fluent-anchor.bg-green::part(control) {    
    color: #fff;
    --neutral-fill-rest: green;
}

But is the best way> It works, but I rather do something that the system supports and falls into its design language.

We do not have a specific 'best way'. If it works for you and your needs then great! In general, if you need to change these kinds of settings, going with CSS adjustments is the way to go. The library heavily uses shadow dom so changing parts and CSS variables is generally ok. Just be aware that setting variables can have effects somewhere else in you app as well.

As a side note, I was able to use Fill with fluent-badge in a more intuitive way, though very similar to the above:

<FluentBadge Fill="success">val23</FluentBadge>
//CSS
fluent-badge {
    --badge-fill-success: green;
    --badge-color-success: #fff;
}

The badge seems like it wants to support my various badge colors (makes sense I think) whereas anchor/button, maybe not.

That is exactly it. In the badge design, the developers made some entries for doing just that. Buttons are not that flexible.

While I love the library and want to use it for Blazor projects going forward, I am concerned with how stuck I will be with the minimal amount of styling possible.

I think that is something that comes with choosing a specific design system. Yes, that come with some 'restrictions', but it also provides you with consistency and logical defaults. It is just a different thing than implementing and working with a CSS framework (like Bootstrap or Bulma)

vnbaaij commented 7 months ago

After thinking about this some more, I believe for the case you described (and a lot of others as well) we do have a solution out-of-the-box. This is basically what the DesignToken implementation is for.

I don't have time now, but will post an example here later.

vnbaaij commented 7 months ago

The example is given in https://www.fluentui-blazor.net/DesignTokens in the Using design tokens from code section.

The page describes the most common used design tokens. In the library we have made all of the design tokens available. You can inject them into your component ant then target specifc elements in you component with them. As you can see in the example code, a FluentButton is given a different accent color:

await AccentBaseColor.SetValueFor(ref2!.Element, "#185ABD".ToSwatch());

The implementation requires to always use a .ToSwatch when a color is involved. An important thing to note here is that the current design token implementation fro the web components (which is what we expose and use) is that colors are always handeled by the Adaptive color system to ensure contrast. This means you will almost never get the exact color you specify and there is nothing we can do about that at the moment.

By using the design tokens, you automatically have:

  1. the components handles dark/light switching
  2. certainty the change only targets the element you specify
  3. conformity with contrast requirements (WCAG / a11y)
vnbaaij commented 7 months ago

I'm moving this over to the discussion area and closing this here