Skip to content

westonwalker/unccss

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

☕ unc.css

A utility CSS library designed for simplicity, zero tooling, and easy extension.

  • No build step, no CLI, no config files
  • Driven by CSS variables — retheme by overriding tokens
  • Consistent variant naming: .utility-hover, .utility-focus, .utility-active, .utility-md
  • Extend with a single CSS file

Installation

Add two <link> tags. That's it.

<link rel="stylesheet" href="unc.css">
<link rel="stylesheet" href="unc-extend.css">

Load unc-extend.css after unc.css so your overrides take precedence.


Design Tokens

All tokens are CSS custom properties defined in :root. Override any of them in unc-extend.css.

Colors

Semantic color tokens with four built-in states each.

--color-primary:        #3b82f6;
--color-primary-hover:  #2563eb;
--color-primary-focus:  #1d4ed8;
--color-primary-active: #1e40af;

--color-secondary:        #8b5cf6;
--color-secondary-hover:  #7c3aed;
--color-secondary-focus:  #6d28d9;
--color-secondary-active: #5b21b6;

--color-muted:        #6b7280;
--color-surface:      #f9fafb;
--color-background:   #ffffff;
--color-text:         #111827;
--color-border:       #e5e7eb;
--color-success:      #22c55e;
--color-danger:       #ef4444;
--color-warning:      #eab308;
--color-white:        #ffffff;
--color-black:        #000000;

Each color (except white/black) has -hover, -focus, and -active variants.

Spacing

A 0–10 scale used across margin, padding, and gap utilities.

--space-0:  0;
--space-1:  0.25rem;   /*  4px */
--space-2:  0.5rem;    /*  8px */
--space-3:  0.75rem;   /* 12px */
--space-4:  1rem;      /* 16px */
--space-5:  1.25rem;   /* 20px */
--space-6:  1.5rem;    /* 24px */
--space-7:  1.75rem;   /* 28px */
--space-8:  2rem;      /* 32px */
--space-9:  2.25rem;   /* 36px */
--space-10: 2.5rem;    /* 40px */

Font Sizes

--text-xs:   0.75rem;
--text-sm:   0.875rem;
--text-base: 1rem;
--text-lg:   1.125rem;
--text-xl:   1.25rem;
--text-2xl:  1.5rem;
--text-3xl:  1.875rem;
--text-4xl:  2.25rem;
--text-5xl:  3rem;
--text-6xl:  3.75rem;
--text-7xl:  4.5rem;

Font Weights

--font-normal:   400;
--font-medium:   500;
--font-semibold: 600;
--font-bold:     700;
--font-black:    900;

Border Radius

--radius-sm:   0.125rem;
--radius-md:   0.375rem;
--radius-lg:   0.5rem;
--radius-full: 9999px;

Shadows

--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);

Transitions

--transition-fast: 150ms ease;
--transition-base: 200ms ease;
--transition-slow: 300ms ease;

Utilities

Display

<div class="block">...</div>
<div class="inline-block">...</div>
<div class="inline">...</div>
<div class="flex">...</div>
<div class="inline-flex">...</div>
<div class="grid">...</div>
<div class="hidden">...</div>

Position

<div class="relative">
  <div class="absolute top-0 right-0">pinned</div>
</div>

<div class="fixed">...</div>
<div class="sticky">...</div>

Inset helpers: .inset-0 .top-0 .right-0 .bottom-0 .left-0

Overflow

<div class="overflow-hidden">...</div>
<div class="overflow-auto">...</div>
<div class="overflow-x-auto">...</div>
<div class="overflow-y-auto">...</div>

Flexbox

<!-- Direction -->
<div class="flex flex-row gap-4">...</div>
<div class="flex flex-col gap-2">...</div>

<!-- Justify content -->
<div class="flex justify-start">...</div>
<div class="flex justify-center">...</div>
<div class="flex justify-end">...</div>
<div class="flex justify-between">...</div>
<div class="flex justify-around">...</div>
<div class="flex justify-evenly">...</div>

<!-- Align items -->
<div class="flex items-start">...</div>
<div class="flex items-center">...</div>
<div class="flex items-end">...</div>
<div class="flex items-stretch">...</div>

<!-- Grow & shrink -->
<div class="flex">
  <div class="flex-none">fixed</div>
  <div class="flex-1">grows to fill</div>
</div>

<!-- Wrap -->
<div class="flex flex-wrap">...</div>

Grid

<div class="grid grid-cols-2 gap-4">...</div>
<div class="grid grid-cols-3 gap-4">...</div>
<div class="grid grid-cols-4 gap-4">...</div>

<!-- Column spanning -->
<div class="grid grid-cols-4 gap-4">
  <div class="col-span-2">spans 2</div>
  <div class="col-span-full">full width</div>
