folderweb/docs/reference/css-variables.md
2025-11-02 13:46:47 +01:00

10 KiB

CSS Variables Reference

Complete reference for all CSS custom properties available in FolderWeb.

Overview

FolderWeb uses CSS custom properties (variables) for theming. Override these in /custom/styles/base.css to customize your site's appearance.

Color Variables

Primary Colors

:root {
    --color-primary: oklch(0.65 0.15 250);
    --color-secondary: oklch(0.50 0.12 250);
    --color-light: oklch(0.97 0.01 250);
    --color-grey: oklch(0.37 0 0);
}
Variable Default Description
--color-primary Blue (OKLCH) Primary brand color, links, buttons
--color-secondary Dark blue (OKLCH) Secondary accents, hover states
--color-light Off-white (OKLCH) Background, light sections
--color-grey Dark grey Body text, headings

OKLCH Color Space

FolderWeb uses OKLCH for perceptually uniform colors:

oklch(lightness chroma hue)
  • Lightness: 0 (black) to 1 (white)
  • Chroma: 0 (grey) to ~0.4 (vibrant)
  • Hue: 0-360 degrees

Examples:

/* Blue hues (250°) */
--color-primary: oklch(0.65 0.15 250);

/* Orange hues (30°) */
--color-primary: oklch(0.65 0.20 30);

/* Green hues (150°) */
--color-primary: oklch(0.60 0.15 150);

/* Red hues (0°) */
--color-primary: oklch(0.60 0.20 0);

/* Purple hues (300°) */
--color-primary: oklch(0.60 0.18 300);

Alternative Color Formats

You can use hex, rgb, or hsl instead:

:root {
    /* Hex */
    --color-primary: #4169E1;
    --color-secondary: #1E3A8A;
    
    /* RGB */
    --color-primary: rgb(65, 105, 225);
    --color-secondary: rgb(30, 58, 138);
    
    /* HSL */
    --color-primary: hsl(225, 73%, 57%);
    --color-secondary: hsl(225, 64%, 33%);
}

Typography Variables

Font Families

:root {
    --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-heading: Georgia, "Times New Roman", serif;
}
Variable Default Description
--font-body System sans-serif stack Body text, paragraphs
--font-heading Serif stack Headings (h1-h6)

Custom Fonts:

