@atlaskit/primitives
Version:
Primitives are token-backed low-level building blocks.
177 lines (134 loc) • 5.9 kB
text/mdx
---
title: XCSS
description: XCSS is a safer, tokens-first approach to CSS-in-JS.
order: 0
---
import { MediaQueriesTable } from '@af/design-system-docs-ui';
import SectionMessage from '@atlaskit/section-message';
<SectionMessage title="Caution" appearance="warning">
<p>
We are planning on deprecating XCSS. We recommend using{' '}
<a href="/components/css">/css</a> instead.{' '}
</p>
</SectionMessage>
XCSS is an Atlassian Design System styling API that natively integrates with Atlassian's
[design tokens](/tokens) and [primitives](/components/primitives/overview).
To ensure future compliance with XCSS as it evolves over time, we highly recommend you enable our
ESLint plugins and adhere to the
[UI Styling Standard](/components/eslint-plugin-ui-styling-standard) guidelines by writing local,
type-safe, static styles.
- [/eslint-plugin-design-system](/components/eslint-plugin-design-system)
- [/eslint-plugin-ui-styling-standard](/components/eslint-plugin-ui-styling-standard)
The XCSS utility behaves similarly to the `css` utility in libraries like `styled-components`,
` ` or ` `, and is built off of `/react` today. If you've used these
libraries, XCSS will feel familiar, with a few additional features and constraints.
Familiar features:
- XCSS is applied as an Emotion `className` to our primitive components
- XCSS works with the basic CSS object interface found elsewhere
- XCSS supports style precedence and conditional styles
Key differences:
- XCSS has type-safety that ensures token name usage for all CSS properties represented by design
tokens
- XCSS restricts nested selectors completely from usage
## Usage
To get started, import the function from `@atlaskit/primitives` and create a style:
```tsx
import { xcss } from '@atlaskit/primitives';
// Creates a basic style
const someStyles = xcss({
display: 'block',
});
```
Apply this style to a component through the `xcss` prop:
```tsx
import { Box, xcss } from '@atlaskit/primitives';
// Creates a basic style
const someStyles = xcss({
display: 'block',
});
const MyBox = () => {
return <Box xcss={someStyles} />;
};
```
The `xcss` prop and the `xcss` function are direct complements and are designed to be used together.
It is important to note that styles generated from `xcss` cannot be applied directly to the
`className` property or `css` as they are with other CSS-in-JS libraries.
### Type safety
XCSS uses strongly-typed values generated from design token definitions, making it simpler to apply
the right token to the right CSS property. This is intended to be more ergonomic and intuitive, but
also prevent the misapplication of tokens to the wrong properties.
Any [valid token name](/components/tokens/all-tokens) is available to be applied against its
matching CSS property. For example, the token name `space.200` is a valid value below for `padding`
but will not appear as a color, or a font.
```tsx
import { xcss } from '@atlaskit/primitives';
const someStyles = xcss({
padding: 'space.200', // <--- works
color: 'space.200', // <--- invalid and will error
borderRadius: 'border.radius.100', // <--- also valid
});
```
### Restricted nesting
XCSS is flexible enough to implement any design, but it does restrict the application of styles in
one key way. Selectors cannot be nested or target elements beyond the element on which styles are
applied. This restriction is intended to encourage better component encapsulation, reduce
side-effects and make the codebase more resilient to change.
```tsx
import { xcss } from '@atlaskit/primitives';
const someStyles = xcss({
':hover': {
transform: 'scale(1)', // this is okay
},
// This is not okay as this selector affects any nested div in
// the component tree.
'div:hover': {
transform: 'scale(1)',
},
// Neither is this
'> * > div:hover': {
transform: 'scale(1)',
},
});
```
These unsafe selectors will throw a type error if applied. Find richer examples of how to use XCSS
in the [XCSS examples](/components/primitives/xcss/examples).
### Media Queries
XCSS can create responsive layouts at predefined breakpoints that are consistent with the Atlassian
Design System. To enable responsive behavior, XCSS exposes the following pre-defined breakpoints:
<MediaQueriesTable />
Media queries can be applied through keys imported from `/primitives/responsive`. Find more
in depth examples on how to enable responsive behavior in the
[responsive documentation](/components/primitives/xcss/examples#responsiveness).
The objects defined at each breakpoint behave in much the same way as a normal XCSS object, and can
apply responsiveness to any CSS. The only limitation is that a media query can't contain another
media query. This is to prevent arbitrary nesting.
Additionally, pseudo-selectors can't contain media queries. To use media queries and pseudos, the
media query must contain the pseudo.
```tsx
import { xcss } from '@atlaskit/primitives';
import { media } from '@atlaskit/primitives/responsive';
const someStyles = xcss({
// This is okay, since media queries can contain pseudos
[media.above.md]: {
':hover': {
backgroundColor: 'color.background.neutral.hovered',
},
},
// This is not okay, we don't allow pseudos to contain media queries
':hover': {
[media.above.md]: {
backgroundColor: 'color.background.neutral.hovered',
},
},
// This is not okay, since media queries can't contain media queries
[media.above.md]: {
[media.above.xs]: {
backgroundColor: 'color.background.neutral.hovered',
},
},
});
```
## Related
- [Use box for a generic container with access to design tokens](/components/primitives/box/usage)
- [Manage horizontal layout using an inline component](/components/primitives/inline/usage)
- [Manage vertical layout using a stack component](/components/primitives/stack/usage)