> ## Documentation Index
> Fetch the complete documentation index at: https://www.beeq.design/llms.txt
> Use this file to discover all available pages before exploring further.

# Spacing

> BEEQ spacing defines the rhythm between elements, sections, and layouts using a shared 4px-based scale.

export const CodeLivePreview = ({code, children, height, removePadding = false, mode = 'shadow'}) => {
  const previewRef = useRef(null);
  const BEEQ_ESM_URL = 'https://esm.sh/@beeq/core/dist/beeq/beeq.esm.js';
  const BEEQ_CSS_URL = 'https://esm.sh/@beeq/core/dist/beeq/beeq.css';
  const BEEQ_ICONS_URL = 'https://esm.sh/@beeq/core/dist/beeq/svg';
  const ensureParentBeeqRuntime = () => {
    if (document.querySelector('script[data-beeq-parent-runtime]')) return;
    const script = document.createElement('script');
    script.type = 'module';
    script.src = BEEQ_ESM_URL;
    script.dataset.beeqParentRuntime = BEEQ_ICONS_URL;
    document.head.appendChild(script);
  };
  const executeSnippetScripts = (root, runtimeWindow, previewRootArg, skipAttr) => {
    root.querySelectorAll('script').forEach(oldScript => {
      if (skipAttr && oldScript.hasAttribute(skipAttr)) return;
      if (oldScript.src) {
        const newScript = runtimeWindow.document.createElement('script');
        newScript.src = oldScript.src;
        oldScript.replaceWith(newScript);
        return;
      }
      runtimeWindow.Function('previewRoot', oldScript.textContent || '')(previewRootArg);
      oldScript.remove();
    });
  };
  const syncIframeMode = iframeDoc => {
    const root = document.documentElement;
    const explicitMode = root.getAttribute('bq-mode');
    const isDark = root.classList.contains('dark');
    const resolvedMode = explicitMode || (isDark ? 'dark' : 'light');
    iframeDoc.documentElement.setAttribute('bq-mode', resolvedMode);
    iframeDoc.body.setAttribute('bq-mode', resolvedMode);
  };
  useEffect(() => {
    if (mode === 'shadow') ensureParentBeeqRuntime();
  }, [mode]);
  useEffect(() => {
    const container = previewRef.current;
    if (!container) return;
    if (removePadding) container.style.padding = '0';
    container.innerHTML = '';
    if (mode === 'iframe') {
      const iframe = document.createElement('iframe');
      iframe.className = 'preview-iframe';
      iframe.style.width = '100%';
      iframe.style.border = '0';
      iframe.style.display = 'block';
      iframe.style.minHeight = height ?? '0px';
      iframe.setAttribute('title', 'Live code preview');
      iframe.setAttribute('loading', 'lazy');
      iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
      container.appendChild(iframe);
      const iframeDoc = iframe.contentDocument;
      const iframeWin = iframe.contentWindow;
      if (!iframeDoc || !iframeWin) return;
      iframeDoc.open();
      iframeDoc.write(['<!doctype html>', '<html>', '<head>', '  <meta charset="utf-8" />', '  <meta name="viewport" content="width=device-width, initial-scale=1" />', '  <style>html,body{margin:0;padding:0;min-height:100%;}</style>', `  <link rel="stylesheet" href="${BEEQ_CSS_URL}" />`, `  <script type="module" src="${BEEQ_ESM_URL}" data-beeq-iframe-runtime="${BEEQ_ICONS_URL}"></script>`, '</head>', '<body>', code, '</body>', '</html>'].join('\n'));
      iframeDoc.close();
      syncIframeMode(iframeDoc);
      const modeObserver = new MutationObserver(() => syncIframeMode(iframeDoc));
      modeObserver.observe(document.documentElement, {
        attributes: true,
        attributeFilter: ['class', 'bq-mode']
      });
      executeSnippetScripts(iframeDoc, iframeWin, iframeDoc, 'data-beeq-iframe-runtime');
      return () => modeObserver.disconnect();
    }
    const shadowRoot = container.shadowRoot ?? container.attachShadow({
      mode: 'open'
    });
    if (!shadowRoot.adoptedStyleSheets.length) {
      const fixSheet = new CSSStyleSheet();
      fixSheet.replaceSync(`
        bq-dropdown::part(panel),
        bq-panel::part(panel),
        bq-select::part(panel),
        bq-date-picker::part(panel) { z-index: 9999; }
        bq-tooltip::part(panel) { position: absolute; }
      `);
      shadowRoot.adoptedStyleSheets = [fixSheet];
    }
    shadowRoot.innerHTML = [`<link rel="stylesheet" href="${BEEQ_CSS_URL}">`, code].join('');
    executeSnippetScripts(shadowRoot, window, shadowRoot);
    return undefined;
  }, [code, mode, height]);
  return <div className="code-live-preview not-prose">
      {}
      <div className="preview" ref={previewRef} style={{
    minHeight: height
  }} />

      {}
      {children && <div className="code">{children}</div>}
    </div>;
};