</div>

Gap

<div class="flex gap-2">...</div>
<div class="flex gap-4">...</div>
<div class="grid grid-cols-3 gap-6">...</div>
<div class="grid grid-cols-2 gap-x-4 gap-y-2">...</div>

Values: gap-0 through gap-10, gap-x-*, gap-y-*

Padding

<div class="p-4">all sides</div>
<div class="px-6 py-3">horizontal + vertical</div>
<div class="pt-4 pb-2 pl-4 pr-4">individual sides</div>

Values: p-0 through p-10, px-*, py-*, pt-*, pr-*, pb-*, pl-*

Margin

<div class="mx-auto max-w-md">centered</div>
<div class="mt-4 mb-8">vertical margin</div>
<div class="ml-auto">push right</div>

Values: m-0 through m-10, mx-*, my-*, mt-*, mr-*, mb-*, ml-*, m-auto, mx-auto, ml-auto, mr-auto

Width & Height

<div class="w-full">100%</div>
<div class="w-auto">shrink to content</div>
<div class="w-fit">...</div>
<div class="w-screen">100vw</div>

<div class="h-full">...</div>
<div class="h-screen">100vh</div>
<div class="min-h-screen">...</div>

Max Width

<div class="max-w-sm mx-auto">...</div>   <!-- 24rem -->
<div class="max-w-md mx-auto">...</div>   <!-- 28rem -->
<div class="max-w-lg mx-auto">...</div>   <!-- 32rem -->
<div class="max-w-xl mx-auto">...</div>   <!-- 36rem -->
<div class="max-w-2xl mx-auto">...</div>  <!-- 42rem -->
<div class="max-w-4xl mx-auto">...</div>  <!-- 56rem -->
<div class="max-w-7xl mx-auto">...</div>  <!-- 80rem -->
<div class="container">...</div>          <!-- max 80rem, auto margins, padded -->

Typography

<!-- Size -->
<p class="text-xs">Extra small</p>
<p class="text-sm">Small</p>
<p class="text-base">Base</p>
<p class="text-lg">Large</p>
<p class="text-xl">X-Large</p>
<p class="text-2xl">2X-Large</p>
<p class="text-3xl">3X-Large</p>
<p class="text-4xl">4X-Large</p>
<p class="text-5xl">5X-Large</p>
<p class="text-6xl">6X-Large</p>
<p class="text-7xl">7X-Large</p>

<!-- Weight -->
<p class="font-normal">Normal 400</p>
<p class="font-medium">Medium 500</p>
<p class="font-semibold">Semibold 600</p>
<p class="font-bold">Bold 700</p>
<p class="font-black">Black 900</p>

<!-- Alignment -->
<p class="text-left">...</p>
<p class="text-center">...</p>
<p class="text-right">...</p>

<!-- Style & transform -->
<p class="italic">...</p>
<p class="uppercase">...</p>
<p class="capitalize">...</p>
<p class="underline">...</p>
<p class="line-through">...</p>
<p class="truncate">truncated with ellipsis...</p>

<!-- Line height -->
<p class="leading-tight">1.25</p>
<p class="leading-normal">1.5</p>
<p class="leading-relaxed">1.625</p>
<p class="leading-loose">2</p>

Colors

<!-- Text -->
<p class="text-primary">...</p>
<p class="text-secondary">...</p>
<p class="text-muted">...</p>
<p class="text-success">...</p>
<p class="text-danger">...</p>
<p class="text-warning">...</p>
<p class="text-white">...</p>
<p class="text-black">...</p>

<!-- Background -->
<div class="bg-primary">...</div>
<div class="bg-surface">...</div>
<div class="bg-success">...</div>
<div class="bg-danger">...</div>
<div class="bg-white">...</div>
<div class="bg-transparent">...</div>

<!-- Border color -->
<div class="border border-primary">...</div>
<div class="border border-danger">...</div>

Borders

<div class="border">all sides, default color</div>
<div class="border-t">top only</div>
<div class="border-r">right only</div>
<div class="border-b">bottom only</div>
<div class="border-l">left only</div>
<div class="border border-2">2px</div>
<div class="border border-4">4px</div>
<div class="border border-dashed">dashed</div>
<div class="border border-dotted">dotted</div>
<div class="border-0">remove border</div>

Border Radius

<div class="rounded-sm">...</div>
<div class="rounded-md">...</div>
<div class="rounded-lg">...</div>
<div class="rounded-full">pill or circle</div>
<div class="rounded-none">no radius</div>

<!-- Top/bottom only -->
<div class="rounded-t-lg">...</div>
<div class="rounded-b-md">...</div>

Shadows

