Utilities
Spacing
Create spacing utilities for margin and padding with directional variants and full type safety.
Overview
Spacing utilities help you control the space around and inside elements using margin and padding. These utilities include comprehensive directional variants for fine-grained control.
Why Use Spacing Utilities?
Spacing utilities help you:
- Create consistent spacing: Reference design tokens for uniform spacing across your application
- Control direction: Apply spacing to specific sides using directional variants
- Support RTL layouts: Use logical properties (start/end) for internationalization
- Build responsive designs: Combine with modifiers for responsive spacing
useMarginUtility
The useMarginUtility() function creates utility classes for setting margins.
styleframe.config.ts
import { styleframe } from "styleframe";
import { useSpacing } from "@styleframe/theme";
import { useMarginUtility } from "@styleframe/theme";
const s = styleframe();
const { ref } = s;
const { spacing, spacingSm, spacingMd, spacingLg, spacingXl } = useSpacing(s, {
default: '1rem',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
xl: '2rem',
} as const);
useMarginUtility(s, {
'0': '0',
sm: ref(spacingSm),
md: ref(spacingMd),
lg: ref(spacingLg),
xl: ref(spacingXl),
auto: 'auto',
});
export default s;
styleframe/index.css
:root {
--spacing: 1rem;
--spacing--sm: 0.5rem;
--spacing--md: 1rem;
--spacing--lg: 1.5rem;
--spacing--xl: 2rem;
}
._margin\:0 { margin: 0; }
._margin\:sm { margin: var(--spacing--sm); }
._margin\:md { margin: var(--spacing--md); }
._margin\:lg { margin: var(--spacing--lg); }
._margin\:xl { margin: var(--spacing--xl); }
._margin\:auto { margin: auto; }
<div class="_margin:md">Medium margin all sides</div>
<div class="_margin:auto">Auto margin (for centering)</div>
Directional Margin Variants
| Utility | CSS Property | Description |
|---|---|---|
useMarginUtility | margin | All sides |
useMarginInlineUtility | margin-left, margin-right | Horizontal (left & right) |
useMarginBlockUtility | margin-top, margin-bottom | Vertical (top & bottom) |
useMarginTopUtility | margin-top | Top only |
useMarginRightUtility | margin-right | Right only |
useMarginBottomUtility | margin-bottom | Bottom only |
useMarginLeftUtility | margin-left | Left only |
useMarginInlineStartUtility | margin-inline-start | Inline start (RTL-aware) |
useMarginInlineEndUtility | margin-inline-end | Inline end (RTL-aware) |
styleframe.config.ts
import { styleframe } from "styleframe";
import {
useMarginUtility,
useMarginInlineUtility,
useMarginBlockUtility,
useMarginTopUtility,
useMarginBottomUtility,
} from "@styleframe/theme";
const s = styleframe();
const spacingValues = {
'0': '0',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
auto: 'auto',
};
useMarginUtility(s, spacingValues);
useMarginInlineUtility(s, spacingValues);
useMarginBlockUtility(s, spacingValues);
useMarginTopUtility(s, spacingValues);
useMarginBottomUtility(s, spacingValues);
export default s;
styleframe/index.css
._margin\:md { margin: 1rem; }
._margin-inline\:md { margin-left: 1rem; margin-right: 1rem; }
._margin-block\:md { margin-top: 1rem; margin-bottom: 1rem; }
._margin-top\:md { margin-top: 1rem; }
._margin-bottom\:md { margin-bottom: 1rem; }
/* ... more values */
<div class="_margin-top:md">Top margin only</div>
<div class="_margin-inline:lg">Left and right margin</div>
<div class="_margin-block:sm">Top and bottom margin</div>
usePaddingUtility
The usePaddingUtility() function creates utility classes for setting padding.
styleframe.config.ts
import { styleframe } from "styleframe";
import { useSpacing } from "@styleframe/theme";
import { usePaddingUtility } from "@styleframe/theme";
const s = styleframe();
const { ref } = s;
const { spacingSm, spacingMd, spacingLg, spacingXl } = useSpacing(s, {
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
xl: '2rem',
} as const);
usePaddingUtility(s, {
'0': '0',
sm: ref(spacingSm),
md: ref(spacingMd),
lg: ref(spacingLg),
xl: ref(spacingXl),
});
export default s;
styleframe/index.css
:root {
--spacing--sm: 0.5rem;
--spacing--md: 1rem;
--spacing--lg: 1.5rem;
--spacing--xl: 2rem;
}
._padding\:0 { padding: 0; }
._padding\:sm { padding: var(--spacing--sm); }
._padding\:md { padding: var(--spacing--md); }
._padding\:lg { padding: var(--spacing--lg); }
._padding\:xl { padding: var(--spacing--xl); }
<div class="_padding:md">Medium padding all sides</div>
<div class="_padding:lg">Large padding all sides</div>
Directional Padding Variants
| Utility | CSS Property | Description |
|---|---|---|
usePaddingUtility | padding | All sides |
usePaddingInlineUtility | padding-left, padding-right | Horizontal |
usePaddingBlockUtility | padding-top, padding-bottom | Vertical |
usePaddingTopUtility | padding-top | Top only |
usePaddingRightUtility | padding-right | Right only |
usePaddingBottomUtility | padding-bottom | Bottom only |
usePaddingLeftUtility | padding-left | Left only |
usePaddingInlineStartUtility | padding-inline-start | Inline start |
usePaddingInlineEndUtility | padding-inline-end | Inline end |
useSpaceUtility
The useSpaceUtility() creates spacing between child elements using the "lobotomized owl" selector pattern.
styleframe.config.ts
import { styleframe } from "styleframe";
import { useSpaceXUtility, useSpaceYUtility } from "@styleframe/theme";
const s = styleframe();
useSpaceXUtility(s, {
'0': '0',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
});
useSpaceYUtility(s, {
'0': '0',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
});
export default s;
styleframe/index.css
._space-x\:sm > * + * { margin-left: 0.5rem; }
._space-x\:md > * + * { margin-left: 1rem; }
._space-x\:lg > * + * { margin-left: 1.5rem; }
._space-y\:sm > * + * { margin-top: 0.5rem; }
._space-y\:md > * + * { margin-top: 1rem; }
._space-y\:lg > * + * { margin-top: 1.5rem; }
<div class="_space-x:md">
<span>Item 1</span>
<span>Item 2</span>
<span>Item 3</span>
</div>
<div class="_space-y:lg">
<div>Row 1</div>
<div>Row 2</div>
</div>
Pro tip: For flex and grid layouts, prefer
gap utilities over space utilities. Gap doesn't require negative margins and works more predictably.Examples
Card with Consistent Padding
styleframe.config.ts
import { styleframe } from "styleframe";
import { useSpacing } from "@styleframe/theme";
import { usePaddingUtility, useMarginBottomUtility } from "@styleframe/theme";
const s = styleframe();
const { ref } = s;
const { spacingMd, spacingLg } = useSpacing(s, {
md: '1rem',
lg: '1.5rem',
} as const);
usePaddingUtility(s, {
md: ref(spacingMd),
lg: ref(spacingLg),
});
useMarginBottomUtility(s, {
md: ref(spacingMd),
});
export default s;
styleframe/index.css
:root {
--spacing--md: 1rem;
--spacing--lg: 1.5rem;
}
._padding\:md { padding: var(--spacing--md); }
._padding\:lg { padding: var(--spacing--lg); }
._margin-bottom\:md { margin-bottom: var(--spacing--md); }
Usage in HTML:
<div class="card _padding:lg">
<h2 class="_margin-bottom:md">Card Title</h2>
<p>Card content goes here.</p>
</div>
Centered Container with Auto Margins
styleframe.config.ts
import { styleframe } from "styleframe";
import { useMarginInlineUtility, usePaddingInlineUtility } from "@styleframe/theme";
const s = styleframe();
useMarginInlineUtility(s, { auto: 'auto' });
usePaddingInlineUtility(s, { md: '1rem', lg: '2rem' });
export default s;
styleframe/index.css
._margin-inline\:auto { margin-left: auto; margin-right: auto; }
._padding-inline\:md { padding-left: 1rem; padding-right: 1rem; }
._padding-inline\:lg { padding-left: 2rem; padding-right: 2rem; }
Usage in HTML:
<div class="_margin-inline:auto _padding-inline:md" style="max-width: 1200px;">
Centered content with horizontal padding
</div>
Best Practices
- Use design tokens: Reference your spacing scale with
ref()for consistent spacing - Prefer gap over space utilities: For flex/grid, gap is cleaner and more predictable
- Use logical properties for RTL:
margin-inline-startadapts to text direction - Keep spacing scales consistent: Use the same scale for both margin and padding
- Avoid magic numbers: Use named spacing values instead of arbitrary pixel values
FAQ
Use margin for space between elements and padding for space inside elements. Margins can collapse (vertically), while padding cannot. Use padding when you need the space to be part of the element's clickable area or background.
margin-inline uses CSS logical properties that adapt to text direction (LTR/RTL). In LTR, margin-inline-start equals margin-left. In RTL, it equals margin-right. Use logical properties for better internationalization support.Space utilities use the
* + * selector which adds margin to all children except the first. This can cause issues with hidden elements, dynamically rendered content, or when combined with other margin utilities. Gap utilities are generally more predictable.Yes, you can define negative margin values in your utility configuration. Negative margins are useful for pulling elements together or creating overlapping effects, but use them sparingly as they can make layouts harder to understand.