<story><title>How to build a website without frameworks and tons of libraries</title><url>https://www.kodingkitty.com/blog/how-to-build-a-website/</url></story><parent_chain><item><author>nickelpro</author><text>&amp;gt; First, your dark mode is implemented wrong in the lazy corner-cutting way of doing JS post-load ...&lt;p&gt;I agree with your whole comment, but the media query approach is also tricky.&lt;p&gt;You typically still want to &lt;i&gt;offer&lt;/i&gt; a toggle while respecting prefers-color-scheme, and you &lt;i&gt;may&lt;/i&gt; want to give priority to whatever choice the user has made with that toggle if they&amp;#x27;ve used it on your site before. This still requires JS and localstorage.&lt;p&gt;So what to do? My preferred choice is having an inline style element of:&lt;p&gt;body {visibility: hidden; opacity: 0;}&lt;p&gt;This will maintain the previous page until DOMContentLoaded, at which point you can query prefers-color-element and localstorage, set the body class correctly, and let the page paint.</text></item><item><author>gwern</author><text>This seems to fall into the &amp;#x27;simplistic, not simple&amp;#x27; school of thought. You can have a relatively simple website if it doesn&amp;#x27;t &lt;i&gt;do&lt;/i&gt; anything and if it cuts corners.&lt;p&gt;Take your dark mode, which is just about the only nontrivial feature I see on this page. (One could also criticize the low contrast of the appearance and other problems, but that&amp;#x27;s less relevant to the simplicity thesis you&amp;#x27;re claiming.)&lt;p&gt;First, your dark mode is implemented wrong in the lazy corner-cutting way of doing JS post-load instead of the correct way of CSS body classes; so you get the &amp;#x27;flash of white&amp;#x27; unavoidably on every page load - just what every dark mode user with their phone to their face at midnight wants to see! (If your solution doesn&amp;#x27;t work, it doesn&amp;#x27;t matter if it&amp;#x27;s &amp;#x27;simple&amp;#x27; or &amp;#x27;complex&amp;#x27;.)&lt;p&gt;Second, you implement what is like 3 lines of JS (setting localstorage &amp;amp; dark-mode) by pulling in what looks like an entire interpreter for a custom &amp;#x27;hyperscript&amp;#x27; &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;hyperscript.org&amp;#x2F;&quot; rel=&quot;nofollow noreferrer&quot;&gt;https:&amp;#x2F;&amp;#x2F;hyperscript.org&amp;#x2F;&lt;/a&gt; language which seems to mostly just offer some sugar over JS; now, maybe you use &amp;#x27;hyperscript&amp;#x27; elsewhere for reasonable purposes, but surely pulling in a 96kb (uncached) library solely to run&lt;p&gt;def saveMode() if first classList.value of &amp;lt;html&amp;#x2F;&amp;gt; contains &amp;#x27;dark&amp;#x27; set localStorage.kkColorMode to &amp;#x27;dark&amp;#x27; else  set localStorage.kkColorMode to &amp;#x27;light&amp;#x27; end end&lt;p&gt;&lt;pre&gt;&lt;code&gt;  init if localStorage.kkColorMode is empty set localStorage.kkColorMode to &amp;#x27;light&amp;#x27; end if localStorage.kkColorMode is &amp;#x27;dark&amp;#x27; add .dark to &amp;lt;html&amp;#x2F;&amp;gt; end
&lt;/code&gt;&lt;/pre&gt;
is a bit against the spirit of this &amp;quot;simplicity is the ultimate perfection&amp;quot; enterprise...? Personally, I feel like I see some easy perfection to add right there. (And is this hyperscript stuff also why the HTML doesn&amp;#x27;t validate?)&lt;p&gt;Third, this binary toggle is a bad way to implement dark mode because it ignores system&amp;#x2F;browser settings, so if a user has, say, enabled dark-mode on their smartphone OS, they still get served light-mode until they manually enable it; note that some systems change it based on local time&amp;#x2F;ambient light too, which is quite nice... if websites &amp;amp; apps respect it instead of overriding it. And since localstorage expires and users switch devices, they would have to do so repeatedly. Is this a good thing? A user probably would disagree with the developer who is touting how &amp;#x27;simple&amp;#x27; the dark-mode implementation is because they cut corners in handling system settings&amp;#x2F;auto-dark-mode...</text></item></parent_chain><comment><author>gwern</author><text>The nuts-and-bolts implementation of inlined-CSS to avoid flash-of-white is separate from the UX toggle question, which is why I listed them as separate criticisms.&lt;p&gt;The former is just wrong of OP: no user &lt;i&gt;wants&lt;/i&gt; the FOUC flash-of-white, end of story; similarly for some of the other solutions proposed here (block the entire page, really? talk about burning down the village to save it). The latter has more leeway for design: we settled on a tri-toggle to use the media-query but allow users to override and hardwire light&amp;#x2F;dark mode, and that seems to work most naturally. But there may be other contexts where something else would be better.&lt;p&gt;Indeed, for toggles, you could even try not having a toggle at all and relying on the system setting through the media-query. (However, as appealing as this is - why have separate controls when the user &lt;i&gt;already&lt;/i&gt; has a global control and can enable&amp;#x2F;disable it? - we found this confused &amp;amp; angered users: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;gwern.net&amp;#x2F;design-graveyard#automatic-dark-mode&quot; rel=&quot;nofollow noreferrer&quot;&gt;https:&amp;#x2F;&amp;#x2F;gwern.net&amp;#x2F;design-graveyard#automatic-dark-mode&lt;/a&gt; So, gotta have a toggle. At least for now; maybe as dark-mode becomes universal, at some point users will become educated enough that you can afford to use only the system setting?)</text></comment>
<story><title>How to build a website without frameworks and tons of libraries</title><url>https://www.kodingkitty.com/blog/how-to-build-a-website/</url></story><parent_chain><item><author>nickelpro</author><text>&amp;gt; First, your dark mode is implemented wrong in the lazy corner-cutting way of doing JS post-load ...&lt;p&gt;I agree with your whole comment, but the media query approach is also tricky.&lt;p&gt;You typically still want to &lt;i&gt;offer&lt;/i&gt; a toggle while respecting prefers-color-scheme, and you &lt;i&gt;may&lt;/i&gt; want to give priority to whatever choice the user has made with that toggle if they&amp;#x27;ve used it on your site before. This still requires JS and localstorage.&lt;p&gt;So what to do? My preferred choice is having an inline style element of:&lt;p&gt;body {visibility: hidden; opacity: 0;}&lt;p&gt;This will maintain the previous page until DOMContentLoaded, at which point you can query prefers-color-element and localstorage, set the body class correctly, and let the page paint.</text></item><item><author>gwern</author><text>This seems to fall into the &amp;#x27;simplistic, not simple&amp;#x27; school of thought. You can have a relatively simple website if it doesn&amp;#x27;t &lt;i&gt;do&lt;/i&gt; anything and if it cuts corners.&lt;p&gt;Take your dark mode, which is just about the only nontrivial feature I see on this page. (One could also criticize the low contrast of the appearance and other problems, but that&amp;#x27;s less relevant to the simplicity thesis you&amp;#x27;re claiming.)&lt;p&gt;First, your dark mode is implemented wrong in the lazy corner-cutting way of doing JS post-load instead of the correct way of CSS body classes; so you get the &amp;#x27;flash of white&amp;#x27; unavoidably on every page load - just what every dark mode user with their phone to their face at midnight wants to see! (If your solution doesn&amp;#x27;t work, it doesn&amp;#x27;t matter if it&amp;#x27;s &amp;#x27;simple&amp;#x27; or &amp;#x27;complex&amp;#x27;.)&lt;p&gt;Second, you implement what is like 3 lines of JS (setting localstorage &amp;amp; dark-mode) by pulling in what looks like an entire interpreter for a custom &amp;#x27;hyperscript&amp;#x27; &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;hyperscript.org&amp;#x2F;&quot; rel=&quot;nofollow noreferrer&quot;&gt;https:&amp;#x2F;&amp;#x2F;hyperscript.org&amp;#x2F;&lt;/a&gt; language which seems to mostly just offer some sugar over JS; now, maybe you use &amp;#x27;hyperscript&amp;#x27; elsewhere for reasonable purposes, but surely pulling in a 96kb (uncached) library solely to run&lt;p&gt;def saveMode() if first classList.value of &amp;lt;html&amp;#x2F;&amp;gt; contains &amp;#x27;dark&amp;#x27; set localStorage.kkColorMode to &amp;#x27;dark&amp;#x27; else  set localStorage.kkColorMode to &amp;#x27;light&amp;#x27; end end&lt;p&gt;&lt;pre&gt;&lt;code&gt;  init if localStorage.kkColorMode is empty set localStorage.kkColorMode to &amp;#x27;light&amp;#x27; end if localStorage.kkColorMode is &amp;#x27;dark&amp;#x27; add .dark to &amp;lt;html&amp;#x2F;&amp;gt; end
&lt;/code&gt;&lt;/pre&gt;
is a bit against the spirit of this &amp;quot;simplicity is the ultimate perfection&amp;quot; enterprise...? Personally, I feel like I see some easy perfection to add right there. (And is this hyperscript stuff also why the HTML doesn&amp;#x27;t validate?)&lt;p&gt;Third, this binary toggle is a bad way to implement dark mode because it ignores system&amp;#x2F;browser settings, so if a user has, say, enabled dark-mode on their smartphone OS, they still get served light-mode until they manually enable it; note that some systems change it based on local time&amp;#x2F;ambient light too, which is quite nice... if websites &amp;amp; apps respect it instead of overriding it. And since localstorage expires and users switch devices, they would have to do so repeatedly. Is this a good thing? A user probably would disagree with the developer who is touting how &amp;#x27;simple&amp;#x27; the dark-mode implementation is because they cut corners in handling system settings&amp;#x2F;auto-dark-mode...</text></item></parent_chain><comment><author>theallan</author><text>Doesn&amp;#x27;t that make the page completely unreadable for those few who have Javascript disabled though?</text></comment>