Features & Behavior¶
What it is¶
Void isn't a static theme β it's an interactive documentation app that happens to build as plain HTML. This section documents every behavior: keyboard shortcuts, overlays, navigation, persistence, offline support, and how the theme degrades gracefully when JavaScript is unavailable.
How it works¶
All features are driven by void.js (β5,500 lines), the theme's
single-file JavaScript runtime. Every behavior is registered through an
init*() function and called once at boot, then re-run after each SPA
swap. Configuration is injected into a <script id="__config"> block at
build time, and all feature states are persisted in localStorage under
the void- prefix.
Features¶
Navigation & search¶
- Search β full-screen modal,
/shortcut, suggestions, context snippets, highlighting, copy-link per result. - SPA navigation & scroll restore β prefetch-on-hover, client-side page swaps, scroll position memory, resume-to-last-page.
Productivity overlays¶
- Reading mode β
Alt+Shift+Rdistraction-free reading view that hides chrome and widens the article. - Action cluster β
Alt+Shift+Afloating action button that expands into quick-access shortcuts. - Focus timer β
Alt+Shift+TPomodoro-style countdown with TOC widget and reading chip. - Notes panel β
Ctrl+Shift+Nsticky notes with export, TTL, and cross-page persistence. - Keyboard reference β
?modal listing every binding, built dynamically from config.
Chrome behavior¶
- Reading progress β progress bar at the top of the article.
- Back-to-top β floating button that appears after scrolling.
- TOC scrollspy β active-heading highlight in the "On this page" rail.
Offline & PWA¶
- Service worker & caching β
sw.jsstrategy diagram, cache names, versioned assets. - PWA manifest β
manifest.webmanifestauto-generation, installability, icons.
Persistence & external data¶
- Persistence β every
localStoragekey the theme reads and writes. - Repo popover β
Ctrl+Shift+GGitHub project card with 1-hour cache.
Graceful degradation¶
The table below shows what still works when JavaScript is disabled, when the
device is offline, when prefers-reduced-motion: reduce is active, or when
the browser lacks backdrop-filter support.
| Feature | No JS | Offline (previously visited) | Reduced motion | No backdrop-filter |
|---|---|---|---|---|
| Search | β β no worker, no modal | β β search index not cached by SW | β | β |
| SPA navigation | β β full page reloads | β β browser cache serves pages | β | β |
| Prefetch | β β no hover prefetch | β β pages may be in browser cache | β | β |
| Reading mode | β β no JS toggle | β β CSS-only hiding when persisted | β | β |
| Action cluster | β β no JS rendering | β β rendered by server on first load | β | β |
| Focus timer | β β no JS countdown | β β timer state in localStorage | β | β |
| Notes panel | β β no JS overlay | β β panel rendered on first load | β | β |
| Keyboard shortcuts | β β no key handling | β β help modal rendered on first load | β | β |
| Reading progress | β β no scroll handler | β β bar rendered, stays at 0% | β | β |
| Back-to-top | β β no scroll handler | β β button stays hidden | β | β |
| TOC scrollspy | β β no scroll handler | β β no active highlight | β | β |
| Glass morphism | β | β | β | β β falls back to flat semi-transparent fill |
| Animations (page, toast, stagger) | β | β | β β CSS prefers-reduced-motion: reduce disables transitions and keyframes |
β |
| Palette toggle | β β server-rendered scheme; no runtime toggle | β β scheme stored in localStorage | β | β |
| Tabs | β β <input type="radio"> fallback renders all panels |
β | β | β |
| Task lists | β β native checkboxes still function | β β state in localStorage | β | β |
| Admonitions (collapsible) | β β native <details> toggles work |
β | β | β |
| Lightbox | β β no JS overlay | β | β | β |
| Toast | β β no JS notification | β β toast element hidden | β | β |
| Repo popover | β β no JS fetch | β β API data not cached by SW | β | β |
| Service worker | β | β β assets served from void-static-v4 / void-cdn-v4 caches |
β | β |
| PWA install | β | β β manifest + SW already registered | β | β |
| Cookie consent | β β banner rendered server-side | β β state in localStorage | β | β |
Legend: β = fully functional; β = not functional; β = not applicable (feature doesn't depend on that condition).
Configuration¶
Features are toggled under theme.void.components and theme.void.*:
theme:
void:
components:
search:
show: true
notes:
show: true
keyboard_help:
show: true
prefetch:
show: true
external: false
exclude: []
repo_popover:
show: true
toast:
show: true
Under the hood¶
void.jsboots viainitTheme()βinitSearch()βinitSPANavigation()βinitPrefetch()βinitScrollBehavior()βinitBackToTop()βinitTocTracking()β and the remaininginit*()functions. Each is idempotent and re-runs after SPA swaps viareinitPageScoped().- Configuration lives in
window.__config(parsed from the#__config<script>tag); the plugin injectstheme.void.*as a flat JSON object at build time. - All persistence uses
localStorageunder thevoid-prefix (e.g.void-color-scheme,void-notes,void-scroll-pos).
Accessibility notes¶
- Every overlay (search, notes, help, timer settings) traps focus and can
be closed with
Esc. - Keyboard shortcuts are configurable and can be remapped or disabled
individually under
theme.void.keyboard.shortcuts. - Reading mode and the focus timer honor
prefers-reduced-motionand can be disabled per-feature via config. - The action cluster renders with
aria-labelon each button androle="group"on the menu.