Hey everyone,
I’m not sure where to post this, I’ll let @phenomlab edit it if necessary.
Already posted here : https://community.nodebb.org/topic/19318/focus-mode-simply-immersive-reading-for-nodebb
I’ve been working on a small client-side script that adds an simply immersive reading mode to NodeBB. No plugin required, just a few lines of custom JS and CSS dropped into the ACP.
I’m just sharing this here for fun : https://github.com/DroidBV8/nodebb-focus-mode
[image: input.gif]
What it does
Pressing F (or clicking the icon in the right sidebar) hides everything that isn’t the content you’re trying to read:
Both sidebars
Header / brand bar
Footer
Topic thumbnails and sidebar tools (reply, follow, timeline)
The content area reflows to a centered 860px column, font size bumps up slightly, and a reading progress bar appears at the top of the page.
To exit: press F again, Escape, or click the floating button that appears in the bottom-right corner.
Details
Activation effect : a subtle CRT glitch effect plays on toggle. Three CSS variables let you dial the intensity up or down without touching the keyframes:
--fm-glitch-opacity: 1; /* 0.5 = subtle | 2 = heavy */
--fm-glitch-skew: 1deg;
--fm-glitch-shift: 4px;
Keyboard : F to toggle. Ctrl+F, Cmd+F and Alt+F are ignored so you don’t accidentally trigger it when searching the page.
Scroll preservation : when toggling, the layout shifts because sidebars appear/disappear. The script measures the position of the nearest visible post before and after the layout change, then compensates with scrollBy so you stay exactly where you were.
Topic-only : the button is greyed out on non-topic pages with a tooltip explaining why. Pressing F outside a topic shows a small toast instead of doing nothing silently.
Mobile: disabled entirely under 768px. No button injected, no state restored.
Theming : all colors reference Bootstrap CSS variables (--bs-body-bg, --bs-border-color, --bs-primary, etc.) so it adapts automatically to any NodeBB theme, light or dark.
State : saved in localStorage, restored on next visit. Uses try/catch so it degrades gracefully in private browsing.
Implementation notes
The script is a self-contained IIFE, hooking into the standard NodeBB client-side events:
$(window).on('action:ajaxify.end', function () { focusMode(); });
$(window).on('action:topic.loaded', function () { focusMode(); });
// etc.
The glitch effect is pure CSS @keyframes , the JS only adds/removes classes. Layout compensation is synchronous (getBoundingClientRect → scrollBy) with no setTimeout on the scroll itself, which avoids triggering NodeBB’s scroll-based URL updater in a loop.
Compatibility
Tested on NodeBB 3.x with Bootstrap 5 themes. Should work on any setup using the standard sidebar components (nav.sidebar-left, nav.sidebar-right).