--- version: "1.0" date: "2025-01-15" author: "DWS Foldsite Team" title: "Styles Guide" description: "Understanding Foldsite's CSS cascade system" summary: "Learn how CSS styles cascade through your Foldsite project - from base styles to page-specific customizations." quick_tips: - "base.css is required and loaded on every page" - "All matching styles are loaded (unlike templates where first match wins)" - "Styles cascade down through directory structure like templates" --- # 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 ```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):** 1. **Base style** (always) ``` /styles/base.css ``` 2. **Type + extension** styles (from root to specific) ``` /styles/__file.md.css /styles/blog/__file.md.css ``` 3. **Type + category** styles ``` /styles/__file.document.css /styles/blog/__file.document.css ``` 4. **Specific file** style ``` /styles/blog/my-post.md.css ``` **All found styles are included!** ### Rendered HTML ```html ``` ## 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:** 1. `base.css` - Loaded first 2. General styles (`__file.md.css`) 3. Section styles (`blog/__file.md.css`) 4. Specific styles (`blog/my-post.md.css`) **Later styles override earlier ones** (standard CSS behavior). ### Example Cascade **Given page:** `blog/tutorial.md` **Loaded styles:** ```html ``` **base.css:** ```css h1 { color: black; /* Default */ } ``` **__file.md.css:** ```css h1 { color: #333; /* Slightly lighter */ } ``` **blog/__file.md.css:** ```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 ```css /* 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 ```css /* 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 ```css @import url('components/typography.css'); @import url('components/layout.css'); @import url('components/navigation.css'); ``` **components/typography.css** ```css body { font-family: Georgia, serif; line-height: 1.6; } h1 { font-size: 2.5rem; } /* ... */ ``` **components/navigation.css** ```css nav { display: flex; justify-content: space-between; } /* ... */ ``` ### Pattern 3: Layout Variants Different layouts for different sections: **layouts/document.css** ```css .document-layout { display: grid; grid-template-columns: 250px 1fr; gap: 2rem; } .docs-sidebar { /* sidebar styles */ } .docs-content { /* content styles */ } ``` **layouts/gallery.css** ```css .gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; } .photo-item { /* photo card styles */ } ``` **Include in templates:** ```html
``` ### Pattern 4: Responsive Design Mobile-first approach: ```css /* 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:** ```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:** ```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:** ```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:** ```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:** ```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:** ```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:** ```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 ```css :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 ```css /* 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 ```css /* Remove unnecessary spaces/newlines in production */ /* Use a CSS minifier */ ``` ### 2. Avoid @import ```css /* Slow - additional HTTP request */ @import url('components/typography.css'); /* Better - combine files or use build tool */ /* Or let browser load multiple tags in parallel */ ``` ### 3. Optimize Selectors ```css /* Fast */ .class-name { } #id-name { } /* Slower */ div > ul > li > a { } [data-attribute="value"] { } /* Use classes for styling */ ``` ### 4. Use Will-Change Sparingly ```css /* 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 1. **Inspect element** - Right-click → Inspect 2. **Check computed styles** - See which rules apply 3. **See cascade** - Understand override order 4. **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/)** - Templates use these styles - **[Template Discovery](../templates/template-discovery.md)** - How styles are discovered - **[Recipes](../recipes/)** - Complete examples with CSS Master the style system to create beautiful, maintainable Foldsites!