Skip to content

Layouts and navigation

How zer0-mistakes structures pages, sidebars, table of contents, navbar, and floating action buttons (FABs).

Related docs: Configuration · Components · JavaScript API


Layout hierarchy

root.html          ← HTML shell, head, header, footer, scripts
  └── default.html   ← Three-column docs layout (sidebar + content + TOC)
        └── article.html, note.html, …
  └── landing.html   ← Marketing homepage
  └── admin.html     ← Settings / admin pages
  └── welcome.html   ← Onboarding wizard
  └── stats.html     ← Build-time stats dashboard
Layout Inherits Use case
root Base shell; full-bleed pages
default root Docs, pages with sidebar + TOC
article default Blog posts
note default Obsidian-style notes
notebook default Jupyter notebook pages
landing root Homepage (README.md at /)
section default Section landing with nav
admin root Theme/settings admin UI
stats root Analytics/stats dashboard

Example page front matter

---
layout: default
title: Installation guide
sidebar:
  nav: tree
toc_sticky: true
---
---
layout: article
title: My post
post_type: standard
sidebar: true
---

Hide sidebars for full-bleed reading:

---
layout: default
title: Release notes
sidebar: false
---

Featured/breaking posts auto-disable sidebar when sidebar is omitted:

---
layout: article
post_type: featured   # → sidebar: false
---

Default layout structure

From _layouts/default.html:

┌─────────────────────────────────────────────────────────────┐
│  #navbar (fixed-top, auto-hide on scroll)                    │
├──────────┬────────────────────────────────────┬─────────────┤
│ bd-sidebar│  bd-main                           │ bd-toc      │
│ (left)   │  ├─ intro (title, breadcrumbs)     │ (right)     │
│          │  └─ bd-content ({{ content }})     │             │
└──────────┴────────────────────────────────────┴─────────────┘
│  footer + FAB stack (back-to-top, TOC, sidebar, local graph) │
└─────────────────────────────────────────────────────────────┘

Bootstrap classes:

  • .bd-layout — CSS grid for three columns
  • .bd-sidebar — left nav (--zer0-sidebar-width: 17rem)
  • .bd-toc — right TOC (--zer0-sidebar-toc-width: 12rem)
  • .bd-content — main prose area

Styles: _sass/core/_docs-layout.scss, tokens in _sass/tokens/_spacing.scss.


Front matter

sidebar:
  nav: auto          # best mode for the page's collection: curated
                     # _data/navigation/<collection>.yml → live collection
                     # folder tree → post categories
  # nav: collection  # live folder tree of the page's collection
  # nav: categories  # posts grouped by category
  # nav: tags        # posts grouped by tag
  # nav: sdk         # _data/navigation/sdk.yml (any other value = data file)
  # title: "Guides"  # panel heading override
  # icon: bi-book    # heading icon override

Or boolean shorthand:

sidebar: true   # enables layout sidebar logic (default for many collections)
sidebar: false  # full-width content

Resolution is centralized in _includes/navigation/sidebar-config.html: page front matter → collection sidebar: metadata (in _config.yml collections:) → site.sidebar → nothing. See /docs/features/sidebar-navigation/ for the full option reference (collection/sort/expand for collection mode, limit for taxonomy modes, sidebar_exclude: true per document).

# _data/navigation/sdk.yml
- title: Overview
  url: /sdk/
  icon: bi-book
- title: Guides
  icon: bi-folder
  expanded: true
  children:
    - title: Getting Started
      url: /sdk/start/
    - title: Authentication
      url: /sdk/auth/

Render in a custom layout:

{% include navigation/nav-tree.html nav="sdk" %}

Legacy nav_list.html delegates to nav-tree.html.

Left column visibility

The left column renders only when navigation data exists for the resolved sidebar.nav value. sidebar: true without a resolvable nav file still enables the right TOC but does not reserve an empty left column.


Table of contents (TOC)

Generated by Kramdown when headings exist. Container: #TableOfContents.

Front matter

toc_sticky: true    # sticky right TOC on desktop (default for docs)

Desktop (≥992px)

  • Right column .bd-toc — sticky, scrollable
  • Scroll spy highlights active section (assets/js/modules/navigation/scroll-spy.js)

Mobile (<992px)

  • TOC moves into offcanvas #tocContents
  • FAB button .bd-toc-fab opens TOC drawer
  • Toggle visibility with .bd-toc-visibility-toggle (persists to localStorage)

