# Bleed (/docs/bleed)





## API Reference [#api-reference]

`Bleed` is a moduix layout primitive and does not wrap a Base UI primitive.
Use `inline="none"` or `block="none"` to keep an axis constrained. Supported
bleed amounts are `xs`, `sm`, `md`, `lg`, `xl`, plus `full` on the inline axis.
Use `as` to render a semantic element or custom component while keeping the same
bleed behavior.

## Basic [#basic]

<Preview cssProperties="bleedPlaygroundCssProperties">
  <BleedExample />

  <Preview.Code>
    {`
          import { Bleed, Text } from "moduix";

          export function BleedDemo() {
            return (
              <div className={styles.container}>
                <Text tone="muted">Container content stays constrained.</Text>
                <Bleed className={styles.bleed}>
                  <Text weight="semibold">
                    This block bleeds to the viewport edges.
                  </Text>
                </Bleed>
                <Text tone="muted">
                  Following content returns to the container width.
                </Text>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .container {
            display: flex;
            width: min(28rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-4);
            padding: var(--spacing-4);
            border: var(--border-width-sm) dashed var(--color-border);
          }

          .bleed {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: var(--spacing-4);
            background-color: var(--color-muted);
            text-align: center;
          }
        `}
  </Preview.CSS>

  <Preview.CSSProperties>
    {(context) => <BleedCssPropertiesPanel {...context} />}
  </Preview.CSSProperties>

  <Preview.CSSPlayground>
    {(context) => <BleedCssPlaygroundPanel {...context} />}
  </Preview.CSSPlayground>
</Preview>

## Anatomy [#anatomy]

`Bleed` is a single root layout primitive. It applies negative inline and/or block margins so
content can extend beyond a constrained parent while staying in normal document flow.

```text
Bleed
└─ children
```

```tsx
<Bleed inline="md" block="none">
  <div className={styles.panel}>Escaped content</div>
</Bleed>
```

| Part    | Role                                                                       |
| ------- | -------------------------------------------------------------------------- |
| `Bleed` | Root layout wrapper. Controls inline/block bleed amounts and element type. |

## Composition [#composition]

Use `Bleed` props `inline` and `block` to control bleed amount per axis, and `as` when the root
should be a specific semantic element such as `section` or `figure`. The component forwards refs to
the rendered element, so it can be measured, focused, or passed to animation libraries like any
native element.

`Bleed` has no internal service slots, so customization is done directly with `className` and
bleed CSS variables on the root element.

## Examples [#examples]

### Inline Amounts [#inline-amounts]

Use `inline` to choose how far content escapes the container on the inline axis.

<Preview>
  <BleedInlineAmountsExample />

  <Preview.Code>
    {`
          import { Bleed, Text } from "moduix";

          export function BleedInlineAmountsDemo() {
            return (
              <div className={styles.container}>
                <Bleed inline="sm" className={styles.panel}>
                  <Text>Small inline bleed</Text>
                </Bleed>
                <Bleed inline="lg" className={styles.panel}>
                  <Text>Large inline bleed</Text>
                </Bleed>
                <Bleed inline="full" className={styles.panel}>
                  <Text>Full inline bleed</Text>
                </Bleed>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .container {
            display: flex;
            width: min(28rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-4);
            padding: var(--spacing-4);
            border: var(--border-width-sm) dashed var(--color-border);
          }

          .panel {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: var(--spacing-4);
            background-color: var(--color-muted);
            text-align: center;
          }
        `}
  </Preview.CSS>
</Preview>

### Block Bleed [#block-bleed]

Use `block` when a surface should also escape vertical container padding.

<Preview>
  <BleedBlockExample />

  <Preview.Code>
    {`
          import { Bleed, Text } from "moduix";

          export function BleedBlockDemo() {
            return (
              <div className={styles.paddedContainer}>
                <Text tone="muted">Container padding above.</Text>
                <Bleed inline="md" block="md" className={styles.panel}>
                  <Text>Inline and block bleed</Text>
                </Bleed>
                <Text tone="muted">Container padding below.</Text>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .paddedContainer {
            display: flex;
            width: min(28rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-4);
            padding: var(--spacing-6);
            border: var(--border-width-sm) dashed var(--color-border);
          }

          .panel {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: var(--spacing-4);
            background-color: var(--color-muted);
            text-align: center;
          }
        `}
  </Preview.CSS>
</Preview>

### Semantic Element [#semantic-element]

Use `as` when the escaping content has a more specific semantic role.

<Preview>
  <BleedSemanticExample />

  <Preview.Code>
    {`
          import { Bleed, Text } from "moduix";

          export function BleedSemanticDemo() {
            return (
              <div className={styles.container}>
                <Bleed as="figure" className={styles.figure}>
                  <div className={styles.media} />
                  <Text tone="muted" size="sm">
                    Full-width media with a constrained parent.
                  </Text>
                </Bleed>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .container {
            display: flex;
            width: min(28rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-4);
            padding: var(--spacing-4);
            border: var(--border-width-sm) dashed var(--color-border);
          }

          .figure {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: var(--spacing-3);
            padding: var(--spacing-4);
            background-color: var(--color-muted);
            text-align: center;
          }

          .media {
            width: min(28rem, 100%);
            min-height: 8rem;
            border-radius: var(--radius-md);
            background: linear-gradient(135deg, rgb(0 0 0 / 0.14), transparent 45%), var(--color-accent);
          }
        `}
  </Preview.CSS>
</Preview>

### Custom Styles [#custom-styles]

Pass `className` when styling the root or overriding bleed variables in local CSS.

<Preview>
  <CustomStylesBleedExample />

  <Preview.Code>
    {`
          import { Bleed, Text } from "moduix";

          export function CustomStylesBleedDemo() {
            return (
              <div className={styles.container}>
                <Bleed className={styles.customBleed}>
                  <Text weight="semibold">Customized bleed amount.</Text>
                </Bleed>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .container {
            display: flex;
            width: min(28rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-4);
            padding: var(--spacing-4);
            border: var(--border-width-sm) dashed var(--color-border);
          }

          .customBleed {
            --bleed-inline-full: calc(var(--spacing-8) * -1);
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: var(--spacing-4);
            background-color: var(--color-muted);
            text-align: center;
          }
        `}
  </Preview.CSS>
</Preview>
