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.
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).
> 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).
I dunno, much as I dislike CSS and its lack of useful modularity, it's never something I'd describe as "write-only" or "unusable". The selector syntax is fairly nice and concise and the cascade of properties works as one would expect (most of the time). I doubt CSS would benefit from throwing some SGML at it, because CSS is fundamentally just a list of selector-property pairs and not a mixed-content document.
The real problem with CSS is two-fold: first, the users of CSS have turned the class= attribute of HTML into an awful ad-hoc inline styling language (with the requisite awful and nightmarish stylesheets). And second, there is a huge amount of legacy cruft because it took 20 years of evolution for us to finally figure out a sane document layout model.
The non-Turing-completeness of CSS has a very very useful attribute: given a parsed stylesheet (a styling tree where selectors are nodes and properties are leaves) it is possible to annotate an HTML document with the correct style properties in a single forward pass without backtracking! That's because everything in CSS is done strictly in accordance with document order. It's not possible for an element to change the styling applied to any elements that precede it in the document.
I've clicked the first five google search results for "DSSSL" and not one of them dares to show an actual example of DSSSL code. I think that says enough.
Well, it's a Lisp. Complaining about the syntax tends to suggest less about the Lisp than about the person complaining, viz. that they have not learned Lisp, or that they have and did not enjoy the experience.
By the same token, if we go searching for code in a 20-years-dead language and make wisecracks comparing some random sample, to something that's had many years of development since; irrespective of whether it is representative (and it isn't, particularly), this still doesn't say much about what might've been. As a more equal basis of comparison, I remember working with the CSS and HTML of twenty years ago, and this was invariably excruciating. The CSS we work with today is the result of two decades of polishing, and it's still mediocre, inconsistently implemented, and still riddled with issues and oh-for-heavens-sake-why-can't-it-just-do-X moments.
Back to the point, however; the canonical DSSSL application was DocBook, and we can still visit the much more lovely DSSSL source at its resting place in https://github.com/docbook/dsssl.
It's not so much the syntax as that I have never once thought that I wanted an imperative stateful language with variables and loops (!) for applying styles to the DOM, instead of a declarative one. And it seems like a disastrous idea to me.
And I haven't been thinking this for 20 years or something set in my ways, I was previously only vaguely aware of this "controversy". In fact, while you suggest the unfamiliarity or dislike of Lisp syntax is behind opposition, I think it's probably the reverse, most of the people (especially in 2020) pining over DSSSL are specifically those in love with Lisp who were hoping it would make it an again mainstream technology -- I'm going to reverse it and say your advocacy is less about the idea of using a full programming language for HTML styling and more about just liking Lisp and wanting an application for it.
But also, sure, syntax matters for technology accessibility. It is arguably inappropriate to require someone to "learn Lisp" in order to style HTML.
(I did learn and enjoy Scheme in undergrad CS curriculum long ago, I admittedly haven't used it since).
> less about the idea of using a full programming language for HTML styling
And yet, here I am in 2021 writing an execjs wrapper to compile Tailwind via Sprockets because of how much I've come to loathe Webpack.
> more about just liking Lisp and wanting an application for it
Well, yes, or rather more specifically Scheme, and I do believe that was my opening confession in the top level comment.
> It is arguably inappropriate to require someone to "learn Lisp" in order to style HTML
And it never should've been so, and it didn't need to be so with DSSSL either, because how much further might we have come in twenty years with an underlying language that wasn't basically hobbled out of the gate? Yet styling HTML with raw CSS is still programming, requiring knowledge of tree structures, a vast and ever-growing array of selectors and pseudo-classes and properties, recursion, priority ordering, an expression syntax not a million miles from S-expressions, the HTML DOM, four or five different box & layout models, and typography, not to mention all the browser quirks; oh, and - in practice, let's face it - Javascript; and yet 2 out of 3 major browsers still can't consistently size & center a top-level absolute block element, !important is the standard voodoo prayer for many, and fixing misbehaving CSS is basically debugging but in a language that lacks almost any first-class construct that might help.
So after all this further reflection, and notwithstanding that I've built up tons of valuable-in-practice crystallized experience in bending CSS to my will, I'm even more irked about the way things turned out.
> It is arguably inappropriate to require someone to "learn Lisp" in order to style HTML.
It's entirely appropriate to require people to learn something new, like a Lisp-based template language instead of HTML, if you're paying them to do a job.
Requiring people to learn stuff for a job is one way that shit languages proliferate; why deny that advantage to others?
There's XSL:FO which allows you to transform XML into PDF documents, and you would not want to be writing that every time you wanted to add some basic styling to a webpage:
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.
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.
> > 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 ~).
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.
It would have nudged people in the direction of using direct descendants much more of the time, which is a Good Thing, as they are far easier to optimise, and are much less likely to match things by accident.
That would have made applying broad strokes design choices much harder, and is generally less useful. CSS is general-first, specific second. Making people use direct descendants more often would make stylesheets more verbose and complicated. It would have stymied the power and expressivity of the language.
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.
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?
SCSS seems like it gets out of control after a while though without rigor from the developers. The last app I worked on had a half-assed SCSS approach that started off with a decent base, and then got tacked onto with a ton of ad-hoc styles that weren't nested where they "belonged." Inconsistent usage of paddings/margins everywhere. It was a mess.
At some level, this is unavoidable and just something to get used to. But those longer selectors can be mitigated somewhat with a sane CSS methodology. One of the benefits of CSS is that there are 100 different ways to achieve the same result—and I personally wouldn't trade that for a more opinionated CSS spec.
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.
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.
Around 1997 (basically when CSS first came out) many books praised the default box model as sensible and disparaged the border-box model as IE's bastardization of CSS. People hated IE so they hated IE's broken box model.
IE had better CSS support than anything else up until they froze IE6 and eventually Firefox (Chimera!) caught up and surpassed it. The hatred of IE came because it was frozen and non-standard and full of bugs. It wasn’t that the default box model was ever good, it was just that it was the spec, and there was a big push to follow the spec instead of blindly copying bugs from other browsers. At that time, we also thought XHTML was a good idea, but eventually experience taught us how to balance the spec with practicality.
'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
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.
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.
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.
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.
As a viable option, I'd like to see absolute coordinates* added to HTML/DOM/CSS so that we can pick a layout engine of our own choosing on the server side. The server-side engine would do the layout calculations and then pass raw vector coordinates to the browser.
Trying to be everything to everybody has made CSS an inconsistent bloated buggy mess. If we had the above, we could have domain-specific layout engines that trim features and behaviors not needed by the domain, and reduce the problems of client/browser differences since the real work is done on the server. I'm not saying do away with existing browsers, just allow off-client layout engines when desired.
* (Yes, CSS does have a rough notion of absolute coordinates, but it's too screwed up to be practical. If it worked right, we wouldn't need the PDF standard.)
I just straight up think short hand properties the way they are designed are a bad idea. I've been writing CSS for about 15 years at this point, and I still can't remember the order of any short hand, I have to look it up every time, so I just type it all out instead. At least then I know what I'm looking at when I look at the code next time 'round.
I'd rather see something like named parameters, e.g.:
So, I'm sitting down to create CSS ... what does the browser need to do first: margins on body ... which of them comes first as you scroll down: the top of the body ...
If you came from print publishing, and assume that the browser handles the gutter spacing with defaults then it might even be argued that the right margin should come next!
It's just something you have to learn, none of the options seem more logical to me.
Note I first wrote HTML using pico on a Sun workstation in ~1995; developing with the developments in web development probably causes one to develop strangely. Or, in other words, it's hard to take a fresh view when you've had to deal with IE5.
Maybe someone that looked at a clock or compass? TRBL matches 12o'clock, 3o'clock, 6o'clock, 9o'clock. It also matches N E S W going around the circle
I agree that I'm more familiar with left being first but then should it be LRTB or LTRB. LRTB is common to say. But many APIs take x,y first which would arguably be LT.
Basically I think you could justify almost any order
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.
Not exactly CSS's fault but I'm definitely in the "img should be a block" camp. It's what people expect almost all of the time and would prevent people new to web design from diagnosing the small gap left underneath despite removing margins.
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:
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.
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.
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.
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?
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.
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.
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
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.
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.
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