Greetings, Developers! This page will walk you through all the basics of using the design system, but another good way to get a jump start is to look through our example projects on GitHub.
As you go through this documentation, keep in mind that the CMS Design System is a family of design systems, and each of these design systems is distributed under a different package name:
design-system
(Core Design System)ds-healthcare-gov
(Healthcare.gov Child Design System)ds-medicare-gov
(Medicare.gov Child Design System)
Getting the design system assets
How you get the design system assets depends on the needs of your project and your workstyle. You could...
- Install the npm package
- Good option if your project already uses npm for package management
- Makes it easy to get patch updates for your major/minor version
- Reference files directly from the CDN
- Good option if your project doesn't use npm
- CDN files are versioned, so you always know what version you're using, and those files will be cached by the client's browser
- Download the design system assets directly from GitHub
- This is not recommended, but it's available if no other options will work for your project
Option 1: Install using npm
If you already have npm or yarn set up for your project, you can add it to your list of dependencies using one of the commands below. Note that the following example will display a different package name depending on the theme you have selected.
npm install --save @cmsgov/design-system
# or
yarn add @cmsgov/design-system
Once you've installed the package, read the sections on how to include the CSS and importing the components into a JavaScript project.
Option 2: Reference assets from the CDN
You can also choose to load the assets directly from our content delivery network (CDN) to your clients' browsers. All packages and their available versions are listed and linked to on our CDN index page. Each version index page lists all its available resources. CDN resources use the following URL convention:
https://design.cms.gov/cdn/<package-name>/<version>/<resource>
What is a CDN and why would I use it?
A content delivery network (CDN) is a collection of servers that dynamically allocate resources based on the requester's geographic location in order to optimize the distribution of assets. Some benefits and applications for utilizing the design system via CDN are:
- Quickly utilize design system code and style assets for development/prototyping
- The CDN caches assets for fast loading and scales automatically in case of a large number of requests
- Ability to utilize a specific version of the design system easily
Example loading CSS via CDN
<link rel="stylesheet" href="https://design.cms.gov/cdn/design-system/7.0.0/css/index.css" />
<link rel="stylesheet" href="https://design.cms.gov/cdn/design-system/7.0.0/css/core-theme.css" />
Example loading web components via CDN
<script src="https://design.cms.gov/cdn/design-system/7.0.0/web-components/bundle/web-components.js"></script>
Option 3: Download assets directly
If you'd like to take a look at the static assets that we publish through npm and our CDN, you can download a tar file for any of the releases on our GitHub Releases page. You will find these files in the "Assets" section at the bottom of each release.
Including the CSS
No matter what framework you use to build your application, you will need to include the design system styles in order for your application to look the way it should.
With HTML
You will need to include both the main index.css
along with a theme file which contains all of the CSS variables needed by the main stylesheet. The simplest way to do that is to include resource link elements in your HTML document, like this:
<head>
<link rel="stylesheet" href="https://design.cms.gov/cdn/design-system/7.0.0/css/index.css" />
<link rel="stylesheet" href="https://design.cms.gov/cdn/design-system/7.0.0/css/core-theme.css" />
</head>
If you are getting the files from npm, you will want to change the href
to reference the files from your local node_modules
folder. Likewise if you've downloaded the files directly, the href
will point to wherever you've put your files.
With an asset bundler
For projects that use an asset bundler, include the assets in whatever way your bundler recommends. For instance, in a WebPack or create-react-app project, you might include the styles in your CSS like this:
@import '@cmsgov/design-system/css/index';
@import '@cmsgov/design-system/css/core-theme';
Or you might import it from your JavaScript like this:
import '@cmsgov/design-system/css/index.css';
import '@cmsgov/design-system/css/core-theme.css';
Issues with fonts and images
Note that some bundlers have trouble finding the font and image files when the CSS files are imported through Sass. In those cases, we recommend either adding the .css
extension to the imports or importing the CSS files directly from JavaScript to avoid limitations of the Sass compiler and/or the WebPack configuration.
CSS Custom Properties
The CMSDS utilizes CSS Custom Properties to allow for flexible styling of components, layout, animation, typography and color. Lists of variables and their values can be found throughout this documentation.
These custom properties allow for a degree of customization of the design systems components and layout. To modify a CSS variable simply re-define them within a given context. The default context for all CSS Custom properties is as follows:
:root,
::before,
::after,
::backdrop {
--variable-name: value;
}
This allows these classes to apply globally to the entire page they're loaded on. By re-defining these variables in this same scope or defining a variable in a custom scope, such as a specific class, you can overwrite these variables:
.ds-c-button {
--button__border-color--hover: green;
}
Fonts and images
Note that our stylesheets also reference fonts and images, so you will need to make sure these assets (dist/fonts
and dist/images
) are available to your site/application at the correct relative paths. You don't need to think about this if you're loading the stylesheet from the CDN, and most asset bundlers will be able to locate these additional assets without additional configuration.
Using the CSS
Design system styles can be broken down into the following categories:
- Reset styles - Standardizes the appearance of base elements to overwrite user-agent styles across browsers
- Layout styles - For implementing visual structure in your application
- Please see the layout grid documentation to get started
- Further resources can be found in the Layouts section of the doc site
- Typography styles - For visually differentiating between kinds of text
- Component styles - A collection of designed, self-contained UI elements
- See the Using components section below
- Utility classes - For applying single CSS properties to elements using standard values
- See the Utilities section of the doc site for more details
CSS class naming conventions
Most of our CSS classes follow a specific naming pattern, outlined below:
Note that the design system favors clarity over succinctness. This means the class names may be verbose but should deliver clarity, predictability, and legibility in exchange.
Namespace
To avoid conflicting with other libraries and existing code, the design system namespaces its CSS class names with ds-
.
Prefix
Prefixes are added to class names to make it more apparent what job the class is doing.
Prefix | Description |
---|---|
l- | Indicates layout-related styles. Example: .ds-l-container |
c- | Indicates a component. Example: .ds-c-button |
u- | Indicates a utility. Example: .ds-u-color--base |
These prefixes can sometimes be followed by a "breakpoint prefix". Learn more about breakpoint prefixes.
BEM syntax
Following the namespace and prefix is a name conforming to BEM syntax, like [BLOCK]__[ELEMENT]--[MODIFIER]
, where...
- BLOCK is a standalone entity that is meaningful on its own. For example:
.ds-c-card
,.ds-c-button
- ELEMENT is a part of a block that has no standalone meaning and is semantically tied to its block, such as
.ds-c-card__title
- MODIFIER is a flag on a block or element and is used to change appearance or behavior. For example:
.ds-c-button--primary
,.ds-u-color--base
,.ds-l-col--3
Using components
Our design system components are more than a collection of styles for making widgets on a page. They embody guidelines, best practices, and interactive behaviors that have been designed for good accessibility and user experience.
While you can apply these styles to your own HTML elements, we strongly recommend using the JavaScript versions of our components. The JavaScript components give you those interactive behaviors for free, and without them you'll have to implement the dynamic parts yourself based on the guidance in our documentation. We've made these JavaScript components available as React, Preact, and web components (though only a subset of our full library is represented by web components at the moment). Please take a look at our example projects on GitHub for details about each option.
Using React/Preact components
Inside a React/Preact project, you will import and use the components as you would any other React/Preact component. See the Importing into a JavaScript project below for more details.
Outside a React/Preact project, your usage will depend on the framework you're using. Our CDN projects show you how to use our React or Preact components in a plain HTML page. Note that for components that don't have interactive behaviors like Badge, you may not need to invoke React or Preact at all.
More React/Preact prop documentation, examples, and guidance can be found on component documentation pages.
Importing into a JavaScript project
If you've installed the design system via npm, the components can be imported from the package entry point using the syntax below. Note that the following example will display a different package name depending on the theme you have selected.
import { Button, TextField } from '@cmsgov/design-system';
Why switch to Preact?
If you have a React project, chances are you can actually start using Preact today and save on your total bundle size. For our own component library, we found that switching to Preact shrunk our bundle by about 92KB. The Preact library itself is smaller than React, and so far its claim of full compatability with React has proven true.
Check out our preact-react-app example if you're curious how to make the switch in an existing React project without changing any of your source code.
If your project is based on Preact and not React, we've provided an import path for you to use the Preact version of our components directly. To import the Preact versions, add /preact
to the end of your import path like this:
import { Button, TextField } from '@cmsgov/design-system/preact';
Using web components
We've also begun offering web components as a framework-agnostic alternative to our React or Preact components. We will be working on expanding this library over time, but at a moment only a subset of our JavaScript components are represented in this library. The easiest way to consume these components is by loading them from the CDN; however, they can also be installed via npm and imported by appending /web-components
to your import path.
From the CDN, there are two ways of importing the web components:
- Import all of them at once using the
all.js
file. - Pick and choose which ones you want by importing the
base.js
file first and then the file that matches the component you want to use (likeds-alert.js
).
See further instructions for both of these on your version's CDN page.
Applying component CSS classes manually
If you can't use React, you can apply the appropriate component CSS classes directly to elements in your HTML. Our component documentation pages provide HTML code for the inert states of components, but you'll be responsible for writing the correct markup and updating classes and DOM attributes in response to user events.
The following example shows how you can manually apply ds-c-label
and ds-c-field
classes to HTML to achieve more or less the same affect as using the <TextField>
React component. Note that you would have to update the HTML to show field errors when validating user input or to achieve other dynamic behaviors.
<div>
<label class="ds-c-label" for="field_1">
<span>Text Field Label</span>
<span class="ds-c-hint">Helpful hint text</span>
</label>
<input class="ds-c-field" type="text" name="text-field-example" id="field_1" />
</div>
Internationalization
Providing your own internationalized content
The design system attempts to make all of its components' text content assignable through their React props. That means you can use your own internationalization solutions to provide the content in your applications. Here is an example:
// Example of an application providing its own internationalized content
import { Alert } from '@cmsgov/design-system';
import i18n from 'i18n';
export default function () {
return <Alert heading={i18n('success')}>{i18n('account.created')}</Alert>;
}
Default internationalized content in the design system
{/* TODO: Once it is true that all default content is internationalized, we can use this opening paragraph instead
While we want components to be flexible, we also want them to be easy to use, so for some components we do provide default content. When we do this, the content comes in English and Spanish.*/}
{/ TODO: Replace this paragraph with the above paragraph /}
While we want components to be flexible, we also want them to be easy to use, so for some components we do provide default content. If a component does not yet have Spanish translations for its default content, that will be noted in the component maturity section of the component documentation page.
For applications that have a lang
attribute on their html element, the language will be detected automatically. If that language is not English or Spanish, the language of the design system will fall back to English. If automatic language detection does not work for your use case, the language can be set manually through the setLanguage
function. Similarly, the current language can also be read from the getLanguage
function. Here's an example:
import { getLanguage, setLanguage } from '@cmsgov/design-system';
// Set the design system language to something other than the document's detected language
setLanguage('es');
// Get the design system's current language
console.log(getLanguage());
Analytics
See component-analytics documentation.
Further resources
We hope this page and our example projects provide you with everything you need to get started with the design system, but if you run into trouble please reach out. If you have specific suggestions for how we can improve these docs, please feel free to edit this page (with the link under the table of contents) and submit a pull request!