<Frame className="px-4 py-4" caption="BEEQ spacing overview">
  <img className="block dark:hidden" src="https://mintcdn.com/beeq/hgUwMulNnDymPSd1/foundations/images/spacing/spacing-overview-light.svg?fit=max&auto=format&n=hgUwMulNnDymPSd1&q=85&s=1b7716d8622c7034e126680b18de3462" alt="BEEQ spacing overview - light mode" width="1246" height="442" data-path="foundations/images/spacing/spacing-overview-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/beeq/hgUwMulNnDymPSd1/foundations/images/spacing/spacing-overview-dark.svg?fit=max&auto=format&n=hgUwMulNnDymPSd1&q=85&s=310c6c75a37d94385d58291b25c36af5" alt="BEEQ spacing overview - dark mode" width="1246" height="442" data-path="foundations/images/spacing/spacing-overview-dark.svg" />
</Frame>

Spacing controls how close elements feel, how clearly sections separate, and how easily users can scan an interface. BEEQ uses one shared spacing scale for padding, margin, and gaps so product layouts stay consistent across components and screens.

Use BEEQ spacing tokens instead of one-off pixel values. The scale gives designers and developers the same language for compact details, grouped content, and larger page regions.

***

## 4px grid system

BEEQ spacing is built from a 4px grid. Most values are multiples of 4px, which creates predictable alignment and helps layouts scale cleanly across viewports.

<Frame className="px-4 py-4" caption="BEEQ 4px spacing grid system">
  <img className="block dark:hidden" src="https://mintcdn.com/beeq/hgUwMulNnDymPSd1/foundations/images/spacing/spacing-grid-system-light.svg?fit=max&auto=format&n=hgUwMulNnDymPSd1&q=85&s=601e56dae8d1653900622aaf5ae306d5" alt="BEEQ 4px spacing grid system - light mode" width="1230" height="457" data-path="foundations/images/spacing/spacing-grid-system-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/beeq/hgUwMulNnDymPSd1/foundations/images/spacing/spacing-grid-system-light.svg?fit=max&auto=format&n=hgUwMulNnDymPSd1&q=85&s=601e56dae8d1653900622aaf5ae306d5" alt="BEEQ 4px spacing grid system - dark mode" width="1230" height="457" data-path="foundations/images/spacing/spacing-grid-system-light.svg" />
</Frame>

The scale uses T-shirt naming from `xs3` through `xxl4`. Smaller values support tight relationships inside components, while larger values create separation between regions.

