8.1 KiB
How to Customize Styles
This guide shows you how to override the default styles with your own CSS.
Overview
FolderWeb uses a fallback system for styles:
- Check
/custom/styles/base.css - Fall back to
/app/default/styles/base.css
The framework automatically versions CSS files with MD5 hashes for cache busting.
Quick Start
Step 1: Create Custom Stylesheet
mkdir -p custom/styles
touch custom/styles/base.css
Step 2: Override CSS Variables
The easiest way to customize is to override CSS custom properties:
:root {
--color-primary: oklch(0.65 0.20 30); /* Orange */
--color-secondary: oklch(0.50 0.18 30); /* Dark orange */
--color-light: oklch(0.98 0.01 30); /* Warm white */
--color-grey: oklch(0.40 0 0); /* Grey */
--font-body: "Helvetica Neue", Arial, sans-serif;
--font-heading: "Georgia", serif;
--spacing-unit: 1.5rem;
--border-radius: 8px;
}
Step 3: Test Your Changes
Refresh your browser. If changes don't appear, do a hard refresh (Ctrl+Shift+R or Cmd+Shift+R).
Available CSS Variables
Colors
--color-primary: oklch(0.65 0.15 250); /* Primary blue */
--color-secondary: oklch(0.50 0.12 250); /* Dark blue */
--color-light: oklch(0.97 0.01 250); /* Off-white */
--color-grey: oklch(0.37 0 0); /* Dark grey */
Note: FolderWeb uses OKLCH colors for perceptually uniform color spaces. You can also use hex, rgb, or hsl if preferred.
Typography
--font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--font-heading: Georgia, "Times New Roman", serif;
--font-size-base: 1.125rem; /* 18px */
--font-size-small: 0.875rem; /* 14px */
--line-height-base: 1.6;
--line-height-heading: 1.2;
Spacing
--spacing-unit: 1.5rem; /* Base spacing (24px) */
--spacing-small: 0.75rem; /* 12px */
--spacing-large: 3rem; /* 48px */
Layout
--max-width: 70rem; /* Content max-width */
--border-radius: 4px; /* Corner rounding */
Adding Custom Fonts
Step 1: Add Font Files
mkdir -p custom/fonts
# Copy your .woff2 files here
cp ~/Downloads/MyFont-Regular.woff2 custom/fonts/
cp ~/Downloads/MyFont-Bold.woff2 custom/fonts/
Step 2: Declare Font Faces
In custom/styles/base.css:
@font-face {
font-family: 'MyFont';
src: url('/custom/fonts/MyFont-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'MyFont';
src: url('/custom/fonts/MyFont-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
:root {
--font-body: 'MyFont', sans-serif;
}
Note: Font files are automatically served by FolderWeb's static file handler.
Page-Specific Styling
FolderWeb adds dynamic CSS classes to the <body> element:
<body class="section-blog page-2025-11-02-my-post">
Use these for targeted styling:
/* Style all blog pages */
.section-blog {
--color-primary: oklch(0.60 0.15 150); /* Green for blog */
}
/* Style a specific page */
.page-about {
font-size: 1.25rem;
}
/* Combine for precision */
.section-docs.page-installation {
background: var(--color-light);
}
Responsive Design
FolderWeb uses modern CSS features for responsiveness. Use clamp() for fluid typography:
:root {
--font-size-base: clamp(1rem, 0.9rem + 0.5vw, 1.25rem);
--spacing-unit: clamp(1rem, 0.8rem + 1vw, 2rem);
}
h1 {
font-size: clamp(2rem, 1.5rem + 2vw, 3.5rem);
}
Use container queries for component responsiveness:
.card-grid {
container-type: inline-size;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: var(--spacing-unit);
}
@container (min-width: 600px) {
.card {
padding: var(--spacing-large);
}
}
Dark Mode
Add a dark mode using CSS custom properties and media queries:
:root {
--color-bg: oklch(0.97 0.01 250);
--color-text: oklch(0.20 0 0);
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg: oklch(0.20 0 0);
--color-text: oklch(0.95 0 0);
--color-light: oklch(0.25 0 0);
--color-primary: oklch(0.70 0.15 250);
}
}
body {
background: var(--color-bg);
color: var(--color-text);
}
List Template Styling
Style the different list templates:
Grid Layout
.list-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: var(--spacing-unit);
}
.list-grid article {
border: 1px solid var(--color-light);
border-radius: var(--border-radius);
overflow: hidden;
}
.list-grid img {
aspect-ratio: 16 / 9;
object-fit: cover;
width: 100%;
}
Card Grid
.card-grid .card {
background: var(--color-light);
padding: var(--spacing-unit);
border-radius: var(--border-radius);
transition: transform 0.2s ease;
}
.card-grid .card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
FAQ Layout
.faq details {
border: 1px solid var(--color-light);
border-radius: var(--border-radius);
padding: var(--spacing-unit);
margin-block-end: var(--spacing-small);
}
.faq summary {
cursor: pointer;
font-weight: 700;
user-select: none;
}
.faq summary:hover {
color: var(--color-primary);
}
Modern CSS Features
FolderWeb encourages use of modern CSS:
CSS Nesting
.article {
padding: var(--spacing-unit);
& h2 {
color: var(--color-primary);
margin-block-start: var(--spacing-large);
}
& a {
color: var(--color-secondary);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
Logical Properties
Use logical properties for internationalization:
/* Instead of: margin-left, margin-right */
article {
margin-inline: auto;
padding-inline: var(--spacing-unit);
padding-block: var(--spacing-large);
}
/* Instead of: text-align: left */
.content {
text-align: start;
}
Modern Color Functions
:root {
/* OKLCH: lightness, chroma, hue */
--primary: oklch(0.65 0.15 250);
/* Adjust lightness for hover */
--primary-hover: oklch(0.55 0.15 250);
/* Or use color-mix */
--primary-light: color-mix(in oklch, var(--primary), white 20%);
}
Performance Tips
Minimize Custom Styles
Override only what's necessary. The default stylesheet is already optimized.
Use CSS Variables
Variables reduce repetition and improve maintainability:
/* Good */
:root {
--card-padding: var(--spacing-unit);
}
.card { padding: var(--card-padding); }
.box { padding: var(--card-padding); }
/* Less maintainable */
.card { padding: 1.5rem; }
.box { padding: 1.5rem; }
Avoid !important
FolderWeb uses low-specificity selectors, so you shouldn't need !important.
Debugging Styles
Check Which Stylesheet is Loaded
View source and look for:
<link rel="stylesheet" href="/app/styles/base.css?v=abc123...">
If you see /app/styles/, your custom stylesheet is being used.
If you see /app/default-styles/, the default is being used.
Browser DevTools
- Right-click element → Inspect
- Check "Computed" tab to see which properties are applied
- Check "Sources" tab to verify your CSS file is loaded
- Use "Network" tab to ensure CSS isn't cached with old version
Hard Refresh
Always do a hard refresh after CSS changes:
- Chrome/Firefox: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac)
- Safari: Cmd+Option+R
Complete Override
If you want complete control, you can replace the entire stylesheet. Copy the default:
cp app/default/styles/base.css custom/styles/base.css
Then edit freely. Remember: you're responsible for all styles when you do this.