Incomplete List of Mistakes in the Design of CSS
Posted23 days agoActive18 days ago
wiki.csswg.orgTech DiscussionstoryHigh profile
informativeneutral
Debate
20/100
CSSWeb DevelopmentApi_design
Key topics
CSS
Web Development
Api_design
Discussion Activity
Very active discussionFirst comment
25m
Peak period
110
0-12h
Avg / period
18.7
Comment distribution131 data points
Loading chart...
Based on 131 loaded comments
Key moments
- 01Story posted
Dec 10, 2025 at 11:20 PM EST
23 days ago
Step 01 - 02First comment
Dec 10, 2025 at 11:45 PM EST
25m after posting
Step 02 - 03Peak activity
110 comments in 0-12h
Hottest window of the conversation
Step 03 - 04Latest activity
Dec 15, 2025 at 6:21 PM EST
18 days ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 46227619Type: storyLast synced: 12/14/2025, 4:15:19 AM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
So many weird design choices in computing are because one person said "this seems right to me" without considering other viewpoints or consulting with the wider community.
Sure, you probably dont want death by committee, but a tiny cabal engaging in groupthink often produces unhelpful results.
There was some (academic) reaserch behind early CSS concept, but the original vision for it didn't pan out ("cascading" was meant to blend style preferences of users, browsers and page authors, but all we got is selector specificity footguns).
Netscape was planning to release their own imperative styling language, and ended up shipping a buggy CSS hackjob instead.
Once IE was dominant, Microsoft didn't think they have to listen to anybody, so for a while W3C was writing CSS specs that nobody implemented. It's hard to do user research when nothing works and 90% of CSS devs' work is fighting browser bugs.
Mistakes in the Design of CSS (2013) - https://news.ycombinator.com/item?id=38363698 - Nov 2023 (143 comments)
Incomplete List of Mistakes in the Design of CSS - https://news.ycombinator.com/item?id=25891435 - Jan 2021 (68 comments)
Incomplete List of Mistakes in the Design of CSS - https://news.ycombinator.com/item?id=18297757 - Oct 2018 (150 comments)
Incomplete List of Mistakes in the Design of CSS - https://news.ycombinator.com/item?id=10453850 - Oct 2015 (106 comments)
Incomplete List of Mistakes in the Design of CSS - https://news.ycombinator.com/item?id=7665667 - April 2014 (1 comment)
Default heading styles should not have equal top and bottom margin. Headings should be closer to the content they label than to the content they are setting their content apart from.
h1, h2, h3 should not have different styles. it's an anti-pattern that leads to broken accessibility
there should really be one h tag and it’s level should be based on some nesting depth
One way I've dealt with this in react is combine a Heading component with ContentGroup component. Each content group needs exactly one heading, and heading can't exist without it. Content group can contain other content groups. The tag for heading can then be determined by how many content groups are in the tree above it.
This works pretty well ime, but it can be hard to get devs to use (or think about accessibility at all).
[1] https://www.w3schools.com/html/html5_semantic_elements.asp
You can't do away with stacking contexts, you need those to isolate content you don't control to prevent it from breaking the stacking order of content you do control.
I completely agree with you about h* tags, though. I wish html5 sectioning hadn't been killed by the browser vendors. As is there's no safe way to put headings inside custom elements. We almost had it, it was specified and everything.
https://www.w3.org/TR/xhtml2/mod-structural.html#edef_struct...
How does that hurt accessibility? Are you saying people use h3 in order to get its style even when they didn't mean h3?
I think the opposite could happen too - if they all have the same style then people might just use h1 everywhere which is probably just as bad. People tend not to use elements that have no obvious use, like <output> which apparently has better accessibility but does absolutely nothing else, so nobody bothers. The whole "semantic web" thing failed partly because of this.
yes, and that people assume the purpose of having different tags is to control styling
I came across it when reading Butterick's Practical Typography and it's possibly the lowest effort/clearest improvement guideline in the book.
Now I can't unsee websites that do it wrong.
Related: I also love when I can't paste tabular data into Excel/etc. anymore
With css grid, I can tell each element which area or column+row to occupy.
If I add or remove a random element, the rest of the elements stay in the correct place.
But do that with a table and you end up trying to glue your house back together shard by shard whilst trying not to cut yourself or breaking things more.
This complaint highlights how absurdly not fit-for-purpose html+css actually is. Okay, you may want to do "responsive" design, but you have the semantic layout fixed, therefore you try and contort a styling engine into pretending to be a layout engine when in reality it is three stylesheets in a trenchoat.
I need to write this up properly, but one of my bugbears with responsive design is that it became normalised to push the sidebar down below the content on small screens. And if you didn't have a sidebar, to interweave everything in the content no matter what screensize you were viewing on.
What I want is a way to interleave content and asides on small screens, and pull them out into 1+ other regions on larger screens. Reordering the content on larger screens would be the icing on the cake but for now I'll take just doing it.
This CSS Grid approach adds gaps: https://codepen.io/pbowyer/pen/azNarbZ
Using named grid-template-areas stacks the items you move to the sidebar on top of each other, so you only see one of them.
'Good' old floats get most of the way, but put the item in the sidebar exactly where it falls. Plus they're a pain to work with overall: https://codepen.io/pbowyer/pen/jEqdJgP
this not fit for purpose may in fact be historically superseded usages that still are baked in to some usages affected by the relatively rapid change of the various platforms that must interact and use the respective technologies, the specification version of "technical debt"
that is to say some subsets of the numerous technologies can be used to construct something fit for the purpose that you are describing, but as a general rule anything constructed in a solution will probably be using other subsets not fit for that particular purpose, but maybe fit for some other purpose.
Today it's usually implicitly designed for iphone, designed for 1080p, or ipad, and you have to guess, strong correlation with whatever device the designer uses in his personal life.
Today sites certainly can and some (many) so. But some (also many) definitely don't…
A lot are locked to a maximum width, which is OK enough as l……o……n……g lines of text are unpleasant to read, but only because browsers hack the meaning of dimension settings to make text zoom work consistently.
A lot also have an effective minimum width (even if they use responsive styling to move/ minimise/hide side decoration before a certain point) that is not always convenient. Try browsing with a thin window so you can have something in the other side of your screen. Some assume no one on desktop will ever have a browser window less wide than 1280 pixels (or equivalent on a zoomed higher res screen) - not the case on my 1080p portrait screen and I sometimes want things thinner than 1280 on my 2560x1440 screen. You could say I'm just odd and they can't cater for everyone, but 1080 or a bit less wide is hardly miles away from many devices physical layout so if a design can't display nice in that can it really call itself "responsive" (I suspect any such design would fail on many mobile devices too - 1080px effective width is rather common there, as are smaller widths).
Isn't this a trivial problem to solve that doesn't require introducing any new layout mechanisms?
And just in case, nobody ever said tables were dead. Tables were declared bad practice for page formatting, not for tabular data.
Use grid instead.
The most important thing is to use the right tool for the job. If grid lets you express what you want in the most straightforward way, use it; if flexbox does - even if it needs nesting - then use it instead. Don't shoehorn one into a situation where the other makes more sense. And sometimes either will work for a particular situation and that's fine too; use whatever you find most ergonomic. They're both very good in their own way.
Therefore, to calculate the size of an item, the sizes of other items need to be known. Now, if one of the items is a flexbox, its item sizes cannot be known until the previous flexbox is laid out.
Of course, properly using flex-grow and flex-shrink can optimize that calculation, but what about deeper nested flexboxes?
I made a stunning landscape photo one time that looked great only when displayed at roughly the size of a hand. If made larger undesirable details became visible (littering), when smaller important details were lost (a formation of birds over a fishing vessel).
Not beyond a point, but it's still very useful to be flexible up to that. For example, I'm very grateful that a web page will reflow text rather than print everything on one line and force horizontal scrolling.
We are having a lot of fun pretending it is possible.
Usually I declare victory when they say that tables might get depreciated in the future.
They at one point really wanted to get rid of framesets. I asked how to make the classic scrollable resizable side top bottom UI in pure CSS. We've tried for hours, everything we tried looked ugly and didn't fully work. framesets are here to stay now :)
I still have one of the funnier "how to make this without tables?" challenges. It's not a very good example of the use of tables but did make me laugh.
https://go-here.nl/omg-tables.html
that sounds like a use for tables, so I find it difficult to imagine a non-table layout that would want this.
>Resizing columns by size of cell content.
I can sort of see this as a requirement for non-table layouts that would not work well, however my experience from table time was that was one of the biggest irritants at least for me, that columns would haphazardly resize based on what was in them, and sometimes you wanted them to and sometimes not. As a general rule I found it better design wise to truncate text rather than have things expanding and contracting in response to what copy editors were doing.
>framesets are here to stay now
woo yeah, I see them a lot in the wild. I mean really the only time I really see frames used anymore are iframes and generally in eCommerce and similar security requiring solutions where the frame can be partially controlled by the storefront, but is more fully controlled by the payment provider. I just find the statement "framesets are here to stay now" really weird and triumphal for something that is so rarely used?
>I still have one of the funnier "how to make this without tables?" challenges.
I followed the link, I would think it is better suited to a "why would you make this" challenge. I'm not sure
1. it shouldn't be a table. seems like maybe it should be
2. why the freaky animation. or for that matter why the animation nearly crashed my browser.
I'm definitely sure lots of designs could not be adequately achieved without tables and framesets, but my experience seems to have run contrary to yours because for me CSS was a godsend in fixing the things I found irritating about those two technologies, this does not mean that I never encountered situations where I thought this would be easier with tables, but as soon as I tried putting tables back in I found all those irritants came back in.
From my experience tables and framesets were best suited to layouts that are rarely ever wanted, and when used to implement slightly different layouts had too many problems and irritants to be useful.
Your mileage has obviously differed, but I'm not sure that "here is a particular problem that people seldom wish to solve and which I have constructed, that plays to the strengths of my favored technology while avoiding its pitfalls" is as impressive an argument as you seem to think it is.
I think it's fairly easy to understand if you understand what it was a backlash against. Tables today are used sensibly, for the most part, but the pre-CSS world was truly absurd in its table use.
The reaction may well have been over-the-top, but it wasn't disproportionate given the state of table usage at the time.
There were some reasonable concerns. Using tables for both layout and literal tables removes semantic meaning, nested tables can get complicated to layout, and layout the whole page as a giant table makes it difficult to adapt to screen size. But the first could easily be solved by adding a tag that works exactly like table but is for layout, the other two are about overuse of tables in the absence of viable options. We could have easily kept table layouts for the parts where it makes sense and augmented it with something css-like for the parts where it doesn't.
The simple solution:
<table type="layout"> (or "data")
Except that’s exactly where tables should be used. So if you can’t, someone has really misunderstood CSS.
Use it for tables, not for layout.
I'd argue that if you have so many rows that DOM can't handle, humans won't either. Then you need search, filtering, data exports, not JS attaching a faked scrollbar to millions of rows.
Is there anyone who does not agree that we can reliably center things in CSS nowadays?
The argument doesn't make sense because it is not too hard for a screenreader to understand whether a table is used for layout and even if it was hard the problem would more easily be solved by just adding an attribute to the table to indicate that it is used for layout.
In the words of one of my CS profs, from a few decades ago: "There are only 3 numbers - zero, one, and infinity. And 'one' is often a mistake"
https://developer.mozilla.org/en-US/docs/Learn_web_developme...
A lingering bit of weirdness is that all !important declarations, no matter the layer they appear on, are interpreted as being part of their own implicit layer.
5 different types (default, force_default, normal, override, force_override)
which can be in 4 different places (attribute, node, environment, role) but not all of the types can be in all of the places
PLUS the "automatic" type, which is from somewhere else entirely
Oh and there's inheritance and merging which does not behave intuitively at all because it's not exactly inheritance.
In other words I have early career trauma from someone's extremely unwise priority implementation and am deeply suspicious of ANY priority override system which isn't just code I've written in a normal programming language.
I like that in Flutter they do exactly as you suggest: they call it mainAxisAlignment and crossAxisAlignment
You should be able to write
<div color="red" font-weight="bold"/>
Instead of
<div style="color: red; font-weight: bold;"/>
How about to control the color of links, add the color attributes for links in body?
https://www.w3.org/TR/2018/SPSD-html32-20180315/#body
Why can't this be dealt with with CSS versioning/features where you can opt into your current-color and a lot of more substantive style behavior while leaving currentColor functional?
This already exists:
>Comments shouldn't have been allowed basically everywhere in CSS (compare to HTML, which basically only allows them where content goes), because it makes them basically unrepresentable in the object model, which in turn makes building editing directly on top of the object model impossible
When you parse an AST with comments (or a CST), they do become "just another node in a uniform tree". Think about it - in HTML you have a tree of nodes but comments can be anywhere, which is exactly as obnoxious to deal with as a CST where comment nodes can be anywhere.
This is a terrible reason to not support comments. If it was really important, then probably you should support comments in only a couple of places, e.g. on attributes or on selectors.
But I don't think it is very important. I can't think of a single tool that loads CSS, rearranges it, and then spits it back out in a form that would benefit from comments.
If CSS had mandated that comments could only appear in certain places (e.g. before a rule or attribute) I think that would have been fine too, though maybe slightly confusing given the resemblance to C-style comments which are allowed almost anywhere.
HTML comments are basically just a HTML tag that isn't rendered. Tools that 'compile' the HTML code into a document tree, including browsers, preserve comments as nodes without any extra effort.
CSS comments can go anywhere:
Tools that transform/parse CSS can either: 1. Strip comments before parsing, meaning anything based on the parsed version will lose the comments. 2. Dedicate a disproportionate amount of complexity to retaining the comments, and still not really have a good way to handle them through edits/transformations.A similar issue is CDATA in XML which is not retained when round-tripped. Very annoying, but in line with the spec.
If the mentioned mistakes or similar language design mistakes were made. Because mistakes will always be made.
(Unison lang comes to mind but it’s refactor failsafe seems narrow. How about: Antifragile language design? Self-correcting language?)
For example, the Circle compiler extends C++ with its `#feature` directive: https://github.com/seanbaxter/circle/blob/master/new-circle/...
Sadly, the closest I've personally seen to this sort of thing in widespread use is `"use strict";` in JavaScript, which is only a single binary switch. You can't, say, turn on a new keyword, disable a keyword, switch to a different incompatible version of some browser API, etc.
I encourage all language designers to include a feature mechanism in a forward-compatible way. Don't overthink the difficulty: It doesn't need to do anything at first, it just needs to not be a parsing error. Treat it like a comment. FYI, this is the same as having a version number or header size in a binary file format's header, which all sane formats have (there are a lot of insane formats out there...).
text-transform: CASE; text-transform: case; text-transform: Case; text-transform: casE; text-transform: cASe; text-transform: CaSE; etc...
I've wanted the latter to write headlines about NeWS and NeXT and NeRF.
A use case for specifying device pixel sizes are thin-lined grids, that can have inconsistent spacing and line width due rounding when you use px on hi-DPI.
How it should be (and OSes should do it) is: - There is the device pixel e.g. "dp"
- There is a UI scaling unit "u" (the equivalent to CSS px, but not with a misleading name). It could be e.g. defined to be the height of a standard button. This is used for most screen-oriented elements, and u-based sizes can be optionally rounded to whole dp.
- There are physical units independent of u. There is a ratio of these to dp. For print the ratio is e.g. so that 1in = 300dp if it is a 300dpi print. For screen the ratio is based on the actual physical pixel density the OS can either derive from a display device, or the user calibrates it. Physical unit based sizes can optionally be rounded to whole dp.
- The user can obviously set the UI scaling and overwrite the physical unit scaling.
As a result you can get display pixel based sizes simply and reliably, UI scaling is not based on a often misunderstood "virtual pixel", and physical objects can be displayed on screen with its actual size (or whatever scaling the user wants).
Trying to optimize to some kind of perfect pixel alignment shouldn't be a goal anymore. We use antialiasing instead to ensure that widths and weights maintain proportionality no matter what resolution and zoom level you use. Trying to snap to pixels is an anti-feature with modern screens. It made sense when everyone used low-resolution screens and antialiasing wasn't commonly used. It doesn't make sense anymore.
If you're trying to display pixel art (or make games with pixel art), being able to have integral upsizing is very useful. Antialiasing doesn't cut it, and the eye notices when you do non-integral nearest-neighbour upscaling and some pixels are the wrong size.
Anti-aliasing is not a good solution for orthogonal lines with low device pixel ratios like 1.25 or 1.5. which will be around for a long time. Browsers disagree with you - they don't use anti-aliasing for orthogonal measurements, they round.
I agree that it can be misused like using device pixels for UI, but my suggestions makes the distinction more explicit.
I wish that one were we elaborated on more :)
They do with left+right, and have done this for a very long time. You only get the anchoring if you additionally set width.
- Values for properties with just two valid values available should have been true and false rather than having one more unique word combo to remember forEach.
- I cant quite describe them but float at times has some weird unexpected behavior.
https://stackoverflow.com/questions/23154201/weird-behaviors...
Just kidding. To me the biggest mistake was the standards' slowness in the early 2010s to provide badly needed new functionality such as a proper replacement for table layout, vertical alignment, etc. The cult of knowing specific tricks to get things working properly carried on for too long and made a lot of people annoyed at the semantic web (rip).
More importantly to me, "display" has been overloaded with two meanings: Display of the element this rule applies to/how it interacts with surrounding elements (none, block, inline, inline-block) and display of the contents of this element (flex, grid).
Which is why we now also have inline-flex and inline-grid.
I also don't understand why they never specced the (much simpler) `text-align: -moz-left/-moz-right/-moz-center' which already had precedent in HTML with `<div align=left/right/center>'. It's the saddest part of the "center a div" saga, all the W3C had to do to fix it is to assign a standard keyword to a feature that everybody already implemented, but to this day it still hasn't happened.[2]
[1]: https://pcwalton.github.io/_posts/2014-02-25-revamped-parall...
[2]: After many long decades, they did finally specify block-level `justify-items'. Two problems: a) it's backwards-incompatible with text-align, b) it still doesn't work in Gecko.