shading #
Moss is designed around two simplistic models of light, one for dark mode and one for light mode, mapping to the web platform's color-scheme. The goal is easy authoring with simple and consistent rules for arbitrary compositions and states. Each theme can choose to implement either light mode or dark mode or both.
Light mode's starting point is plain white documents (like paper) where we can think of UI construction as assembling elements that contrast against the white background, replacing some of the white blankness with darkened values/color/shape. In other words, we start with full lightness and subtract light to make visuals. Black shadows on the white background make natural sense, and white glows against a white background are invisible.
In contrast, dark mode's starting point is a lightless void where we add light. We add elements which emanate light. I think of videogames and virtual/augmented/actual reality. Black shadows are invisible against a black background, and white glows make natural sense against a black background.
This distinction leads to complication. For example, applying a black shadow to an element has a particular visual impact on the typical light mode page, but viewed in dark mode, it would disappear completely against a black background.
Moss provides APIs that simplify or hide this complexity. For example, the lighten
and darken
variables are the same in light and dark modes, but fg
and bg
are equivalent values that swap places in dark mode. Thus bg
and fg
are called color-scheme-aware, and lighten
and darken
are color-scheme-agnostic. (maybe you can think of better terminology? I
like the word "adaptive" but idk) The colors docs elaborate more on this point
and the shadows docs implement more of the idea.
Opacity is used to enable arbitrary stacking that visually inherits its context. Not all cases are properly handled yet, and some choices are made for performance reasons, like avoiding opacity on text. (assuming this is still a thing?)
Shades and highlights #
darken
and lighten
#
darken
and lighten
bg
and fg
#
bg
and fg
In light mode, bg
is the same as lighten
and fg
is
the same as darken
. In dark mode, they're swapped.
Stacking transparency #
Many styles are designed to stack, so things can appear in different contexts while retaining relative color value distinctiveness ("color value" as in darkness-lightness). Internally this uses simple transparency instead of complex selectors or other structure.
<div class="fg_1 p_sm">
<div class="fg_1 p_sm">
<div class="fg_1 p_sm">
<div class="fg_1 p_sm">
<div class="bg p_sm">
...
</div>
</div>
</div>
</div>
these shades use opacity, but notice how contrast changes with depth, creating limitations
This adds some complexity and performance costs, and it's currently incomplete, but so far it feels like an elegant solution with many unfinished details, and I plan to continue integrating the idea in more places while considering alternative designs. However alpha transparency has multiple costs, so I'm trying to be mindful to not use alpha for text and other cases that are more performance-sensitive, but we may need to change this behavior for the base cases, or include performance themes.
Opacity #
Interpreted utility classes, 0 to 100 (%).