Why web components
Building sites with components has a lot of benefits for site visitors and the teams that run them.
How components work
Components are bite-sized sections of code that link together to create a website. They’re kind of like LEGO bricks. They’re often uniform and reusable.
Components help developers and designers save time. They help you avoid rewriting redundant code. You can also easily plug them into and remove them from code using HTML tags.
Examples of our components
The homepage also uses the feature card component. This component requires only HTML & CSS.
In some cases, we can embed components in other components. For example, we put a button in the feature card.
Web component advantages
Web components work anywhere
All framework support web components. You get this component model with its API built into all browsers. If you still need to support Internet Explorer, a polyfill is available. We use the @webcomponents/webcomponentsjs polyfill on covid19.ca.gov.
Web components help ensure longevity of code
Preferred web stacks evolve. Many mature organizations maintain applications written in a variety of frameworks. Each rewrite or launch is an opportunity to update codebases to the “modern approach,” but that changes over time.
Web components allow us to take our frontend widgets off this cycle of getting rebuilt in the newest framework flavor. Standardized features are built into all browsers. This means they’re supported forever. We are not subject to breaking changes in new versions of frameworks. We also do not worry about developers who prefer to write widgets that only work with a specific underlying technology.
Easier component management
Publishing each component individually lets us take advantage of separate versioning. Site owners can get dependabot notifications when there are updates to each npm package. This comes with associated semver compliant version numbers and published changelogs. Site owners can decide if they want to upgrade or ignore the change on their own timeline. Owners can add, upgrade, or remove components
more easily than if its code was part of the whole site. We learn a lot from other modular design systems like:
- The U.S. Web Design System
- Other systems also built with web components, like Adobe’s Spectrum
- Systems with fantastic documentation for new contributors, like Clarity
Components encapsulate code
The code for each widget is within the custom element class. Our component patterns with local variables protect us from accidentally influencing global variables. The custom element API provides a clear interface for interacting with the rest of the application. It receives events responding to instantiation, removal, and attribute updates.
When we use web components
We cannot depend on every device supporting our web components, even if they work in the latest version of all browsers. Older devices get locked out of update cycles. Some people avoid freely available software updates.
If a component is not critical to a site’s mission, we skip progressive enhancement. We have not made the page feedback component progressively enhanced because it's not why people visit the page. That element is only visible when the visitor’s browser successfully executes its code. We also use
Features of web components we use
We use plain custom elements. This does not stop us from depending on advanced base classes, but we get a lot of mileage out of the supported API now.
Applying CSS only to instantiated elements
For example we reference the custom element inside our CSS file with and without :defined:
We often communicate between components with custom events. This is not a web component-specific tool, but it works nicely with any DOM element, including our own custom elements.
One example is our reusable county search box component on COVID-19 site pages. It fires events with county details when a visitor chooses from an autocomplete list. Chart components that need to use the county can subscribe to the custom event fired by the search custom element. They then update the data as needed.
Lots of other ways to communicate data between components
Web components provide lifecycle callbacks that respond to attribute changes. You can pass information in through attributes as strings. If you want to pass in a complex object, you can assign it to the custom element in the DOM via:
document.querySelector("my-element").bigOjbect = myJSON;
You can refer to this inside the component via:
Custom elements can read their own interior HTML. We translate components server-side by writing translated HTML inside the custom element. Complex elements like charts need translated strings for things like tooltips and legends.
We use this pattern with our static site generator to provide these translations. 11ty builds a different version of each HTML page for each language we support. Then the charts on that page receive their translated strings in the page HTML.
Collaborate with us
Do you have an idea for a new component? Does your team already have a useful widget you think would be helpful on other sites? Let’s use web components to iterate together and refine reusable tech that works anywhere.
You can suggest changes or new components by opening issues in the open source Design System repository. If you have a component that’s built for a certain platform, we can work together to make it stack agnostic.
- Using custom elements documentation from MDN
- Custom elements everywhere tracks the frameworks that support all the aspects of custom elements
- Design systems built with web components
- Microsoft’s FAST design system
- SalesForce’s Lightning design system
- Adobe’s Spectrum design system
- The component.gallery that lets you sort their list of design systems by tech
- Web component libraries and patterns from
- Google’s Lit
- The Open-WC project
- Div RIOT's Webcomponents.dev
- Articles supporting web components in design systems