<div class="shadow-sm">subtle</div>
<div class="shadow-md">medium</div>
<div class="shadow-lg">large</div>
<div class="shadow-xl">extra large</div>
<div class="shadow-none">remove shadow</div>

Opacity

<div class="opacity-100">fully visible</div>
<div class="opacity-75">75%</div>
<div class="opacity-50">50%</div>
<div class="opacity-25">25%</div>
<div class="opacity-0">invisible</div>

Transitions

<div class="transition">all properties, base speed</div>
<div class="transition-fast">150ms</div>
<div class="transition-slow">300ms</div>
<div class="transition-colors">color, background, border only</div>
<div class="transition-opacity">opacity only</div>
<div class="transition-transform">transform only</div>
<div class="transition-none">disable</div>

Cursor

<button class="cursor-pointer">...</button>
<span class="cursor-not-allowed opacity-50">disabled</span>
<div class="cursor-grab">...</div>

State Variants

All state variants use a suffix, consistent with responsive variants.

Hover — .utility-hover

Applied only on :hover. Each color has a dedicated --color-*-hover variable.

<!-- Background changes on hover -->
<button class="bg-primary bg-primary-hover transition-colors">Button</button>

<!-- Border highlights on hover -->
<div class="border border-primary-hover transition-colors">Card</div>

<!-- Text color changes on hover -->
<a class="text-muted text-primary-hover transition-colors">Link</a>

<!-- Shadow lifts on hover -->
<div class="shadow-sm shadow-md-hover transition">Card</div>

<!-- Opacity dims on hover -->
<img class="opacity-100 opacity-75-hover transition-opacity">

Available: bg-*-hover, text-*-hover, border-*-hover, shadow-*-hover, opacity-*-hover

Focus — .utility-focus

Applied on :focus. Essential for accessible form inputs.

<input class="border outline-none-focus border-primary-focus transition-colors">

<!-- ring-focus adds a 2px outline using --color-primary-focus -->
<button class="ring-focus">Accessible button</button>

Available: bg-*-focus, text-*-focus, border-*-focus, outline-none-focus, ring-focus, ring-danger-focus

Active — .utility-active

Applied on :active (while pressed).

<!-- Full interactive state stack -->
<button class="bg-primary bg-primary-hover bg-primary-active transition-colors">
  Button
</button>

Available: bg-*-active, text-*-active, border-*-active, opacity-*-active


Responsive Variants

Breakpoint variants use a -{breakpoint} suffix and are mobile-first (min-width).

Suffix Breakpoint
-sm 640px+
-md 768px+
-lg 1024px+
<!-- Stack on mobile, side by side at md -->
<div class="flex flex-col flex-row-md gap-4">
  <div>Column 1</div>
  <div>Column 2</div>
</div>

<!-- Hide on mobile, show at lg -->
<nav class="hidden flex-lg">...</nav>

<!-- 1 col on mobile, 2 at sm, 3 at md -->
<div class="grid grid-cols-1 grid-cols-2-sm grid-cols-3-md gap-4">
  ...
</div>

<!-- Larger text on bigger screens -->
<h1 class="text-3xl text-5xl-md text-7xl-lg">Heading</h1>

Available responsive utilities: display, flex direction, justify, align items, grid columns, text sizes, width


Extending

Use unc-extend.css to override tokens or add custom utilities. It loads after unc.css so everything cascades correctly.

Override a token

/* unc-extend.css */
:root {
  --color-primary:        #e11d48;
  --color-primary-hover:  #be123c;
  --color-primary-focus:  #9f1239;
  --color-primary-active: #881337;
}

Add a custom color

:root {
  --color-brand:        #f97316;
  --color-brand-hover:  #ea6c0a;
  --color-brand-focus:  #c2540a;
  --color-brand-active: #9a3e06;
}

.bg-brand   { background-color: var(--color-brand); }
.text-brand { color: var(--color-brand); }

.bg-brand-hover:hover   { background-color: var(--color-brand-hover); }
.bg-brand-focus:focus   { background-color: var(--color-brand-focus); }
.bg-brand-active:active { background-color: var(--color-brand-active); }

Add a custom component class

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-5);
  background: var(--color-primary);
  color: var(--color-white);
  font-weight: var(--font-medium);
  border-radius: var(--radius-md);
  border: none;
  cursor: pointer;
  transition: background var(--transition-fast);
}

.btn:hover  { background: var(--color-primary-hover); }
.btn:active { background: var(--color-primary-active); }

.btn-outline {
  background: transparent;
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
}

.btn-outline:hover {
  background: var(--color-primary);
  color: var(--color-white);
}

About

A utility CSS library designed for simplicity, zero tooling, and easy extension.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors