<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[NodeBB] Focus Mode : simply immersive reading for NodeBB]]></title><description><![CDATA[<p dir="auto">Hey everyone,</p>
<p dir="auto">I’m not sure where to post this, I’ll let <a class="plugin-mentions-user plugin-mentions-a" href="/user/phenomlab" aria-label="Profile: phenomlab">@<bdi>phenomlab</bdi></a> edit it if necessary.</p>
<p dir="auto">Already posted here : <a href="https://community.nodebb.org/topic/19318/focus-mode-simply-immersive-reading-for-nodebb" target="_blank" rel="noopener noreferrer nofollow ugc">https://community.nodebb.org/topic/19318/focus-mode-simply-immersive-reading-for-nodebb</a></p>
<p dir="auto">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 <span class="glossary-wrapper" title="Cascading Style Sheets" data-bs-toggle="tooltip" data-bs-placement="top"><span class="glossary-word">CSS</span></span> dropped into the ACP.</p>
<p dir="auto">I’m just sharing this here for fun : <a href="https://github.com/DroidBV8/nodebb-focus-mode" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/DroidBV8/nodebb-focus-mode</a></p>
<p dir="auto"><img src="https://i.ibb.co/2Y5KZNhj/input.gif" alt="" class=" img-fluid img-markdown" /></p>
<h2>What it does</h2>
<p dir="auto">Pressing <strong>F</strong> (or clicking the icon in the right sidebar) hides everything that isn’t the content you’re trying to read:</p>
<ul>
<li>Both sidebars</li>
<li>Header / brand bar</li>
<li>Footer</li>
<li>Topic thumbnails and sidebar tools (reply, follow, timeline)</li>
</ul>
<p dir="auto">The content area reflows to a centered <strong>860px</strong> column, font size bumps up slightly, and a <strong>reading progress bar</strong> appears at the top of the page.</p>
<p dir="auto">To exit: press <strong>F</strong> again, <strong>Escape</strong>, or click the floating button that appears in the bottom-right corner.</p>
<hr />
<h2>Details</h2>
<p dir="auto"><strong>Activation effect</strong> : a subtle <span class="glossary-wrapper" title="cathode ray tube" data-bs-toggle="tooltip" data-bs-placement="top"><span class="glossary-word">CRT</span></span> glitch effect plays on toggle. Three <span class="glossary-wrapper" title="Cascading Style Sheets" data-bs-toggle="tooltip" data-bs-placement="top"><span class="glossary-word">CSS</span></span> variables let you dial the intensity up or down without touching the keyframes:</p>
<pre><code class="css">--fm-glitch-opacity: 1;   /* 0.5 = subtle | 2 = heavy */
--fm-glitch-skew:    1deg;
--fm-glitch-shift:   4px;
</code></pre>
<p dir="auto"><strong>Keyboard</strong> : <code>F</code> to toggle. <code><span class="glossary-wrapper" title="Control key" data-bs-toggle="tooltip" data-bs-placement="top"><span class="glossary-word">Ctrl</span></span>+F</code>, <code>Cmd+F</code> and <code>Alt+F</code> are ignored so you don’t accidentally trigger it when searching the page.</p>
<p dir="auto"><strong>Scroll preservation</strong> : 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 <code>scrollBy</code> so you stay exactly where you were.</p>
<p dir="auto"><strong>Topic-only</strong> : the button is greyed out on non-topic pages with a tooltip explaining why. Pressing <code>F</code> outside a topic shows a small toast instead of doing nothing silently.</p>
<p dir="auto"><strong>Mobile</strong>: disabled entirely under 768px. No button injected, no state restored.</p>
<p dir="auto"><strong>Theming</strong> : all colors reference Bootstrap <span class="glossary-wrapper" title="Cascading Style Sheets" data-bs-toggle="tooltip" data-bs-placement="top"><span class="glossary-word">CSS</span></span> variables (<code>--bs-body-bg</code>, <code>--bs-border-color</code>, <code>--bs-primary</code>, etc.) so it adapts automatically to any NodeBB theme, light or dark.</p>
<p dir="auto"><strong>State</strong> : saved in <code>localStorage</code>, restored on next visit. Uses <code>try/catch</code> so it degrades gracefully in private browsing.</p>
<hr />
<h2>Implementation notes</h2>
<p dir="auto">The script is a self-contained IIFE, hooking into the standard NodeBB client-side events:</p>
<pre><code class="javascript">$(window).on('action:ajaxify.end',   function () { focusMode(); });
$(window).on('action:topic.loaded',  function () { focusMode(); });
// etc.
</code></pre>
<p dir="auto">The glitch effect is pure <span class="glossary-wrapper" title="Cascading Style Sheets" data-bs-toggle="tooltip" data-bs-placement="top"><span class="glossary-word">CSS</span></span> <code>@keyframes</code> ,  the JS only adds/removes classes. Layout compensation is synchronous (<code>getBoundingClientRect</code> → <code>scrollBy</code>) with no <code>setTimeout</code> on the scroll itself, which avoids triggering NodeBB’s scroll-based URL updater in a loop.</p>
<hr />
<h2>Compatibility</h2>
<p dir="auto">Tested on NodeBB 3.x with Bootstrap 5 themes. Should work on any setup using the standard sidebar components (<code>nav.sidebar-left</code>, <code>nav.sidebar-right</code>).</p>
]]></description><link>https://sudonix.org/topic/741/nodebb-focus-mode-simply-immersive-reading-for-nodebb</link><generator>RSS for Node</generator><lastBuildDate>Wed, 13 May 2026 09:58:54 GMT</lastBuildDate><atom:link href="https://sudonix.org/topic/741.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 08 May 2026 23:24:49 GMT</pubDate><ttl>60</ttl></channel></rss>