@font-face {
    font-family: 'MyFont';
    src: url('/custom/fonts/MyFont.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

:root {
    --font-body: 'MyFont', sans-serif;
}

Font Sizes

:root {
    --font-size-base: 1.125rem;     /* 18px */
    --font-size-small: 0.875rem;    /* 14px */
}
Variable Default Description
--font-size-base 1.125rem (18px) Body text size
--font-size-small 0.875rem (14px) Small text, metadata

Responsive Sizing:

:root {
    /* Fluid typography */
    --font-size-base: clamp(1rem, 0.9rem + 0.5vw, 1.25rem);
}

h1 {
    font-size: clamp(2rem, 1.5rem + 2vw, 3.5rem);
}

Line Heights

:root {
    --line-height-base: 1.6;
    --line-height-heading: 1.2;
}
Variable Default Description
--line-height-base 1.6 Body text line height
--line-height-heading 1.2 Heading line height

Spacing Variables

:root {
    --spacing-unit: 1.5rem;         /* 24px */
    --spacing-small: 0.75rem;       /* 12px */
    --spacing-large: 3rem;          /* 48px */
}
Variable Default Description
--spacing-unit 1.5rem (24px) Base spacing unit
--spacing-small 0.75rem (12px) Small gaps
--spacing-large 3rem (48px) Large gaps, section spacing

Usage:

.card {
    padding: var(--spacing-unit);
    margin-block-end: var(--spacing-large);
}

.tag {
    padding: var(--spacing-small);
}

Responsive Spacing:

:root {
    --spacing-unit: clamp(1rem, 0.8rem + 1vw, 2rem);
}

Layout Variables

:root {
    --max-width: 70rem;             /* 1120px */
    --border-radius: 4px;
}
Variable Default Description
--max-width 70rem (1120px) Content max-width
--border-radius 4px Corner rounding

Usage:

.contain {
    max-inline-size: var(--max-width);
    margin-inline: auto;
}

.card {
    border-radius: var(--border-radius);
}

Complete Variable List

:root {
    /* Colors */
    --color-primary: oklch(0.65 0.15 250);
    --color-secondary: oklch(0.50 0.12 250);
    --color-light: oklch(0.97 0.01 250);
    --color-grey: oklch(0.37 0 0);
    
    /* Typography */
    --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-heading: Georgia, "Times New Roman", serif;
    --font-size-base: 1.125rem;
    --font-size-small: 0.875rem;
    --line-height-base: 1.6;
    --line-height-heading: 1.2;
    
    /* Spacing */
    --spacing-unit: 1.5rem;
    --spacing-small: 0.75rem;
    --spacing-large: 3rem;
    
    /* Layout */
    --max-width: 70rem;
    --border-radius: 4px;
}

Customization Examples

Orange Theme

:root {
    --color-primary: oklch(0.65 0.20 30);
    --color-secondary: oklch(0.50 0.18 30);
    --color-light: oklch(0.97 0.01 30);
}

Dark Mode

@media (prefers-color-scheme: dark) {
    :root {
        --color-primary: oklch(0.70 0.15 250);
        --color-secondary: oklch(0.80 0.12 250);
        --color-light: oklch(0.25 0 0);
        --color-grey: oklch(0.90 0 0);
    }
}

Large Text

:root {
    --font-size-base: 1.25rem;      /* 20px */
    --line-height-base: 1.7;
    --spacing-unit: 2rem;
}

Tight Layout

:root {
    --max-width: 50rem;             /* 800px */
    --spacing-unit: 1rem;           /* 16px */
    --spacing-large: 2rem;          /* 32px */
}

Rounded Design

:root {
    --border-radius: 12px;
}

Using Variables

In Your Styles

.card {
    background: var(--color-light);
    color: var(--color-grey);
    padding: var(--spacing-unit);
    border-radius: var(--border-radius);
}

.button {
    background: var(--color-primary);
    color: white;
    padding: var(--spacing-small) var(--spacing-unit);
    border-radius: var(--border-radius);
}

.button:hover {
    background: var(--color-secondary);
}

With Fallbacks

Provide fallbacks for older browsers:

.card {
    background: #F5F5F5;                        /* Fallback */
    background: var(--color-light);             /* Variable */
}

With calc()

Combine with calculations:

.card {
    padding: calc(var(--spacing-unit) * 2);
    margin-block-end: calc(var(--spacing-large) - 1rem);
}

With color-mix()

Create variations:

.button {
    background: var(--color-primary);
}

.button:hover {
    background: color-mix(in oklch, var(--color-primary), black 10%);
}

.button-light {
    background: color-mix(in oklch, var(--color-primary), white 80%);
}

Adding Custom Variables

Define your own variables:

:root {
    /* Custom color palette */
    --color-accent: oklch(0.70 0.15 180);
    --color-warning: oklch(0.70 0.20 60);
    --color-danger: oklch(0.60 0.20 10);
    --color-success: oklch(0.65 0.15 140);
    
    /* Custom spacing */
    --spacing-xs: 0.25rem;
    --spacing-xl: 4rem;
    --spacing-2xl: 6rem;
    
    /* Custom typography */
    --font-mono: 'Monaco', 'Courier New', monospace;
    --font-size-large: 1.5rem;
    --font-size-xlarge: 2rem;
    
    /* Custom layout */
    --sidebar-width: 20rem;
    --header-height: 4rem;
    --content-gap: 2rem;
}

Use them:

.sidebar {
    width: var(--sidebar-width);
    background: var(--color-light);
}

code {
    font-family: var(--font-mono);
    background: var(--color-accent);
    padding: var(--spacing-xs);
}

Scoped Variables

Override variables for specific sections:

/* Global defaults */
:root {
    --color-primary: oklch(0.65 0.15 250);
}

/* Blog section uses green */
.section-blog {
    --color-primary: oklch(0.60 0.15 150);
}

/* About page uses orange */
.page-about {
    --color-primary: oklch(0.65 0.20 30);
}

/* Variables cascade to children */
.section-blog .button {
    background: var(--color-primary);  /* Green in blog */
}

Responsive Variables

Change variables at breakpoints:

:root {
    --spacing-unit: 1rem;
    --font-size-base: 1rem;
    --max-width: 60rem;
}

@media (min-width: 768px) {
    :root {
        --spacing-unit: 1.5rem;
        --font-size-base: 1.125rem;
        --max-width: 70rem;
    }
}

@media (min-width: 1200px) {
    :root {
        --spacing-unit: 2rem;
        --font-size-base: 1.25rem;
        --max-width: 80rem;
    }
}

Browser Support

CSS custom properties are supported in all modern browsers:

  • Chrome 49+
  • Firefox 31+
  • Safari 9.1+
  • Edge 15+

For older browsers, provide fallbacks or use PostCSS with custom properties plugin.

Debugging Variables

Inspect variables in browser DevTools:

  1. Right-click element → Inspect
  2. Check "Computed" tab
  3. Scroll to custom properties section
  4. See resolved values

Or log in console:

getComputedStyle(document.documentElement).getPropertyValue('--color-primary')

Best Practices

Use Semantic Names

/* Good - semantic */
--color-primary
--color-text
--color-background

/* Avoid - non-semantic */
--color-blue
--color-444
:root {
    /* Colors */
    --color-primary: ...;
    --color-secondary: ...;
    
    /* Typography */
    --font-body: ...;
    --font-heading: ...;
    
    /* Spacing */
    --spacing-unit: ...;
}

Document Your Variables

:root {
    /* Brand colors from design system */
    --color-primary: oklch(0.65 0.15 250);  /* Blue - primary CTA */
    --color-secondary: oklch(0.50 0.12 250); /* Dark blue - accents */
    
    /* Layout constraints */
    --max-width: 70rem;  /* 1120px - content max width */
}

Provide Fallbacks

.card {
    background: #F5F5F5;
    background: var(--color-light);
}