Skip to content

[NodeBB] Focus Mode : simply immersive reading for NodeBB

Customisation
1 1 187
  • 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

    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 (getBoundingClientRectscrollBy) 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).

  • DownPWundefined DownPW marked this topic as a regular topic on

Related Topics
  • Planned sunset of NTFY plugin

    Pinned Announcements push nodebb ntfy
    7
    1
    8 Votes
    7 Posts
    2k Views
    I’ve noticed that I’m the only one subscribed to the push notifications on this site. If you were using NTFY previously, and have noticed that you’ve not had any alerts for a while, it’s because this feature has been disabled. You’ll now need to use the push notification to replace NTFY as mentioned in the first post.
  • Test of youtube embeds

    Solved Configure nodebb
    14
    11 Votes
    14 Posts
    3k Views
    @phenomlab Perfect!!! Many thanks.
  • Page control arrows for PWA

    Solved Customisation nodebb
    27
    25 Votes
    27 Posts
    10k Views
    @crazycells it is, yes - I think I’ll leave it as there is no specific PWA CSS classes I know of. Well, you could use something like the below, but this means multiple CSS files for different operating systems. /** * Determine the mobile operating system. * This function returns one of 'iOS', 'Android', 'Windows Phone', or 'unknown'. * * @returns {String} */ function getMobileOperatingSystem() { var userAgent = navigator.userAgent || navigator.vendor || window.opera; // Windows Phone must come first because its UA also contains "Android" if (/windows phone/i.test(userAgent)) { return "Windows Phone"; } if (/android/i.test(userAgent)) { return "Android"; } if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) { return "iOS"; } return "unknown"; // return “Android” - one should either handle the unknown or fallback to a specific platform, let’s say Android } Once you’re in that rabbit hole, it’s impossible to get out of it.
  • Forum Icons NodeBB

    Solved Customisation icons forum nodebb
    13
    0 Votes
    13 Posts
    3k Views
    @cagatay That matches what I see [image: 1667218162107-4f0f858d-9812-42b1-9f61-ffb13d31dccd-image.png]
  • How to downgrade plugin version on NodeBB

    Solved Customisation downgrade nodebb
    11
    3 Votes
    11 Posts
    3k Views
    @cagatay no problems
  • NodeBB inline videoplayer

    Solved Customisation nodebb
    12
    3 Votes
    12 Posts
    3k Views
    @phenomlab YAY! It works Thanks so much
  • [NodeBB] Import custom Font

    Solved Customisation custom fonts nodebb css
    12
    3 Votes
    12 Posts
    3k Views
    @cagatay you’ll need to define this in the body tag (or another element if you want greater or more granular targets) - for example body { font-family: "Poppins"; font-size: 16px; } Essentially, you use the font-size CSS directive.
  • NodeBB Discord Plugins

    Unsolved Customisation nodebb discord plugin
    7
    0 Votes
    7 Posts
    3k Views
    @RiekMedia hi. Just following up on this thread (I know it’s old) but was curious to understand if it’s still an issue or not ?