Mixins
Mixins are the primary API of css-is-awesome. Every visual decision is token-driven — mixin bodies read from CSS custom properties that the active theme defines, so the same @include produces a sketchbook button, a brutalist button or a corporate button depending on the loaded theme. Consume mixins from your own SCSS and the system stays small, fast and easy to re-skin.
Import setup
Two @use lines cover the whole surface. _mixins.scssis the barrel for core layout, typography, colour, interactive and effect mixins — the atomic vocabulary. Each component partial in scss/components/* exports its own composite mixins (btn-primary, card-base, input-base, etc.) so you only import the components you need and your compiled CSS stays lean.
// your-app.scss @use 'cia/scss/mixins' as m; @use 'cia/scss/components/buttons' as b; @use 'cia/scss/components/forms' as f; .my-cta { @include b.btn-primary(); @include m.elevation(2); }
The rest of this page is a reference of every public mixin, grouped by category. Internal helpers (anything prefixed with _ or used only by _generator.scss) are omitted.
Bare-tag styling (opt-in)
By default the library does not touch bare HTML — drop the CSS and you get tokens, utilities and React components, but raw <button>, <table> and <h1> stay browser-default. That keeps the library non-invasive: dropping it into an existing project never silently restyles your nav links or third-party components.
If you want a Pico-style "drop-in and it looks decent" experience, add the bare-tags recipe in one line at the top of your app's SCSS entry:
// your-app.scss @use 'css-is-awesome/scss/recipes/bare-tags'; // done — h1-h6, p, code, pre, hr, ul, ol, table, // button, input, select, textarea, label, details // all styled with the active theme.
The recipe uses normal selectors (specificity 0,0,1) — no @layer or :where() machinery. Override anything with any class-based selector and it wins automatically:
.checkout button { background: gold; // (0,1,1) > (0,0,1) — wins }
Heads up: bare-tag styling is global. If you mount third-party React components that render their own <button> internally (Radix, react-select, react-datepicker, cmdk), they will inherit these rules. Either skip the recipe and write your own scoped wrappers, or copy the recipe contents into a .cia-prose wrapper in your own SCSS to scope it.
Prefer to roll your own? The recipe is just one-line includes per tag — copy the file or write your own:
@use 'css-is-awesome/scss/mixins' as m; @use 'css-is-awesome/scss/components/buttons' as b; @use 'css-is-awesome/scss/components/data' as d; button { @include b.btn(primary); } table { @include d.table-base; } h1 { @include m.type(heading-1); }
Layout
Layout mixins cover flex helpers, responsive grids, page-level scaffolding, containers and dividers. All spacing arguments accept a numeric space token (1–9) or a t-shirt alias (xs/sm/md/lg/xl).
flex-center
Centers children horizontally and vertically with flexbox.
// signature @mixin flex-center; // usage .hero { @include m.flex-center; }
flex-between
Flex row with space-between — ideal for toolbars and card headers.
@mixin flex-between; .toolbar { @include m.flex-between; }
stack
Vertical flex stack with a token-aware gap. Default gap is 4.
@mixin stack($gap: 4, $align: stretch); .feed { @include m.stack(3); }
inline
Horizontal flex row with gap, alignment and wrapping controls.
@mixin inline($gap: 2, $align: center, $wrap: nowrap); .toolbar { @include m.inline(2, center, wrap); }
container
Page-width container with responsive horizontal padding. Sizes: sm, md, lg, xl, 2xl, full.
@mixin container($size: xl, $px: null); .page { @include m.container(lg); }
grid
Responsive CSS grid. Pass a column count, auto for auto-fit, or a minimum track size. Collapses to one column below the supplied breakpoint.
@mixin grid($cols: 1, $gap: 4, $bp: md, $min: null); .gallery { @include m.grid(3, $gap: 5); } .cards { @include m.grid(auto, $min: 250px); }
subgrid
Child inherits the parent grid's column or row tracks. Direction: columns, rows, both.
@mixin subgrid($direction: columns); .card { @include m.subgrid; grid-column: span 3; }
page-layout
Full-page grid with sticky footer. Variants: default, sidebar-left, sidebar-right. Pair with page-header, page-main, page-footer, page-sidebar grid-area helpers.
@mixin page-layout($variant: default); body { @include m.page-layout(sidebar-left); } header { @include m.page-header; } aside { @include m.page-sidebar; } main { @include m.page-main; } footer { @include m.page-footer; }
section
Vertical page section with consistent top/bottom padding.
@mixin section($py: 8, $px: null); section { @include m.section($py: 9); }
row and col
Simple flex row / column with token-aware gap and alignment defaults.
@mixin row($gap: 4, $align: center, $justify: flex-start, $wrap: wrap); @mixin col($gap: 4, $align: stretch, $justify: flex-start); .form-row { @include m.row(3); } .form-col { @include m.col(2); }
inset, inset-x, inset-y, squish
Padding helpers. inset applies even padding on all sides, inset-x/inset-y split axes, squish takes a Y/X pair.
@mixin inset($size: 4); @mixin inset-x($size: 4); @mixin inset-y($size: 4); @mixin squish($y: 2, $x: 4);
divider / divider-vertical
Horizontal or vertical divider with token-aware spacing.
above
below
@mixin divider($color: border-default, $spacing: 4); @mixin divider-vertical($color: border-default, $spacing: 4);
Breakpoints & container queries
Responsive at viewport and component level. Breakpoint mixins take a token (sm, md, lg, xl,2xl) or a literal width. Container-query mixins pair with container to make components respond to their own width.
bp, bp-down, bp-between
Viewport media queries — min-width, max-width, and ranged.
@mixin bp($size); @mixin bp-down($size); @mixin bp-between($min, $max); .hero { font-size: 2rem; @include m.bp(md) { font-size: 3rem; } }
Alias mixins
Convenience aliases for common breakpoint ranges: mobile-only, tablet, tablet-only, desktop, wide.
.nav { @include m.mobile-only { display: none; } @include m.desktop { display: flex; } }
container, cq, cq-down, cq-between
Container queries. Name the container with container, then query it with cq variants.
@mixin container($name: null, $type: inline-size); @mixin cq($size, $name: null); @mixin cq-down($size, $name: null); @mixin cq-between($min, $max, $name: null); .card { @include m.container(card); @include m.cq(md, card) { display: grid; } }
Typography
All typography is token-driven. font composes weight, style, size, line-height and letter-spacing in one mixin; type pulls from the named scale (display,heading-1…heading-4, body,body-sm, caption, overline).
font
Sets weight, style, size, line-height, letter-spacing from one call. Size/lh/ls accept a token name or a literal value. Pass $family to set a font-family — if it's a name registered via font-load, the registered fallback is auto-applied; if it's a CSS-native value (with comma or var()), it passes through; if it's a single-word name that isn't loaded, the build fails with @error so typos surface at compile time.
@mixin font($type: reg, $size: null, $lh: null, $ls: null, $family: null); .lede { @include m.font(medium, $size: 4, $lh: 2); }
font-load & font-load-local
Drop a one-off font into a single page or section without forking the theme. font-load registers a Google Fonts URL once (idempotent across the compile), emits the @import, and optionally aliases the loaded family to one of the theme's font tokens (display, script, serif, sans, mono, primary) so the rest of the page can keep using var(--font-display) with no further changes. font-load-local is the sister mixin for self-hosted woff2/ttf via @font-face.
// Load + apply (Google Fonts) @include m.font-load('Pacifico', 'https://fonts.googleapis.com/css2?family=Pacifico&display=swap'); .headline { @include m.font(reg, 7, $family: 'Pacifico'); } // Load + alias to a theme token (page-scoped --font-display override) @include m.font-load('Pacifico', '<url>', $alias: display); // Self-hosted file @include m.font-load-local('Untitled Sans', '/fonts/UntitledSans.woff2');
Tip: drop the font-load call inside a per-route CSS Module (e.g. src/app/special-landing/page.module.scss) and Next will scope the font download to that route only — pages that don't import the module never see the font in their network tab.
type
Applies a named type-scale preset: size + weight + line-height + letter-spacing in one include.
@mixin type($preset); h1 { @include m.type(heading-1); } .label { @include m.type(overline); }
truncate
Single-line ellipsis by default, or multi-line clamp with $lines.
@mixin truncate($lines: 1); .headline { @include m.truncate(2); }
Colour, borders & effects
These wrap raw theme values in runtime-override-capable custom properties, so a consumer can re-skin a single site without rebuilding the library.
border
Applies a border on all sides, one side, or a list of sides, with token-aware colour.
@mixin border($width: 1px, $style: solid, $color: border-default, $sides: all); .panel { @include m.border($sides: (top, bottom)); }
elevation
Applies a theme-driven shadow level (0–5).
@mixin elevation($level: 2); .card { @include m.elevation(3); }
Interactive states
Focus ring, hover transitions, disabled state, and a composite interactive mixin that wires hover, active and disabled in one call.
focus-ring
Accessible focus-visible ring using border-focus by default.
@mixin focus-ring($color: border-focus, $width: 3px, $offset: 0); .btn { @include m.focus-ring; }
hover
One-property transition + hover change in a single line.
@mixin hover($prop, $value, $speed: fast); .link { @include m.hover(color, m.color(action-primary-hover)); }
interactive
Composite: transitions background-color, applies hover + active backgrounds, and disables the element when disabled.
@mixin interactive($bg-hover: interactive-hover, $bg-active: interactive-active); .row { @include m.interactive; }
transition
Variadic — pass any number of CSS properties plus an optional speed (instant/fast/normal/slow/slower) and easing token (smooth/bounce/etc.). Respects prefers-reduced-motion.
@mixin transition($props...); .btn { @include m.transition(background-color, color, fast, smooth); }
disabled
Standard disabled styling — dimmed, not-allowed cursor, pointer events off.
@mixin disabled($opacity: 0.5);
sr-only
Visually hide an element while keeping it available to screen readers.
@mixin sr-only; .skip-link { @include m.sr-only; }
Resets
Strip user-agent styling from common elements.
@mixin button-reset; // appearance, background, border, padding, cursor @mixin list-reset; // list-style + margin + padding @mixin header-reset; // h1..h6 within scope @mixin form-reset; // input/select/textarea full-width
Animation
Keyframes are declared once and referenced by name. All animation mixins respect prefers-reduced-motion.
animate
Trigger a named animation with configurable speed, delay, iteration and timing. Names live in _animations.scss (fade-in, fade-out, slide-up, slide-down, spin, pulse, shimmer, etc.).
@mixin animate( $name, $speed: normal, $delay: 0s, $iteration: 1, $fill: both, $timing: var(--ease, cubic-bezier(0.33, 0.66, 0.33, 1)) ); .modal { @include m.animate(slide-up); } .spinner { @include m.animate(spin, $iteration: infinite, $timing: linear); }
animate-on
Interaction-triggered animations. Events: hover, focus, active. Effects: lift, glow, press, fade.
@mixin animate-on($event: hover, $effect: lift); .card { @include m.animate-on(hover, lift); }
Shortcuts
Pre-baked animation helpers that inject the keyframes in the same call.
@mixin spin($duration: 1s); @mixin pulse($duration: 2s); @mixin fade-in($duration: normal); @mixin slide-up($duration: normal, $distance: 1rem);
Icons
SVG and Font Awesome helpers. Prefer svg for inline icon styling, svg-bg for background-image masks, svg-text for inline-text alignment. Font Awesome mixins require fa-load once at the root to inject the shared @font-face rules.
@mixin svg(...); @mixin svg-bg(...); @mixin svg-text(...); @mixin fa-load; @mixin fa($name); @mixin fa-icon($name); @mixin fa-text($name); @mixin fa-spin($name, $size, $style); :root { @include m.fa-load; } .icon-check { @include m.fa-icon(check); }
Component mixins
Composite mixins live in scss/components/*.scss and compose the atomic mixins above into real UI primitives. Every base mixin wraps its override-controlled properties in var(--<key>, <default>), so a theme can tweak padding, radius, shadow or colour without a rebuild.
Buttons
From components/buttons. Import as @use '.../components/buttons' as b;.
@mixin btn-base($py: 1, $px: 4, $r: md, $font-weight: medium, $font-size: null); @mixin btn($variant, $bg, $bg-hover, $bg-active, $color, $border, $args...); // $variant: primary | secondary | outline | ghost | info | success | warning | error | disabled @mixin btn-icon($size: 2.5rem, $r: md); // Author your own class — variant is a mixin arg, not a --modifier suffix .hero-cta { @include b.btn(primary); } .checkout-cancel { @include b.btn(outline); }
Data display — cards, lists, tables, avatars
From components/data.
Warm paper
Card-base composes padding, radius, shadow and surface colour.
Themable
Swap the theme — every card re-skins without markup changes.
@mixin table-base($striped: false, $hover: false, $bordered: false, $compact: false); @mixin table-responsive; @mixin card-base($p: 4, $r: lg, $shadow: 1, $bg: surface-default); @mixin card-header($pb: 2); @mixin card-footer($pt: 2); @mixin card-interactive; @mixin list-base($gap: 0, $dividers: false); @mixin list-item($py: 2, $px: 4, $interactive: false); @mixin avatar($size: 2.5rem, $r: full); @mixin avatar-placeholder($size, $r, $bg, $color); @mixin avatar-group($overlap: -0.5rem);
Feedback — alerts, toasts, badges, tags, progress
From components/feedback. Status-coloured variants read status-* tokens.
@mixin alert-base($py: 2, $px: 4, $r: md, $border-width: 1px); @mixin alert($status: info, $py: 2, $px: 4, $r: md); @mixin toast-base($py: 2, $px: 4, $r: lg, $shadow: 3); @mixin badge-base($py, $px, $r: full, $font-size: 1); @mixin badge($status: info); @mixin tag($py: 2xs, $px: 2, $r: md, $font-size: 2, $removable: false); @mixin progress-track($height, $r: full, $bg: surface-muted); @mixin progress-fill($color: action-primary-default); @mixin spinner(...); @mixin skeleton(...);
Forms — inputs, selects, checks, radios, switches, sliders
From components/forms. All form primitives share the same focus treatment and disabled contract.
@mixin input-base($py: 1, $px: 2, $r: md, $border-width: 1px, $bg, $border-color); @mixin select-base(...); @mixin textarea-base(...); @mixin check-base($size: 1.125rem, $r: sm, $color: action-primary-default); @mixin radio-base($size: 1.125rem, $color: action-primary-default); @mixin switch-base(...); @mixin slider-base(...); @mixin label-base($size: 2, $weight: medium, $color: text-primary); @mixin form-layout($columns: 1, $gap: 4); @mixin form-group($gap: 1, $direction: column); @mixin form-row($gap: 2, $align: center); @mixin form-help($color: text-muted); @mixin form-error;
Navigation — navbar, nav, breadcrumb, tabs, pagination
From components/navigation.
@mixin navbar-base(...); @mixin navbar-brand($gap: 2); @mixin navbar-nav($gap: 1); @mixin navbar-link($py: 1, $px: 2, $r: md); @mixin nav-base($direction: row, $gap: 1); @mixin breadcrumb($gap: 1, $separator: "/"); @mixin tabs-base($gap: 0, $border: true); @mixin tab-item($py: 2, $px: 4, $active-color: action-primary-default); @mixin pagination($gap: 2xs); @mixin pagination-item($size: 2.25rem, $r: md);
Overlays — modals, tooltips, popovers, dropdowns
From components/overlay.
@mixin modal-backdrop($bg: rgba(0, 0, 0, 0.5)); @mixin modal-base($p: 5, $r: xl, $shadow: 5, $max-width: 500px); @mixin modal-header($pb: 2); @mixin modal-footer($pt: 2); @mixin tooltip-base($py, $px, $r: md, $bg, $color); @mixin popover-base($p: 4, $r: lg, $shadow: 3, $max-width: 320px); @mixin dropdown-menu($py: 1, $r: md, $shadow: 2, $min-width: 12rem); @mixin dropdown-item($py: 1, $px: 4); @mixin dropdown-divider($spacing: 1);
Writing your own mixins
When you extend the system, follow the same contract: read every visual value from a token helper (color(), space(), radius(), shadow(), font-size()), wrap override-controlled properties in var(--<key>, <default>) so themes can tweak them at runtime, and compose atomic mixins rather than duplicating their bodies.
// good — token-driven, override-capable @mixin note-base($p: 4, $r: md, $bg: surface-muted) { padding: var(--note-padding, #{m.space($p)}); border-radius: var(--note-radius, #{m.radius($r)}); background: m.color($bg); @include m.border($sides: left, $color: border-focus); }
The full contributor guide — naming conventions, parameter order, how to add a mixin to the barrel — lives in CONTRIBUTING.md alongside the component authoring guide.
Full index
Every public mixin at a glance. Jump to the section above for usage examples.
- Layout:
flex-center,flex-between,stack,inline,inset,inset-x,inset-y,squish,container,grid,subgrid,page-layout,page-header,page-main,page-footer,page-sidebar,section,row,col,divider,divider-vertical - Breakpoints:
bp,bp-down,bp-between,mobile-only,tablet,tablet-only,desktop,wide - Container queries:
container,cq,cq-down,cq-between - Typography:
font,type,truncate - Borders & effects:
border,elevation - Interactive:
focus-ring,hover,interactive,transition,disabled,sr-only - Resets:
button-reset,list-reset,header-reset,form-reset - Animation:
animate,animate-on,spin,pulse,fade-in,slide-up - Icons:
svg,svg-bg,svg-text,fa-load,fa,fa-icon,fa-text,fa-spin - Buttons:
btn-base,btn-primary,btn-secondary,btn-outline,btn-ghost,btn-icon - Data:
table-base,table-responsive,card-base,card-header,card-footer,card-interactive,list-base,list-item,avatar,avatar-placeholder,avatar-group - Feedback:
alert-base,alert,toast-base,badge-base,badge,tag,progress-track,progress-fill,spinner,skeleton - Forms:
input-base,select-base,textarea-base,check-base,radio-base,switch-base,slider-base,label-base,form-layout,form-group,form-row,form-help,form-error - Navigation:
navbar-base,navbar-brand,navbar-nav,navbar-link,nav-base,breadcrumb,tabs-base,tab-item,pagination,pagination-item - Overlays:
modal-backdrop,modal-base,modal-header,modal-footer,tooltip-base,popover-base,dropdown-menu,dropdown-item,dropdown-divider