[HN Gopher] Incomplete List of Mistakes in the Design of CSS
       ___________________________________________________________________
        
       Incomplete List of Mistakes in the Design of CSS
        
       Author : Tomte
       Score  : 118 points
       Date   : 2021-01-24 12:19 UTC (10 hours ago)
        
 (HTM) web link (wiki.csswg.org)
 (TXT) w3m dump (wiki.csswg.org)
        
       | lucideer wrote:
       | This list is a good idea for the reason stated in a sibling
       | comment: it could highlight gotchas for people learning CSS.
       | 
       | However it fails to do so. The list is mostly subjective
       | preferences, and as such is far too long, leaving the actual
       | universally-accepted gotchas to get completely lost among the
       | rest.
       | 
       | Even some of the points that most would agree on are still such
       | minor gripes as to be almost irrelevant, so listing them just
       | detracts from the significance of some of the very large actual
       | mistakes in CSS.
       | 
       | Here's a few choice subjective examples:
       | 
       | > _Table layout should be sane._
       | 
       | This is not a helpful bullet point without expanding further.
       | 
       | > _The 4-value shorthands like margin should go counter-clockwise
       | (so that the inline-start value is before the block-start
       | value)._
       | 
       | This would make sense for an implementer and make resulting CSS
       | more terse for common use cases but it would be less intuitive
       | for people newly learning CSS.
       | 
       | > _z-index should be called z-order or depth and should Just Work
       | on all elements (like it does on flex items)._
       | 
       | This would have caused a lot of arms race z-indices, particularly
       | in sites loading widgets generated by third party scripts. It
       | would make z-index less confusing but without scoped CSS this
       | change could get quite problematic.
       | 
       | > _The top and bottom margins of a single box should never have
       | been allowed to collapse together automatically as this is the
       | root of all margin-collapsing evil._
       | 
       | I 100% agree but I acknowledge that many don't, so I don't think
       | this belongs here. This is basically like the tabs and spaces
       | debate.
       | 
       | > _descendant combinator should have been >> and indirect sibling
       | combinator should have been ++, so there 's some logical
       | relationships among the selectors' ascii art_
       | 
       | wat
       | 
       | > _:empty should have been :void, and :empty should select items
       | that contain only white space FIXED in the spec, waiting for
       | implementations to check for Web-compat..._
       | 
       | This is BAD. Whitespace isn't empty (nor does it display as such,
       | it collapses to one space, not zero), so that change is
       | incredibly unintuitive. :empty should stay as currently, :blank
       | might fit the new use case.
        
         | Izkata wrote:
         | > > descendant combinator should have been >> and indirect
         | sibling combinator should have been ++, so there's some logical
         | relationships among the selectors' ascii art
         | 
         | > wat
         | 
         | Skipping the combined character mistake, it means it should
         | have been: > for direct descendant, >> for indirect descendants
         | (instead of just a space), + for direct siblings, ++ for
         | indirect siblings (instead of ~).
        
           | inopinatus wrote:
           | Oh, but it makes so much sense as >>. It's an expensive
           | operator, it should be harder to type.
        
           | the_other wrote:
           | Indirect descendant uses just whitespace because it's the
           | most common and most useful relation. Making it two
           | characters would have annoyed everyone using the language
           | every time they used it.
        
         | chrismorgan wrote:
         | And :void would be a singularly terrible name anyway, because
         | "void element" has a particular meaning in HTML ([?]
         | https://html.spec.whatwg.org/multipage/syntax.html#void-
         | elem...): an element that cannot have any children and
         | accordingly has no end tag in the HTML serialisation, such as
         | <img>, <hr> and <br>. Renaming :empty to :void would completely
         | undermine this, since :empty matches any elements that have no
         | text or element children (note: not "have no children", because
         | comments are allowed), regardless of whether or not they _can_.
         | 
         | The whole idea of allowing :empty to match elements containing
         | only whitespace is fraught. Whitespace could be collapsed
         | completely, to one space, or not at all, depending on both the
         | surrounding markup and the values of such properties as display
         | and white-space. If you decided the concept was worthwhile
         | supporting, then :blank would be a decent name. But changing
         | :empty to accept whitespace, well, that'd be a far worse design
         | mistake.
        
       | inopinatus wrote:
       | This is a somewhat superficial list that omits discussing the
       | fundamental idea behind CSS, viz. the semantic model; from which
       | everything else is, directly or otherwise, a consequence.
       | 
       | Two decades ago I was overjoyed to discover that Scheme was
       | finally going to have a useful application beyond illustrating
       | SICP and writing koans to amuse myself, because DSSSL was on the
       | cusp of evolving into the last document styling language anyone
       | would ever need.
       | 
       | Unfortunately following an incident with a broken Lisp machine, a
       | liquid lunch, and an unlicensed particle accelerator, I became
       | trapped in a parallel universe where the HTML ERB anointed CSS by
       | mistake during a drunken night out in Oslo.
       | 
       | The primordial concept of CSS (best revealed by H.W.Lie's thesis
       | IMO[1]) was to create a rich and versatile and (crucially) _non-
       | Turing-complete_ set of structural selectors in lieu of DSSSL 's
       | recursive expressions, and to allow styles to overlay one another
       | (the "cascade"); two design choices that only by the application
       | of gallons of irony can explain why most web pages are composed
       | of a bunch of nested DIV elements with hashed IDs and overloaded
       | semantic class attributes, and everyone compiles their assets
       | into a static file.
       | 
       | [1] https://www.wiumlie.no/2006/phd/css.pdf
        
         | tannhaeuser wrote:
         | Non-Turing-completeness is a plausible goal if and only if you
         | enumerate and hold up all use cases against their realization
         | for weighing idioms vs idiosyncrasies. However, if you just
         | can't stop extending CSS' basic mechanism of property-value
         | assertions with ever more layout model magic, exceptions, and
         | microsyntax, then you get the clusterfuck that is CSS today,
         | where any semblance of intent, locality, or other cognitive aid
         | whatsoever is lost in the written code artifact.
         | 
         | Drunken or not, I can't also really fathom the primordial
         | mindset of looking at HTML (eg. SGML's already heavy attribute
         | and element syntax infrastructure), then come up _with a
         | completely redundant syntax out of nowhere_ for holding the
         | exact same thing that went into attributes yet with weaker type
         | checks.
         | 
         | The result is the write-only mess that is CSS today, unusable
         | without CSS debuggers, inaccessible to most devs and
         | traditional graphic designers let alone laymen, yet always
         | insufficient for innovators, seemingly perpetuated only by
         | folks who mistake their huge effort into learning CSS with its
         | merit (aka Stockholm syndrome).
        
       | c-smile wrote:
       | Flexbox shall not exist. At least in the way it is defined.
       | 
       | 1. It breaks CSS box model that postulates that "width" defines
       | element width. With flexbox that is not so as width can be
       | overridden by flexbox in non-trivial manner.
       | 
       | 2. flexibility shall be defined by flex/fraction units like in
       | Grid module. So we may have:                   width: 10fr;
       | margin-left: 2fr;         border-spacing: 1fr;
       | 
       | 3. CSS and HTML shall have unified flex units. Flexibility in
       | HTML uses ** units like                   <frameset
       | rows="200,1*,200">          <frameset rows="200,2*,1*">
       | <td width="2*">
       | 
       | and so CSS might use that as                   width: 10*;
       | margin-left: 2*;
       | 
       | 4. Flexibility as an entity shall be expressed uniformly among
       | different CSS modules. Instead of bunch of separate flex-**
       | properties and separate FR units it should be just flex units
       | width:2*; and flex functions if that is needed.
       | 
       | -----------------------
       | 
       | "box-sizing" shall have also padding-box value.
       | 
       | When defined padding shall go into scrollable content :
       | https://terrainformatica.com/2019/10/17/css-overflow-padding...
       | 
       | In general box-sizing is broken (or under specified) in regard of
       | paddings of the element.
       | 
       | -----------------------
       | 
       | "outline" shortcut property shall include outline-offset value
       | too.
       | 
       | -----------------------
       | 
       | "visibility" shall have "none" value.
       | visibility:none;
       | 
       | shall be treated as display:none and display shall not have none
       | value. So for hiding/showing a table for example we can use
       | .some {           visibility:none;           visibility:visible;
       | }
       | 
       | But not                  .some {           display:none;
       | display:block;         }
       | 
       | which is obviously wrong.
       | 
       | In short: visibility and display model shall be orthogonal.
       | 
       | -----------------------
       | 
       | Syntax:
       | 
       | Modules shall use functional notation rather introducing bunch of
       | conflicting prefixed properties, so use this
       | display: grid(           column: 2 / 4,           row: 1 / 3
       | );
       | 
       | instead of                   grid-column: 2 / 4;         grid-
       | row: 1 / 3;
       | 
       | Different modules in future may also want to have grid-columns,
       | etc.
       | 
       | ------------------------
       | 
       | // - line ending comments please
        
       | FrontAid wrote:
       | Many good points in there. One that I run into on a regular base
       | and that can't be fixed right now:
       | 
       | > Selectors have terrible future-proofing. We should have split
       | on top-level commas, and only ignored unknown/invalid segments,
       | not the entire thing.
       | 
       | That forces you to duplicate declarations for backward-
       | compatibility. For example, you can't combine those two
       | selectors:                   /* works */         :user-invalid {}
       | :-moz-ui-invalid {}              /* breaks */         :user-
       | invalid, :-moz-ui-invalid {}
       | 
       | Somewhat related to the link:
       | https://github.com/jensimmons/cssremedy tries to "fix" some of
       | those issues.
        
       | asiando wrote:
       | Don't read this because you can't unsee. I prefer to be ignorant
       | of _what it could have been_ because I don't want to groan about
       | it for the rest of my days.
        
       | wackget wrote:
       | Extremely misleading title. These are not "mistakes" as much as
       | subjective preferences.
       | 
       | A better title would be "some random person's opinion about what
       | should be changed in the CSS spec".
        
         | soperj wrote:
         | lol. Yes, a random person who some how managed to post on the
         | CSS working group. A random person who's been a css spec writer
         | since 2004 (17 years).
        
         | Geminidog wrote:
         | Not only that, every language and design ever made on the face
         | of the earth doesn't have any design mistakes at all.
         | Everything is just an opinion and subjective preference.
         | 
         | In fact point out any mistake to me ever made and I'll just
         | tell you that it's just your opinion and I have a different
         | one.
         | 
         | I'll take it a step further and say that people can hold
         | opinions but those opinions can be categorically wrong or
         | right.
         | 
         | So this article is about one persons subjective opinion, but
         | all his subjective opinions are definitively right and anyone
         | who shares opposing opinions is wrong.
         | 
         | Just want to caveat this post with the fact that I'm just
         | sharing my subjective opinion on this issue, you can agree or
         | disagree.
         | 
         | But if you disagree with me then you are categorically
         | mistaken, but again it's just my opinion you have the freedom
         | to form your own opinion.
         | 
         | Maybe it's pointless to call something an objective opinion
         | because literally that's what everything is. The man calls
         | aspects of css a design mistake, you disagree, prove to me why
         | he's wrong
        
           | chrismorgan wrote:
           | The logical extrapolation of your argument also says that
           | there's no such thing as a bug--just software that doesn't do
           | what you in particular, or perhaps everyone, wanted and
           | expected it to do.
           | 
           | Also you suggest that there's no such thing as a design
           | mistake, yet that opinions can be categorically wrong or
           | right. These seem to me to be mutually incompatible. At the
           | very least, the first part necessarily restricts the _type_
           | of opinions that can be categorically wrong, so that the
           | designer of something can't correctly declare something a
           | mistake.
           | 
           | One popular list of design mistakes in a language is
           | https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/.
           | Many of them can be quibbled over, but many of them are
           | unequivocally at the very least suboptimal, where the
           | behaviour that was complained of was quite indefensible--and
           | commonly has been fixed since, because in many cases it was
           | considered a bug. (And so you see how the line between a
           | design mistake and a bug can be fairly arbitrary.)
           | 
           | Another example I'd use of an unequivocally bad design is
           | MySQL's Unicode charsets: that you had utf8, then utf8mb3 and
           | finally utf8mb4. utf8 and utf8mb3 were both stupidly broken
           | from the very start, utterly unfit for purpose. They should
           | probably never have been invented, but at the very least they
           | should have been named differently--tens or hundreds of
           | thousands have learned the hard way that "utf8" is
           | dangerously broken, and that "utf8mb4" is what they need.
        
             | Geminidog wrote:
             | That's just your subjective opinion on the matter and you
             | are free to have it. I share different thoughts on the
             | issue though.
             | 
             | In all seriousness my post is lampooning the absurdity of
             | calling something an objective opinion because anything can
             | be classified as such and I'm subtly hinting at the fact
             | that it's pointless and we should have the capability to
             | label certain things as wrong or right rather then call it
             | just a collection of opinions. I think you're mistaken
             | here, we are actually in agreement.
             | 
             | All of Css is a design mistake and guess what? I'm not
             | saying that's my opinion, that's fact.
        
       | bluedevil2k wrote:
       | 'display' is way too overloaded. block/inline-block/inline are
       | fine, defining how other elements stack against this element.
       | Visibility should not be included though - display:none; should
       | instead be visible: true|false. Then the layouts are shoved
       | inside this property too: grid, flex, table. There should instead
       | be a layout: grid|flex|table
        
         | 0df8dkdf wrote:
         | There is a difference between dispaly and visible in CSS. One
         | just hides the element but doesn't rearrange the other elements
         | around it, the other display as if the element doesn't exist.
         | 
         | https://www.tutorialrepublic.com/css-tutorial/css-visibility...
        
           | bluedevil2k wrote:
           | I just learned something today, and I do CSS (amongst other
           | things) for a living. Maybe it should be visible:
           | true|false|ghost
        
             | ivanhoe wrote:
             | Seriously, never had to deal with visibility:hidden before?
             | To quote the Pythons: You lucky, lucky bastard....
        
               | bluedevil2k wrote:
               | It's kind of unusual to set visibility to hidden in CSS,
               | it's more something you'd code in jQuery, or handle in
               | the React code itself.
        
           | inopinatus wrote:
           | In addition, visibility may participate in animations. In
           | particular we can delay the transition of visibility to
           | false, but not of display to hidden. So it is very helpful in
           | some pure-CSS disappearance animations, such as fading out a
           | modal's background overlay.
        
         | naniwaduni wrote:
         | To make matters worse, the "visibility" property _exists_ ,
         | with values "visible", "hidden", and "collapse".
         | 
         | "collapse" works _kind of_ like display: none, but ... not in
         | all contexts.
        
         | unabst wrote:
         | I would go far as to say it's obfuscation. But I don't think
         | the CSS people feel the same. At this point I've chalked it up
         | to a difference in philosophy and ideology.
         | 
         | Brevity, explicitness, obviousness, conciseness, and symmetry
         | all contribute to the simplicity and order of a language, which
         | minimizes the learning curve and maximizes ease of utility.
         | 
         | If that were the goal, there are tons of things that could and
         | would have been done differently.
         | 
         | Most lists such as that of the OP and most criticism of CSS I
         | find to be about users from a user standpoint criticising
         | something about CSS that is either obfuscating or obstructive
         | to their experience and productivity.
        
         | inopinatus wrote:
         | CSS Display Module Level 3 sort of takes this criticism on
         | board and has a more compositional approach to display. It's
         | still one property but the attribute is multi-valued. c.f.
         | https://hacks.mozilla.org/2019/10/the-two-value-syntax-of-
         | th.... However browser support is very limited, it's not yet in
         | Chrome or Safari, and whether this goes far enough is a matter
         | of taste.
        
       | ahmedfromtunis wrote:
       | !important should've been --force. I remember struggling to
       | understand what important is and why it was everywhere I looked,
       | back in the day.
        
       | tomaszs wrote:
       | Still number one thus. It is the most stable and rich part of web
       | dev. I could never understand why people cripple CSS with SCSS
       | and BEM. Don't you think CSS is underestimated?
        
         | vehemenz wrote:
         | SCSS and BEM are methodologies, whereas CSS is just a
         | specification with various implementations and is methodology-
         | agnostic.
        
           | noema wrote:
           | SCSS isn't a methodology, it's a tool for reducing repetition
           | and capturing syntactic complexity in CSS.
        
             | vehemenz wrote:
             | You're right, I was thinking of SMACSS.
             | 
             | SCSS (or SASS, more generally) does benefit some
             | methodologies more than others though; I've never found
             | much use for it while using Tachyons or Tailwind, for
             | example.
        
           | tomaszs wrote:
           | Whatever we call these it does not change the fact that both
           | methodologies cripple CSS in many ways, and shadow things
           | covered already by CSS and other means. I think both are
           | responsible for how CSS is received and it is sad, because
           | CSS is not responsible for these horrible methodology
           | mistakes.
        
       | foreigner wrote:
       | This is actually a useful list of gotchas to watch out for if
       | you're just learning CSS and expect things to work in the
       | intuitive way.
        
       | IshKebab wrote:
       | It would be good if they split out the naming nitpicks into a
       | separate list. `display` should have been called `display-mode`?
       | Maybe, but I'm not sure everyone would agree and it's very minor.
       | Box sizing should be `border-box` by default? Yeah this is an
       | obvious mistake that I don't think anyone would disagree with,
       | and I imagine is the first thing people set when starting a new
       | project.
        
         | vehemenz wrote:
         | For those of us who started using CSS in the late 90s (well
         | before box-sizing was a property), the original box model made
         | perfect sense. And it took me a long time to adjust to box-
         | sizing: border-box, which I only adopted because so many
         | frameworks started using it as default in their base styles.
         | 
         | I don't disagree that there wouldn't be a consensus now, but
         | that's only because the border-box convention has completely
         | taken over.
        
           | earthboundkid wrote:
           | Hard disagree. I've been making websites since 1997, and the
           | default box model is garbage and unusable.
        
       | moron4hire wrote:
       | Almost all of this could be handled with a keyword replacing text
       | macro. To me, that says nothing about the _design_ of CSS, rather
       | than nitpicking minor implementation details.
       | 
       | My biggest gripe with the _design_ of CSS is the lack of rules
       | nesting. Having to repeat a selector slug to make a rule for
       | children of something I 've already defined gets very verbose.
       | 
       | I also find the whole situation with animations nigh inscrutable,
       | but that could be my lack of experience with them. All I know is
       | that it's nearly impossible to guess at the right values for
       | animation rules, even with intellisense hints.
        
         | vehemenz wrote:
         | Lack of rules nesting is more about CSS's incompatibility with
         | the predominant paradigm of stylesheet design (mapping high
         | abstraction class names to specific elements). And honestly,
         | you can easily solve this problem with preprocessors if you
         | like that way of doing things.
         | 
         | Can you give an example of repeating the selector slug to make
         | a rule for children?
        
       | eyelidlessness wrote:
       | I think I agree with basically everything on the list except one
       | (I don't think rgb/hsl should accept alpha arguments, rather
       | rgba/hsla should have been available from the start; but that's
       | probably an unrealistic expectation given the performance impact
       | at the time), but haven't thought through all the ramifications.
       | 
       | But one thing I'm disappointed isn't on the list is a syntax
       | sanity and unification proposal. CSS is a DSL so it gets some
       | flexibility here, but there are _far too many_ syntax variations
       | for the same basic language primitives.
       | 
       | - Either all functions should require arguments separated by
       | commas, or treat all commas between arguments as whitespace
       | (helllloooo lisp)
       | 
       | - More to the point, a slash as an argument separator is bonkers.
       | The rgb/hsl syntax breaks my brain every time I see them with an
       | alpha value.
       | 
       | - Every shorthand should have a longhand equivalent (they're
       | finally fixing transform, but this is another syntax disaster).
       | 
       | - Lists should have delimiters at all. Or they should be an
       | explicit function.
       | 
       | - Keywords should have some kind of sigil. The current state is
       | untenable, as the keyword space is enormous and ever growing,
       | making invalid bare strings (often used for browser compat)
       | dangerously likely to become valid on unmaintained sites. The
       | "don't break the web" counter-instinct makes introducing new
       | features almost guarantee more syntax fracturing.
       | 
       | - Either media queries should have been a part of selectors, or
       | nesting should have been made available across the board (though
       | I've seen rumors that this is being considered).
       | 
       | - Existing properties should get new values rather than
       | introducing an ever growing, increasingly confusing, set of
       | similar properties that do slightly different things in ways that
       | are so inscrutable that even MDN can't explain them in plain
       | language.
       | 
       | - Feature forking should have its own syntax (eg or/cond type
       | functions), not implemented as multiple definitions of the same
       | property.
       | 
       | Partly syntax, partly behavior:
       | 
       | - Every pseudoclass should have a -within suffix equivalent, not
       | just focus.
       | 
       | - Equal-specificity rules should be considered more specific by
       | the order they apply to elements (ie the order classes are
       | applied in markup), not the order they're defined in the
       | stylesheet. Atomic CSS is brilliant, but a minefield to generate
       | programmatically (with any library in the space left to write
       | tomes on ordering caveats), because the specificity spec is just
       | plain wrong.
       | 
       | - Functions should be composable. And I'm thinking specifically
       | about color manipulation here, so while I'm on the topic, HSLuv
       | or some other perceptual color space should be supported.
       | 
       | - Styles in general should be composable _in stylesheets_. This
       | can be as simple as a native extends keyword modeled on SASS, or
       | as a function.
        
         | chrismorgan wrote:
         | transform is not a shorthand: rather, it's a set of
         | transformation functions, akin to how background-image is a set
         | of background images.
         | 
         | The new properties for individual transforms (translate,
         | rotate, scale) are new, supplementing the transform property
         | and not supplanting it. See https://drafts.csswg.org/css-
         | transforms-2/#individual-transf... and
         | https://drafts.csswg.org/css-transforms-2/#ctm for details.
        
           | eyelidlessness wrote:
           | You're right, and this is a good clarification. And it's a
           | list, where order matters, as each transform applies to the
           | result of the previous transform. This is a place where any
           | kind of composition syntax would be a huge improvement, as it
           | behaves much more akin to a pipe than a list.
        
       | riggsdk wrote:
       | >> background-position and border-spacing (all 2-axis properties)
       | should take _vertical_ first, to match with the 4-direction
       | properties like margin.
       | 
       | I disagree. We are inherently used to 2D coordinate systems being
       | X, then Y.
       | 
       | I would instead have made the directional properties go "left,
       | top, right, bottom" instead.
        
         | soperj wrote:
         | other properties like padding, and margin take vertical first.
         | They're asking for consistency.
        
         | realusername wrote:
         | I also have the same opinion, if you did not know anything
         | about CSS, nobody would pick "top" to be the first one instead
         | of just "left".
        
           | paulryanrogers wrote:
           | Really? What about cultures that write right to left or
           | vertically?
        
         | wizzwizz4 wrote:
         | There are several orders that make sense:
         | 
         | * left, right, up, down
         | 
         | * North, South, East, West
         | 
         | * clockwise from the top
         | 
         | * anticlockwise from positive x
         | 
         | * +X, +Y, -X, -Y
         | 
         | The list goes on. Consistency is the most important thing.
        
       | hshshs2 wrote:
       | This list is highly opinionated to the point that it deviates
       | from the concept of a miatake. A better title would be "what I
       | think css gets wrong."
        
       ___________________________________________________________________
       (page generated 2021-01-24 23:00 UTC)