This release focuses on two goals:
- Making Duomo structurally more sound and future-proof
- Implementing MVP dark mode Sass APIs
Structurally sound
What does structurally more sound mean? One of the end-goals of Duomo is that you don’t need to using purging technologies in order to leverage Duomo via CDN or the Sass API.
How is this possible? Optimizations! There are many optimizations that can be taken to decrease the generated CSS file. Besides the basics -- like constraining ranges and colors -- grouping selectors is one of the most effective methods.
What does grouping selectors mean in practice? Essentially the following:
// duomo.scss (optimized for development)
.class { ... }
.hover\:class { ... }
.focus\:class { ... }
// duomo.min.scss (optimized for production)
.class,
.hover\:class,
.focus\:class { ... }
This means that classes that implement variants do not generate their own bodies in production mode. This optimization makes it possible for selectors to be effectively grouped. For Duomo, this cuts the generated CDN footprint by as much as 22%!
The cleancss
CLI tool was also added to the build process, which shaves off another ~3%. These two techniques combined make up for a 25% file size reduction for the standard Duomo CDN link, which now weighs 421kB uncompressed and 19kB with Brotli compression. Note that if you are using the Sass APIs, you can expect significantly smaller file sizes, as you can configure the library to your liking. Omitting colors, for example, helps dramatically.
Dark mode APIs (Sass)
The previous dark mode Sass API has been deprecated in favor of a simpler, less magical API. The new themes
API simply interpolates maps associated with light and dark mode schemes but does not generate classes automatically.
Here’s a rough idea of the new direction for the Sass dark mode API:
@use "@zaydek/duomo" as * with ($headless: true);
$light: (
app-color: color(black),
app-bg: color(white),
hoverable-bg: color(black, 0.05),
);
$dark: (
app-color: color(white),
app-bg: color(black),
hoverable-bg: color(white, 0.05),
);
@at-root {
@include themes((light: $light, dark: $dark), 700ms, timing(ease-out));
}
.x-app {
@include theme-transition {
color: var(--app-color);
background-color: var(--app-bg);
}
}
The light and dark maps are interpolated as simple CSS variables using the :root
and :root[data-theme="dark"]
selectors. The final arguments, 700ms
and timing(ease-out)
simply set --default-theme-transition-duration
and --default-theme-transition-timing
so you don’t have to.
Finally, you are meant to compose your own classes, name them to your liking, and simply reference the CSS variables that were generated for you in either the $light
and or $dark
maps.
The reason maps are used is because it removes a lot of unnecessary syntax: no need to delimit CSS variables with --
or wrap values with #{...}
because expressions are eagerly (rather than lazily) processed.
The idea with this API is to enable support for more than light and dark modes in the future, by simply providing more maps than $light
and $dark
.
Finally, there are two mixins that are provided to make your life easier when coordinating theme-aware classes.
theme-transition
theme-variants
theme-transition
theme-transition
simply adds transition: var(--theme-transition)
at the end of a class body. This enables classes to transition gracefully between light and dark modes as their properties are theme-aware.
For example:
.x-app {
@include theme-transition {
color: var(--app-color);
background-color: var(--app-bg);
}
}
// -> .x-app {
// -> color: var(--app-color);
// -> background-color: var(--app-bg);
// -> transition: var(--theme-transition);
// -> }
theme-variants
theme-variants
is designed to make authoring variant-based classes easier (such as hover
or focus
) and are theme-aware by default.
Here’s the basic idea:
.x-hoverable {
@include theme-variants((hover), 250ms, timing(ease-out)) {
background-color: var(--hoverable-bg);
}
}
// -> .x-hoverable {
// -> transition: var(--theme-transition);
// -> }
// ->
// -> :root:not([data-theme-effect]) .x-hoverable {
// -> transition: 250ms background-color cubic-bezier(0, 0, 0.2, 1), ...
// -> }
// ->
// -> .x-hoverable:hover {
// -> background-color: var(--hoverable-bg);
// -> }
Both of these APIs are experimental and may be deprecated in the future.
Note: theme-variants
does not yet support group-*
-based variants.
New getters
Range-based getters have been added to make iterating over range-based values easier. These are used throughout the library extensively.
nspaces() // Negative spaces, from -1 up to -128
spaces() // Non-negative spaces, from 0 up to 128
sizes() // From 0 up to 640
font-sizes() // From 8 up to 64
border-widths() // From 0 up to 8
border-radii() // From 0 up to 32
Revised aspect ratio API
The aspect ratio API has been upgraded to use utility classes as opposed to the style selector that was previously used. This is because style selectors cannot reasonably support responsive variants.
If you know Tailwind CSS-based aspect ratios, the API is the same:
<!-- Non-responsive -->
<div class="aspect aspect-w-16 aspect-h-9">...</div>
<!-- Responsive -->
<div class="aspect aspect-w-16 md:aspect-w-9 aspect-h-9 md:aspect-h-16">
...
</div>
Other improvements:
- HStack, VStack, and ZStack have been internally simplified.
cursor-default
,cursor-pointer
, andcursor-none
classes have been added (thanks to @joyact!).justify
andjustify-self
classes have been added (thanks to @joyact!).- Skeleton has been renamed to Layout; the Layout CDN / API does not generate color-based classes at all now.
- Plural getters (like
colors
) now return a key-value map instead of list of values. - The standard range has simplified (see
src/configuration/configuration.scss
for more information). - color(transparent) and color(current) or color(currentColor) no longer return an erroneous value.
- Added (back) the placement API
- Stacks are designed to be simpler and more internally consistent (auto-centering fixed-size elements has been deprecated)
Deprecations:
- The
hidden
,unhidden
API has been renamed tohide
,show
. Don’t @ me. duomo.full.css
andduomo.full.min.css
have been deprecated in favor ofduomo.css
andduomo.min.scss
(https://unpkg.com now points toduomo.css
by default).- The
-var
getters have been deprecated. - Colors are intentionally no longer exported as CSS variables. In order to leverage colors and other design tokens provided by Duomo, you should opt for the Sass APIs, which provide more power for less code.
Known regressions:
- The
bg-placeholder
class has been temporarily disabled. - The
transition
classes have been temporarily disabled.