<Frame className="px-4 py-4" caption="BEEQ spacing tokens">
  <img className="block dark:hidden" src="https://mintcdn.com/beeq/hgUwMulNnDymPSd1/foundations/images/spacing/spacing-tokens-light.svg?fit=max&auto=format&n=hgUwMulNnDymPSd1&q=85&s=29ad09750c6db1a21896350533e85fe8" alt="BEEQ spacing tokens - light mode" width="1058" height="386" data-path="foundations/images/spacing/spacing-tokens-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/beeq/hgUwMulNnDymPSd1/foundations/images/spacing/spacing-tokens-dark.svg?fit=max&auto=format&n=hgUwMulNnDymPSd1&q=85&s=80f27db700705357a8a4f8a5ac487758" alt="BEEQ spacing tokens - dark mode" width="1058" height="386" data-path="foundations/images/spacing/spacing-tokens-dark.svg" />
</Frame>

***

## Spacing scale

The current BEEQ spacing scale is exposed as CSS custom properties and Tailwind spacing keys.
BEEQ defines spacing values in `rem` so layouts can scale with the root font size.
Pixel values are shown as the default equivalent, based on a `16px` root font size.

| Token  | CSS variable        | Tailwind key | Value              |
| ------ | ------------------- | ------------ | ------------------ |
| `xs3`  | `--bq-spacing-xs3`  | `xs3`        | `0.125rem` / `2px` |
| `xs2`  | `--bq-spacing-xs2`  | `xs2`        | `0.25rem` / `4px`  |
| `xs`   | `--bq-spacing-xs`   | `xs`         | `0.5rem` / `8px`   |
| `s`    | `--bq-spacing-s`    | `s`          | `0.75rem` / `12px` |
| `m`    | `--bq-spacing-m`    | `m`          | `1rem` / `16px`    |
| `l`    | `--bq-spacing-l`    | `l`          | `1.5rem` / `24px`  |
| `xl`   | `--bq-spacing-xl`   | `xl`         | `2rem` / `32px`    |
| `xxl`  | `--bq-spacing-xxl`  | `xxl`        | `2.5rem` / `40px`  |
| `xxl2` | `--bq-spacing-xxl2` | `xxl2`       | `3.5rem` / `56px`  |
| `xxl3` | `--bq-spacing-xxl3` | `xxl3`       | `4rem` / `64px`    |
| `xxl4` | `--bq-spacing-xxl4` | `xxl4`       | `4.5rem` / `72px`  |

The example below shows a representative subset of the spacing scale. Use the table above as the complete reference for the tokens available in BEEQ.

