Stitches
The Washington Post Design System utilizes the css-in-js library, Stitches, to optimize app performance and dev experience. For more context about why we use Stitches, check out this post by the WPDS team.
Stitches functions
Stitches functions make creating and styling components easy. Below, we’ll dive into the functions most useful to a user of our UI Kit, but check out Stitches’ other functions if you’re curious.
Styled
The styled
function is used to simply create React components with styles. The arguments to the function are:
- either an HTML element or a react component
- styles
Component variants may also be specified. For example:
import { styled, css } from '@washingtonpost/wpds-ui-kit'
// create a new component, 'FancyButton', which modifies a 'button' element
const FancyButton = styled('button', {
// base styles
variants: {
variant: {
fancier: {
// fancier styles
},
fanciest : {
// fanciest styles
},
},
},
});
// Use it
<FancyButton>I'm fancy!</FancyButton>
<FancyButton variant="fancier">I am fancier!</FancyButton>
CSS
The css
function can be used to create reusable styles through the application of a class name or used inline to style individual elements. Here’s an example of inline use, utilizing the already defined FancyButton
from before:
<FancyButton css={{ //base styles, optional variants }}>I'm fancy!</FancyButton>
And below demonstrates the application of css through the classname property:
const newButton = css({
// base styles
});
// Use it
<div className={newButton()}>I'm new!</div>;
**note: style property names use camel case in these functions (example: z-index
becomes zIndex
)
Keyframes
Another function available in Stitches is the keyframes
function. Using the keyframe animation technique, Stitches allows the creation of global CSS keyframe rules, which lets transitions be easily reused across code. Below is an example of a simple fading-out animation:
import { keyframes } from '@washingtonpost/wpds-ui-kit'
const fadeOut = keyframes({
from: { opacity: 1 },
to: { opacity: 0 },
});
// Use it
const fadingInButton = styled("button", {
'&hover': {
animation: `${fadeOut} 200ms ease-out`,
"@reducedMotion": {
animation: "none",
},
}
)};
Theme object and tokens
The theme object contains useful token data that can be applied when styling an element. WPDS specifies its own tokens for many attributes, which can be explored throughout the foundations section of our documentation. Tokens can be accessed in code by using the theme
object, which is is preferred over using the $
reference symbol because it provides additional checks. For more information about using our theme tokens, check out this tutorial.
const WPDS
is pre-defined in the UI Kit's stitches.config.ts
file.
const WPDS = stitches.createStitches({
prefix,
theme: {
colors: {
...tokens.light,
...tokens.staticColors,
...tokens.defaultTheme,
},
sizes: tokens.sizes,
...
},
media: { ... },
utils: { ... },
});
// Use it
const BestButton = styled('button', {
// use the size token $200, which is equivalent to 2rem or 32px
marginTop: theme.space["200"],
// use the color token $primary, which is equivalent to rgba(17, 17, 17, 1)
// color tokens change automatically when a color theme is applied
color: theme.colors.primary,
});
Breakpoints
Stitches is also capable of defining breakpoints, which are reusable media queries useful for responsive styling. The WPDS UI Kit supports a variety of size breakpoints and custom themes, which can be explored in the kit's stitches.config.ts
file. The button in the example below would be uniquely styled when the viewport is smaller than 768px
, or sm
.
const WPDS = stitches.createStitches({
prefix,
theme: { ... },
media: {
sm: "(max-width: 767px)",
md: "(min-width: 768px) and (max-width: 899px)",
lg: "(min-width: 900px) and (max-width: 1023px)",
...
},
utils: { ... },
});
// Use it
const VariableButton = styled('button', {
// Base styles
"@sm" {
// small-screen styles
},
});
Note: the "@dark"
and "@light"
media queries are responsive only to OS preferences, so styles specified with these will not affect elements based on the theme toggled in the application. To style an element based on local theme, consider stying based on the parent html
element using the syntax: [".<className> &"]
. For example:
// Adding opacity to an image when local dark mode is enabled.
const StyledImage = styled(Image, {
paddingRight: "$075",
[".wpds-dark &"]: { opacity: "0.9" },
});
Utils
Utils allow the creation of custom shortcuts to write certain styling properties. For example, the WPDS ui kit has defined utils px
and py
, which affect horizontal and vertical padding, respectively. px
could then be used in place of padding-left
and padding-right
when styling elements. Check out the other utils WPDS supports defined in the config file.
const WPDS = stitches.createStitches({
prefix,
theme: { ... },
media: { ... },
utils: {
px: (value: Stitches.PropertyValue<"padding">) => ({
paddingLeft: value,
paddingRight: value,
}),
py: (value: Stitches.PropertyValue<"padding">) => ({
paddingTop: value,
paddingBottom: value,
}),
...
},
});
// Use it
<p css={{ px: "$075", py: "$100" }}>Paragraph with padding</p>
Global styles
Another feature of the UI Kit that provides greater consistency is globalStyles
. In the globalStyles
definition, default styles for certain properties are specified by using Stitches’ globalCSS
function. A darkModeGlobalStyles
modification is also specified, which alters default color styles in dark mode.
Dark theme
The WPDS UI Kit currently supports a light and a dark theme. Using the Stitches function createTheme
, tokens specified in the theme
object can be overwritten to create custom themes. In the case of our UI Kit, the dark theme is employed when the breakpoint dark
is toggled.
Contributing
If your team would benefit from an additional util, breakpoint, or something else, please reach out to the WPDS team!