Padding and margin — all sides, individual, axes, and auto. Fixed values and fluid ranges that scale between viewports.
p-{min}-{max}p-8-16
p-16-32
p-24-48
p-32-64
pt pb ps pept-24
pb-24
ps-24
pe-24
Fluid: pt-16-48, pb-8-24, ps-12-32, pe-12-32
Uses logical properties (padding-inline-start / padding-inline-end) — in LTR these sit left/right as expected; in RTL they automatically flip.
px / pypx-24-48 (left + right)
py-24-48 (top + bottom)
p-{bp}-{min}-{max}p-md-16-48 — fluid padding from md up
p-lg-24-64 — fluid padding from lg up
m-{value}m-16
mt-16 mb-16
ms-16 me-16
m-{min}-{max}mt-16-48 (fluid)
mb-16-48 (fluid)
mx / mymx-24-48 (left + right)
my-24-48 (top + bottom)
mx-auto / ms-autoSupports breakpoints: mx-md-auto, ms-lg-auto, etc.
mx-auto maxw-400
ms-auto maxw-400
mb-{bp}-{min}-{max}mb-md-16-32 — fluid margin-bottom from md up
mt-lg-24-48 — fluid margin-top from lg up
stack-{min}-{max}One class on the parent spaces all direct children — :where(.stack-16-32) > * + * { margin-top: clamp(…) }. No space above the first or below the last child. Made for markup you don't class per-element: CMS body fields, form items, card innards.
Every child is unclassed — the parent provides the rhythm.
Fluid: the spacing itself scales with the viewport.
Last child — no trailing space below.
Normal rhythm here.
This one has mt-32-48 — child utilities always win (the stack rule has zero specificity via :where()).
mt-0 glues this to the one above.
Fixed and breakpoint forms work as usual: stack-24, stack-md-16-32. Use gap when the parent is already flex or grid; stack works in normal document flow.
n prefixmt-n10 → margin-top: -0.625rem. Useful for pull-ups, overlapping cards, bleeding full-width sections out of a padded parent. All margin prefixes (m mt mb ms me mx my) opt in. Fluid ranges too: mt-n10-n5.
parent, padding-24
mt-n10 — pulls up into the one above
ms-n16 me-n16 — bleeds left and right past the parent's padding