UI Styling Standard

The eslint plugin to enforce and educate on Atlassian's UI Styling Standard

no-container-queries

Blocks @container at-rules (container queries, (opens new window)) by default. The rule allows a narrowly-scoped exception when the named container is declared in the same file and the query is dimension-based (width/height or a range). Style queries, unnamed queries, and IDs shared across files remain blocked.

Container queries are unsafe because they:

  • break the rules of scope
  • aren't deterministic
  • aren't type-safe
  • aren't fully supported across our frontend tech stacks

Approved queries must use satisfies with the default type import from @atlaskit/css/at-rules/container, and the name after @container must match the local containerName declaration:

import { cssMap } from '@atlaskit/css';
import type ContainerQuery from '@atlaskit/css/at-rules/container';

const styles = cssMap({
    root: { containerName: 'sidebar', containerType: 'inline-size' },
    content: {
        ['@container sidebar (width > 300px)' satisfies ContainerQuery]: {},
    },
});

export const Card = () => (
    <div css={styles.root}>
        <div css={styles.content}>Card content</div>
    </div>
);

Test approved responsive states at 400% zoom and 270–320px widths. Do not use style queries such as @container sidebar style(--density: compact).

Examples

Incorrect

import { css } from '@compiled/react';
import { token } from '@atlaskit/tokens';

const headingStyles = css({
    '@container (width > 400px)': {
        font: token('font.heading.large'),
    },
});

Correct

Media queries

import { css } from '@atlaskit/css';
import type MediaAboveSm from '@atlaskit/css/at-rules/media-above-sm';
import { token } from '@atlaskit/tokens';

const headingStyles = css({
    ['@media (min-width: 48rem)' satisfies MediaAboveSm]: {
        font: token('font.heading.large'),
    },
});

WidthObserver

import { useState } from 'react';
import { css, cssMap } from '@compiled/react';
import throttle from 'lodash/throttle';
import { WidthObserver } from '@atlaskit/width-detector';
import { token } from '@atlaskit/tokens';

const containerStyles = css({
    // Required for the `WidthObserver`, which is absolutely positioned
    position: 'relative',
});

const headingStyles = cssMap({
    small: {
        font: token('font.heading.small'),
    },
    large: {
        font: token('font.heading.large'),
    },
});

const ResponsiveH2 = () => {
    const [width = 0, setWidth] = useState<number | undefined>(undefined);
    const throttledSetWidth = throttle(setWidth, 50);

    return (
        <div css={containerStyles}>
            <WidthObserver setWidth={throttledSetWidth} />
            <h2 css={width < 400 ? headingStyles.small : headingStyles.large}>Title</h2>
        </div>
    );
};

Options

importSources: string[]

By default, this rule will check styles using:

  • @atlaskit/css
  • @atlaskit/primitives
  • @compiled/react
  • @emotion/react
  • @emotion/core
  • @emotion/styled
  • styled-components

Override this list with the importSources option, which accepts an array of package names.

Was this page helpful?
We use this feedback to improve our documentation.
© 2026 AtlassianTrademark, (opens new window)Privacy, (opens new window)License