How does quarto site layout works

Comprehensive guide to Quarto’s layout system including sidebars, navigation, and custom enhancements
Author

Dario Airoldi

Published

July 2, 2025

Modified

November 3, 2025

📋 Table of Contents


Understanding how Quarto’s site layout works is crucial for creating effective documentation websites and implementing custom features like Related Pages navigation.

🔍 How Quarto Site Layout Works

1. Core Layout Architecture

Quarto’s layout system uses a three-panel approach that provides flexibility while maintaining consistency:

┌─────────────────────────────────────────────────────────────┐
│                    Navbar (Top)                             │
├──────────────┬─────────────────────────┬───────────────────┤
│              │                         │                   │
│   Sidebar    │     Main Content        │   Right Margin    │
│   (Left)     │      (Center)           │    (Right)        │
│              │                         │                   │
│ - Navigation │ - Article Content       │ - Table of Contents│
│ - Sections   │ - Headers/Footers       │ - Related Pages   │
│ - Links      │ - Body Text             │ - Custom Widgets  │
│              │                         │                   │
└──────────────┴─────────────────────────┴───────────────────┘

Key Components:

  • Navbar: Top-level navigation with site branding
  • Sidebar: Left navigation panel with site structure
  • Main Content: Central area for article/page content
  • Right Margin: Secondary content like TOCs and Related Pages

2. Layout Components Structure

The layout is controlled by several configuration layers:

**_quarto.yml Configuration:**

website:
  navbar:
    # Top navigation bar
  sidebar:
    # Left navigation panel
  page-footer:
    # Bottom footer content

format:
  html:
    grid:
      sidebar-width: 300px    # Left sidebar width
      body-width: 900px       # Main content width  
      margin-width: 280px     # Right margin width

HTML Structure:

  • #quarto-sidebar: Left navigation container
  • #quarto-content: Main content area
  • #quarto-margin-sidebar: Right margin container
  • #quarto-header: Top navigation header

3. Advanced Sidebar State Management

Our implementation uses a two-phase collapsed-first approach that eliminates flickering and provides smooth restoration:

Phase 1: Pre-Render Collapse (Silent)

// Force all sections to collapsed state without animations
function preRenderCollapseAll() {
  // Disable transitions completely
  // Force all .collapse elements to display: none
  // Set all chevrons to point right
  // No persistence logic - just clean reset
}

Benefits:

  • Eliminates flickering - no visible state changes
  • Clean starting point - consistent collapsed state
  • Fast execution - no animations or delays
  • Override Quarto defaults - works regardless of Quarto’s initial state

Phase 2: Progressive Restore (Visible)

// Smoothly restore saved state with staggered animations
function progressivelyRestoreSidebarState() {
  // Read saved state from localStorage
  // Enable smooth transitions and animations
  // Progressively expand sections with 75ms delays
  // Beautiful visual restoration effect
}

Benefits:

  • Smooth perception - progressive loading feels intentional
  • Visual polish - staggered animations look professional
  • Performance friendly - spreads DOM updates over time
  • User feedback - shows restoration progress

Implementation Strategy:

/* CSS: Force collapsed-first state */
#quarto-sidebar .collapse {
  display: none !important;
  height: 0 !important;
  overflow: hidden !important;
}

#quarto-sidebar .sidebar-item-text .bi::before {
  content: "\f285" !important; /* chevron-right */
}
// JavaScript: Two-phase initialization
document.addEventListener('DOMContentLoaded', function() {
  // Phase 1: Silent collapse (immediate)
  preRenderCollapseAll();
  
  // Phase 2: Progressive restore (delayed, animated)
  setTimeout(() => {
    progressivelyRestoreSidebarState();
  }, 100);
});

3. Client-Side Rendering Process

Quarto’s layout rendering follows this process:

  1. HTML Generation: Quarto processes markdown and generates HTML structure
  2. CSS Application: Themes and custom styles are applied to layout containers
  3. JavaScript Initialization: Client-side scripts initialize interactive components
  4. Dynamic Updates: Navigation states, active sections, and custom widgets update based on user interaction

JavaScript Event System:

// Quarto fires these events during layout updates
window.document.addEventListener("quarto-sectionChanged", function(e) {
  // Fires when user navigates between sections
});

window.document.addEventListener("DOMContentLoaded", function() {
  // Fires when initial layout is ready
});

🛠️ Layout Extension Options

Option 3: Quarto Configuration Extensions

Quarto’s built-in configuration options provide layout control without custom code.

Layout Configuration:

format:
  html:
    grid:
      sidebar-width: 250px
      body-width: 800px
      margin-width: 300px
    include-after-body:
      - _includes/custom-layout.html  # Custom HTML widgets
    css:
      - custom-layout.css             # Layout-specific styles

Sidebar Configuration:

website:
  sidebar:
    style: "floating"     # or "docked"
    search: true
    collapse-level: 2
    contents:
      # Navigation structure

Pros:

  • No programming required
  • Changes apply globally across the project
  • Well-integrated with Quarto’s theming system

Cons:

  • Limited to options exposed by Quarto
  • Cannot create truly custom functionality

Option 4: Quarto Extension Development

For complex, reusable layout enhancements, Quarto extensions provide the most powerful option.

Extension Structure:

my-layout-extension/
├── _extension.yml      # Extension metadata
├── custom-layout.lua   # Pandoc filters
├── layout.css         # Custom styles  
├── layout.js          # Custom scripts
└── templates/         # Custom templates

Pros:

  • Deep integration with Quarto’s build system
  • Reusable across projects
  • Can define new layout patterns

Cons:

  • Requires understanding of Quarto’s extension API
  • More upfront development work

🎯 My Recommendations

Based on real implementation experience, here’s the recommended approach:

Decision Guide:

  1. Start with Option 3 - Use Quarto’s built-in configuration for basic layout changes
  2. Move to Option 1 - Add CSS for visual enhancements and responsive behavior
  3. Implement Option 2 - Use JavaScript for dynamic features like Related Pages
  4. Consider Option 4 - Develop extensions for reusable complex features

Key Extension Points:

Layout Containers:

// Access main layout containers
const sidebar = document.querySelector('#quarto-sidebar');
const content = document.querySelector('#quarto-content'); 
const rightMargin = document.querySelector('#quarto-margin-sidebar');

Navigation Integration:

// Hook into Quarto's navigation events
window.document.addEventListener("quarto-sectionChanged", function(e) {
  updateCustomWidgets();
});

// Access sidebar navigation structure
const sidebarItems = document.querySelectorAll('.sidebar-item-text');
const activeItem = document.querySelector('.sidebar-item-text.active');

Configuration Integration:

// Load site configuration data
async function loadSiteConfig() {
  const response = await fetch('/navigation.json');
  return response.json();
}

Responsive Behavior:

/* Mobile-first responsive design */
@media (max-width: 800px) {
  #custom-right-nav {
    display: none; /* Hide custom widgets on mobile */
  }
}

@media (min-width: 1200px) {
  .page-columns {
    grid-template-columns: 320px 1fr 300px; /* More space on large screens */
  }
}

Performance Considerations:

  • Lazy loading: Only load custom widgets when needed
  • Event delegation: Use efficient event handling for navigation
  • Caching: Cache configuration data to reduce HTTP requests
  • Progressive enhancement: Ensure base functionality works without JavaScript

The beauty of Quarto’s layout system is that it uses standard web technologies while providing powerful extension points for custom functionality. The Related Pages implementation demonstrates how to create sophisticated features that feel native to the Quarto experience.

Would you like me to help you implement a specific layout enhancement or explore advanced customization techniques?