Utility Classes
While Oat is a classless framework at its core, it provides a comprehensive set of utility classes for layout, spacing, typography, and responsive design. No Angular wrappers needed — just add the class.
Flexbox
Stack layouts
hstack (horizontal)
<div class="hstack gap-2">
<div>A</div>
<div>B</div>
<div>C</div>
</div>vstack (vertical)
<div class="vstack gap-2">
<div>A</div>
<div>B</div>
<div>C</div>
</div>Flex utility classes
| Class | CSS |
|---|---|
.flex | display: flex |
.flex-col | flex-direction: column |
.flex-row | flex-direction: row |
.flex-wrap | flex-wrap: wrap |
.flex-1 | flex: 1 |
.hstack | flex + center + wrap + gap |
.vstack | flex-column + gap |
Alignment
Live: justify & align
justify-center + items-center
justify-between + items-center
justify-end
<!-- Center both axes -->
<div class="flex justify-center items-center" style="min-height: 80px;">
<div>Centered</div>
</div>
<!-- Space between -->
<div class="flex justify-between items-center">
<div>Left</div>
<div>Right</div>
</div>
<!-- Align end -->
<div class="flex justify-end">
<div>End</div>
</div>| Class | CSS |
|---|---|
.items-center | align-items: center |
.items-start | align-items: flex-start |
.items-end | align-items: flex-end |
.justify-center | justify-content: center |
.justify-between | justify-content: space-between |
.justify-end | justify-content: flex-end |
.justify-start | justify-content: flex-start |
Responsive flex direction
Items stack vertically on mobile and switch to horizontal on medium screens.
<!-- Vertical on mobile, horizontal on md+ -->
<div class="flex flex-col md:flex-row gap-2">
<div class="flex-1">First</div>
<div class="flex-1">Second</div>
<div class="flex-1">Third</div>
</div>| Class | Breakpoint |
|---|---|
.sm:flex-row / .sm:flex-col | 640px+ |
.md:flex-row / .md:flex-col | 768px+ |
.lg:flex-row / .lg:flex-col | 1024px+ |
Gap
Live: gap sizes
gap-1
gap-2
gap-4
gap-6
<div class="hstack gap-1">...</div>
<div class="hstack gap-2">...</div>
<div class="hstack gap-4">...</div>
<div class="hstack gap-6">...</div>| Class | Value | Responsive |
|---|---|---|
.gap-1 | var(--space-1) = 0.25rem | — |
.gap-2 | var(--space-2) = 0.5rem | .sm:gap-2 / .md:gap-2 |
.gap-3 | var(--space-3) = fluid | — |
.gap-4 | var(--space-4) = fluid | .sm:gap-4 / .md:gap-4 |
.gap-6 | var(--space-6) = fluid | .sm:gap-6 / .md:gap-6 |
.gap-8 | var(--space-8) = fluid | .sm:gap-8 / .md:gap-8 |
Spacing
Live: padding scale
p-2p-4p-6p-8<div class="p-2">Small padding</div>
<div class="p-4">Medium padding</div>
<div class="p-6">Large padding</div>
<div class="p-8">XL padding</div>Live: responsive padding
This box starts with small padding and grows at each breakpoint.
p-2 sm:p-4 md:p-6Resize to see padding grow
<!-- Grows at each breakpoint -->
<div class="p-2 sm:p-4 md:p-6">
Responsive padding
</div>Margin
| Class | CSS |
|---|---|
.mt-0 | margin-block-start: 0 |
.mt-2 | margin-block-start: var(--space-2) |
.mt-4 | margin-block-start: var(--space-4) |
.mt-6 | margin-block-start: var(--space-6) |
.mt-8 | margin-block-start: var(--space-8) |
.mb-0 | margin-block-end: 0 |
.mb-2 | margin-block-end: var(--space-2) |
.mb-4 | margin-block-end: var(--space-4) |
.mb-6 | margin-block-end: var(--space-6) |
.mb-8 | margin-block-end: var(--space-8) |
Padding
| Class | CSS | Responsive |
|---|---|---|
.p-0 | padding: 0 | — |
.p-2 | padding: var(--space-2) | — |
.p-4 | padding: var(--space-4) | .sm:p-4 / .md:p-4 |
.p-6 | padding: var(--space-6) | .sm:p-6 / .md:p-6 |
.p-8 | padding: var(--space-8) | .sm:p-8 / .md:p-8 |
.px-2 | padding-inline: var(--space-2) | — |
.px-4 | padding-inline: var(--space-4) | .sm:px-4 / .md:px-4 |
.py-2 | padding-block: var(--space-2) | — |
.py-4 | padding-block: var(--space-4) | — |
Width
Live: max-width classes
max-w-sm (384px)max-w-md (448px)max-w-lg (512px)max-w-xl (576px)w-100 (100%)<div class="max-w-sm">max-w-sm (384px)</div>
<div class="max-w-md">max-w-md (448px)</div>
<div class="max-w-lg">max-w-lg (512px)</div>
<div class="max-w-xl">max-w-xl (576px)</div>
<div class="w-100">w-100 (100%)</div>| Class | CSS |
|---|---|
.w-100 | width: 100% |
.w-auto | width: auto |
.max-w-sm | max-width: 24rem (384px) |
.max-w-md | max-width: 28rem (448px) |
.max-w-lg | max-width: 32rem (512px) |
.max-w-xl | max-width: 36rem (576px) |
Display
Live: responsive display
Resize to see elements appear/disappear at breakpoints.
<!-- Always visible -->
<div>Always visible</div>
<!-- Hidden on mobile, shown at 640px+ -->
<div class="d-none sm:d-block">Hidden on mobile</div>
<!-- Hidden below 768px -->
<div class="d-none md:d-block">Hidden below 768px</div>
<!-- Visible only on mobile -->
<div class="d-block sm:d-none">Mobile only</div>| Class | CSS |
|---|---|
.d-none | display: none |
.d-block | display: block |
.d-flex | display: flex |
.d-grid | display: grid |
.d-inline | display: inline |
.d-inline-block | display: inline-block |
.d-inline-flex | display: inline-flex |
Responsive display
| Prefix | Breakpoint | Available classes |
|---|---|---|
sm: | 640px+ | .sm:d-block / .sm:d-flex / .sm:d-grid / .sm:d-none |
md: | 768px+ | .md:d-block / .md:d-flex / .md:d-grid / .md:d-none |
lg: | 1024px+ | .lg:d-block / .lg:d-flex / .lg:d-grid / .lg:d-none |
xl: | 1280px+ | .xl:d-block / .xl:d-flex / .xl:d-grid / .xl:d-none |
Convenience shortcuts
<div class="hide-mobile">Hidden below 640px</div>
<div class="show-mobile">Hidden above 640px</div>| Class | Behavior |
|---|---|
.hide-mobile | Hidden below 640px |
.show-mobile | Hidden above 640px |
Typography
Live: text sizes
text-1 — Display
text-2 — Heading XL
text-3 — Heading LG
text-4 — Heading MD
text-5 — Heading SM
text-6 — Body
text-7 — Small
text-8 — XS
<p class="text-1">text-1 — Display</p>
<p class="text-2">text-2 — Heading XL</p>
<p class="text-3">text-3 — Heading LG</p>
<p class="text-4">text-4 — Heading MD</p>
<p class="text-5">text-5 — Heading SM</p>
<p class="text-6">text-6 — Body</p>
<p class="text-7">text-7 — Small</p>
<p class="text-8">text-8 — XS</p>Live: responsive text sizes
This heading scales from small on mobile to large on desktop.
Responsive heading
text-5 → sm:text-4 → md:text-3 → lg:text-1
<!-- Scales up at each breakpoint -->
<p class="text-5 sm:text-4 md:text-3 lg:text-1 font-bold">
Responsive heading
</p>Live: text colors
Default text color
text-light
text-lighter
text-muted
text-primary
text-success
text-danger
text-warning
<p>Default text color</p>
<p class="text-light">text-light</p>
<p class="text-lighter">text-lighter</p>
<p class="text-muted">text-muted</p>
<p class="text-primary">text-primary</p>
<p class="text-success">text-success</p>
<p class="text-danger">text-danger</p>
<p class="text-warning">text-warning</p>Live: font weights
font-normal (400)
font-medium (500)
font-semibold (600)
font-bold (700)
<p class="font-normal">font-normal (400)</p>
<p class="font-medium">font-medium (500)</p>
<p class="font-semibold">font-semibold (600)</p>
<p class="font-bold">font-bold (700)</p>Live: text alignment
<div class="text-left">text-left</div>
<div class="text-center">text-center</div>
<div class="text-right">text-right</div>Live: responsive alignment
Centered on mobile, left-aligned on medium screens.
<!-- Center on mobile, left on md+ -->
<div class="text-center md:text-left">
text-center md:text-left
</div>Live: truncation & line clamp
truncate (single line)
This is a very long piece of text that will be truncated with an ellipsis because the container is too narrow to fit it all.
line-clamp-2
This is a longer paragraph of text that will be clamped to exactly two lines using the line-clamp utility class. Any content beyond the second line will be hidden with an ellipsis.
line-clamp-3
This is a longer paragraph of text that will be clamped to exactly three lines using the line-clamp utility class. Any content beyond the third line will be hidden with an ellipsis. This gives you more visible content while still preventing overflow.
<!-- Single-line ellipsis -->
<p class="truncate">Very long text that gets truncated...</p>
<!-- Clamp to 2 lines -->
<p class="line-clamp-2">Multi-line text that clamps at 2 lines...</p>
<!-- Clamp to 3 lines -->
<p class="line-clamp-3">Multi-line text that clamps at 3 lines...</p>Full reference
| Category | Classes |
|---|---|
| Size | .text-1 … .text-8, .text-small, .text-xs, .text-regular |
| Color | .text-light, .text-lighter, .text-danger, .text-success, .text-warning, .text-primary, .text-muted |
| Weight | .font-normal, .font-medium, .font-semibold, .font-bold |
| Family | .font-sans, .font-mono |
| Alignment | .text-left, .text-center, .text-right + responsive variants |
| Line-height | .leading-none, .leading-tight, .leading-snug, .leading-normal, .leading-relaxed, .leading-loose |
| Spacing | .tracking-tighter … .tracking-widest |
| Transform | .uppercase, .lowercase, .capitalize, .normal-case |
| Decoration | .underline, .line-through, .no-underline, .overline |
| Wrapping | .text-balance, .text-pretty, .text-nowrap |
| Overflow | .truncate, .line-clamp-1 … .line-clamp-4, .line-clamp-none |
| White-space | .whitespace-normal, .whitespace-nowrap, .whitespace-pre, .whitespace-pre-line, .whitespace-pre-wrap |
| Word break | .break-normal, .break-words, .break-all |
| Responsive size | .sm:text-*, .md:text-*, .lg:text-* |
Overflow
Live: overflow behavior
overflow-hidden
overflow-auto
<!-- Content is clipped -->
<div class="overflow-hidden" style="height: 60px;">
Long content...
</div>
<!-- Content is scrollable -->
<div class="overflow-auto" style="height: 60px;">
Long content...
</div>| Class | CSS |
|---|---|
.overflow-auto | overflow: auto |
.overflow-hidden | overflow: hidden |
.overflow-x-auto | overflow-x: auto |
Misc utilities
Live: sr-only & unstyled
sr-only (visually hidden, accessible)
unstyled list
- No bullet markers
- Clean list items
- Perfect for nav menus
<!-- Screen-reader only -->
<span class="sr-only">Hidden visually</span>
<!-- Remove list styling -->
<ul class="unstyled">
<li>Clean item</li>
</ul>| Class | What it does |
|---|---|
.truncate | Single-line ellipsis overflow |
.sr-only | Screen-reader only (visually hidden) |
.unstyled | Remove list markers and link underlines (use on ul, ol, or a) |
Margin (expanded)
Full margin utilities including inline (mx), block (my), and individual directions (ml, mr). Uses CSS logical properties.
Live: mx-auto centering
mx-auto max-w-smBlock element centered with auto inline margin
<!-- Center a block element with mx-auto -->
<div class="mx-auto max-w-sm p-4">
Centered block with max-width
</div>Full margin reference
| Class | CSS | Responsive |
|---|---|---|
.m-0 … .m-8 | margin: var(--space-*) | sm: / md: / lg: |
.m-auto | margin: auto | — |
.mx-0 … .mx-8 | margin-inline: var(--space-*) | sm:mx-4 etc. |
.mx-auto | margin-inline: auto | sm: / md: / lg: |
.my-0 … .my-8 | margin-block: var(--space-*) | sm: / md: / lg: |
.my-auto | margin-block: auto | — |
.mt-0 … .mt-12 | margin-block-start: var(--space-*) | sm: / md: / lg: |
.mt-auto | margin-block-start: auto | — |
.mb-0 … .mb-12 | margin-block-end: var(--space-*) | sm: / md: / lg: |
.mb-auto | margin-block-end: auto | — |
.ml-0 … .ml-8 | margin-inline-start: var(--space-*) | sm:ml-auto |
.ml-auto | margin-inline-start: auto | sm: / md: / lg: |
.mr-0 … .mr-8 | margin-inline-end: var(--space-*) | sm:mr-auto |
.mr-auto | margin-inline-end: auto | sm: / md: / lg: |
Padding (expanded)
Full directional padding — pt, pb, pl, pr plus expanded px/py scales including 6 and 8.
Live: directional padding
pt-6pb-6pl-8pr-8px-6 py-3<!-- Directional padding -->
<div class="pt-6">padding-block-start</div>
<div class="pb-6">padding-block-end</div>
<div class="pl-8">padding-inline-start</div>
<div class="pr-8">padding-inline-end</div>
<div class="px-6 py-3">inline 6, block 3</div>Full padding reference
| Class | CSS | Responsive |
|---|---|---|
.p-0 … .p-12 | padding: var(--space-*) | sm: / md: / lg: |
.px-0 … .px-8 | padding-inline: var(--space-*) | sm: / md: / lg: |
.py-0 … .py-8 | padding-block: var(--space-*) | sm: / md: / lg: |
.pt-0 … .pt-8 | padding-block-start: var(--space-*) | sm: / md: / lg: |
.pb-0 … .pb-8 | padding-block-end: var(--space-*) | sm: / md: / lg: |
.pl-0 … .pl-8 | padding-inline-start: var(--space-*) | — |
.pr-0 … .pr-8 | padding-inline-end: var(--space-*) | — |
Center utilities
Quick centering shortcuts — no need to set flex + align + justify manually.
Live: center & place-center
.center (flex)
.place-center (grid)
<!-- Flex center -->
<div class="center" style="min-height: 100px;">
<span>Centered!</span>
</div>
<!-- Grid place-center -->
<div class="place-center" style="min-height: 100px;">
<span>Grid centered!</span>
</div>| Class | CSS | Responsive |
|---|---|---|
.center | display: flex; align-items: center; justify-content: center | sm: / md: / lg: |
.place-center | display: grid; place-items: center | — |
.mx-auto | margin-inline: auto (horizontally center a block) | sm: / md: / lg: |
Space-x / Space-y
Add spacing between child elements using the lobotomized owl selector (> * + *). Works like Tailwind's space-x/y.
Live: child spacing
space-x-4 (horizontal)
space-y-3 (vertical)
<!-- Horizontal child spacing -->
<div class="flex space-x-4">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<!-- Vertical child spacing -->
<div class="space-y-3">
<div>First</div>
<div>Second</div>
<div>Third</div>
</div>| Class | CSS | Responsive |
|---|---|---|
.space-x-1 … .space-x-8 | > * + * margin-inline-start | sm: / md: / lg: (2, 4) |
.space-y-1 … .space-y-8 | > * + * margin-block-start | sm: / md: / lg: (2, 4) |
Gap axis (gap-x / gap-y)
Control column-gap and row-gap independently, in addition to the existing .gap-* shorthand.
| Class | CSS | Responsive |
|---|---|---|
.gap-x-1 … .gap-x-8 | column-gap: var(--space-*) | sm: / md: / lg: (2, 4) |
.gap-y-1 … .gap-y-8 | row-gap: var(--space-*) | sm: / md: / lg: (2, 4) |
Grid
CSS Grid utilities for column layouts. Responsive — stack on mobile, expand on larger screens.
Live: responsive grid
<!-- Responsive grid: 1 col → 2 cols → 4 cols -->
<div class="d-grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>Live: col-span
<!-- Column spanning -->
<div class="d-grid grid-cols-3 gap-4">
<div class="col-span-2">col-span-2</div>
<div>1 col</div>
<div>1 col</div>
<div class="col-span-2">col-span-2</div>
</div>| Class | CSS | Responsive |
|---|---|---|
.grid-cols-1 … .grid-cols-12 | grid-template-columns: repeat(n, minmax(0, 1fr)) | sm: / md: / lg: |
.col-span-1 … .col-span-6 | grid-column: span n | sm: / md: / lg: |
.col-span-full | grid-column: 1 / -1 | sm: / md: / lg: |
.place-items-center | place-items: center | — |
.place-content-center | place-content: center | — |
Width & Height (expanded)
Fractional widths, full-screen heights, and responsive variants.
Live: fractional widths
w-full (100%)w-3/4 (75%)w-2/3 (66.7%)w-1/2 (50%)w-1/3 (33.3%)w-1/4 (25%)<!-- Fractional widths -->
<div class="w-full">100%</div>
<div class="w-3/4">75%</div>
<div class="w-2/3">66.7%</div>
<div class="w-1/2">50%</div>
<div class="w-1/3">33.3%</div>
<div class="w-1/4">25%</div>Width reference
| Class | CSS | Responsive |
|---|---|---|
.w-full | width: 100% | sm: / md: / lg: |
.w-screen | width: 100vw | — |
.w-fit | width: fit-content | — |
.w-auto | width: auto | sm: / md: / lg: |
.w-1/2 | width: 50% | sm: / md: / lg: |
.w-1/3, .w-2/3 | width: 33.3% / 66.7% | sm: / md: / lg: |
.w-1/4, .w-3/4 | width: 25% / 75% | sm: / md: / lg: |
.min-w-0, .min-w-full | min-width: 0 / 100% | — |
.max-w-2xl … .max-w-7xl | 42rem … 80rem | — |
.max-w-none, .max-w-full, .max-w-screen | none / 100% / 100vw | — |
Height reference
| Class | CSS | Responsive |
|---|---|---|
.h-auto | height: auto | sm: / md: / lg: |
.h-full | height: 100% | sm: / md: / lg: |
.h-screen | height: 100vh | sm: / md: / lg: |
.h-fit | height: fit-content | — |
.min-h-0, .min-h-full, .min-h-screen | min-height: 0 / 100% / 100vh | sm: / md: / lg: (screen) |
.max-h-full, .max-h-screen | max-height: 100% / 100vh | — |
Position
| Class | CSS | Responsive |
|---|---|---|
.relative | position: relative | sm: / md: / lg: |
.absolute | position: absolute | sm: / md: / lg: |
.fixed | position: fixed | — |
.sticky | position: sticky | sm: / md: / lg: |
.static | position: static | sm: / md: / lg: |
.inset-0 | inset: 0 | — |
.inset-x-0 | inset-inline: 0 | — |
.inset-y-0 | inset-block: 0 | — |
.top-0, .right-0, .bottom-0, .left-0 | top/right/bottom/left: 0 | — |
Border & Radius
Live: border utilities
.border .rounded.border-t.border-b.rounded-lg.rounded-full<!-- Border with rounded corners -->
<div class="border rounded p-4">border + rounded</div>
<div class="border-t p-4">border-t (top only)</div>
<div class="border-b p-4">border-b (bottom only)</div>
<div class="border rounded-lg p-4">rounded-lg</div>
<div class="border rounded-full p-4 px-6">rounded-full</div>| Class | CSS |
|---|---|
.border | border: 1px solid var(--border) |
.border-0 | border: 0 |
.border-t, .border-b, .border-l, .border-r | Single-side 1px solid border |
.rounded-none | border-radius: 0 |
.rounded-sm | border-radius: var(--radius-small) |
.rounded / .rounded-md | border-radius: var(--radius-medium) |
.rounded-lg | border-radius: var(--radius-large) |
.rounded-full | border-radius: 9999px |
Background
Live: background colors
bg-backgroundbg-cardbg-mutedbg-primarybg-secondarybg-accentbg-dangerbg-successbg-warning<!-- Background color utilities -->
<div class="bg-background border rounded p-3">bg-background</div>
<div class="bg-card border rounded p-3">bg-card</div>
<div class="bg-muted rounded p-3">bg-muted</div>
<div class="bg-primary rounded p-3">bg-primary</div>
<div class="bg-secondary rounded p-3">bg-secondary</div>
<div class="bg-accent rounded p-3">bg-accent</div>
<div class="bg-danger rounded p-3">bg-danger</div>
<div class="bg-success rounded p-3">bg-success</div>
<div class="bg-warning rounded p-3">bg-warning</div>Shadow
Live: shadow scale
shadow-smshadowshadow-mdshadow-lg<!-- Shadow scale -->
<div class="shadow-sm rounded p-4 bg-card">shadow-sm</div>
<div class="shadow-md rounded p-4 bg-card">shadow-md</div>
<div class="shadow-lg rounded p-4 bg-card">shadow-lg</div>| Class | CSS |
|---|---|
.shadow-none | box-shadow: none |
.shadow-sm | var(--shadow-small) |
.shadow / .shadow-md | var(--shadow-medium) |
.shadow-lg | var(--shadow-large) |
Flex extras
| Class | CSS |
|---|---|
.flex-shrink-0 | flex-shrink: 0 |
.flex-grow | flex-grow: 1 |
.flex-grow-0 | flex-grow: 0 |
.flex-none | flex: none |
.flex-nowrap | flex-wrap: nowrap |
.self-auto, .self-start, .self-center, .self-end, .self-stretch | align-self: * |
.order-first | order: -9999 |
.order-last | order: 9999 |
.order-none | order: 0 |
Visual & Interactive
Opacity, visibility, z-index, cursor, pointer-events, transitions, object-fit, and aspect-ratio utilities.
Live: opacity scale
<!-- Opacity scale -->
<div class="opacity-100 bg-primary p-3">100</div>
<div class="opacity-75 bg-primary p-3">75</div>
<div class="opacity-50 bg-primary p-3">50</div>
<div class="opacity-25 bg-primary p-3">25</div>
<div class="opacity-0 bg-primary p-3">0</div>Reference
| Category | Classes |
|---|---|
| Opacity | .opacity-0, .opacity-25, .opacity-50, .opacity-75, .opacity-100 |
| Visibility | .visible, .invisible |
| Z-index | .z-0, .z-10, .z-20, .z-30, .z-40, .z-50 |
| Cursor | .cursor-default, .cursor-pointer, .cursor-not-allowed, .cursor-wait, .cursor-grab |
| Pointer events | .pointer-events-none, .pointer-events-auto |
| User select | .select-none, .select-all, .select-auto |
| Transitions | .transition-none, .transition-all, .transition, .transition-colors, .transition-opacity, .transition-transform |
| Object fit | .object-cover, .object-contain, .object-fill, .object-none |
| Aspect ratio | .aspect-auto, .aspect-square, .aspect-video |