Flexbox & Grid
Overview
Flexbox and grid utilities help you create flexible, responsive layouts. These utilities cover flex properties, grid templates, gap spacing, and alignment controls.
Why Use Flexbox & Grid Utilities?
Flexbox and grid utilities help you:
- Build responsive layouts: Create flexible layouts that adapt to different screen sizes
- Control alignment: Position items precisely within containers
- Manage spacing: Use gap utilities for consistent spacing between items
- Integrate with design tokens: Reference spacing values from your design system
Flex Utilities
useFlexUtility
The useFlexUtility() function creates utility classes for the flex shorthand property.
import { styleframe } from "styleframe";
import { useFlexUtility } from "@styleframe/theme";
const s = styleframe();
// Uses built-in defaults: 1, auto, initial, none
useFlexUtility(s);
export default s;
._flex\:1 { flex: 1 1 0%; }
._flex\:auto { flex: 1 1 auto; }
._flex\:initial { flex: 0 1 auto; }
._flex\:none { flex: none; }
<div class="_display:flex">
<div class="_flex:1">Grows to fill space</div>
<div class="_flex:none">Fixed size</div>
</div>
Default Flex Values
| Key | Value | Description |
|---|---|---|
1 | 1 1 0% | Grow and shrink, ignore initial size |
auto | 1 1 auto | Grow and shrink based on content |
initial | 0 1 auto | Don't grow, but shrink if needed |
none | none | Don't grow or shrink |
useFlexGrowUtility & useFlexShrinkUtility
Control individual flex grow and shrink properties.
import { useFlexGrowUtility, useFlexShrinkUtility } from "@styleframe/theme";
useFlexGrowUtility(s, { '0': '0', '1': '1' });
useFlexShrinkUtility(s, { '0': '0', '1': '1' });
useFlexBasisUtility
Set the initial size of flex items.
import { useFlexBasisUtility } from "@styleframe/theme";
useFlexBasisUtility(s, {
'0': '0px',
auto: 'auto',
'1/2': '50%',
'1/3': '33.333333%',
'2/3': '66.666667%',
full: '100%',
});
useFlexDirectionUtility
Control the direction of flex items.
import { styleframe } from "styleframe";
import { useFlexDirectionUtility } from "@styleframe/theme";
const s = styleframe();
useFlexDirectionUtility(s, {
row: 'row',
'row-reverse': 'row-reverse',
col: 'column',
'col-reverse': 'column-reverse',
});
export default s;
._flex-direction\:row { flex-direction: row; }
._flex-direction\:row-reverse { flex-direction: row-reverse; }
._flex-direction\:col { flex-direction: column; }
._flex-direction\:col-reverse { flex-direction: column-reverse; }
<div class="_display:flex _flex-direction:row">Horizontal layout</div>
<div class="_display:flex _flex-direction:col">Vertical layout</div>
useFlexWrapUtility
Control how flex items wrap.
import { useFlexWrapUtility } from "@styleframe/theme";
useFlexWrapUtility(s, {
wrap: 'wrap',
'wrap-reverse': 'wrap-reverse',
nowrap: 'nowrap',
});
Grid Utilities
useGridTemplateColumnsUtility
Define grid column templates.
import { styleframe } from "styleframe";
import { useGridTemplateColumnsUtility } from "@styleframe/theme";
const s = styleframe();
useGridTemplateColumnsUtility(s, {
'1': 'repeat(1, minmax(0, 1fr))',
'2': 'repeat(2, minmax(0, 1fr))',
'3': 'repeat(3, minmax(0, 1fr))',
'4': 'repeat(4, minmax(0, 1fr))',
'6': 'repeat(6, minmax(0, 1fr))',
'12': 'repeat(12, minmax(0, 1fr))',
none: 'none',
subgrid: 'subgrid',
});
export default s;
._grid-cols\:1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
._grid-cols\:2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
._grid-cols\:3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
._grid-cols\:4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
._grid-cols\:6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
._grid-cols\:12 { grid-template-columns: repeat(12, minmax(0, 1fr)); }
._grid-cols\:none { grid-template-columns: none; }
._grid-cols\:subgrid { grid-template-columns: subgrid; }
<div class="_display:grid _grid-cols:3 _gap:md">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
useGridColumnUtility
Control how elements span grid columns.
import { useGridColumnUtility, useGridColumnStartUtility, useGridColumnEndUtility } from "@styleframe/theme";
useGridColumnUtility(s, {
auto: 'auto',
'span-1': 'span 1 / span 1',
'span-2': 'span 2 / span 2',
'span-3': 'span 3 / span 3',
'span-full': '1 / -1',
});
useGridColumnStartUtility(s, { '1': '1', '2': '2', '3': '3', auto: 'auto' });
useGridColumnEndUtility(s, { '1': '1', '2': '2', '3': '3', auto: 'auto' });
useGridAutoFlowUtility
Control how auto-placed items flow in the grid.
import { styleframe } from "styleframe";
import { useGridAutoFlowUtility } from "@styleframe/theme";
const s = styleframe();
// Uses built-in defaults
useGridAutoFlowUtility(s);
export default s;
._grid-flow\:row { grid-auto-flow: row; }
._grid-flow\:col { grid-auto-flow: column; }
._grid-flow\:dense { grid-auto-flow: dense; }
._grid-flow\:row-dense { grid-auto-flow: row dense; }
._grid-flow\:col-dense { grid-auto-flow: column dense; }
<div class="_display:grid _grid-flow:dense">
Dense auto-placement grid
</div>
Gap Utilities
useGapUtility
Set the gap between flex or grid items. Gap utilities support both named values and multiplier values.
import { styleframe } from "styleframe";
import { useSpacing } from "@styleframe/theme";
import { useGapUtility, useGapXUtility, useGapYUtility } from "@styleframe/theme";
const s = styleframe();
const { ref } = s;
const { spacing, spacingSm, spacingMd, spacingLg } = useSpacing(s, {
default: '1rem',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
} as const);
const createGap = useGapUtility(s, {
'0': '0',
sm: ref(spacingSm),
md: ref(spacingMd),
lg: ref(spacingLg),
});
// Add multiplier values for flexible gap sizing (with @ prefix)
createGap(["@1.5", "@2", "@0.5"]);
useGapXUtility(s, {
sm: ref(spacingSm),
md: ref(spacingMd),
});
useGapYUtility(s, {
sm: ref(spacingSm),
md: ref(spacingMd),
});
export default s;
:root {
--spacing: 1rem;
--spacing--sm: 0.5rem;
--spacing--md: 1rem;
--spacing--lg: 1.5rem;
}
._gap\:0 { gap: 0; }
._gap\:sm { gap: var(--spacing--sm); }
._gap\:md { gap: var(--spacing--md); }
._gap\:lg { gap: var(--spacing--lg); }
/* Multiplier values (with fallback) */
._gap\:1\.5 { gap: calc(var(--spacing, 1rem) * 1.5); }
._gap\:2 { gap: calc(var(--spacing, 1rem) * 2); }
._gap\:0\.5 { gap: calc(var(--spacing, 1rem) * 0.5); }
._gap-x\:sm { column-gap: var(--spacing--sm); }
._gap-x\:md { column-gap: var(--spacing--md); }
._gap-y\:sm { row-gap: var(--spacing--sm); }
._gap-y\:md { row-gap: var(--spacing--md); }
<div class="_display:flex _gap:md">Equal gap all around</div>
<div class="_display:grid _gap-x:lg _gap-y:sm">Different horizontal/vertical gaps</div>
<div class="_display:flex _gap:1.5">1.5x base spacing gap</div>
Alignment Utilities
useJustifyContentUtility
Align items along the main axis.
import { styleframe } from "styleframe";
import { useJustifyContentUtility } from "@styleframe/theme";
const s = styleframe();
// Uses built-in defaults
useJustifyContentUtility(s);
export default s;
._justify\:normal { justify-content: normal; }
._justify\:start { justify-content: flex-start; }
._justify\:end { justify-content: flex-end; }
._justify\:center { justify-content: center; }
._justify\:between { justify-content: space-between; }
._justify\:around { justify-content: space-around; }
._justify\:evenly { justify-content: space-evenly; }
._justify\:stretch { justify-content: stretch; }
<div class="_display:flex _justify:center">Centered items</div>
<div class="_display:flex _justify:between">Space between items</div>
<div class="_display:flex _justify:evenly">Evenly distributed</div>
Alignment Utilities Reference
| Utility | CSS Property | Purpose |
|---|---|---|
useJustifyContentUtility | justify-content | Align items on main axis |
useJustifyItemsUtility | justify-items | Align grid items on inline axis |
useJustifySelfUtility | justify-self | Align individual item on inline axis |
useAlignContentUtility | align-content | Align rows on cross axis |
useAlignItemsUtility | align-items | Align items on cross axis |
useAlignSelfUtility | align-self | Align individual item on cross axis |
usePlaceContentUtility | place-content | Shorthand for align + justify content |
usePlaceItemsUtility | place-items | Shorthand for align + justify items |
usePlaceSelfUtility | place-self | Shorthand for align + justify self |
useOrderUtility
Control the order of flex and grid items.
import { useOrderUtility } from "@styleframe/theme";
useOrderUtility(s, {
first: '-9999',
last: '9999',
none: '0',
'1': '1',
'2': '2',
});
Examples
Responsive Card Grid
import { styleframe } from "styleframe";
import { useDisplayUtility } from "@styleframe/theme";
import { useGridTemplateColumnsUtility, useGapUtility } from "@styleframe/theme";
const s = styleframe();
useDisplayUtility(s);
useGridTemplateColumnsUtility(s, {
'1': 'repeat(1, minmax(0, 1fr))',
'2': 'repeat(2, minmax(0, 1fr))',
'3': 'repeat(3, minmax(0, 1fr))',
});
useGapUtility(s, { md: '1rem', lg: '1.5rem' });
export default s;
._display\:grid { display: grid; }
._grid-cols\:1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
._grid-cols\:2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
._grid-cols\:3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
._gap\:md { gap: 1rem; }
._gap\:lg { gap: 1.5rem; }
Usage in HTML:
<div class="_display:grid _grid-cols:1 _gap:md md:_grid-cols:2 lg:_grid-cols:3 lg:_gap:lg">
<div>Card 1</div>
<div>Card 2</div>
<div>Card 3</div>
</div>
Centered Flex Container
import { styleframe } from "styleframe";
import { useDisplayUtility, useJustifyContentUtility, useAlignItemsUtility } from "@styleframe/theme";
const s = styleframe();
useDisplayUtility(s);
useJustifyContentUtility(s);
useAlignItemsUtility(s);
export default s;
._display\:flex { display: flex; }
._justify\:center { justify-content: center; }
._align-items\:center { align-items: center; }
Usage in HTML:
<div class="_display:flex _justify:center _align-items:center" style="height: 100vh;">
<div>Centered content</div>
</div>
Best Practices
- Use gap instead of margins: Gap utilities are cleaner and don't require negative margins
- Leverage design tokens: Reference spacing values for consistent gaps
- Use semantic column counts: Define columns by purpose (1, 2, 3) rather than arbitrary numbers
- Combine flex and grid: Use flexbox for one-dimensional layouts, grid for two-dimensional
- Test wrapping behavior: Ensure layouts work when items wrap to new lines
- Consider RTL support: Alignment values like
startandendwork in both LTR and RTL
FAQ
display: flex with justify-content: center and align-items: center. Or use the place-items: center shorthand which sets both at once.flex: 1 (which is flex: 1 1 0%) means the item will grow to fill available space, can shrink if needed, and its initial size is 0 (so all items start equal and grow proportionally).