<CodeLivePreview
  mode="iframe"
  height="20rem"
  removePadding
  code={`
<style>
body {
  box-sizing: border-box;
  padding: var(--bq-spacing-m);
  color: var(--bq-text--primary);
  background: var(--bq-background--primary);
}

.spacing-scale {
  display: grid;
  gap: var(--bq-spacing-m);
  max-width: 42rem;
}

.spacing-row {
  display: grid;
  grid-template-columns: 4rem 1fr 7.5rem;
  align-items: center;
  gap: var(--bq-spacing-m);
}

.spacing-bar {
  block-size: var(--bq-spacing-m);
  border-radius: var(--bq-radius--full);
  background: var(--bq-ui--brand);
}

.spacing-bar--xs3 {
  inline-size: var(--bq-spacing-xs3);
}

.spacing-bar--xs {
  inline-size: var(--bq-spacing-xs);
}

.spacing-bar--m {
  inline-size: var(--bq-spacing-m);
}

.spacing-bar--l {
  inline-size: var(--bq-spacing-l);
}

.spacing-bar--xl {
  inline-size: var(--bq-spacing-xl);
}

.spacing-bar--xxl2 {
  inline-size: var(--bq-spacing-xxl2);
}

.spacing-bar--xxl4 {
  inline-size: var(--bq-spacing-xxl4);
}

.spacing-value {
  color: var(--bq-text--secondary);
  font-size: var(--bq-font-size--s);
  text-align: end;
}
</style>

<div class="spacing-scale" aria-label="Representative BEEQ spacing values">
<div class="spacing-row">
  <strong>xs3</strong>
  <span class="spacing-bar spacing-bar--xs3"></span>
  <span class="spacing-value">0.125rem / 2px</span>
</div>
<div class="spacing-row">
  <strong>xs</strong>
  <span class="spacing-bar spacing-bar--xs"></span>
  <span class="spacing-value">0.5rem / 8px</span>
</div>
<div class="spacing-row">
  <strong>m</strong>
  <span class="spacing-bar spacing-bar--m"></span>
  <span class="spacing-value">1rem / 16px</span>
</div>
<div class="spacing-row">
  <strong>l</strong>
  <span class="spacing-bar spacing-bar--l"></span>
  <span class="spacing-value">1.5rem / 24px</span>
</div>
<div class="spacing-row">
  <strong>xl</strong>
  <span class="spacing-bar spacing-bar--xl"></span>
  <span class="spacing-value">2rem / 32px</span>
</div>
<div class="spacing-row">
  <strong>xxl2</strong>
  <span class="spacing-bar spacing-bar--xxl2"></span>
  <span class="spacing-value">3.5rem / 56px</span>
</div>
<div class="spacing-row">
  <strong>xxl4</strong>
  <span class="spacing-bar spacing-bar--xxl4"></span>
  <span class="spacing-value">4.5rem / 72px</span>
</div>
</div>
`}
>
  <CodeGroup>
    ```css CSS icon="css" expandable theme={"theme":{"light":"one-light","dark":"night-owl"}}
    .spacing-scale {
      display: grid;
      gap: var(--bq-spacing-m);
      max-width: 42rem;
    }

    .spacing-row {
      display: grid;
      grid-template-columns: 4rem 1fr 7.5rem;
      align-items: center;
      gap: var(--bq-spacing-m);
    }

    .spacing-value {
      text-align: end;
    }

    .spacing-bar--xs3 {
      inline-size: var(--bq-spacing-xs3);
    }

    .spacing-bar--xs {
      inline-size: var(--bq-spacing-xs);
    }

    .spacing-bar--m {
      inline-size: var(--bq-spacing-m);
    }

    .spacing-bar--l {
      inline-size: var(--bq-spacing-l);
    }

    .spacing-bar--xl {
      inline-size: var(--bq-spacing-xl);
    }

    .spacing-bar--xxl2 {
      inline-size: var(--bq-spacing-xxl2);
    }

    .spacing-bar--xxl4 {
      inline-size: var(--bq-spacing-xxl4);
    }
    ```

    ```html HTML icon="html5" expandable theme={"theme":{"light":"one-light","dark":"night-owl"}}
    <div class="spacing-scale" aria-label="Representative BEEQ spacing values">
      <div class="spacing-row">
        <strong>xs3</strong>
        <span class="spacing-bar spacing-bar--xs3"></span>
        <span class="spacing-value">0.125rem / 2px</span>
      </div>
      <div class="spacing-row">
        <strong>xs</strong>
        <span class="spacing-bar spacing-bar--xs"></span>
        <span class="spacing-value">0.5rem / 8px</span>
      </div>
      <div class="spacing-row">
        <strong>m</strong>
        <span class="spacing-bar spacing-bar--m"></span>
        <span class="spacing-value">1rem / 16px</span>
      </div>
      <div class="spacing-row">
        <strong>l</strong>
        <span class="spacing-bar spacing-bar--l"></span>
        <span class="spacing-value">1.5rem / 24px</span>
      </div>
      <div class="spacing-row">
        <strong>xl</strong>
        <span class="spacing-bar spacing-bar--xl"></span>
        <span class="spacing-value">2rem / 32px</span>
      </div>
      <div class="spacing-row">
        <strong>xxl2</strong>
        <span class="spacing-bar spacing-bar--xxl2"></span>
        <span class="spacing-value">3.5rem / 56px</span>
      </div>
      <div class="spacing-row">
        <strong>xxl4</strong>
        <span class="spacing-bar spacing-bar--xxl4"></span>
        <span class="spacing-value">4.5rem / 72px</span>
      </div>
    </div>
    ```
  </CodeGroup>
