14 KiB
version, date, author, title, description, summary, quick_tips
version | date | author | title | description | summary | quick_tips | |||
---|---|---|---|---|---|---|---|---|---|
1.0 | 2025-01-15 | DWS Foldsite Team | Styles Guide | Understanding Foldsite's CSS cascade system | Learn how CSS styles cascade through your Foldsite project - from base styles to page-specific customizations. |
|
Styles Guide
Foldsite's style system follows the same hierarchical logic as templates, allowing you to organize CSS in a maintainable, scalable way.
The Style System
Key Differences from Templates
Templates | Styles |
---|---|
First match wins | All matches load |
One template per page | Multiple stylesheets per page |
Must have at least one | base.css required |
Why the difference?
CSS is designed to cascade and layer. Loading multiple stylesheets allows you to:
- Share base styles
- Add section-specific styles
- Override with page-specific styles
Required Style: base.css
Every Foldsite project must have styles/base.css
.
This file is loaded on every page, providing:
- Typography
- Layout basics
- Color scheme
- Resets/normalizes
Minimal base.css
/* styles/base.css */
* {
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.5em;
margin-bottom: 0.5em;
line-height: 1.2;
}
a {
color: #0066cc;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
img {
max-width: 100%;
height: auto;
}
Style Discovery
Styles follow a hierarchical discovery pattern similar to templates.
For File: blog/my-post.md
All matching styles load (in order):
-
Base style (always)
/styles/base.css
-
Type + extension styles (from root to specific)
/styles/__file.md.css /styles/blog/__file.md.css
-
Type + category styles
/styles/__file.document.css /styles/blog/__file.document.css
-
Specific file style
/styles/blog/my-post.md.css
All found styles are included!
Rendered HTML
<link rel="stylesheet" href="/styles/base.css">
<link rel="stylesheet" href="/styles/__file.md.css">
<link rel="stylesheet" href="/styles/blog/__file.md.css">
Style Naming Patterns
File Styles
Pattern: __file.{extension}.css
or __file.{category}.css
styles/
├── __file.md.css # All markdown files
├── __file.document.css # All document files
├── __file.image.css # Individual images (rare)
└── __file.other.css # Other file types
Folder Styles
Pattern: __folder.{category}.css
styles/
├── __folder.md.css # Folders with markdown
├── __folder.image.css # Photo galleries
└── __folder.html # Any folder view
Specific Page Styles
Pattern: {path/to/file}.css
styles/
├── index.md.css # Only homepage
├── about.md.css # Only about page
└── blog/
└── special-post.md.css # One specific post
Directory Structure
Basic Structure
styles/
├── base.css # Required: Base styles
├── __file.md.css # Markdown file styles
└── __folder.image.css # Gallery styles
Advanced Structure
styles/
├── base.css # Base
├── __file.md.css # General markdown
├── __folder.image.css # General galleries
├── blog/
│ ├── __file.md.css # Blog posts
│ └── __folder.md.css # Blog index
├── docs/
│ └── __file.md.css # Documentation
├── layouts/
│ ├── document.css # Document layout
│ ├── gallery.css # Gallery layout
│ └── landing.css # Landing pages
└── components/
├── navigation.css # Navigation
├── footer.css # Footer
└── breadcrumbs.css # Breadcrumbs
Cascade & Specificity
CSS Cascade Order
Load order matters:
base.css
- Loaded first- General styles (
__file.md.css
) - Section styles (
blog/__file.md.css
) - Specific styles (
blog/my-post.md.css
)
Later styles override earlier ones (standard CSS behavior).
Example Cascade
Given page: blog/tutorial.md
Loaded styles:
<link rel="stylesheet" href="/styles/base.css">
<link rel="stylesheet" href="/styles/__file.md.css">
<link rel="stylesheet" href="/styles/blog/__file.md.css">
base.css:
h1 {
color: black; /* Default */
}
__file.md.css:
h1 {
color: #333; /* Slightly lighter */
}
blog/__file.md.css:
h1 {
color: #0066cc; /* Blue - wins! */
}
Result: Blog headings are blue.
Common Patterns
Pattern 1: Base + Overrides
Start with comprehensive base, override as needed:
base.css - Everything
/* Typography */
body { font-family: sans-serif; }
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
/* Layout */
.container { max-width: 1200px; }
/* Components */
nav { /* navigation styles */ }
footer { /* footer styles */ }
blog/__file.md.css - Blog-specific
/* Override heading colors for blog */
h1 { color: #0066cc; }
/* Add blog-specific components */
.post-meta { /* metadata styles */ }
Pattern 2: Modular Components
Split styles into reusable modules:
base.css - Minimal
@import url('components/typography.css');
@import url('components/layout.css');
@import url('components/navigation.css');
components/typography.css
body {
font-family: Georgia, serif;
line-height: 1.6;
}
h1 { font-size: 2.5rem; }
/* ... */
components/navigation.css
nav {
display: flex;
justify-content: space-between;
}
/* ... */
Pattern 3: Layout Variants
Different layouts for different sections:
layouts/document.css
.document-layout {
display: grid;
grid-template-columns: 250px 1fr;
gap: 2rem;
}
.docs-sidebar { /* sidebar styles */ }
.docs-content { /* content styles */ }
layouts/gallery.css
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1rem;
}
.photo-item { /* photo card styles */ }
Include in templates:
<!-- __file.md.html for docs -->
<link rel="stylesheet" href="/styles/layouts/document.css">
<div class="document-layout">
<!-- content -->
</div>
Pattern 4: Responsive Design
Mobile-first approach:
/* base.css - Mobile first */
body {
padding: 1rem;
}
.container {
display: block;
}
/* Tablet */
@media (min-width: 768px) {
body {
padding: 2rem;
}
.container {
display: grid;
grid-template-columns: 1fr 300px;
}
}
/* Desktop */
@media (min-width: 1200px) {
body {
padding: 3rem;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
}
Practical Examples
Example 1: Blog Site
styles/
├── base.css # Site-wide styles
├── __file.md.css # General markdown
├── __folder.md.css # Folder listings
└── blog/
├── __file.md.css # Blog posts
└── __folder.md.css # Blog index
base.css:
/* Basic layout and typography */
body {
font-family: Georgia, serif;
line-height: 1.6;
max-width: 800px;
margin: 0 auto;
padding: 2rem;
}
a { color: #0066cc; }
__file.md.css:
/* Default markdown styles */
article {
margin: 2rem 0;
}
code {
background: #f4f4f4;
padding: 0.2em 0.4em;
border-radius: 3px;
}
pre {
background: #f4f4f4;
padding: 1rem;
overflow-x: auto;
}
blog/__file.md.css:
/* Blog post specific */
.post-header {
border-bottom: 2px solid #eee;
padding-bottom: 1rem;
margin-bottom: 2rem;
}
.post-meta {
color: #666;
font-size: 0.9rem;
}
.post-tags {
margin-top: 2rem;
}
.tag {
display: inline-block;
padding: 0.25rem 0.75rem;
background: #f0f0f0;
border-radius: 3px;
margin-right: 0.5rem;
font-size: 0.85rem;
}
blog/__folder.md.css:
/* Blog index */
.post-list {
list-style: none;
padding: 0;
}
.post-item {
margin: 2rem 0;
padding: 1.5rem;
border: 1px solid #eee;
border-radius: 4px;
}
.post-item:hover {
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
Example 2: Photo Gallery
styles/
├── base.css
└── galleries/
└── __folder.image.css
galleries/__folder.image.css:
.photo-gallery {
padding: 2rem;
}
.photo-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}
.photo-item {
position: relative;
overflow: hidden;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: transform 0.2s, box-shadow 0.2s;
}
.photo-item:hover {
transform: translateY(-4px);
box-shadow: 0 4px 16px rgba(0,0,0,0.15);
}
.photo-item img {
width: 100%;
height: auto;
display: block;
}
.photo-caption {
padding: 0.75rem;
background: white;
font-size: 0.85rem;
color: #666;
}
/* Responsive */
@media (max-width: 768px) {
.photo-grid {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
}
Example 3: Documentation Site
styles/
├── base.css
├── layouts/
│ └── document.css
└── docs/
└── __file.md.css
layouts/document.css:
.docs-layout {
display: grid;
grid-template-columns: 250px 1fr;
gap: 3rem;
max-width: 1400px;
margin: 0 auto;
}
.docs-sidebar {
position: sticky;
top: 2rem;
height: calc(100vh - 4rem);
overflow-y: auto;
}
.docs-content {
min-width: 0; /* Prevent grid blowout */
}
@media (max-width: 1024px) {
.docs-layout {
grid-template-columns: 1fr;
}
.docs-sidebar {
position: static;
height: auto;
}
}
docs/__file.md.css:
.documentation {
max-width: 800px;
}
/* Table of contents */
.doc-toc {
background: #f8f8f8;
padding: 1rem;
border-radius: 4px;
margin: 2rem 0;
}
/* Code blocks */
.documentation pre {
background: #282c34;
color: #abb2bf;
padding: 1.5rem;
border-radius: 6px;
overflow-x: auto;
}
.documentation code {
font-family: 'Monaco', 'Courier New', monospace;
}
/* Callouts */
.note,
.warning,
.tip {
padding: 1rem 1.5rem;
margin: 1.5rem 0;
border-left: 4px solid;
border-radius: 4px;
}
.note {
background: #e3f2fd;
border-color: #2196f3;
}
.warning {
background: #fff3e0;
border-color: #ff9800;
}
.tip {
background: #e8f5e9;
border-color: #4caf50;
}
CSS Variables
Use CSS custom properties for theming:
base.css with Variables
:root {
/* Colors */
--color-primary: #0066cc;
--color-secondary: #6c757d;
--color-text: #333;
--color-background: #fff;
--color-border: #dee2e6;
/* Typography */
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
--font-serif: Georgia, serif;
--font-mono: 'Monaco', 'Courier New', monospace;
/* Spacing */
--space-xs: 0.5rem;
--space-sm: 1rem;
--space-md: 2rem;
--space-lg: 3rem;
/* Breakpoints (for reference) */
/* Use in @media queries */
}
body {
color: var(--color-text);
background: var(--color-background);
font-family: var(--font-sans);
}
a {
color: var(--color-primary);
}
/* ... */
Dark Mode
/* base.css */
@media (prefers-color-scheme: dark) {
:root {
--color-text: #e4e4e4;
--color-background: #1a1a1a;
--color-border: #333;
}
}
/* Or toggle with class */
body.dark-mode {
--color-text: #e4e4e4;
--color-background: #1a1a1a;
--color-border: #333;
}
Performance Tips
1. Minimize File Size
/* Remove unnecessary spaces/newlines in production */
/* Use a CSS minifier */
2. Avoid @import
/* Slow - additional HTTP request */
@import url('components/typography.css');
/* Better - combine files or use build tool */
/* Or let browser load multiple <link> tags in parallel */
3. Optimize Selectors
/* Fast */
.class-name { }
#id-name { }
/* Slower */
div > ul > li > a { }
[data-attribute="value"] { }
/* Use classes for styling */
4. Use Will-Change Sparingly
/* Only for elements that will actually animate */
.photo-item {
transition: transform 0.2s;
}
.photo-item:hover {
transform: translateY(-4px);
will-change: transform; /* Hint to browser */
}
Debugging Styles
Browser DevTools
- Inspect element - Right-click → Inspect
- Check computed styles - See which rules apply
- See cascade - Understand override order
- Live edit - Test changes instantly
Debug Checklist
Styles not loading:
- File exists in
styles/
directory - Filename matches expected pattern
- No syntax errors in CSS
- Browser cache cleared
Styles not applying:
- Check CSS specificity
- Check cascade order
- Look for typos in selectors
- Verify HTML classes match CSS
Wrong styles applying:
- Check for conflicting rules
- Verify file loading order
- Look for !important (avoid if possible)
Next Steps
- Templates Guide - Templates use these styles
- Template Discovery - How styles are discovered
- Recipes - Complete examples with CSS
Master the style system to create beautiful, maintainable Foldsites!