Design System Team/Projects/CSS-only components

Project Overview & Background

edit

CSS-only components will be a group of Codex components that are implemented solely by creating standard, shared styles for each component, meaning JavaScript is not required to use them. For example, to use a CSS-only Message component, a developer would either write or generate the markup for the message, then apply the shared styles to their markup, resulting in a no-JS message that has visual consistency with the Vue version of the Message component.

Currently, nearly all Codex components are implemented as Vue.js components, meaning they require JavaScript running on the client to work. Eventually, we hope to have a solution for rendering Vue components on the server (server-side rendering, or SSR), but this will take time, and there still may be use cases for no-JS versions of Codex components even if we have full SSR.

Impact

edit

End users:

  • + Users without JavaScript can see and use UIs that have a consistent design that matches our canonical design system, across wikis
  • + Users with slow connections can see and start to use visually consistent UI components while they await the fully interactive JS version of the UI to load
  • + All users benefit from simple UIs that can be rendered on the server, which load quickly and provide a consistent experience
  • + Non-WMF wikis have a way to provide consistent server-rendered UIs without having to set up SSR
  • - Easily available API could mean misuse on-wiki, e.g. applying interface styles to content, or more potential for breaking visual changes due to high usage of CSS classes

Engineers:

  • + While they await an SSR solution, or in situations where SSR cannot be used, engineers can use CSS-only Codex components to style server-rendered elements, enabling them to use the current design system and reducing the need for custom code.
  • + Engineers with no JavaScript or Vue experience can build UIs with Codex components
  • + We can eventually deprecate old, inconsistent parts of our systems in favor of a single, centralized set of styles, leading to lower maintenance costs, less confusion, and easier onboarding of new developers
  • + Abstracting styles out of Vue components will mean having a set of implementation-agnostic base styles that could be applied to a new implementation in the future (e.g. React or a new framework)
  • - Development and maintenance costs: building this set of components will require time from DST and other teams to develop and test

Designers:

  • + Since styles are shared between CSS-only and Vue components in Codex, designers will have less to review when adding or changing components
  • + Once we deprecate old systems, designers will have fewer things to keep track of and work on, leading to greater velocity on the current system
  • + Designers who know HTML and CSS can use CSS-only components for rapid prototyping or to make code changes for production UIs

Proposed implementation strategy

edit
  1. Use cdx- classes for styling ("Bootstrap-style" approach). We are already writing BEM-style CSS inside our Vue components, so we don't need to make any changes here.
  2. Continue writing styles within Vue single-file components (SFCs). Where necessary, components will make distinctions between two sets of styles. The first is styles that only appear in the CSS-only version, and styles that only appear in the Vue version (both SSR-ed and mounted). We can distinguish these styles by adding -vue to the relevant classes to target Vue-only styles. The second is styles that only appear in a no-JS environment, and styles that only appear in a JS-enabled environment. We can distinguish these styles by adding a --js-on or --mounted class suffix when the component is mounted. Finally, we will add a ref to most components that will be set to true on (or right before) mount, via a composition function, which can be used to conditionally show different markup depending on whether the SSR-ed component has been hydrated or not (this last part could be done in the future during SSR implementation).
  3. Define a series of new Codex sub-packages which are intended for use within MediaWiki. Each new package will group together a set of related components (maybe corresponding to the component groups we were considering adding to the documentation site). This will work similar to how we are handling codex-search currently. Each new package will get built in Vite’s library-mode, so a single JS and CSS file gets built with only the data for the relevant subset of components. An example of this can be seen in this patch, which creates a demo codex-buttons package: https://gerrit.wikimedia.org/r/c/design/codex/+/865840
  4. Each Codex sub-package gets its own ResourceLoader module containing only its CSS and JS files. Users only need to load the packages corresponding to the components they need in their feature.
  5. Load CSS and JS separately: There are two ways we can do this.
    • We could update ResourceLoader so that a user can get only the styles, or only the scripts, or both, when using a module that contains both CSS and JS. Currently this is only possible through an annoying work-around.
    • Alternatively, we will have to do this work manually. Each Codex sub-package would need to have two modules in MW – one containing only the CSS, i.e. codex-buttons-styles, and one containing only the JS files, i.e. codex-buttons. The latter package would depend on the former, but the former can be used without the latter.
  6. Interaction with SSR: In the future, we expect that a more robust SSR system will be available in at least some situations. SSR-based features would basically create their own bundle instead of relying on the pre-split ones that we’d be providing here. Such builds will depend on the full Codex package (which contains all CSS and JS code). The SSR tooling will be able to tree-shake out all unnecessary code for these features, so the regular Codex modules will not be needed at all. See also: Design System Team/Projects/Modern user interfaces for all users