</CodeLivePreview>

***

## Using spacing in code

BEEQ exposes one spacing scale. Gap utilities do not use separate gap tokens; they use the same values as padding and margin.

| Use case            | Example                               |
| ------------------- | ------------------------------------- |
| CSS custom property | `padding: var(--bq-spacing-m);`       |
| Tailwind padding    | `p-m`, `px-l`, `py-xs`                |
| Tailwind margin     | `m-l`, `mt-xl`, `mb-xs2`              |
| Tailwind gap        | `gap-m`, `gap-xl`                     |
| Logical padding     | `p-b-m`, `p-bs-xs`, `p-be-l`, `p-i-m` |
| Logical margin      | `m-b-l`, `m-bs-m`, `m-be-xl`, `m-i-m` |

Use logical utilities for layouts that need to adapt to writing direction or avoid left/right assumptions. Use CSS custom properties when writing custom CSS outside Tailwind utility composition.

<CodeLivePreview
  mode="iframe"
  height="18rem"
  removePadding
  code={`
<style>
body {
  box-sizing: border-box;
  padding: var(--bq-spacing-m);
  color: var(--bq-text--primary);
  background: var(--bq-background--primary);
}

.settings-panel {
  max-width: 34rem;
}

.settings-panel__content {
  display: grid;
  gap: var(--bq-spacing-xs);
}

.settings-panel__description {
  color: var(--bq-text--secondary);
}
</style>

<bq-card class="settings-panel">
<div class="settings-panel__content">
  <h2>Workspace settings</h2>
  <p class="settings-panel__description">
    The card owns its internal padding. The content controls the smaller gap between related text.
  </p>
  <bq-button appearance="primary">Save changes</bq-button>
</div>
</bq-card>
`}
>
  <CodeGroup>
    ```css CSS icon="css" expandable theme={"theme":{"light":"one-light","dark":"night-owl"}}
    .settings-panel {
      max-width: 34rem;
    }

    .settings-panel__content {
      display: grid;
      gap: var(--bq-spacing-xs);
    }
    ```

    ```html HTML icon="html5" expandable theme={"theme":{"light":"one-light","dark":"night-owl"}}
    <bq-card class="settings-panel">
      <div class="settings-panel__content">
        <h2>Workspace settings</h2>
        <p class="settings-panel__description">
          The card owns its internal padding. The content controls the smaller gap between related text.
        </p>
        <bq-button appearance="primary">Save changes</bq-button>
      </div>
    </bq-card>
    ```
  </CodeGroup>
</CodeLivePreview>

***

## Internal and external spacing

Internal spacing is the space inside an element or component. It usually uses smaller values because the content is related. External spacing is the space between elements, groups, or page regions. It usually uses larger values to create separation and improve scanability.

Component internals already use BEEQ spacing. When you build custom layouts, use the same scale so page-level rhythm matches the components inside it.

<Frame className="px-4 py-4" caption="Spacing inside and between components">
  <img className="block dark:hidden" src="https://mintcdn.com/beeq/hgUwMulNnDymPSd1/foundations/images/spacing/spacing-usage-overview-light.svg?fit=max&auto=format&n=hgUwMulNnDymPSd1&q=85&s=121f529ad46aae05a6aee094a90be663" alt="Spacing inside and between components - light mode" width="1344" height="646" data-path="foundations/images/spacing/spacing-usage-overview-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/beeq/hgUwMulNnDymPSd1/foundations/images/spacing/spacing-usage-overview-dark.svg?fit=max&auto=format&n=hgUwMulNnDymPSd1&q=85&s=e856a5292e1abad65c9bbfbdadf0dece" alt="Spacing inside and between components - dark mode" width="1344" height="646" data-path="foundations/images/spacing/spacing-usage-overview-dark.svg" />
