This is a somewhat superficial history that only briefly touches on origins, and doesn't discuss the fundamental idea behind CSS, 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 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.
Wow, I'd absolutely love to hear more about this if you've got something to share ...
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.
> I can only imagine where we'd be now if DSSSL had won over 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.
I did a lot of XSLT at one point. I think if I still had to do it I'd need to be on medication.
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.
Except it isn't. JS has lexical closures, but that's not the only feature that makes Scheme what it is. JS got one thing right and about a dozen other things very badly wrong.
Don't forget the gigabytes of code spent trying to work around the cascade and produce some kind of framework for styling "components" that doesn't leak crazy state from the enclosing context (but does inherit the good stuff). The "cascade" was, for sure, a mistake.
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?
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?
Replying to myself: What if you want to have a link or a span inside your list though? Wouldn't it look weird if they have different size than the surrounding text?
The cascade is what makes it possible to override parts of a stylesheet. Without this, each stylesheet would have to define all styles for every html element in use. It would be an enormous amount of boilerplate in each and every stylesheet.
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
James Mickens has a talk about doing exactly this [1]. It's a perfectly sensible proposal and the talk is well worth the time to listen to. He makes a solid argument for why this should be done.
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.
I think it would worth it to start over with today's knowledge. The whole stack is garbage: HTTP should be replaced with HTTP2 or Quick, vanilla Javascrip is horrible, CSS feel even worse, HTML is not too bad.
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.
There's a lot I agree about starting over, but perhaps one of the main features of the web is its backwards compatibility. Most often when things are built from scratch, they fail miserably, unless one entity has full control of the entire stack. Unfortunately, that doesn't really describe the web. We're kind of stuck with a mess.
I have a really dim recollection of an IBM WebExplorer variant that had limited support of DSSSL but it may have been tied to the work we were doing with HyTime. None of the interesting WebExplorer variants ever saw the light of day in public and it was killed fairly quickly by neglect.
IMHO this article inadvertently shows why people hated CSS at the start. He spends a lot of time talking about color space conversions that few developers care about and Unicode filtering that even fewer people know about but glosses over basic layout by mentioning how floats allow for better inline images.
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 remember spending ages on various ways to implement "the golden layout" or whatever it was called. Edit: Holy Grail. One header on top, then three columns, and then a footer. And the middle of the three columns should scale with screen width and screen height, such that the rightmost column was at the edge, and the footer was at the bottom of the screen if content was less than screen height.
And then a-list-aparts "faux columns" to make the columns seem to have the same height.
I have a CSS book from that time, one I kept too long because I felt it was one of the better CSS books in its time and hasn't been replaced as I keep a certain amount of books for decorative purposes and haven't bought new development books in a while.
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.
".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."
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.
I think there's two separate issues. Firstly they really ought to have been able to anticipate the need for more precise layout tooling by late 1996. Sure, the web was a much more flexible looking place, but grids for high profile commercial sites like AOL and Space Jam already existed, and it's not like they didn't have decades of print layouts to learn from.
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.
> 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
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.
display:table; doesn't actually replace table based layouts though, because it can't do colspan/rowspan, even today. Ran into this when trying to make a table (containing actual tabular data) responsive
Heck, I would have been happy to have had flexbox day one.
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.
I often use grids when flex would do just to take advantage of the grid gap features. Once the more general gap feature lands in most browsers I’ll probably start using flex more again.
Yeah there's reason to use grids, particularly if you're comfortable with them. I like to start with flexbox if I don't know where things are going / I'll need grid and .. surprisingly I rarely have to move on to grid.
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.
I too am looking forward to that. 99% of the time `&>:not(:last-child) { margin-right: 4px; }` does the trick, but that 1% (usually wrapping) normally leads to compromises.
It's not really 1 vs the other IMO. I use flexbox within grid quite often, for example. They're two different tools with some overlap...
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.
wish I could use grid yet, I'm still supporting ie11 and safari 9 (i know ie has a janky grid prototype, I would maybe even put up with that if safari worked as well)
Counterpoint: I think that if we'd solidified flexbox or grids too early, before people started making full-fledged single-page apps with toolbars and sidebars and panels oh my... we might have easily missed crucial use cases, and the "anti-table war" turning into the "anti-flexbox war" might have shattered the ecosystem. And the inevitable "display: flexierbox" to fix the shortcomings would be a recipe for disaster. With such high bars for backwards compatibility, it's good that we moved slowly.
Not denying there was plenty of innovation in the layout manager space. But it's very possible that the standards committees for browsers weren't looking to those for inspiration at the time, especially before Gmail showed what was possible. Of course they might have done everything right, but just noting that hindsight is 20/20.
These kinds of layouts were incredibly common on the web by late 90s already. I remember wondering back then why all the desktop UI frameworks (it wasn't just Tcl!) have such flexible and powerful layouts, but HTML/CSS does not, even though it would obviously help solve a very common need.
Table-based layouts are basically really practical for layouts. It could really have been extended to make it more styleable and also to allow for stackable columns and more responsive layouts instead of whole sale replacing them with CSS and DIVs.
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.
<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>
...
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.
There's the experimental :has pseudo-class which appears to be doing what you want [1].
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.
> a legacy of overcomplicated and badly specified ad-hoc styling rules that don't compose to a reasonable whole
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.
You can't work out the logical consequences of seemingly obvious properties. That is unlike 95% of most programming I do in any programming language I've ever used. Since I have zero interest in learning unintuitive interfaces to GUI design, I have zero interesting in excusing CSS. It is not difficult to learn, it is not difficult to understand in terms of conceptual understanding, it is downright tedious to learn though - and you don't get anything unique out of it that can't be done in anything else: you get a nice looking website. Amazing.
Probably because very few learn CSS right. In particular: the box model.
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.
I keep seeing this excuse, "If you don't like CSS you must not understand the box model". The box model is easy to understand but it still doesn't make CSS good.
This is more like saying you don't need to learn algebra and then saying you hate math because it takes too much work to get the answer you need. A surprising number of developers are under the mistaken belief that not learning how the web works is saving them time and over the years I've been amazed by how many people will instead unquestioningly spend years playing bug whack-a-mole with megabytes of JavaScript sturggling to replicate built-in behaviours.
You've said everything I wanted to say but I wasn't able to express. CSS is nothing like programming. I am a decent programmer and I can write actual code in virtually any language that's new to me, in minutes. CSS is always tedious and God forbid I don't use it for a couple of months - then I've got to go back and re-learn everything. I'm on my fourth round of re-learning about CSS because I'm not purely a front-end developer.
For me the hard part is remembering all the arbitrary rules and special conditions. Most tech "makes sense", once you get it it has system that helps you to remember stuff.
Css has semblance of system, but mostly it us a lot of rules with no rhyme slapped together.
Though any self-respecting web developer should sit down and learn CSS.
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.
It's a terrible waste of time if you can find a good alternative. Luckily Elm-UI is exactly that.
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.
My point is that there's nothing in CSS that's exceedingly difficult to understand once you sit down to learn it - it's that you're often sitting down to learn things that are entirely idiosyncratic to CSS and act as impediments to creating anything beautiful. I could abandon CSS and use SVG to create prettier things pretty quickly, because although SVG has some gnarly parts, programmatically manipulated it makes much more sense. CSS is designed to solve different problems to the ones I often want to solve in isolation - i.e. it's document oriented as opposed to element oriented, if that makes sense. Then I'm dealing with the interaction of specific elements and document flow and everything is liable to fall apart the second some mismatch between my mental model of layouts and CSS's actual model occurs. At least it's getting better, as gradual as it is.
> Then I'm dealing with the interaction of specific elements and document flow and everything is liable to fall apart the second some mismatch between my mental model of layouts and CSS's actual model occurs
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.
Haskell's problem is that it's so consistent (e.g. in enforcing purity, to the point of frustration for common tasks), if you don't understand it, you won't get anywhere. CSS's problem is rather the opposite - or if it's consistent it's consistent in its own, rather frustrating way. Mathematics may not be how we inherently reason, but I feel good having solved a problem in Haskell. I feel bad having solved most problems in CSS.
SVG is simpler than CSS because it doesn't tackle the inherently difficult problems of adapting typography and layout to a wide variety of devices and aspect ratios. It is simpler in the same way it is simpler to create a PDF than to create an adaptive layout.
SVG is just scalable vector graphics, like Postscript which is the basis of PDF.
Same here. Most of the devs I know who don't like CSS actually never read the docs, or really understand the box model and padding vs margin, etc. They don't treat it like a real language, and so they hate it. I've even worked with someone even recount that once they read the manual, it got a lot easier!
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.
I understand the box model well and I still hate CSS. I just feel like CSS has way too many unique things to remember that have no apparent logic to them.
CSS clicked for me from the very start. It was always fun, I never had problems with it (aside from the browser bugs, of course).
Maybe problem others have with it is not because of the nature of the CSS, but because of people ignoring that nature and refusing to learn it and trying to carry over their experience with other technologies to CSS.
You were never asked to implement a simple three column layout in CSS where the center column expands with the screen size? That’s often the first thing people were asked to do in the early days after being asked to replace the old table based layout. CSS grid/flexbox took way too long to arrive.
I did lot of things, and even had to implement pixel perfect designs in IE5.
Honestly, those challenges were a part of the fun. Not sure I'd want to go through the same again, but it was fun back then.
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.
You're correct about not being able to target parent selectors without some JS intervention - BUT - if you avoid any property declarations on your default img elements you can achieve what you desire.
> to select a <p> which has only a <img> as a child
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 ...
Give me better composition options with css. I will love it. Until then, it is a toxic relationship. I have to use a preprocessor for that and it increases the time to see feedback from the browser.
Don't get me wrong, of course if you'd ask me whether I could envision something better and more elegant than CSS I would immediately have ideas in the back of my mind — however if you'd tell me I'd be stuck with CSS as it is my response would probably be a neutral shrug. It could be better, but it is okay and the direction things are going (CSS variables, Grids, ...) are not too bad either.
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.
Functional css totally changed my perspective on css. In the same way that react made me enjoy writing JS again Tailwind made me enjoy styling with css again. All that nasty coupling disappears.
The biggest issue with CSS I think for many is the emergent complexity from the interaction of different properties. Especially those inherited through the cascade. Much of this emergent complexity is not always consistent cross-browser.
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.
..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).
Given the choice between making life easier for developers who are too lazy to learn some new syntax and literally breaking the whole of the internet because websites stop rendering correctly with the changed meaning of things, I think I'd side with the adding more syntax. It's not even a hard decision.
You just mentioned another property that interacts with others, how does that remove the "emergent complexity from the interaction of different properties"?
nitpick, but if you're just looking to vertically center, you'll have much better browser support (e.g. ie11) doing display:flex; align-items:center; justify-content:center;
One thing I've been realizing is that layout and style are two different thing. Layout I almost always want done on the parent element, and style, I almost always want done on the child element.
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.
And then you discover semantic classes for styling elements, eg `.amazing_h1.with_padding` and use nested selectors for layout like `.blog_post > h1` or maybe even utility classes `.amazing_h1.with_padding.centered'.
If you're doing class='centered' or class='with_padding', I don't see any reason not to just do style='align-self:center;' or style='padding: 1rem;' instead. The class names communicate less (Is that centering the content of the element, or the element itself? Is that vertical or horizontal centering, or both? Is the text being centered?). And it doesn't allow you to make sitewide changes like a semantic class does (You might want to change all .blog-title elements from centered to left-aligned, but do you really want to change all .centered elements from centered to left-aligned?). I'd go so far as to say this is an antipattern.
Disagree. This is utility classing and you can target pseudo elements and deal with responsiveness. Tailwind is pretty popular and uses this methodology.
> Typically you have a design system that keeps things consistent. So you would have maybe 5-6 different padding sizes, eg padding-s, padding-xl or whatever. That's why you don't just do style='padding: 1rem;'.
Well, I'm not saying you should do style='padding: 1rem;', I'm saying that padding-s has all the downsides of mixing styles into your markup, with none of the clarity of just using inline CSS. The solution isn't to use inline CSS, it's to use semantic class names.
I can see the convenience of naming your padding sizes for consistency: that's what SASS inheritance does.
> As for me using .centered, it was just a quick example, and you took it in bad faith and now are nitpicking minor details.
1. Cool it. Nobody is attacking you, you don't need to attack me. We're discussing ideas, not each others' faith.
2. I've encountered this antipattern in production code, so regardless of whether you were actually proposing it as a serious idea, some people do take this idea seriously, so it needs to be addressed. The problems I pointed out aren't theoretical: I've dealt with them in practice.
> I'm saying that padding-s has all the downsides of mixing styles into your markup, with none of the clarity of just using inline CSS.
I don't think it does, it's semantic with respect to your design system, not your content. The use of utility classes is to avoid the proliferation of "header-foo", "header-foo-large-padding", "button-foo", "button-foo-large-padding" or even worse usage of overly specific selectors, relying on element position, eg .main-content > header-foo { padding: 1rem } etc . Instead, you can just "header-foo.p3", "button-foo.p3".
> 1. Cool it. Nobody is attacking you, you don't need to attack me.
Sorry, not a native speaker, it didn't sound like an attack in my mind. With argument in bad faith I meant fixating on the simplified .centered example instead of discussing the general idea of design systems and utility classes.
I guess cause I got flagged I need to "cool it".
> I've encountered this antipattern in production code, so regardless of whether you were actually proposing it as a serious idea, some people do take this idea seriously, so it needs to be addressed. The problems I pointed out aren't theoretical: I've dealt with them in practice.
I don't understand this argument. A lot of major css libs and frameworks use utility classes. I'm sure they deal with production code and practice all the time. I know I do.
This comment I take as very dismissive.
> I don't think it does, it's semantic with respect to your design system, not your content. The use of utility classes is to avoid the proliferation of "header-foo", "header-foo-large-padding", "button-foo", "button-foo-large-padding" or even worse usage of overly specific selectors, relying on element position, eg .main-content > header-foo { padding: 1rem } etc . Instead, you can just "header-foo.p3", "button-foo.p3".
How is the proliferation of "padding-s", "padding-left-s", "padding-top-left-bottom" any better?
The solution here is don't do either of these things. Strictly stick to semantics. "primary-button", "secondary-button", "post-header", "comment-header", etc.
> I don't understand this argument. A lot of major css libs and frameworks use utility classes. I'm sure they deal with production code and practice all the time. I know I do. This comment I take as very dismissive.
Just because a lot of people do something doesn't mean it's a good thing to do.
Article revealing origins of CSS should at least mention that one of its (at least initial) primary goals was to set that "entirely different academic yet simple presentation language" in a way it would allow dialogue among at least three agents expressing their visual preferences. This mechanism, cascade - the the "C" in "CSS" - is that mechanism that sets rules how different preferences should be merged together and conflicting resolved in final visual presentation of documents.
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.)
CSS is amazing. It's hilarious to watch the twisted ways people will work around it, or spend time making libraries to find solutions to problems that don't exist; without ever even trying to get comfortable with it. Its an amazing and simple piece of technology. Kind of a shame. Id love a real history and critical discussion on the "tools" we have now for web dev.
I'd rather it be a programming language, which Netscape tried to do with Javascript Style Sheets in the late 90s. Was way more flexible, but was never accepted as a standard and of course, was not supported by IE.
I was trying to articulate why CSS is so unpleasant for me. I've learned enough tricks and techniques to tolerate it, but there's still plenty of times where I despise it. There's a few glaring issues:
- 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.
I think most of the complaints against CSS is because don't understand the problems CSS is trying to solve. It is not just a question of putting text and colors on a screen. You can do that with Postscript or PDF or SVG or several other comparatively simple technologies. CSS is trying to tackle a much harder problem:
- 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.
I've found that since using utility/functional CSS in the form of Tailwind that I actually enjoy making UI's now. Coupled with componentization in the form of a JS framework like Vue, I don't need to stress over CSS anymore.
No more LESS or SASS, no more .header-container, .header-parent-inner crap.
This article would have much less of a problem with CSS if they actually used the cascade. All those instances of double underscore in class names should be two separate classes: ".author-bio__name" becomes ".author-bio .name". Then you can style the generic .name while also having control over specifically author names.
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.
I also find utility CSS libraries like Tailwind help address the difficulty in naming CSS styles. Once your team learns the common design system implemented by Tailwind everyone is speaking the same language.
I have noticed a commonality between systems that are unintuitive to use like git and CSS: they didn't sufficiently mimic nature, or common everyday concepts.
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.
CSS is a lot like JavaScript: cobbled together in a hurry and designed to be excruciatingly easy to get started with, almost to the exclusion of all other concerns.
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?
Ever notice how the phrase "I love how CSS works..." is inevitably followed by "but x or y really sucks, is too complex, is inconsistent..." I can't recall meeting a cheerleader for CSS the way you do for, say, lisp/scheme or forth.
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?
It's because CSS is a widespread distributed system which you don't entirely control. Programming language fanboys are usually just not being entirely forthright but they are also usually speaking from easy mode where they control all of the parts of the system, can upgrade at will, and don't need to support anyone else's projects.
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.
As a developer from 2005 or so onwards, I have only ever known the Markup + Stylesheet system, having read a huge number of articles, where it was touted having the document markup separate from the styling was the holy grail of web design and productivity.
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.
"People were excited just to see documents that lived on other computers across the world—and not just in plain text, but with headings and lists, too!" - I remember that feeling so well.
We need a time travel machine to remove the CSS and add Objective-J. Objective-J is great for people who don't want HTML / CSS hell. I asked the Objective-J author about native browser support as JS/HTML/CSS because performance was matter 10 years ago. And got the answer is "they wil never browser builtin other than JS/HTML/CSS". And now we have multiple new ecosystems, template engines, package managers, languages, reactive frameworks, and other 15 standards
As someone not at all involved in web development, if I wanted to learn CSS properly, with all the new flexbox/grid support instead of fighting with margins etc, what are some good recommendations? Like say I don't care about browsers older than a year ago and I only want to use the sane parts of CSS.
HSL is fine. More people are familiar with it than with CIE LCH, and familiarity is the most important thing. There may be better color systems, but to paraphrase the saying, there are also better alphabets.
As flawed as CSS is, it's uniquely special in that you can get by through trial, error, and mimicry without having to read a single book or have any deep understanding.
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.
I don't get it ... for me CSS is very easy. It's logic and clear. But yes you have to learn and work with it. It's ok ... so not everybody can master it drive-by and call themselfs an expert.
My problem with CSS is not so much with its idiosyncrasies - though I still find myself getting tripped up by ::pseudo-elements when they're used for anything more than show-off quote marks.
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>
Yes, Flash was a great tool to create stuff. (I only used it in Macromedia times)
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.
Modern JavaScript frameworks have support for this and a result of Flash's experience is that browsers have specific APIs for that ... however: each new generation of developers has to learn :)
Speaking of Flash and alternatives to CSS there was a whole UI language built to run in the Flash player called Flex which had an amazing layout engine. You could - in code - define your own layouts which could then be used on any components. I've been wishing someone would port this to javascript for years. Imagine if developers could have just created FlexBox when it was needed fifteen years ago instead of waiting on W3C.
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.
I wish everyone in web developemnt stopped only looking at the thing that makes it easier for themselves and start to focus on what's best for the users.
True, although if Flash had stuck around long enough (i.e. if iPhone hadn't signed it's death warrant) I'm sure eventually we could have come up with a solution for a11y.
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.
I haven't tried it yet, but I would look into <s>Silverlight</s> Blazor or the Rust WASM thing instead because both of those languages are more transferrable than Dart.
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.
[1] https://www.wiumlie.no/2006/phd/css.pdf