Why is CSS the way it is?
increment.com
increment.com
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 fundamental concept of CSS (best revealed by H.W.Lie's thesis IMO[1]) was to create a rich and versatile and non-Turing-complete set of structural selectors in lieu of DSSSL's recursive logic, and to allow styles to overlay one another; 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.
To win a sizable portion of HNers, it suffices to say that DSSSL was the Scheme-based styling and transformation language of SGML (implemented by Jade/OpenJade). I can only imagine where we'd be now if DSSSL had won over CSS and similar FOSI-like ad-hoc styling languages (or even SGML's own LINK process declarations that however was kindof questioned by James Clark seeing the need for DSSSL). Personally I'm not into Lisp, but I'm very much missing the Lisp community's relentless search for ultimate simplicity, clarity, and expressiveness in the design of CSS.
We probably wouldn't have dynamic HTML then.
DSSSL is basically the same idea as the XSLT/FO where document in semantic markup is transformed into a different purely presentational markup language (like PDF if it was SGML-based). It is a one-way operation on the whole document, and made totally sense for the intended use case which was to prepare document for print publishing.
Conceptually, I have no issue. Tree-to-tree transformations is a perfectly good concept and you use them a lot, especially if you do work that involves a lot of ASTs, for example. But the specifics matter, and XSLT was designed to be infuriating and punishing and the tools are terrible.
Or if Brendan Eich had prevailed when he wanted to embed Scheme in Netscape instead of Javascript.
https://www.crockford.com/little.html
Javascript is pretty much scheme or lisp.
Not being in this world, though, I do wonder why there's been no real attempt to fix this from the ground up? I mean... it wouldn't really be "hard" to come up with an alternative metaphor for styling a tree of DOM fragments that compiled to CSS where needed but could be implemented as a first class technology with a proper specification.
Modern browsers have multiple competing implementations of all sorts of other technologies. Why has no one tried to do a new style language? What should it look like?
FWIW, tailwind solves this problem (in a tedious way).
Aren't global styles only possible because of the cascade and the child elements inheriting from parent elements? Without cascade, wouldn't you have to re-declare your font size and font family, and line-height, etc. on every element of your markup?
.big-list > li {font-size: 200%}html:
<div><a>Blah</a></div>
css: a { color: red; }
div a { color: blue; }
Where the font color ends up being blue because `div a` is more specific than `a`. a { color: red; }
div { color: blue; }
(Blah will be red now.)(I have little knowledge of CSS.)
div { color: blue; }
without any definition for what 'a' element color will be, it ends up having the color blue because it inherits it.
this is of course why we have the inherit keyword https://developer.mozilla.org/en-US/docs/Web/CSS/inherit so you could do
div { color: blue; }
a { color: red; }
.myspecialdivclass a {color: inherit}
where myspecialdivclass has the default color of blue and as a result the a elements in it will inherit the color.
all that said, inheritance and the cascade sort of leak into each other since they both affect what properties are set for individual elements.
on edit: formatting
1. create a serious styling and scripting framework, basically React as a language since people seem to like it 2. implement an interpreter in WASM. Ship the interpreter with the website unless the browser says not to 3. over time, build the interpreter into the browser
Haha, so sorry, but: no.
And if we're starting over, when just start at the web stack?
Almost all browsers are Webkit based, and there a very few browsers in use (Chrome/Firefox/Safari) which should ease the transition. I can't imagine all the wasted time and energy the world is putting into the current state of the web. A new standard would make navigation more performant, snappier, more responsive and much more reliable.
https://godotforums.org/discussion/21963/early-access-of-god...
For example?
Problem: in reality, it is unworkable and will never happen, and even if it did the actual level of "development" that we actually see in the real world would end up in a situation just as bad as the situation we are in now.
It’s like the designers didn’t even think about layout because that problem was already solved with HTML tables. But the problem was that when CSS came out there it came with the mantra of thou shalt not use tables for layout, but CSS was only specified enough to wrap text around an image, so designers had to torture inline-blocks and floats to try to achieve even basic layout tasks. This ended up bringing out a lot of edge case incompatibilities and fights with the layout engine. CSS had made the hard things possible while making the easy things hard.
It took decades before browsers finally supported CSS grids. A feature that should have been in the spec on day one.
As for those Unicode filters the syntax barely matters. Anybody who needs one is going to Google the magic string for their language and paste it into the document. Nobody wants to build one of those from first principles. That’s true of anything Unicode related—-it’s too complex with too many weird edge cases for mere mortals to handle.
I think flexbox covers 'most' folks layout needs fairly easily, and you can learn it fairly easily and get a lot out of even basic flexbox knowledge.
Tables for layout were horrific. We talk about div spam these days but at least they're all just divs and divs follow divs rules. Unlike divs table, tr, td are all different and don't follow the same rules. And the result of table layouts was table inside tr,td in another table and in another table is its own nightmare and gets ultra inflexible and could require whole hog layout changes just to move a widget if the widget was just a bit too big. Tables were horrible.
Just flexbox day one would have been amazing.
Granted I'm mostly working on business apps, not a lot of complexity there layout wise, flexbox works great for that, and it's not a heavy lift for someone to learn it.
Grid is absurdly more powerful for full-page layout than flexbox (which is amazing for individual columns or rows). Especially once we start getting subgrid. The common comparison is 1 dimensional (flex) vs 2 dimensional (grid) layout.
Tk (https://en.wikipedia.org/wiki/Tk_(software) ) first appeared in 1991. It predates the web. It had efficient and powerful layout managers from the start: http://zetcode.com/gui/tcltktutorial/layout/
The web basically offered... nothing. It just ignored everything else going on.
This does not match my recollections of CSS in the mid 90s.
My recollection is that people in general just laid out a document like you'd lay out a word document, and as such the minimal amount of floating that people did was not that difficult.
I recall a) when table-based layouts became very popular, and b) when they became very unpopular and we had to start doing all kinds of funky things with float to avoid them.
But returning to the birth of CSS if all you want to do is to put an image in a word processor do and have the text wrap around it, float is not too bad. If you want to design a layout system around it, it sucks.
So, like, to understand "why floats" in a historical sense, it's important to understand that the kind of layouts that tables (and yeesh, I can't even remember what they were called... frames maybe) were used to achieve didn't exist when CSS was first being used...
it was more like the generic tools in a basic rich text editor.
Secondly, the later 'thou shalt not use tables' edict from the sort of people who actually joined the relevant W3C committees came after a few years of ubiquitous table use due to the limitations of CSS, but more importantly several years before Flexbox and Grid were even draft specs [other unsuccessful drafts existed]. People used tables because CSS wasn't good at the sort of layout they wanted to achieve, and in response W3C members... told them that tables were evil to screenreaders and they should suck it up and use hacks for at least the next decade
Arguably floats weren't well designed anyway (floating an image inside a box was all kinds of trouble except in IE which disregarded the spec's insistence it was supposed to overhang the bottom) but there was already a case for a proper grid and even that's comparatively minor compared with the 13 year gap before the draft spec for the next gen layout syntax.
This is an unfortunate misunderstanding. CSS did initially aim to provide at least same expressive power as presentational HTML allowed at the time. So it provided the display:table layout model so designers didn't have to use HTML tables for layout. Unfortunately Internet Explorer (which was dominant at the time) did not support this property for a very long time.
Floats were never intended as a general purpose layout tool, but ended up like that for designers which wanted to use pure CSS but at the same time had to cater to IE users.
While flexbox and flexgrid are more powerful and flexible, display:table actually support a lot of the layout functionality designers were clamoring for, like easy to implement expanding sidebars and such. The problem was not with the CSS spec but with the lack of support in the dominant browser.
And then a-list-aparts "faux columns" to make the columns seem to have the same height.
Edit: It was the "Holy Grail" it was named https://en.wikipedia.org/wiki/Holy_grail_(web_design) So hard to do that it even has its own Wikipedia page, heh
The final chapter, in a "putting it all together" style spent most of its time om a holy grail layout.
If I was writing a modern CSS book, this topic would be somewhere in the second quarter in a chapter on grid and flexbox.
Tables - instead - needed the whole chunk to be rendered. i believe this reason is still valid!
Also, it would have been nice if HTML supported the concept of data fields WITHOUT explicitly needing javascript.
HTML could also have allowed for an easier way of specifying different layout types without going into CSS wizardry to support responsive layouts.
For instance, something like the one below where data fields are specified in a separate block, reusable components in another and then finally the actual layouts.
#Data blocks here
<data>
<d name="selectedCity">1</d>
<d name="cities">
[(1, "Barcelona"), (2, "Madrid")]
</d>
<d name="languages">
[("es", "Spanish"), ("en", "English")]
</d>
<d name="nav">
[("Home", "/index.html"), ("Profile", "/profile")]
</d>
<d name="posts">
[{title: "Title comes here", content: "Content comes here"},{title: "Title comes here", content: "Content comes here"}]
</d>
</data># Reusable components here
<components>
<component name="header">
<select id="languages" value="es">#options($languages[0], $languages[1], "es")<select> <!-- Built in handling of options list for select boxes-->
<select id="citySelector" value="$selectedCity">#options($cities[0], $cities[1], $selectedCity)<select>
<div id="navigation"><nav>#links($nav[1], $nav[0])</nav>
<!-- Built in handling of Lists of links etc -->
</div>
</component>
<component name="blog">
#foreach ($posts : $post)
<h1>$post.title</h1>
<p>$post.content</p>
#endforeach
</component>
<component name="footer">
<span>Copyright Company.com</span>
</component>
</components><layouts>
<layout res="(1280, 800)" default>
<!-- use whatever styles of markup needed without worrying about how it impacts another layout - use divs, tables or whatever-->
<block component="header" id="header1"/>
<block component="blog" class="blog"/>
<block component="footer"/>
</layout>
<layout res="(1920, 1080)">
<div...>
<!-- Style for this specific layout -->
<block component="header" id="header1"/>
<block component="blog" class="blog-fhd"/>
<block component="footer"/>
...</div>
</layout>
<layout res="(1080, 1280)">
<table>
<!-- Style for this specific layout. Use tables if needed. Use whatever html markup as needed -->
<block component="header" id="header1"/>
<block component="blog" class="blog-fhd-rotated"/>
<block component="footer"/>
</table>
</layout>
...
</layouts>I kinda like it (although some things could be even a bit more powerful), yet everybody I meet tells me how horrible and hard etc it is. I never had that feeling at all, not even back when I started using it as a teenager to customise my MySpace site.
I cursed at how hard common things like centering a image within a div were, I cursed at the purposeful and ignorant incompatibilities of different browsers, but with CSS3 I was sold, even more so when grid based layouts and flexbox became a thing one could lean on.
The one thing that I miss is a little bit more power when it comes to selectors. E.g. there is no way to select a <p> which has only a <img> as a child, which is coincidentally something that a standard conform markdown to HTML converter will produce. So you cannot — say give your <p> a max-width of 120ch without also limiting the width of the <img> contained within it. AFAIK there is a parent selector planned that might address this if I recall correctly.
Could you expand on this a little / give an example?
If you have the time to learn CSS, you have the time to learn anything else. ;)
Part of the problem with CSS is that we seem to relegate it to something we don't need to learn. "Well, it's just CSS. I'm a developer!" And then we complain when we don't understand it or when our jerry-built sequence of StackOverflow copy-and-pastes is a clusterfuck to deal with.
I myself realized I was working off knowledge I read in a CSS book I read in 2004, so I committed a week of updating my knowledge on my own. I realized very few people actually do that, as I'd easily gone 15 years without doing it, and even with my 2004-level knowledge of CSS I'd always be amazed when a fellow 30-yo web developer didn't know how you can offset absolutely-positioned children inside a relative-positioned parent or something just as entry level. Just like, until recently, I'd probably amaze someone that I didn't know what the rem, vh, and vw units were.
Edit: of course it's worthwhile to learn enough CSS to understand more or less what it does since it's so pervasive. I mean that using it as the main way to lay out pages is a frustrating experience in many cases.
So what is your point? What you lack is motivation to make things pretty so it's not CSS's fault :)
Here lies the problem. If you fix your mental model, then your layout won't fall apart.
It's the same as in any other language. Haskell doesn't match my mental model, but it's not the programming language's fault.
SVG is just scalable vector graphics, like Postscript which is the basis of PDF.
Css has semblance of system, but mostly it us a lot of rules with no rhyme slapped together.
All the devs I know that struggle with CSS don't understand it. The ones that don't have issues have internalized it and don't need to think about it much anymore.
The box model is one of those fundamental building blocks you really should be learning very early on, a bit like an "if" statement in imperative languages - you can hack around it with ternaries and single-iteration loops, but you're never going to be as effective or have as strong an understanding of the language as you should.
The :only-child pseudo-class selector property in CSS represents an element that has a parent element and whose parent element has no other element children.
on edit: sorry I got confused and dropped your requirement to select the parent.
People who call it horrible in my experience often just didn't really take the time to learn it properly. For me to handwrite the CSS for a normal sized personal blog takes maybe 6 hours if I do it from scratch with mobile support etc and most of the time goes into little design adjustments that have nothing to do with CSS. As I said: to me it is not great, but it doesn't really get into my way too much either.
I dread every time I have to touch web or create web stuff and while I loathe JS it’s the CSS I fear.
Personally, I'm against adding any more complexity to CSS, though; and :has fundamentally changes the locality/algorithmics and complexity of CSS selector matching. I think if the goal of CSS was to bring good-enough styling to the masses, it has utterly failed to so, yet has left a legacy of overcomplicated and badly specified ad-hoc styling rules that don't compose to a reasonable whole. CSS is what you get if you're starting with a disruptive mindset at a welcoming phase in an innovation cycle, then just can't stop to add features. I personally know several graphic artists who did fantastic professional animations using sprites (and also Flash), yet couldn't make sense of CSS, at all. To become proficient in CSS, you need years of learning a non-type-checked and bogus hell of half-assed and half-implemented bloat. As a Comp.Sci. nerd, I also question the notion (ie nonsense) that "HTML is for structural semantics, and CSS for presentation"; the reality is that HTML, it being based on SGML, has excellent support for vocabulary evolution. I mean, look at CSS: it's an item-value syntax (sans the selector part). In which world does it it make sense that, starting from generic markup with lots of syntactic features (elements, attribute), to come up with yet another syntax for specifying item-values? Specifying hundreds or thousand of microsyntaxes does not an inherently procedural layout system make, and there were much better styling languages for SGML available. To adequately describe layout mechanisms, a constraint-based formalism makes much more sense.
Agreed. For instance instead of creating the flexbox display, it would have been much nicer to version it out into CSS4 with center aligns, vertical aligns, and a few other things fixed rather than continuing to add new concept layers and increasing the complexity.
It's been long enough I don't remember the details of that earliest method, but even before flex/grid that layout was easy with calc().
Live demo: https://codepen.io/bradleytaunt/pen/LYGapao
Of course, I'm a dinosaur. I still don't know nearly as much about flex, CSS grids, etc. but i actually have very few cases where the CSS that worked 10 years ago doesn't work today. Flex just makes it much easier, at the cost of adding multiple ways to do the same thing. IMO there's a real cost there. I try to use it minimally, but newer devs like to start with flex first.
To basics, this selector
p > img { display:block }
has O(0) complexity (+/-) - for any IMG element you can instantly tell if the selector applies to it. By inspecting its tag and tag of its parent (any element always have valid parent).But this selector:
p:has(> img) { display:block }
has complexity O(N) - in order to test applicability you need to scan all N children of the P.And now consider some JS code that does this
p.append(<img />);
If we would have that :has() feature then that simple statement will force rescan of the whole DOM tree. That will lead to O(N*N) complex updates.> If Builders Built Buildings the Way Programmers Wrote Programs, Then the First Woodpecker That Came Along Would Destroy Civilization
Programmers who write browsers do care about such things, trust me. We have plenty of creative Web desickers who are managing to push browsers to extremes already ...
Additionally, there are often many ways to accomplish the same result but fully understanding the implications of certain approaches over others is also a headache at times.
Speaking personally, something touched on in this article, is that many things don't really make sense to me or at least I don't find them intuitive - and I've been working with CSS daily for 14 years. It does often feel like a scatterbrained, horse designed by committee type of thing.
It's like CSS only makes sense when you learn to see the problem through the eyes of whomever specced out that particular feature, which can also be said for trying to read CSS written by another developer.
And whoever those were, they never ever care about creating a GUI, embedding documents within documents, or reacting to user actions.
..that they haven't looked at it for years and assume it's still as hard to use as it was when it was new. In any discussion about CSS someone will eventually post that "vertical and horizontal centring is really hard, and that's why CSS is terrible"[1], and all it shows is that their skills are out of date.
[1] Seriously, it's as easy as "display: grid; place-items: center;" these days (if the element has width and height somewhere in the cascade).
For example, I probably always want h1 elements to have the same font/weight/size. That's style, and should be defined on the h1.
In contrast, the h1 within a blog post may be positioned very differently from the h1 within a video page, so I'd want to define that in the blog post and video page styles, respectively.
Of course, where this gets complicated, is that there's not always a clear boundary between style and layout. For example, I might always want the same amount of space under the h1 between the h1 and the content it titles (style?) but the top/left/right spacing is probably more dependent on the context (layout?). There are some hard to communicate tradeoffs here.
Simply said, that what style sheets communicates are mere suggestions for appearance: browser has its "default" style sheet, users can set their own set of rules, author sets their, but user and browser still have control what author can and cannot change.
I see this "origin specificity" as very important fundament that explains a lot about the way CSS emerged and evolved. This bit of information, however "obsolete" it may feel nowadays in age of web applications (but not obsolete standards-wise), is perhaps too obvious to most professionals, yet I see it omitted from learning materials, or dug very deep in them.
(Sorry for repeating myself here at HN, and sorry if I overlooked it in the article, I admit I've just skimmed it searching for this exact piece of information.)
the corruption of the net is proportional to the corruption of the tools. a shame really.
- No way to style according to siblings. This is a big mental model shift. Often times I want a div to be the same height as another div. Since CSS doesn't really allow sibling communication, I need to get the parent div to set the height and then tell the children to play along. Or manually set the height on both children.
- Error handling is so so bad. It sucks to have your styles break silently due to an errant comma or space. Well typed styles like bs-css[^1] have made this somewhat tolerable.
- The weird tug of war between positioning yourself versus positioning your child. I understand the reason for both but it's offputting having both as an option.
- Lack of z index positioning. Often I want to superimpose one element on another, say a caption on an image. Right now I need to resort to position absolute, then do the standard dance to center something by computing 50% + half the size of the overlayed element. Not fun. I'd love a flex-direction: into-page that does flexbox over the third dimension. It'd be a little tricky to understand but honestly not too bad.
What's weird is that in some ways these issues have gotten worse with components. Since I can reuse a component, I now need to think of how its styles will work in every usecase. For instance I had forgotten to set my component's background to white, since it was already white by default. When I moved the component to a blue background, boom, it became garishly blue. Of course this is my bad, but it sucks that we have to carefully engineer our styles such that moving a component into a new context won't screw it up.
- Layout and typography which can be readable on various devices with wildly different dimensions, aspect ratios and resolutions.
- Incrementally rendered (i.e. the start of the document can be rendered before the whole document has been loaded)
- Allow users to enlarge the text size while keeping the text legible. (In a PDF you can zoom, but then you will have to scroll vertically back and forth for each line.)
- Backwards compatible with the display model of pre-CSS presentational HTML
No other technology exist which solves all these problems. If you ignore one of more of the above constraints you can probably devise a simpler and more intuitive styling language.
No more LESS or SASS, no more .header-container, .header-parent-inner crap.
https://adamwathan.me/css-utility-classes-and-separation-of-...
I'm sure some puritan naysayer will disagree but whatever. I value design system focused and productive styling for frontend. It works very well.
The end of the article comes to the same kind of conclusion (use multiple classes), while also using CSS as a style standard. But the beginning shouldn't even be an option.
Say you design a new relational DB. You want all the postgres and SQL people to switch so you adopt SQL as the querying language. Your DB becomes so popular that it eventually gains +80% market share. Many people now have to learn SQL as their first querying language and now you've created another git.
Another scenario is a system being appropriated for something else like CSS was (?).
Copying your competitors is simply not a guarantee that your system will stand the test of time. The only constant is nature.
It makes me wonder if it's even possible to design a language that's both easy for abject beginners, while simultaneously being powerful, expressive and productive for experts at scale. Is that even a topic of study in language design?
Sure, everything has gaps, and fans are the first to point them out... but CSS fans always have a lot of fuel to bring up in the flaws dept.
It's starting to feel like css is approach emacs/vim level of argument-starting tinder.
Is that because it's so good, or because we are stuck with it?
Languages like Lisp, Scheme, or Forth have both a selection bias (mostly used by fans) and they just aren't that widely used. If millions of people were writing code expected to run with a standardized API on billions of clients where it might take 5 years or more to drop support for an old version, they'd find more things to complain about. It's not a coincidence that the best thing which happened to CSS was the rise of the evergreen browsers shaving years off of the time between a feature being released and someone being able to rely on it existing.
https://www.youtube.com/kepowob/featured
I learned some obscure CSS features from him.
Nowadays, I see mixing of styling and content to be all the rage, which I actually feel is easy to use. Of course, component systems still split out the styling and document markup, but the line, and developer thought procress is a lot blurrier.
I would love to know if there are any better systems of presentation, compared to the document + markup paradigm.
CSS is not the only victim of this approach, just particularly bad case.
These are resources I used to learn grid and flexbox. http://cssgridgarden.com/ http://flexboxfroggy.com/
The site I inevitably have open looking some how to do something with css https://css-tricks.com/
https://package.elm-lang.org/packages/rtfeldman/elm-css/late...
https://github.com/reasonml-labs/bs-css
Or even a typed alternative to/subset of CSS:
https://package.elm-lang.org/packages/mdgriffith/elm-ui/late...
Because all its original creators were programmers and didn't think to invite even a single person who'd ever worked an hour on visual design. Check on Wikipedia, it's unbelievable but true.
The above statement makes me question both the sincerity and intensity of "best efforts."
Rather, it's with the way people use it.
For instance when working with a code base handed over to me for maintenance, it's often been the case that the code has already passed through several previous developers/companies. And a lot of those people have fixed presentational bugs over the years by adding !important rules in various places across the various CSS files that contribute to the site. It drives me nuts! Also: commenting out huge swathes of CSS code in a file, but not deleting it ... just in case it's needed again. Why??
The other thing that concerns me is the way new functionality gets added to the CSS spec. Take animations - do they belong in the CSS code, or Javascript? Yes CSS animations are (generally) faster, but the more complex the animation, the harder I find it to understand a CSS implementation. And it's gonna get worse in the future thanks to CSS Animation Worklets, which are being developed as part of the CSS Houdini thing.
There comes a point when I have to decide: CSS or Javascript. I can't keep up with developments in both, and I enjoy coding Javascript more than CSS. </end-self-pitying-moan>
It was the player that wasn’t great.
(i'm interpreting 'flash websites' as 'websites made in flash'. i'm not referring to websites that contained flash applets.)
Most of the flash sites that I really remember consuming were actually very simple documents that relied on flash for presentation, so it would be easy to provide a screen reader friendly version of the content.
Also a lot of flash content was cartoons and games which don't lend themselves to screen readers anyway.
This however also lead to an abuse and for a while you had websites, fully in flash which broke so many things (deep linking/bookamrks, browser history, etc.) combined with unintuitive navigation and slowness due to animations ... plain overuse of an otherwise good technology.
Truly we have failed to learn from past mistakes.
I took a 3 year break from anything Frontend. Felt like I had gone through a time machine.
And the standard libraries, cross-platform support, and industry-trailing IDE. They didn't even have a stable debugger for years but that didn't stop them from charging $800/seat to see if they'd fixed any of the problems.
So your solution is to dig the hole even deeper?
He he, that's a funny link. We know the end-state of absolutely unfettered capitalism :-)
We've had it, that's why they invented the guillotine. It was called "feudalism".