</Frame>

<CodeLivePreview
  mode="iframe"
  height="24rem"
  removePadding
  code={`
<style>
body {
  box-sizing: border-box;
  padding: var(--bq-spacing-m);
  color: var(--bq-text--primary);
  background: var(--bq-background--primary);
}

.layout-example {
  display: grid;
  gap: var(--bq-spacing-xl);
  max-width: 42rem;
}

.layout-card__content {
  display: grid;
  gap: var(--bq-spacing-xs);
  padding: var(--bq-spacing-m);
}

.layout-card__content p {
  color: var(--bq-text--secondary);
}
</style>

<div class="layout-example">
<bq-card type="minimal">
  <article class="layout-card__content">
    <h2>Account health</h2>
    <p>Small internal gaps keep title and description connected.</p>
  </article>
</bq-card>
<bq-card type="minimal">
  <article class="layout-card__content">
    <h2>Billing status</h2>
    <p>The larger external gap separates this card from the previous region.</p>
  </article>
</bq-card>
</div>
`}
>
  <CodeGroup>
    ```css CSS icon="css" expandable theme={"theme":{"light":"one-light","dark":"night-owl"}}
    .layout-example {
      display: grid;
      gap: var(--bq-spacing-xl);
      max-width: 42rem;
    }

    .layout-card__content {
      display: grid;
      gap: var(--bq-spacing-xs);
      padding: var(--bq-spacing-m);
    }
    ```

    ```html HTML icon="html5" expandable theme={"theme":{"light":"one-light","dark":"night-owl"}}
    <div class="layout-example">
      <bq-card type="minimal">
        <article class="layout-card__content">
          <h2>Account health</h2>
          <p>Small internal gaps keep title and description connected.</p>
        </article>
      </bq-card>
      <bq-card type="minimal">
        <article class="layout-card__content">
          <h2>Billing status</h2>
          <p>The larger external gap separates this card from the previous region.</p>
        </article>
      </bq-card>
    </div>
    ```
  </CodeGroup>
</CodeLivePreview>

***

## Usage guidelines

<AccordionGroup>
  <Accordion title="Use the BEEQ scale">
    Choose spacing values from the BEEQ scale instead of arbitrary pixels. This keeps layout rhythm aligned with components and design tokens.
  </Accordion>

  <Accordion title="Group related content with smaller spacing">
    Use smaller values such as `xs`, `s`, and `m` for labels, descriptions, icon-text pairs, and content that belongs together.
  </Accordion>

  <Accordion title="Separate regions with larger spacing">
    Use larger values such as `l`, `xl`, `xxl`, and above to separate cards, panels, sections, and page regions.
  </Accordion>

  <Accordion title="Keep vertical rhythm consistent">
    Use repeated spacing decisions for similar content patterns. Consistent rhythm makes pages easier to scan and reduces visual noise.
  </Accordion>

  <Accordion title="Use logical spacing utilities">
    Prefer utilities such as `p-b-m`, `p-i-m`, `m-b-l`, and `m-i-l` when spacing should follow block and inline directions instead of physical top, right, bottom, and left.
  </Accordion>

  <Accordion title="Avoid arbitrary values">
    Avoid values like `10px`, `18px`, or `30px` unless there is a clear exception. Custom values make interfaces harder to align and maintain.
  </Accordion>
</AccordionGroup>

***

## Resources

<CardGroup cols={2}>
  <Card title="Global CSS variables" icon="code" href="/theming/global-css-variables">
    Review the spacing custom properties used by BEEQ themes.
  </Card>

  <Card title="Tailwind spacing source" icon="github" href="https://github.com/Endava/BEEQ/tree/main/packages/beeq-tailwindcss/src/theme/default">
    See the source that defines the BEEQ spacing scale.
  </Card>
</CardGroup>