Risks/Trade-offs

edit
  • This implementation strategy will allow us to keep writing our component styles within the Vue SFCs, which is nice from a familiarity and developer productivity approach.
  • We would need to create some additional packages inside the Codex repo, but this will mostly be a one-time task. As we add new components to Codex we'll need to include them in one of the existing sub-packages or (more rarely) create a new one. But little additional code is required here and once a sub-package has been set up it will rarely change. These will be included in each release just like codex-search is (though we may not need to publish them on NPM since they are intended only for use in MW). See https://gerrit.wikimedia.org/r/c/design/codex/+/866509/ for an example of what this would look like.
  • CSS-only implementations of components will need to be tested; VueTest is a good place to do this (maybe a new sub-page of that extension can be created for the CSS-only components)
  • We'll need to create several additional ResourceLoader modules (especially if we cannot come up with a way to get just the CSS or JS from a module that contains both). But like in the case of the additional Codex packages, most of the work here is a one-time effort.
  • We might want to include some easily copy-pastable markup snippets for users in the absence of a good way to package up CSS-only components in mustache templates or PHP.

Timeline

edit

Project phases come from Wikimedia Foundation's Inclusive Product Development playbook.

Phase What? How? Target Start Target Completion Status
Strategize Articulate “why” and “for whom?”

Assess team's capabilities to deliver.

Surface dependencies and risks.

Establish community engagement strategy.

Create proofs-of-concept T323954, T323955, T324029 Nov 2022 Dec 2022   Done
Discover Better understand the needs and goals of target audience Determine how to mitigate performance concerns T323180 Nov 2022 Dec 2022   Done
Define Turn research, insights, etc. into an addressable and achievable scope of work with a concise problem statement. Draft scope for CSS-only subset of Codex T321354

Determine implementation path T323179

Oct 2022 Dec 2022   Done
Develop Design and development of solutions and experiments from the DEFINE phase, in preparation for the DELIVER phase. Add CSS-only versions of most Codex Vue components T325105 Jan 2023 TBD   In progress
Add CSS-only (or non-client-side-JS) icon T325772 Jan 2023 Mar 2023   Done
Enable use of CSS-only components within MediaWIki T330468 Feb 2023 Apr 2023   Done
Deliver Deliver and test final code and/or interface. This could be either for delivering a smaller scaled test or final scaled experience to production. Redesign the Codex demo to visualize the CSS-only components T325751 TBD TBD   To do
Own Monitor and refine based on positive and negative impacts resulting from the product/code delivered. Improve the developer experience for using CSS-only Codex components in MediaWiki T330469 TBD TBD   To do
Document a migration plan for legacy libraries? TBD TBD   To do

Updates

edit

edit

edit
  • Project page created

edit
  • Implementation proposal complete T321351

edit

How to Engage

edit

We welcome and encourage your participation in this initiative. Here are some ways to engage:

  • Add this page to your watchlist
  • Add your questions, concerns, and ideas to the talk page
  • Subscribe to relevant Phabricator tasks, linked above
  • For Wikimedia Foundation staff: join the #talk-to-design-system-team Slack channel