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

538 lines
10 KiB
Markdown

# 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
```css
: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:
```css
oklch(lightness chroma hue)
```
- **Lightness**: 0 (black) to 1 (white)
- **Chroma**: 0 (grey) to ~0.4 (vibrant)
- **Hue**: 0-360 degrees
**Examples**:
```css
/* 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:
```css
: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
```css
: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**:
```css
@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
```css
: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**:
```css
: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
```css
: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
```css
: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**:
```css
.card {
padding: var(--spacing-unit);
margin-block-end: var(--spacing-large);
}
.tag {
padding: var(--spacing-small);
}
```
**Responsive Spacing**:
```css
:root {
--spacing-unit: clamp(1rem, 0.8rem + 1vw, 2rem);
}
```
## Layout Variables
```css
:root {
--max-width: 70rem; /* 1120px */
--border-radius: 4px;
}
```
| Variable | Default | Description |
|----------|---------|-------------|
| `--max-width` | 70rem (1120px) | Content max-width |
| `--border-radius` | 4px | Corner rounding |
**Usage**:
```css
.contain {
max-inline-size: var(--max-width);
margin-inline: auto;
}
.card {
border-radius: var(--border-radius);
}
```
## Complete Variable List
```css
: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
```css
: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
```css
@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
```css
:root {
--font-size-base: 1.25rem; /* 20px */
--line-height-base: 1.7;
--spacing-unit: 2rem;
}
```
### Tight Layout
```css
:root {
--max-width: 50rem; /* 800px */
--spacing-unit: 1rem; /* 16px */
--spacing-large: 2rem; /* 32px */
}
```
### Rounded Design
```css
:root {
--border-radius: 12px;
}
```
## Using Variables
### In Your Styles
```css
.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:
```css
.card {
background: #F5F5F5; /* Fallback */
background: var(--color-light); /* Variable */
}
```
### With calc()
Combine with calculations:
```css
.card {
padding: calc(var(--spacing-unit) * 2);
margin-block-end: calc(var(--spacing-large) - 1rem);
}
```
### With color-mix()
Create variations:
```css
.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:
```css
: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:
```css
.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:
```css
/* 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:
```css
: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:
```javascript
getComputedStyle(document.documentElement).getPropertyValue('--color-primary')
```
## Best Practices
### Use Semantic Names
```css
/* Good - semantic */
--color-primary
--color-text
--color-background
/* Avoid - non-semantic */
--color-blue
--color-444
```
### Group Related Variables
```css
:root {
/* Colors */
--color-primary: ...;
--color-secondary: ...;
/* Typography */
--font-body: ...;
--font-heading: ...;
/* Spacing */
--spacing-unit: ...;
}
```
### Document Your Variables
```css
: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
```css
.card {
background: #F5F5F5;
background: var(--color-light);
}
```
## Related
- [Custom Styles Guide](../how-to/custom-styles.md)
- [Template Reference](templates.md)
- [File Structure Reference](file-structure.md)