Keyboard shortcuts

Key Action
[ Previous TOC section
] Next TOC section
t Toggle TOC sidebar visibility
b Toggle left sidebar visibility
? Open shortcuts modal

Configure in assets/js/modules/navigation/config.js:

keyboard: {
  enabled: true,
  keys: {
    previousSection: '[',
    nextSection: ']',
    search: '/',
    toggleSidebar: 'b',
    toggleToc: 't'
  }
}

Rendered by _includes/core/header.html. Features:

  • Auto-hide on scroll down (assets/js/auto-hide-nav.js, #navbar.navbar-hidden)
  • Three-column grid on desktop: brand | main nav | utilities (search, settings)
  • Mobile quicklinks — horizontal chip strip (.navbar-mobile-quicklinks) for tablet breakpoints
  • Search — opens modal (/, Cmd/Ctrl+K)
  • Settings — opens #info-section offcanvas
  • Color modehalfmoon.html dropdown

Nanobar under navbar

When nanobar.position: navbar, progress bar mounts in #top-progress-target inside the header.

Unified mobile drawer

navigation:
  unified_mobile_drawer: true

Collapses mobile sidebar + main menu into one tabbed drawer. See _includes/navigation/unified-drawer.html.


FAB stack (floating action buttons)

Fixed buttons stacked from the bottom-right (mobile) or top-right (desktop restore mode). z-index and spacing use design tokens.

FAB Class Layer token Purpose
Back to top #backToTopBtn --zer0-layer-fab-back-to-top Scroll to top
TOC .bd-toc-fab --zer0-layer-fab-toc Open/restore TOC
Sidebar .bd-sidebar-fab --zer0-layer-fab-toc Open/restore left nav
Local graph .obsidian-local-graph-fab --zer0-layer-fab-local-graph Obsidian graph panel

Stacking rules (_sass/layouts/_navbar-extras.scss):

// Mobile: TOC FAB sits above back-to-top
bottom: calc(
  var(--zer0-space-fab-offset) +
  var(--zer0-space-fab-size) +
  var(--zer0-space-fab-gap)
);

FAB size: --zer0-space-fab-size: 3.5rem (from _sass/tokens/_spacing.scss).


Section layout

_layouts/section.html — section landing pages with hierarchical nav. Pair with _sass/layouts/_section.scss.

---
layout: section
title: Documentation
---

Landing layout

_layouts/landing.html — homepage hero, features, get-started bands.

  • Content driven by _data/landing.yml
  • Hero uses .zer0-bg-hero for skin gradients
  • Site root (/) is served by README.md with layout: landing
---
layout: landing
title: My Site
permalink: /
---

Admin layout

_layouts/admin.html — settings pages with admin tab bar.

---
layout: admin
title: Theme settings
permalink: /about/settings/theme/
---

Requires theme ≥ 0.22.10. Install admin pages with ./scripts/migrate.sh.


Stats layout

_layouts/stats.html — build-time statistics dashboard.

---
layout: stats
title: Site statistics
permalink: /about/stats/
---

Loads additional CSS: assets/css/stats.css. Stats are generated at build time by theme plugins.


  • Skip-to-content link (WCAG 2.1 AA) — first focusable element in root.html
  • Focus rings: _sass/utilities/_focus.scss
  • Scroll padding accounts for fixed navbar: scroll-padding-top: 80px

JavaScript modules

Navigation is ES-module based (assets/js/modules/navigation/index.js):

window.zer0Navigation.getModule('scrollSpy');
window.zer0Navigation.getModule('keyboard');
window.zer0Navigation.scrollTo('#my-section');

document.addEventListener('navigation:ready', (e) => {
  console.log('Modules:', e.detail.modules);
});

See js-api.md for the full API.


Customization examples

Replace default layout locally

your-site/_layouts/default.html

Jekyll prefers your copy over the remote theme.

Per-collection defaults

# _config.yml
defaults:
  - scope:
      path: pages/_guides
    values:
      layout: default
      sidebar:
        nav: guides

Wider docs container

Fork spacing tokens:

// _sass/tokens/_spacing.scss
:root {
  --zer0-layout-max-width-xxl: clamp(1600px, 96vw, 1920px);
}

Further reading


User guide: For usage and configuration examples (available layouts, navigation configuration), see Layouts in the user documentation.