XCSS
XCSS is a safer, tokens-first approach to CSS-in-JS.Installation
| Install | yarn add @atlaskit/primitives |
|---|---|
| Source | Bitbucket.org, (opens new window) |
| npm | @atlaskit/primitives, (opens new window) |
| Bundle | unpkg.com, (opens new window) |
Basic
XCSS can pull together different types of interactions and UI in a safer, more composable way.
A Card
With a description.
import React from 'react';
import Heading from '@atlaskit/heading/heading';
import { Box } from '@atlaskit/primitives/box';
import { Stack } from '@atlaskit/primitives/stack';
import { xcss } from '@atlaskit/primitives/xcss/xcss';
const textStyles = xcss({
color: 'color.text',
});
const cardStyles = xcss({
backgroundColor: 'elevation.surface',
padding: 'space.200',
borderColor: 'color.border',
borderWidth: 'border.width',
borderStyle: 'solid',
borderRadius: 'radius.small',
});
const MyCard = (): React.JSX.Element => (
<Box xcss={cardStyles}>
<Stack space="space.100">
<Heading size="medium">A Card</Heading>
<Box xcss={textStyles}>With a description.</Box>
</Stack>
</Box>
);
export default MyCard;Interactivity
To enable interactivity, use familiar selectors like :hover and :focus-visible.
A Card
With a description.
import React from 'react';
import Heading from '@atlaskit/heading/heading';
import { Box } from '@atlaskit/primitives/box';
import { Stack } from '@atlaskit/primitives/stack';
import { xcss } from '@atlaskit/primitives/xcss/xcss';
const textStyles = xcss({
color: 'color.text',
});
const cardStyles = xcss({
backgroundColor: 'elevation.surface',
padding: 'space.200',
borderColor: 'color.border',
borderWidth: 'border.width',
borderStyle: 'solid',
borderRadius: 'radius.small',
':hover': {
backgroundColor: 'elevation.surface.hovered',
},
':focus-visible': {
outlineStyle: 'solid',
outlineWidth: 'border.width.focused',
outlineOffset: 'space.025',
outlineColor: 'color.border.focused',
},
});
const InteractiveCard = (): React.JSX.Element => (
<Box xcss={cardStyles} tabIndex={0}>
<Stack space="space.100">
<Heading size="medium">A Card</Heading>
<Box xcss={textStyles}>With a description.</Box>
</Stack>
</Box>
);
export default InteractiveCard;Responsiveness
XCSS also accepts a subset of media queries at predefined breakpoints.
A Responsive Card
Change your screen width to see me change color.
import React from 'react';
import Heading from '@atlaskit/heading/heading';
import { Box } from '@atlaskit/primitives/box';
import { media } from '@atlaskit/primitives/responsive/media';
import { Stack } from '@atlaskit/primitives/stack';
import { xcss } from '@atlaskit/primitives/xcss/xcss';
const textStyles = xcss({
color: 'color.text',
});
const cardStyles = xcss({
backgroundColor: 'color.background.neutral',
padding: 'space.200',
borderColor: 'color.border',
borderWidth: 'border.width.selected',
borderStyle: 'solid',
borderRadius: 'radius.xsmall',
[media.above.xxs]: {
backgroundColor: 'color.background.accent.red.subtler',
},
[media.above.xs]: {
backgroundColor: 'color.background.accent.yellow.subtler',
},
[media.above.sm]: {
backgroundColor: 'color.background.accent.green.subtler',
},
[media.above.md]: {
backgroundColor: 'color.background.accent.orange.subtler',
},
[media.above.lg]: {
backgroundColor: 'color.background.accent.magenta.subtler',
},
});
const ResponsiveCard = (): React.JSX.Element => (
<Box xcss={cardStyles} tabIndex={0}>
<Stack space="space.100">
<Heading size="medium">A Responsive Card</Heading>
<Box xcss={textStyles}>Change your screen width to see me change color.</Box>
</Stack>
</Box>
);
export default ResponsiveCard;Conditional styles
For conditional styles, try composing styles together via the array with ternary or boolean operators.
Toggle background color:
import React, { useState } from 'react';
import { Box } from '@atlaskit/primitives/box';
import { Inline } from '@atlaskit/primitives/inline';
import { xcss } from '@atlaskit/primitives/xcss/xcss';
import Toggle from '@atlaskit/toggle/toggle';
const baseStyles = xcss({
paddingBlock: 'space.500',
width: '100%',
borderRadius: 'radius.small',
});
const enabledStyles = xcss({
backgroundColor: 'color.background.accent.green.bolder',
});
const disabledStyles = xcss({
backgroundColor: 'color.background.accent.gray.bolder',
});
export default function ConditionalStyles(): React.JSX.Element {
const [isEnabled, setEnabled] = useState(false);
return (
<Box testId="example" padding="space.200">
<Inline alignBlock="center">
<p>Toggle background color:</p>
<Toggle onChange={() => setEnabled((current) => !current)} />
</Inline>
<Box xcss={[baseStyles, isEnabled ? enabledStyles : disabledStyles]} />
</Box>
);
}