Files
foldsite/docs/content/styles/index.md
Tanishq Dubey ad81d7f3db
All checks were successful
Datadog Software Composition Analysis / Datadog SBOM Generation and Upload (push) Successful in 52s
Datadog Secrets Scanning / Datadog Static Analyzer (push) Successful in 1m1s
Datadog Static Analysis / Datadog Static Analyzer (push) Successful in 5m50s
docs refactor
2025-10-09 18:21:23 -04:00

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.
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

/* 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

<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:

  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:

<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);
}
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

  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

Master the style system to create beautiful, maintainable Foldsites!