The Web team is working on T352198: [Spike, carryover] Should MediaWiki codebases use CSS custom properties?, investigating the feasibility and desirability of using CSS custom properties for some or all design tokens in the MediaWiki ecosystem, which could more easily enable a dark mode feature.
Related to that, we should investigate:
- How should Codex support this type of use of CSS custom properties? How could we made Codex components' appearance respond to a change in the value of one of these custom properties? Should this replace the current Less-variable-based system?
- How can CSS custom properties containing Codex design token values best be made available in MediaWiki? Should this replace the Less variables we currently make available?
- How does this impact downstream consumers of design tokens, like OOUI? See T353663 for the Web team's initial findings on custom properties and OOUI.
Acceptance Criteria:
- DST engineers investigate the above questions and come to a shared perspective.
- The investigation findings are documented and shared publicly for review and feedback.
Spike Findings (1/31/24)
Experimental Token Output and Codex build
Codex uses a tool called Style Dictionary to manage and manipulate our system's design tokens. Style Dictionary supports the ability to output one set of tokens in a variety of formats – either predefined (LESS, JSON) or custom. After some trial and error, I was able to define a format that produced an "experimental" LESS file. Just like our normal output, this file contains all of our publicly-exported tokens as LESS variables suitable for use inside MediaWiki, with one important addition – the file begins with a plain CSS :root declaration which defines CSS custom properties for an arbitrary subset of our design tokens (since this is intended to support a future dark mode, I chose to handle most color-related variables in this way). These variables are also defined in LESS (which is how Codex components normally access them for their component-specific styles), but the values here simply refer to the CSS custom properties.
Below is an abridged example of how this new output compares to what we produce currently:
/* Normally, all tokens are resolved to static values for LESS variables */ @color-primary: #36c; @font-family-base: sans-serif;
/* Any exposed tokens would be defined here as CSS custom properties */ :root { --color-primary: #36c; } /* The LESS variable definition now refers to the CSS variable */ @color-primary: var( --color-primary ); /* including a fallback value is also possible. If we wanted we could produce this: */ /* @color-primary: var( --color-primary, #36c ) */ /* Non-exposed values remain unchanged */ @font-family-base: sans-serif;
Once we have this "experimental" set of tokens (where some token values refer to CSS custom properties), we can generate a corresponding "experimental" build of Codex where this new set of tokens is used for the final component styles (which are output as CSS files).
This will result in styles like this being shipped to the client:
.cdx-card { background-color: var(--background-color-base); display: flex; align-items: flex-start; position: relative; border: var(--border-base); border-radius: 2px; padding: 12px; }
Styles which refer to "exposed" tokens will now look for CSS variables of the same name; other styles are unchanged. One important thing to note here is that the Codex styles would not include a :root declaration. Instead, the idea is that a pre-existing root declaration would live on the page containing the default values of all custom properties, and then other CSS selectors or media queries could override those values where needed. Codex could provide a CSS file containing the :root declaration for all the default values which Web could use somewhere, or we could build the styles so fallback values are included whenever --var() is called. If we did the latter, then Web would not need to define the initial state of these color values, only any dark-mode overrides.
Next steps: Short term
It is relatively simple to define a custom format in Style Dictionary and output a set of tokens (and styles) where some values are replaced with CSS custom properties. DST could ship a version of Codex that included these "experimental" tokens and stylesheets sometime in February.
However, this only gives Web the ability to override certain component styles easily. A dark mode color palette will still be necessary here. My assumption is that having a set of "theme-able" Codex components will be helpful to the Web Team as they work on developing a dark color palette and beta-testing it.
- Next sprint – DST finalizes "experimental styles" prototype and releases a version of Codex that includes these new files
- Question: Do we want to include fallbacks (var(--color-primary, #36c)) in these new files?
- Question: Do we expose a particular subset of variables, or do we simply allow *all* tokens to be overridden in the experimental stylesheet? If we did the latter, we probably would want to include fallbacks, or else a really cumbersome :root declaration becomes necessary
- Question: How do we ensure icons work properly (CSS-only icons in particular)? We may need to ensure our SVGs use properties like currentColor correctly in order to ensure that they are theme-able
- If needed, DST can also help to set up some kind of theming sandbox to make it easier for Web to experiment with different color palettes
- March 2024 – Web team begins beta-testing the new dark mode feature using the experimental codex styles
Next steps: Longer term
Exposing a set of Codex design tokens as CSS custom properties seems like a good short-term solution to help with Web's efforts to develop a dark mode color palette and beta test it with users. However, in the longer term, any dark mode palette should probably live within Codex itself so that other skins, extensions, and features can easily use it (and to ensure a consistent experience for users).
Once a good dark-mode color palette has been figured out, we should try to upstream this information into Codex and delete all of the experimental styles and token assets so that other projects don't start to rely on them.
Hopefully by this time Codex will have settled on a definitive "theming architecture" that will allow us to manage alternate sets of styles in an efficient and maintainable way. I have opened a proof-of-concept patch that explores one approach we could take, inspired by this article written by the creator of Style Dictionary.
This work should probably happen in parallel to the Web team's beta-testing of dark mode so that we have a more permanent solution ready in time for the final production launch of this feature.
- Some point between March and June:
- Dark mode color palette is finalized and these values are added as new tokens into Codex
- Codex finalizes its theme architecture and can use these values to produce "official" dark-mode assets which can be used by Web in a way that meets production requirements