It can make sense for a theme selector that works on the server, since you can serve specific HTML when building the page. However, if using a JavaScript-based solution that fetches the theme preference from localStorage, I find this almost always results in a "flashbang" in dark mode, as the retrieval is slower than the first browser paint.
I've been implementing (and recommending) pure CSS-based theming to avoid this problem. Users seem much happier with them, and I haven't heard anybody ask for a theme switcher. We just respect their existing preference. However, I can see this being a problem if you offer multiple color schemes (beyond just light and dark).
I'd be curious to know if anybody has found a way to avoid this issue with JS switchers -- ideally without needing to delay the initial paint.
I do think an interesting approach would be a browser extension that lets you override the prefers-color-scheme property on a per-domain basis, similar to the toggle in dev tools.
Not if you blockingly inline the three lines of JavaScript with a good old script tag right in the HTML.
That way you will have a flash, but if the user set dark mode on their browser/DE, they'll flash in dark, not light.
Or, alternatively, you can always make it flash in dark. I never heard about anybody being annoyed by a dark flash.
I'm not aware of the specifics of regulations in other parts of the world, but this distinction is irrelevant for the EU ePrivacy directive: a) it was never about cookies only, and b) purely functional cookies that record user preferences do not need explicit consent.
From [0]:
> 34,35 Storage of information in the sense of Article 5(3) ePD refers to placing information on a physical electronic storage medium that is part of a user or subscriber’s terminal equipment [..] this includes making use of established protocols such as browser cookie storage as well as customized software, regardless of who created or installed the protocols or software on the terminal equipment.
> 43 This might also be the case for web browsers that process information stored or generated information [sic] inside the device (such as cookies, local storage, WebSQL, or even information provided by the users themselves). The use of such information by an application would not be subject to Article 5(3) ePD as long as the information does not leave the device
https://www.edpb.europa.eu/our-work-tools/documents/public-c...
Thank you for illustrating the fact that the phrase "best practice" means nothing, and is little more than a synonym for "I heard this somewhere."
I remember Firefox used to have an option in the menu for selecting alternative stylesheets, multiple ones not just light and dark, I think it was a standard from CSS, but only Firefox had a way to select them through the UI, for other browsers you had to use Javascript to make a selector.
Presumably, most users wanting flashbang-less browsing experience use Dark Reader extension or similarly radical solutions.
The sad truth is that the user preferences and per-site persistence for stuff like this should always have been browser's responsibility to begin with: just the same way like the font-size/page zoom already is, and likewise some (blatantly limited) security settings. (Bitterly) amusing fact is that there was (and still is) concept of "alternate stylesheets" from the beginning of CSS (still part of the spec [0], no support outside Gecko), that also fade into obsolescence for it's lack of persistence. So to this days, Firefox, for example, has View → Page Style menu, where user can choose alternate stylesheet but the choice is not preserved across navigations, so is pretty useless on its own.
Similarly userstyles: specifications dictate there is like CSS origin level and how they should behave and that all "user agents" are supposed to give user a way to enter the cascade this way, but does not give any official way how to scope individual recipes to concrete origins. That's what the unofficial `@-moz-document` extension was that, and briefly had a chance to be formalised [1]. But I digress.
(Likewise all the "European" cookies banners: tragic example of regulation applied on the wrong level. Instead of putting users in charge with help of their "user agents": implicitly blocking pretty much everything and using permissions system that actually would have a chance to be more than "pinky promise we will not track you if you don't click this toggle inside our banner". But I digress even more, sorry.)
> I'd be curious to know if anybody has found a way to avoid this issue with JS switchers -- ideally without needing to delay the initial paint.
At this point, when browsers do not support per-site user preference for that natively, pragmatic (most robust) way would be to respond with properly set HTML payload straight away. There is even specified HTTP header for this, so once adopted in browsers, we could even ditch HTTP cookies [2] for the persistence, but it seems quite demanding on the server (IIUC negotiating these "Client Hints" takes extra initial request round-trip).
Pragmatically, I guess having early running JS in the HEAD that ensures the proper color-scheme is set on the root not and only proper stylesheets load should pretty much prevent most flashbangs, provided the relevant bit would arrive early enough from the server. I think there does not exist any good no-JS-no-Cookie (or any JS-less persistence) solution that supports navigations, sadly.
[0] https://html.spec.whatwg.org/multipage/links.html#rel-altern...
[1] https://www.w3.org/TR/2012/WD-css3-conditional-20121213/#cha...
[2] https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/...
Most browsers also support per-page overrides, but the only consistent place to find it is Dev Tools, which is a shame.
I think browsers decided to invest in "Reader Mode" as a UX over more direct control of user styles and page styles, and I'm not always sure that is the correct choice, but I can understand how it seems the simpler "one-button" choice.
I feel the same way about salads in restaurants—I don’t want to have to slice produce, add dressing, and toss my own salad at the table without a bowl or proper utensils. I want the professionals who I am paying to prepare my meal to handle that. If I have problems with any of the ingredients, or some desire for unreasonable quantities of dressing, then I can make requests. Serving me a plate of neatly partitioned ingredients strikes me as an insane thing to do…I suppose unless it comes with fondue or I have signed up for some hibachi nonsense to make my dinner more “interactive”.
I have fully lost the thread, apologies, carry on.
The ideal web would give the option of better separating form and function when possible. I'm well aware that this is an old set of values from another time, but today they're more important than ever, not just aesthetically, but with reference to ability and power and dare I say, freedom.
Calling this a “sad state of affairs” is pretty dramatic. You have to gaze upon things that aren’t in your preferred colors, oh my!
What would you do if you had the option to choose any font of your choosing? What color for the headers? The background of the buttons? Should you be able to define the border radius? The CSS transitions? All of CSS?
You can do that. There are extension for that.
I don't think this is a concern for the vast majority of users.
It is ludicrous to expect every web page to give the user control over individual theme elements. If you want such level of control, you can override them yourself with a custom style sheet.
https://github.com/twbs/bootstrap/pull/22377/files
but it's back in the current one:
https://github.com/twbs/bootstrap/blob/main/scss/_variables....
This PR to Bluesky has more recent discussion about it and offers workarounds:
What if you get a terrible font choice on the standard `font-family: sans-serif`? Should all my visitors have to download 100 KB of external fonts because Microsoft are inept?
Meh, for my personal website, I'll keep using system-ui.
Bootstrap later added it back, but in the PR discussion it was pointed out that this is still an issue on Chinese and Korean Windows, at least.
> Meh, for my personal website, I'll keep using system-ui.
Well sure, but in that case you could also use your own personal language that no-one else knows.
I wouldn’t have made any sense of the CSS box model without him back in 2002.
I guess this says something about the evolution of web standards.
I think it is best to take the Kevin Powell approach, as per the article, where you will be leaning in on browser defaults. Clearly you have to do your cross-browser and cross-platform testing, however, after almost two decades of everything coming with a CSS reset lurking in the stylesheets somewhere and mountains of cruft on top (remember frameworks), it is so liberating to get rid of the lot and to use the modern CSS tools such as CSS Grid and CSS variables.
Nowadays CSS is my favourite 'LEGO set' and I love the creative opportunities. This contrasts with the olden days where I hated the hacks based on hacks that was CSS. I have gone from practically drowning despite wearing armbands to being able to effortlessly glide through the water. CSS reset is one of those 'armbands' and it takes courage to go without such things. Same goes for those awful CSS pre-processor things.
Something similar to plain text can be created with the <pre> tag in HTML if you like to add metadata to your page.
Make sure to linewrap on your prefered 50-70ch limit for our reading pleasure, otherwise I will be adding the style="width:70ch" locally to your body tag.
font-family: System UI;
That's incorrect. It should be: font-family: system-ui;
Author has it right in some CSS examples, but not the first one.e.g. this wouldn't work either?
font-family: Times New Roman;
Edit: Well this and just "times" does work fine, which makes me wonder if it's been special cased due to being an older font, or if the matching is very permissive.This is generally referred to as "what pretty much everyone else thinks about your stupid font".
(i collect a lot of these design advice. more: https://github.com/swyxio/spark-joy/)
It seems Astro or Hugo (potentially with Tailwind to customize CSS) are good options. Astro felt more complex than needed, on the other hand, writing html/css manually doesn’t work well either (predefined layouts and easy to use style customization options would be needed). I couldn’t find a suitable Astro theme either (most themes seem to be made for companies, or needlessly fancy, and a few for individual blogs).
In the process of figuring this out, I was surprised how complicated designing a website has become. There are so many frameworks, components, integrations and significant dependancies that I wondered how web developers keep up in this ecosystem.
Sounds like you would enjoy https://mastrojs.github.io – a _minimal_ Astro alternative.
We could not hope that everything would remain simple. Thanks for all the open standards and frameworks that we don't have to license.
And yes, it is a paralysis of choice.
I personally liked Astro's approach to "Components", less glue more "just writing html/md". That is of course a learning curve on its own.
HTML was meant to be hand-authored, not a compilation target. It's like if people forgot you can still cook rice without a rice cooker.
The result is decent, though the organization of the long page could be improved. In my view, a good personal website would include space for a photo, name, and affiliation, along with a simple menu for sections like biography, publication, projects, with a professional style (font and colors), but no more complex. The publication page could have a style for presenting papers in a clean well-formatted list. That may require a theme that comes with a layout and a degree of customization and novelty.
A lot of themes I looked into are not quite professional.
If anything good is left outside the temples of Facebook, etc, it's not much, and I'm embarrassed.
> Granted, if you have images they can cause some overflow issues.
The "fix" breaks zooming in.
> In general, the font-size is a little small as well
It is quite annoying when websites mess with your preferred font, its size, style, and so on, often turning texts illegible. In this case it is made awkwardly large, but often it is made illegibly small, apparently also with the intention to fix the defaults.
> Many people love dark mode, so let’s enable it based on a user’s system preferences.
"color-scheme" is like "viewport": an invocation to tell the browser that the website is not too broken, and the web browser should act more sensibly. Those are practical, but still awkward, not quite how things should be: I wish web browsers defaulted to sensible behaviors. So I rather view it as a choice between adapting to how things are and pushing for how they should be.
> We generally want to try and fall somewhere in the 45-90 characters per line range (for body text, not headlines).
I used to set max-width in ch before removing CSS completely as well, but usually desktop web browser windows are resizable, with the space being there to be used, not to fill with background color. I see it in epub files sometimes as well: huge margins are enforced, being rather annoying when you do not want those, while if you do, you can simply adjust the window size (or set such default styles, as another option).
If you only target modern (5 year window) that one popular reset can be trimmed.
A drop down menu on an iPhone SE is supposed to look different than on an ultra wide monitor on a desktop!
This must be paired with `height: auto`, or your image’s aspect ratio will be messed up if the width gets capped.
> img, svg, video { max-width: 100%; }
… but beware, Chrome 141 has CSS width/height work on nested SVG elements, and auto is being miscalculated. Workaround is to change the `svg` to `svg:where(:not(svg svg))`.
> We’ll just use a basic system-ui for this example. It has pretty good support these days, and looks good on every system without having to worry about loading in any extra fonts.
Please don’t. system-ui is a font for matching the system UI. The UI font is often not good for long content, and in some less common OS/language combinations it’s almost unusable. Stick with sans-serif if that’s what you want. People have been using system-ui as a proxy for a maybe-better sans-serif. This is not what it is, and it is bad to use it so.
> In general, the font-size is a little small as well, so we can bump it up
This is acceptable for larger screens. I reckon 18–20px is a reasonable target, so 1.25rem is fine. But on small screens, please don’t go above 1rem, it’s the platform’s customary size and you don’t have the space to waste.
> the default line-height is always a bit tight, so anything within the 1.5 to 1.7 range should do
Ouch. 1.7 is huge on smaller displays. If you want a single value, I suggest 1.4–1.5. If you want to vary by width, 1.4 on small displays up to 1.6 on large will be reasonable.
> font-family: System UI;
That’s a second glaring error you should instantly observe if you use the stylesheet. I am not encouraged about its quality.
> Some people prefer a dark system theme, but light website themes, and vice-versa.
Sensible browsers let you separate the two. Firefox defaults to having content follow the system theme, but you can change it to just light or just dark.
> main { max-width: min(70ch, 100% - 4rem); margin-inline: auto; }
This is effectively giving a minimum 2rem margin. Well, actually 2rem + 8px once including the default body margin. That’s way too much, and applied in the wrong way.
If you wanted to apply it to the main element, it would be easier and I think more logical to use padding:
main {
max-width: 70ch;
padding-inline: 2rem;
margin-inline: auto;
}
But I doubt that you actually wanted to apply it to main: if you have a site header or footer outside that, you probably still want the same side padding. So it’s probably better to use body margin: body {
margin: 1rem;
}
main {
max-width: 70ch;
margin-inline: auto;
}
… and I have there decreased it from the wildly-excessive ~40px to the reasonable ~16px.Layout wise this is why newspapers arrange their text in columns and books also generally comply with this restriction.
LOL.
Interesting comparison in the context of the top rated discussion about setting width. I'm with @kmoser. The original actually looks better--to me--and I like that I can manage it.
For tips see: https://practicaltypography.com/
Here is an article that was posted to HN which implements the three-state (auto/light/dark) toggle in HTML and CSS only: https://lyra.horse/blog/2025/08/you-dont-need-js/
> Some people prefer a dark system theme, but light website themes, and vice-versa.
Is this common? Why don't those people configure their browser to use a light theme? Or if they prefer different websites to be different themes, use a browser plugin?
...a more general issue is that every website has to re-implement many things. It's a small issue, but it discourages newcomers, and the redundancy on every website adds up. Ideally, a site should look decent with no CSS, but in order to support legacy sites (a good thing) the default styles are the legacy ones (a bad thing); keeping what even back then would probably be considered "bugs" (except, like how crimes become legal, they managed to become "features" by being discovered too late), such as large images causing horizontal overflow. Honestly, is there a single good reason to make the default font Times New Roman 16px?
Configuring the whole browser to have a light theme is the wrong solution - some websites look better in dark mode and some look better in light mode. Also, the browser setting also affects the UI of the browser itself, not just website contents.
These are of course solvable problems, but the most obvious and trivial way to handle this is just to store an extra flag per-website in the same place as the zoom preference.
https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...
Edit: this looks pretty harmless https://github.com/the-code-rider/dark-theme-extension/blob/...
This is particularly important on mobile, as dark is very reflective at day, and light blinds you at night.
img { max-width: 100%; }
(which is one of the things mentioned in that article; it probably would make sense for videos and SVG as well like they mention.) But, if you don't like them, the user should be allowed to customize them. In case this causes problems with web pages that use different styles that interfere with them, then hopefully an attribute could be added to specify that the user's CSS should be used instead of this one (and in some cases the browser might be able to decide this automatically for when the web page does not specify this attribute, e.g. if the styles are only associated with media queries and HTML element names rather than IDs, classes, etc). The user could still override this to disable the web page's CSS entirely if desired, but this would make it possible to specify that the web page's CSS is not needed for styling classes and other more complicated stuff within the specific web page or web app. (If the user does not define their own CSS, then it would use that defined in the web page (or the defaults if there is no CSS in the web page; the defaults probably should be changed to support the light/dark scheme properly for web pages that lack CSS, though), and the hypothetical attribute that I mentioned would be ignored.)Arrogant.
But not as bad as those jerks that use smaller and smaller, progressively lower contrast text as the actual content gets more important. Huge readable repetitive headings, microfiche gray-on-gray for the stuff that mattered.
Hell, Hacker News sets the comment font size smaller than default.
The value of that recommendation is rather dubious considering today's high-resolution displays that allow for smaller font sizes. 80 readable characters at 768p are not the same as 80 readable characters at 4K.
To my surprise the paper actually concludes that fast readers prefer shorter line length.
Edit: Usually books and newspapers are also more or less in compliance with this convention and those where around since before computers where a thing.
Do people actually do this? I have like 10 tabs in a maximized browser window. Am I supposed to keep unmaximizing it and fidgeting with the width? Or am I supposed to just rip the tab out and have to deal with multiple browser windows?
* { box-sizing: border-box }
`body, html { box-sizing: border-box } * { box-sizing: inherit }`
> But a browser should have a minimal set of default styles!
They always have done. My suggestion does not affect that.
> Websites shouldn't be able to turn off default stylings!
Many already literally are, either through CSS resets or simply doing h1 { color: red }.
> What's the point!?
There's a dozen or so popular CSS resets that literally overrides all the browser default styles. It would save time and data to not ship the same styles over and over again.
> It's impossible!
No, no it is not. Simply inform the browser to apply no styling at all. This would be a straightforward feature for browser implementors to create.
all: unset;And, no, I do not want the text I am reading to be full-width on my 32-inch monitor. I'm jumping between a lot of other sites that need to take up the entire space.
I mean, newspapers have a smaller columnar style than any website and have been around for generations.
You hear this, HN?
Please don't do this. Despite what usability studies say, I prefer wide content over scrolling every few seconds and having to make my eyes follow the moving text. I, the user, can already control the content width by resizing my browser, thank you very much.
I'd know, because this is exactly how I temporarily "fix" rubbish, outdated sites that have all their 80 column text appear on the left: I resize my browser window to move the text in to the center of my display. It's immensely annoying. It's annoying enough that sometimes it compels me to spend the (short but anger filled) time and override the site's stylesheet rather. At which point, may as well have served me some plain text instead. Speaking of, I do sometimes just toggle reader mode on too.
Nearly every techie and non-techie I know has a bazillion tabs open 100% of the time. The likelihood that even the top 10 are all single-column text is 0%. And I'd sooner read web pages hot off a dot matrix printer than constantly pecking at the edge of an un-maximized window, resizing it like some kind of meth-addled chicken.
Note: I may be overstating slightly for effect.
Oh the irony that lots complain that mainstream OSes window managers are oh so poor when all people seem to be able to do is fullscreen everything and then tab around.
Meanwhile, macOS gave up on the absolutely brilliant if misunderstood Mac OS X green + a.k.a "zoom" which would miraculously resize windows to the maximum size of its content but no more.
If you could easily shrink a tab, I would prefer websites to not limit text width. Since you can't, I sorta prefer them to do it, though it's much worse than the user controlling it in a nice per tab way
But I, the user, do not. And I will not. Because there are a bazillion websites that I want to browse in a maximized browser window. So limiting the content width help people like me who cannot/would not resize my browser.
solves the paragraph width "usability" and uses the full screen space
not sure why its never used.. I also really dislike the current trend of giant white sidebars
I’m still interested in this layout, but that’s why nobody does it: it’s far more complex from the web dev’s perspective, bad if not executed perfectly, and still has downsides even if perfect.
I think it’s still popular in places where the viewport size and content are both known at design time.
Yes you can already resize the window or zoom but that oftentimes break the design in some way.
Well, nothing happen in tech before it's a trend, so let's just wait and hope.
Most websites abuse the latter two, and makes my mouse wheel spin like a meth addict without a dose.
Please keep the default font size. It's aligned with the system's size, and is precisely what a browser's zoom function will scale.
And no, I absolutely do NOT want the content I’m reading to be full width on my 32” monitor. I have loads of other sites that I’m jumping between which do need to take up the full space.
I mean newspapers have a narrower columnar layout than any website and they’ve been around for centuries.
So then you hug the right edge of the screen, looking for it, where it looks like it is, and where it's been for like the entire history of computing, and then you click, and there's just nothing there.
This is a special case of Fitts's law, where a button at the edge of a screen becomes effectively infinitely wide, as far as ease-of-clicking goes.
This was used intentionally with great effect on usability in the 90s and 2000s. (Scrollbar, start menu, show desktop, etc.)
In the last decade however the trend appears to have reversed: it is now fashionable be to make the scrollbar as difficult to click as possible, by offsetting it, making it narrower, or hiding it altogether.
It's nice of you to consider only your own perspective.
In that case I'd say the problem is exactly what you state
> knows essentially no CSS
The solution is quite obvious then too: learn some. It's not hard. Understanding the basics is a afternoon job. Diving a bit deeper a day, and learning about some often-used more in depth features like "responsive" or flexbox, another day. For a software developer/engineer that builds backends, CSS really isn't that hard.
That's not to say a basic CSS set and some explanation like in TLA, isn't useful.
It's my pet-peeve that in software development, I'm convinced we should understand the stuff that we work with. Not all, and certainly not everything in great detail, but enough to know where to find the info and details when working with it. From sysadmin to the concepts of cryptography and from accessibility to how an OS writes stuff to disk. Even if that means constantly learning.
Anyone making a personal website?