Shoelace: Dark theme experiment, design token thoughts, and theming improvements

Created on 21 Mar 2021  ยท  12Comments  ยท  Source: shoelace-style/shoelace

We already have a dark theme but, based on user feedback, I'd like to experiment a bit more before calling it stable.

Currently, the dark theme uses the same color tokens as the base (light) theme. The idea was that --sl-color-gray-100 would always be light and --sl-color-gray-900 would always be dark. In other words, the color scale never changes.

The problem with this approach is that themes require more than just token changes. Take a look at the current dark theme: https://github.com/shoelace-style/shoelace/blob/next/src/styles/dark.scss

There are many component-specific selectors that become harder to manage as components evolve and new ones are added. Furthermore, third-party components that use the design tokens have to be styled independently.

This experiment will change the context of the color scale for dark themes, effectively reversing the lightness of each color so dark themes can be crafted solely from design token changes. This is a lot like inverting the light theme, but color tokens will be tweaked for better aesthetics.

TL;DR โ€“ The goal of this experiment is to produce a dark theme that _only_ modifies color tokens while enabling the dark theme to apply to all components, including those made by third-parties that utilize Shoelace's design tokens.

I also want to use this experiment as a vehicle for exploring design token improvements (see #423) and other general theming improvements (#437, #438).

themes

Most helpful comment

Another important thing to call out with the current dark theme approach is that it uses a number of light DOM styles. This is problematic for users who nest themed components inside of their own shadow roots (see #390).

This won't be an issue if we can make theming depend solely on design tokens. I think this is the approach @mcjazzyfunky was suggesting early on and would like to acknowledge that. ๐Ÿ˜„

All 12 comments

Another important thing to call out with the current dark theme approach is that it uses a number of light DOM styles. This is problematic for users who nest themed components inside of their own shadow roots (see #390).

This won't be an issue if we can make theming depend solely on design tokens. I think this is the approach @mcjazzyfunky was suggesting early on and would like to acknowledge that. ๐Ÿ˜„

Just a few comments as I have noodled around a little with alternative dark themes. Just in case that your experiment will be successful, the following three minor changes might be useful:

  • renaming --sl-color-black to --sl-color-front (or whatever, but should be a semantic name)
  • renaming --sl-color-white to --sl-color-back (or whatever, but should be a semantic name)
  • [Edit]: Renaming --sl-color-gray to --sl-color-neutral would also be nice (=> semantic name)

  • currently, default buttons and dropdowns use a grayish text color, for example

      .button.button--default {
        color: var(--sl-color-gray-600);
      }
    

    this is not optimal regarding light vs dark themes or regarding providing proper accessible color contrasts.
    Maybe a new token similar to --sl-primary-text could be useful [Edit - changed my mind a bit] ~(I personally would just use --sl-color-black, or whatever it will be called then ... I personally (and I guess most others with bad eyes) do not like grayish text colors at all)~.

To visualize some of the ideas behind this experiment, please find below a desktop-first-and-only protoype of a shoelace theme designer (=> "prototype" as in "don't expect anything to work" :wink:).
This theme designer is inspired by an earlier work by @frederik-jatzkowski, thanks for that Frederik). In that theme designer you'll find a button invert theme which has only the purpose to visualize one of the base ideas behind this "dark theme experiment" (this button will be removed later).
Very important: In the select box "Base theme" you'll find two non-optimized auto-generated dark themes, which are of course only placeholders as long as there are no other compatible dark themes available (they are just the result of modifying the shoelace light theme a bit with the theme designer). Also the "Light (level AA)" theme is just a fake/placeholder.
Ideas behind this theme designer:

  • All two (or four, or six ... light/dark + plus maybe some day accessibility level AA + level AAA) base themes will be hand-crafted (none of these "base themes" will be the result of using this theme designer).
  • The output of this theme editor will ALWAYS be a modification of one of the base templates - means the output does not only depend on the color parameters that can be configured in the theme designer itself.

https://shoelace-theme-designer.vercel.app/

Here is for example a bootstrapish Shoelace light theme.

Wow @mcjazzyfunky, that looks awesome! ๐Ÿ‘๐Ÿ‘

This is really, really nice. Let's work on #413 (since it will add more core design tokens) and revisit this afterwards.

@mcjazzyfunky is this something you'd be interested in contributing to the project as an official theme generator? I could see something like it being hosted at themes.shoelace.style or maybe even as a special page in the docs.

[...] is this something you'd be interested in contributing to the project as an official theme generator?

@claviska
Sure, but please be aware that - like I've already said - it's just a prototype yet. The current feature set is okay, I guess (except for not showing all components yet), but under the hood there's still a lot to do (especially I've to switch to a common UI library - like Preact or whatever ... currently I am using an experimental UI lib, which has to be replaced) ... anyway, when #413 will be done and you'll find some time, we can discuss more.

Absolutely. I have ideas to expand on it โ€” just feeling out whether you'd be open to sharing it with the community. ๐Ÿ™Œ

+1 for using just the Design Tokens instead of parts, parts are great for specific overrides but other than that they seem limiting :)

+1 also for the Theme Generator, which could also be very useful in order to test how flexible Shoelace is in terms of "adapting to a style" or design system, if this is something that matters for the scope of this project of course. Given how flexible and agnostic WCs are, I believe having the ability to use the same components in multiple projects which adopt different Design Systems [by tweaking them in order to resemble the rest of the projects' styles] would be great!

+1 for using just the Design Tokens instead of parts, parts are great for specific overrides but other than that they seem limiting :)

From my comment here:

We need to be careful not to get crazy, though, as we can quickly end up in variable hell.

I feel pretty strongly about _not_ being able to customize individual components with design tokens. Those are best suited for high-level changes that components can share, but most component-specific customizations should be done with parts. (There's more explanation about this in the comment I linked above.)

Yeah I see your point, the Bootstrap example you made was pretty clear. Also I've been looking at other WC kits these days (eg. Ionic) and it seems that most of them indeed offer a decent amount of customization via CSS Variables, but not for everything. Because obviously there'd be the need to just create an infinite amount of variables to support any kind of customization, and you'd never be fully satisfied I guess.

Parts seem indeed the optimal solution for customizing in detail, it's a pity Constructable Stylesheets are not yet adopted by all browsers.

Actually this "issue" made me think about how I'm structuring my apps (since I'd like to build entire apps with a tool like Lit) and I'm thinking about not using Shadow DOM for my own components (unless they're leaf nodes, or part of an UI Kit)! Let's see where it goes :) Thanks!

@UserGalileo I think it's pretty reasonable to build app-level components without Shadow DOM since you know the general lay of the land in terms of styling and markup structure โ€” with the escape hatch that you can always switch it on if you need a more reusable/encapsulation behavior.

@jaredcwhite Yep honestly I'm not particularly concerned about styles but more about losing Slots and the fact that I once saw the argument made by Lit's creator that removing it would not be a best practice. But I think it's fair to say that you can remove it when talking about app-level components, and although it's not the same thing I'll experiment using "render props" instead of slots!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jaredcwhite picture jaredcwhite  ยท  6Comments

lamplightdev picture lamplightdev  ยท  7Comments

SheepFromHeaven picture SheepFromHeaven  ยท  7Comments

trailsnail picture trailsnail  ยท  4Comments

tmladek picture tmladek  ยท  3Comments