There is a long list of folks who I'll never meet, but for whom I'd love to buy a beer, and Meyer is at the top.
After the dot-com crash I found myself coding again, and fell into CSS with his book, and managed to carve out a spot for myself as a bit of an early CSS guru in my professional network. Doing that saved my house, quite literally.
CSS can be gnarly and frustrating. This was even MORE true back then when you basically had to create parallel implementations of the same layout to support IE's willfully wrong interpretations of the box model (oh, and its bugs). But it beat the everliving crap out of what came before.
I've long since left that part of my career -- I mostly talk and tell people what to do now -- but I'll always love CSS a little for that period of my life.
Funny story: I went to An Event Apart in NYC years ago (I think they’ve only had 1 in NYC) and I’m enamored by the people around me and Eric Meyer grabs the seat next to me while Zeldman is on stage and he’s quietly kind of heckling him (like a friend would not in a bad or mean way…and he couldn’t hear it). I’m sitting there, next to a person I very much admired, like Troy meeting LeVar Burton in Community trying to no freak out. It’s hard not to understate the impact Meyer, Zeldman, and A List Apart had on general front end development.
Having worked in multiple platforms — web, native desktop and mobile, it still amazes me how far ahead CSS is as a styling paradigm in terms of expressiveness and power!
Infact, it's the best language for styling content ever created. Think about this the next time you have to create a couple of XML files just to get round corners and shadows in Android.
+100. I did Android dev for like ~7 years and recently have been doing more Web dev. Yes CSS is a tricky language but I always get where I am going. On Android I frequently have to give up and settle for a more vanilla style because what I want to do will require like 1000 lines of code copied from StackOverflow. Even something as simple as "A rounded EditText with inset shadow" is hours of work. With CSS that's two lines.
Two lines today. CSS has come a loooong way... One could argue that the main advantage of CSS is that is a living standard, constantly adding and improving features and seeing a competition between implementations; whereas more traditional technologies are typically mono-vendor and, for one reason or another, have long stagnated.
To be fair, if you wanted to implement it before CSS support, I think you’d have a hard time reaching 1000 lines to do it. 50ish maybe (in JS and HTML).
Compared to other half-assed declarative formats? Yes.
Try covering dynamic-sized image with an svg surface. Try outlining a hovered element so that outline/shadow covers other items around. Try to baseline align text in non-shallow div hierarchy (which is required to workaround other issues).
When there is a moderate visual requirement I’d better mess around with something like GTK+/Cairo, NSView or QPainter rather than pulling hairs at CSS trying to slap few incompatible js-y solutions into one big ball of bs.
> Try covering dynamic-sized image with an svg surface. Try outlining a hovered element so that outline/shadow covers other items around.
I'd appreciate a visual example of what you are talking about. Seems like a far fetched, obscure-as-hell example to use as an argument. A strawman as they would say. CSS isn't perfect but it's pretty damn powerful for something I can teach a 9 year old.
We can certainly get a lot of work done within CSS's limits. For the auto-generated billion div soup, god speed and good luck.
> We can certainly get a lot of work done within CSS's limits.
You can also hit the ugly points very quickly.
E.g., suppose I want to draw diagrams of text connected by Bezier curves. Looks like SVG is the obvious choice for me. But suppose I add editable text to the mix-- well, HTML5 certainly has plenty of options for me there. And the Javascript to glue a solution together however I want.
Yet, none of those options come with any CSS that allows me to align the baseline of the text in my choice of HTML element with an SVG text element of my diagram. I have to scour Stackoverflow for some holy-shit hack of nested div bullshit just to tell the browser to position HTML stuff the way it does for an SVG text element.
These rought seams joining SVG, HTML, and CSS remain very frustrating until you start reading the specs and list archives to figure out that they were very different tech developed by very different teams with very different initial purposes and use cases in mind
Problems from joining SVG and HTML seem like they happen all the time, esp. judging from Stackoverflow questions. Off the top of my head, I remember that an SVG src for an img tag won't inherit from the containing DOM's CSS.
(That's not to say there aren't Javascript exeskeletons that inject the SVG directly into your DOM for you.)
Covering a image with something (whether SVG or not) is very common, though most of the time the image’s size will be known, or at least known in one axis. We’re talking things like putting captions on top of images.
Needing hover effects to render on top of elements around is even more common—if you want a row of buttons that share borders, by far the easiest way involves this very situation. Example where `position:relative` does the magic:
Certainly neither technique for covering an image that I showed in another comment is a hack. They’re both logical, coherent and fairly obvious ways of doing it. Getting hover effects to render on top, well, I wouldn’t consider that a hack either, though it’s a little more subjective (“why does position:relative make it work?”). I say that of course those effects aren’t going to render on top by default, because rendering is done in order unless you fiddle with layers and z-indexes, so shunting the hovered element onto a new layer or increasing its z-index above its surrounds is the obvious thing and the only way it could work.
I know many things that are hacks and that I will acknowledge are hacks, but these two aren’t hacks at all. They’re straightforward and natural CSS, working in exactly the way it was designed (and in areas where that design is completely sensible).
> Certainly neither technique for covering an image that I showed in another comment is a hack. They’re both logical, coherent and fairly obvious ways of doing it.
The absolute "obvious ways":
- a wrapper div that has to be position: relative. And a display block/inline-block because otherwise it won't work. An svg and an image inside that div. The svg has to be position: absolute.
- a full-blown grid. Two elements must be forced to occupy the same cell in the grid
Ah yes. Absolutely logical and coherent and not hacks at all.
> Getting hover effects to render on top, well, I wouldn’t consider that a hack either, though it’s a little more subjective
"Not a hack": rendering is done in order, but you still have to "shunt the hovered element onto a new layer or increasing its z-index above".
And this still doesn't precisely solve the problem of "outlining a hovered element so that outline/shadow covers other items around". Because most likely you'll have layers on top of layers of "logical coherent" wrapper divs to make everything work together, and you have to spend some time figuring out how to make that particular problem actually work.
Yes, absolutely logical and coherent. I’m not saying it’ll be so to someone that knows nothing about CSS, but rather to someone that generally understands CSS, because these solutions I discuss are straightforward and built upon well-known CSS fundamentals; they’re not complex in any way. The only part that is arguably not quite so logical, coherent and obvious is display:inline-block in order to limit the width, but even that I reckon is fairly obvious, that you’ll need that or to contain the element in certain styles of flexbox or grid.
Not everything is straightforward, but the things I was talking of are. (Incidentally on the matter of performance on animating box shadows, that’s actually not fundamental; Firefox has proper GPU rendering of it all, via the WebRender project, so that advice is irrelevant and actually (negligibly) slightly harmful in Firefox; it’s just that Chromium and WebKit haven’t caught up.)
I don't want play a detective with css properties ever, when there is a proper mathematical model for coordinate relations. Those who are fine with current CSS could then continue to craft wands and potions and everyone'd be happy.
> I don't want play a detective with css properties ever, when there is a proper mathematical model for coordinate relations.
Designers and UI devs would probably rather just write custom shaders on canvas if they have that level mathematical prowess. For most, offloading that cognitive load to an abstraction like CSS is worth it. Let the browser do the math. Playing detective then seems like a woefully arbitrary issue to have.
Those who are fine with current CSS could then continue to craft wands and potions and everyone'd be happy.
Isn't this basically a normal tagged image? Like one you'd see on instagram/facebook. It displays a little bubble at a given position with the user name of the person in the picture. When you mouse over it changes to indicate it's a link.
Sounds challenging to implement that in straight CSS :) I'd love to see a demo
> Try covering dynamic-sized image with an svg surface.
This isn’t difficult. Two reasonable approaches immediately occur to me on this.
① The traditional one: <div style=position:relative;display:inline-block><img><svg style=position:absolute;inset:0 /></div>
② Using Grid’s ability to put multiple things in the one cell: <div style=display:grid><img style=grid-row:1;grid-column:1><svg style=grid-row:1;grid-column:1 /></div>
> Try outlining a hovered element so that outline/shadow covers other items around.
On hover, ensure it’s on a layer of its own, and if its surrounds are also on layers bump its z-index above theirs. e.g. `:hover { position: relative; z-index: 1 }`. Definitely hacky, but not difficult, unless you want the decoration to render beyond the bounds of a parent element’s layer, such as if it’s in a scrolling area with 0.5em of padding and you want a 1em box-shadow around it—that simply can’t be done, layers are inviolate; but as consolation, other platforms almost certainly have the same limitation.
Expected: a yellow line crossing an entire 236x236 image, in all three cases.
Explanation: svg default size is lunatic (300x150) and it doesn't care of your layout modes, so it clips all drawing beyond that, unless you specify either width/height attributes (not css properties!), or a viewBox, from which it infers missing width/height.
I lost a day to this once, when parent-filling svg clipped 3 of my 5 shapes for no fucking reason. Shapes coincidentally fell either fully into 300x150 box or fully outside of it -- no easy hint for you.
You can pre-calculate that in js, but if you specify .wrapper's dimensions in non-px, or use some aspect fit, you're screwed as well.
True, SVG itself can be surprising if you don’t know what you’re doing with it—it’s a powerful graphics format that supports flexible sizing and aspect ratio handling, which is much of the reason why width/height and viewBox are separate things, and in cases like this it’s important to understand what they each mean (and how any of them are inferred in the presence of the other).
For the sort of thing that you’re doing here, there are two most likely possibilities for what you want:
① Give the <svg> element a preserveAspectRatio attribute, most likely preserveAspectRatio="none" if you’re just trying to draw a diagonal line across the image. This’ll allow it to stretch the SVG, effectively throwing your stroke-width off a bit so that it could look wrong if you use it on multiple images of different aspect ratios.
② Accomplish a dynamically-sized viewBox with percentages: <svg width="100%" height="100%"><line x2="100%" y2="100%"/></svg>
Fortunately all of this stuff is nailed down pretty well now. IE always had trouble with these more unusual aspects of SVG, even to IE11. I fondly remember a design I implemented a decade or so ago that exercised just these sorts of fiddly areas, causing such issues on IE9 that I gave up and made it use the simpler, not-as-pretty non-SVG fallback that was necessary at that time because of IE6–8.
Technology is only as good as its outcomes are. I didn't instantly realize back then that width/height attributes are required, because SVG as an element (not as a powerful format) doesn't respect given CSS layout. You didn't instantly detect the issue to suggest a working solution, probably because you know too much recipes to pick one off the top of the head. This is the end result of such technology - we both spend much more time learning and/or explaining than it could be. Now multiply that by the factor of world and by general shortage of a single-person skill capacity and time.
If you pick any other technology, e.g. an airport gateway system or a shop checkout line, and apply this "can be surprising if you don’t know what you’re doing with it", you'll get a big congestion instead of a functioning airport or a shop. Users are not to blame when the system is based on some cryptic nonsense. Good systems just work, bad systems require custom effort to fly and never scale. These congestions induced by web tech only pull us back and I can't understand why you're so positive with it (if not condescending; sorry if I mistook that).
> Try covering dynamic-sized image with an svg surface.
You could embed the dynamic-sized image within an svg, perhaps even a fully dynamic inline svg.
> Try outlining a hovered element so that outline/shadow covers other items around. Try to baseline align text in non-shallow div hierarchy
I mean at some point you need to use JS. Still, IMHO it's quite amazing how far you can go with a purely declarative language. That also means a myriad of side effects including smooth reflow being taken care of automatically as long as best-practices are followed. Is there any way to write these examples completely declaratively in GTK+/Cairo, NSView or QPainter?
Yes, XAML was (is?) quite nice to create interfaces, with notably grid and components support years before CSS got them. It has its pain points (including the different incompatible implementations) but I always did somewhat OK designs faster with it than I ever did with CSS. Android AXML is indeed a (bad) joke though.
The problem with CSS has historically been browser conformance—naturally there’s been some workarounds. However, CSS has been a success because of its ubiquity. However, it is somewhat limited in its extensibility.
For app development I really appreciate Qt Quick QML as it’s really nice language for UI development, but also highly extensible. Granted, different use case than CSS in ways.
Bootstrap was effectively the jQuery for CSS, in terms of standardizing what layouts looked like across all browsers.
It gets a bad rap because it's so easy to use for non-designers that a lot of sites that use it don't bother customizing the UI elements like buttons or expand/collapse accordions etc. Or the layout of the page, for that matter. The famous "Every Bootstrap website ever"[0] site outlines this nicely:
No. Ut I’d tell a designer that’s a stupid design and we can get pretty close to it if they really wanted it but overflows will make it look ugly depending on where they want this magic unlimited tab box.
To this day, every CSS I write for a website starts with a copy of the Meyerweb CSS Reset. I've been doing it for so many years yet never thought twice about it.
Only a couple months ago I decided to check what Mr Meyer was up to. I bought his book Design for Real life thinking it was about CSS. I was delightedly surprised by the breadth of new things I learned about design that I had never considered before.
Sometimes I think csszengarden did more harm than good. It was a huge influence as far as letting people see how much you really could do with straight CSS, but on the other hand it also pushed this notion of totally reskinable web sites where you could just swap stylesheets that has never quite materialized.
I recall going to csszengarden to figure out how they were doing layout and seeing a whole lot of stuff like left: 400px. size: 600px in the examples. That sort of fixed layout was exactly the sort of thing I was trying to avoid.
> It didn’t matter if I was using the market-dominating behemoth that was Netscape Navigator or the scrappy, fringe-niche new kid Internet Explorer: very little seemed to line up with the specification, and almost nothing worked consistently across the browsers.
Well I remember a significant difference in the early years of CSS. Netscape Navigator would frequently crash when encountering perfectly valid CSS while IE at worst would render it weirdly. Netscapes habit of crashing probably set back CSS adoption for several years, since you couldn't even introduce CSS as an optional enhancement.
I know a whole generation of designers loathe IE, but this is noting compared to the hate designers felt towards Netscape in the early years!
> Well I remember a significant difference in the early years of CSS. Netscape Navigator would frequently crash when encountering perfectly valid CSS while IE at worst would render it weirdly. Netscapes habit of crashing probably set back CSS adoption for several years, since you couldn't even introduce CSS as an optional enhancement.
It was the right thing to do. CSS and javascript just slow down the computer and run malware.
> All those table tags just felt… wrong. Icky. And yet, I could readily see how not using tables hampered my layout options.
I used the Wayback Machine (Thank you, Internet Archive!) to dig up some of my old designs, and boy, I used tables for all it was worth, and then some.
Unlike Mr. Meyer, it didn't feel wrong. But again, unlike Mr. Meyer, 25 years ago I was ... let's just say "young", around 13-14.
I'm planning to write a small blog post about it some day, because the amount of tables I used for a simple heading is just staggering. It must be at least a full page (in 800x600) for just a simple header. I don't think I can explain how or why without actually posting screenshots.
Every WYSIWYG HTML editor made it super easy to us...abuse tables for layouts. IIRC Dreamweaver was still rocking table layouts until the MX 2004 release. Dreamweaver 4 and MX definitely focused on table layouts. I seem to remember MX supporting CSS but the layout focused on tables.
I remember taking over a website around 2007 that was built completely with tables. I was having a bit of a layout issue, and found many missing </td> and </tr> tags throughout the code. A ha! I'll go and fix everything and validate the HTML. The entire layout was built upon those missing tags, and once added in, everything fell apart much worse than before I had gone in and "fixed" everything.
Programming computers just is like that. You never, ever in any programming language get to say what you mean. You always, without exception, have to speak alien to the computer to get it to do what you want.
> If you think of a table as a discrete coordinate system then it's fairly obvious.
Unfortunately tables did not work like a coordinate system, since cells would grow to accommodate their content. Combined with spacer gifs, tables could be used to generate whitespace padding and aligning content, but it was very tricky to use tables for exact positioning.
At the time, there was serious rage against using table for layout. Everyone had to do it at some point if you wanted proper spacing of elements. Table was one of the only ways to do it and, as you say, a natural choice.
But you could easily lose at a job interview if you were a proponent of this.
At this time it was a perfectly example of why CSS specialists and developers forced into using CSS were talking past each other. The purists insulted table layouts with good reason, but the best they could offer was crazy tricks with floats that made semantically as little sense as tables.
Now that CSS grid is finally useable both sides can agree on a proper answer, but this is 20 years later.
That's the thing about purists, they're not wrong in pointing out the problems, but they're often so obsessed with the problems they fail to critically evaluate the alternative solutions and realize they are also terrible.
This exactly. CSS proponents were badmouthing tables left and right, but tables excelled at the kind of layouts that CSS struggled with. Reactive three column website with tables? Super easy. Reactive three column layout with CSS? Requires a human sacrifice and won't work in half of the browsers of the time. Want the text centered in the column headings? In tables it was a built in feature. With CSS, well, I hope you like pain. These weren't obscure problems either. Many websites were already in a 3 column layout because it was so natural with tables, so converting them over to CSS was an immediate pain point.
That said, if you wanted to do something more complicated then tables could fall apart pretty quickly whereas CSS had a solution. Adding columns to a table when someone expanded their window and reflowing the content into the new columns was basically not possible with tables, but is something CSS can handle for example. Most people only had simple problems though and CSS complicated their life considerably.
There were always tradeoffs involved. A site might be legally required to be accessible, or it may be a business decision. Layouts hacked together with floats were a mess to create and maintain, but tended to adapt better to mobile displays. A competent front-end developer should understand pros and cons and be able to handle both approaches.
Even today you might have to support old internet explorer, so you cant use display:grid.
Of course incompetence can be present on either side of the table in interviews. I have heard about people avoiding display:table in CSS because they heard tables were bad.
I was making a humorous reference to the song, via the line "I was there",
> To all the kids in Tokyo and Berlin.
I'm losing my edge to the art-school Brooklynites in little jackets and borrowed nostalgia for the unremembered eighties.
> But I'm losing my edge.
I'm losing my edge, but I was there.
I was there.
But I was there.
It's a song which has a type of nostalgia analogous to the one in this thread.
Plenty of stuff is still pretty unintuitive in CSS (why do I set `min-width: 0` to stop a flex/grid item overflowing? That doesn't make a lick of sense) but it's in a pretty good place these days.
Flex and grid make the majority of responsive layouts a breeze and the some of the new filter stuff is super powerful, just a shame it took 20+ years to get it. Now let me transition to and from `height/width: auto` damn it.
I often have to set `min-width: 0` if it's a flexbox inside another flexbox. `min-width` defaults to `auto` which means the smaller of the `width` on it and its content width. The content width of a flexbox (being checked here as a flex item) is not defined as the smallest width it could be without overflowing, though. It's based on the content widths of _its_ flex items, regardless of whether or not you put `min-width: 0` on those [1]. So even if that inner flexbox can shrink below the items content width, its default minimum size will be larger than that. It feels wrong when you have to do it, but it also preserves the meaning of minimum _content_, and it might be what you want in other situations.
Width/height: auto require a layout to know the size, so I don't know if we'll ever get that either.
It does but only after a layout. Interpolating from `height: 0;` to `height: 10px` is easy, but interpolating to `height: auto` takes an additional layout. I always assumed that you can't do this either for performance reasons or because it would be really hard to implement.
20 years ago I took a job as a high school computer science teacher. CSS and JS was just taking off and I was fortunate to be in the right place at the right time to teach a bunch of teenagers all about it.
Huge thank you to Eric, Zeldman, Shea, Jeremy Keith (DOM Scripting), etc. for their contributions. Their publications and answers to my emailed questions helped me set my students up for the future of front-end development.
I chuckle recalling all the tricks we had to learn/use to get our pages to work across all browsers and my insistence that all pages validate to receive full credit!
Nice, I graduated highschool in 2004 and wish I had teachers that were clued into that. Bought Zeldman's book on web standards in 02-03 ish. And basically was allowed an independent study to work on my "websites" as the teachers had no idea. I recall a strange argument where they insisted on HTML tags being uppercase.
Do people still manually craft CSS and HTML just to make a page layout? That's like writing VBScript to create a Powerpoint presentation. Why do we use a WYSIWYG for literally every other rich text document, but not web pages? Are we really that bad at changing what we're familiar with?
Most small sites are going for wysiwyg through platforms like wix /squarespace / shopify, Why there is not a great open source version of this is another question? I suspect some snobbery is involved.
Don't know about others, but my web pages aren't just rich text documents. Sometimes they require programmatical definition of rendering dynamic data sets.
As for the general case, every website is different enough that no general-purpose GUI/WYSIWYG exists that could cater to every need, I guess.
I think there's a happy medium where you have validly marked up templates, and then give your end users rich-text editors to create their WYSIWYG content.
That's always my thought as well. People become comfortable with the hacks/quirks of their dominant language(s) and forget about them when comparing to something exotic like CSS.
Reminds me of Darryl in The Office saying generic things that they could use for sound bites: "This person has really gotten him (or her) self into quite a predicament".
His book "CSS The Definitive Guide" really helped me understand of the many quirks and inner workings of CSS that wasn't really obvious and intuitive. Highly recommend it.
Tables were never reliable as a tool for layout, since the rendering algorithm was never specified in detail. IE just tried to reverse-engineer Netscapes rendering, Mozilla reverse-engineered IE and so forth.
Now if you add 1x1px spacer gifs, then you get more consistent control. But you also would have to be a masochist.
The idea of CSS is great, but it's about time for CSS as a language to improve drastically - currently (even with the latest changes) it is just not powerful enough to be used directly instead of being generated or used in combination with javascript. I wish for the day where I can really just write clean semantic html and then add the CSS afterwards on top of it.
For certain layouts and CSS features to work you need to add structure for it AKA additional tags, typically divs and spans because they have no meaning in terms of your document.
So your document becomes a mix of semantic structure and then wrappers, containers, pushers, purely visual areas and so on. Also you're going to have things that are specifically redundant for your use-case, but you still add them for consistency and re-usability.
CSS would have to be quite a bit more powerful to achieve a clean separation of document structure and layout. It would need things like purely visual grouping mechanisms, reactive or backtracking selectors and HTML itself would probably need to be either a relational or graph structure instead of a tree to actually convey the semantics correctly and consistently.
E.g. let's say I have some html like <p class="warning">be very careful<p> and there is some 3rd party CSS that already has nice styling for a warning paragraph. But it uses .warn as a class, not .warning.
I don't want to change my HTML and I also don't want to copy the style.
I want to tell CSS that my own .warning should inherit the style of .warn (and maybe adjust it slightly if necessary)
Because the output is still CSS, this would lead to a lengthened (redundant) selector though. Also, AFAIK it would be impossible with a class that is not part of your SCSS tree. If you are able to import the library CSS in to your own SCSS, OK, no problem. But that would introduce unneeded complexity.
If using a bundler and one output file, copying the library CSS rules and applying them to your own could maybe even lead to the same output as @extend - a combined selector
.warn, warning
(you already kind of addressed all of that already in your "semi-relevant" disclaimer)
I'm always surprised when people show what modern CSS and HTML5 is capable of doing.
What is it that not currently possible with CSS, which requires JavaScript or generated HTML? I understand there's things CSS can not do, because that not it's purpose. I'm not saying that you're wrong, just genuinely curious.
A general issue with HTML and CSS is that HTML is a tree and not a graph or relational structure.
It's maybe a weird comment but HTML feels clunky and rigid and you sometimes need JS to patch over that clunkyness. (CSS just reacts on HTML structure so it is not specifically at fault.
In other words you sometimes need to break out of the HTML tree and move things around so they display and behave as intended by web design.
Another thing that comes up often is breaking out of the default UI controls. Some designs are quite playful and interactive, so you end up zooming, moving, replacing and adding stuff based on user input etc. In short: as soon as you have to listen to more or other using events you are going to use JS.
Also more classic and conservative designs (example: HN) are essentially one dimensional with a bit of two dimensionality to them, AKA just text that flows through a simple layout. There, you typically can avoid using JS for these kind of things. But if your design is more two dimensional it becomes increasingly harder to avoid JS. Flexbox was an addition that provided some notion of two dimensionality and Grid is a feature that goes further into that direction.
A UI is generally not a tree. That’s just how we force ourselves to think of it.
Take how data flows through a template or react components for example. The general case is that two parts display some aspects of a data source, while their structural relation to the tree is accidental or forced by layout rather than their data relation.
Or from a purely UI centric perspective you might have situations where one part has a geometric dependency of another, which may or may not be expressed by the tree/document structure.
What you’re actually doing is translating geometric layout requirements or rather constraints to a tree, because that’s what happens to be your compilation target.
This is a thread about CSS and HTML. We're talking strictly UI and presentation. Your argument is that data dependencies and other non-UI and non-presentational aspects are not a tree. They're not. But all I said is that your UI is always a tree. And I see no examples pointing otherwise.
As a pointer for further investigation: One of the big challenges of teaching coding to designers I face is the mental shift from thinking about UI as an open canvas with arbitrary geometric constraints to thinking of them as a tree structure.
When implementing bespoke interfaces I very often have to do this translation in my head. You’re right that the common case is a tree, or can easily be translated to one. But it’s not the general case.
You want to draw two disjoint circles and a line connecting their centers.
Now the geometric relation is a simple graph. But in HTML/CSS you likely have to use an invisible parent that these objects relate to and maybe a few other tricks. You’re not expressing this directly anymore, but kind of have to traverse around tree nodes so to say.
It can even be worse if those objects are laid atop of others, and things are switching on the Z axis. You’re now breaking the structure or rather changing it constantly. The parent-child relationship often feels forced.
Designers seem to think of UIs more of an open canvas, typically as a layered grid (a fine grid of single digit pixels) where the objects have arbitrary relations to eachother and the grid. The canvas itself is sometimes the only “parent”.
Or even simpler: you have two objects in different containers, but with the same margin to appear aligned. What you’re trying to express is their alignment and not their relation to their “parent” which might be very well invisible.
> You want to draw two disjoint circles and a line connecting their centers.
I wouldn't say two circles connected by a line is very useful in UI to be honest.
Such relationships are more commonly seen in animation software, modeling software, engineering software and games, 2D or 3D, where such relationships are explicitly expressed by scripting or specialized binding systems (like inverse kinematics). The general metaphor for such software is not a tree, not a graph either, but rather a set, upon which set operate a set of systems (like physics and AI etc.).
But all of those things sit, in my mind, distinctly apart from what UI is. And the distinction between UI and just "things on a computer" is that UI is entirely artificial and made for the purpose of conversing with the user, rather that representing or simulating existing phenomena, natural etc. So UI does NOT have to be arbitrary. But it HAS to be easy to comprehend. That is its purpose.
The only place I've seen this used in UI I can recall is Reason (audio software), where you can flip your rack of modules, and connect inputs and outputs with wires. It's quite gimmicky and becomes a mess (just like real cable management does), so I think this also informs us how well arbitrary graphs look on screen. They don't help and become unintelligible at scale.
While a clean hierarchy tends to stay clean, so it's useful in UI where we control our metaphors and optimize them for comprehensibility.
> It can even be worse if those objects are laid atop of others, and things are switching on the Z axis. You’re now breaking the structure or rather changing it constantly. The parent-child relationship often feels forced.
I'm sorry that's a bit abstract, can you provide an example again? You see, a list has a clear enumeration order, you can make the first or last item be "on top". A tree also has a clear traversal.
A graph has no clear traversal order at all, so how would a graph help you at all figuring out z-index for your UI?
If anything, having your UI as a graph would take away the common-sense approach to rendering order which allows you to NOT assign a z-index to literally every element. I've had to deal with such problems, and trust me, you don't want to have that problem. The tree is a friend.
> Or even simpler: you have two objects in different containers, but with the same margin to appear aligned. What you’re trying to express is their alignment and not their relation to their “parent” which might be very well invisible.
A visual example would help. The "parent" exists to provide a transform reference as much as anything else. So it's unclear why you wouldn't use a parent for the purpose it exists, only to eventually do the exact same thing.
> I wouldn't say two circles connected by a line is very useful in UI to be honest.
It is when you think that you can't reliably animate or reposition anything in HTML if it causes a reflow.
Most (any?) other UI toolkits give you distinct "canvas" that can be in more-or-less arbitrary relationships to each other. And if that is not enough, they let you drop down to `onPaint` and paint your own stuff.
HTML+CSS force you into a rigid tree laid out on a rigid 2D-plane. Because at their core they have always been just a tool to (somewhat badly) render text and some images. All the other things we force into/onto them play very badly with this concept.
> In HTML we call this "position: absolute" and "z-index".
Nope. These don't make "more-or-less arbitrary relationships to each other" easier or more obvious. And they are still fully constrained to the hierarchical 2D-plane of HTML.
> In HTML we call this <canvas>
Only it's ... not HTML anymore. It's canvas. And yes, the irony is that to make anything custom properly you have to fully exit anything HTML- or CSS-related and use something entirely outside like Canvas or WebGL.
In any other world you don't: you stay inside whatever framework you started in.
> Nope. These don't make "more-or-less arbitrary relationships to each other" easier or more obvious. And they are still fully constrained to the hierarchical 2D-plane of HTML.
Your requirement that a system should reflect "arbitrary relationships" is non-sense, sorry to be blunt. Nothing anyone could bring forward as an example from any UI system in the world would satisfy the description of "it makes arbitrary relationships obvious". You should probably use more precise language and examples.
Also you're simply wrong about being constrained. Declare your elements fixed (or absolute at root), and you can do whatever you want with them. The document becomes just a retained mode set of disjoint elements. There's no "flow" anymore.
> Only it's ... not HTML anymore. It's canvas. And yes, the irony is that to make anything custom properly you have to fully exit anything HTML- or CSS-related and use something entirely outside like Canvas or WebGL.
The canvas is literally an HTML element. It can be shown inline, or not, you can pepper your regular content with hundreds of tiny canvasses throughout, or you can make a giant one to take over your entire document. Your choice. It's literally a transparent buffer to draw whatever the f you want in it, and that sits in your document. How much more integrated with HTML do you want it to be?
You claim you want to exit the regular HTML flow, and rendering semantics, and when you do, you complain that you've exited the regular HTML flow, and rendering semantics. That's just circular reasoning, you're putting your own requirements in opposition, and blaming HTML for it, which makes no sense.
The modern browser stack allows you to opt out or in of most of what it does. It has never been as powerful, to the point that other UI engines are starting to use web technologies as a basis for their own UI stacks (i.e. Scion for ex.).
There are many little annoyances, as with anything, but all your complaints are honestly invalid. Or if I'm wrong, at least be specific and don't argue with yourself by painting in broad strokes about what it means to "exit HTML" or "not exit it".
State your specific issues, and I'll state a specific solution. So far your specific issue appears to be you're not very familiar with the technologies you're bashing.
> Your requirement that a system should reflect "arbitrary relationships" is non-sense, sorry to be blunt.
I said "more-or-less arbitrary relationships", and that was a deliberate choice of words.
In HTML it's still impossible, or nearly impossible to express an element's size or position in terms of its siblings, or a parent's size and position in terms of its children.
> Also you're simply wrong about being constrained. Declare your elements fixed (or absolute at root), and you can do whatever you want with them.
Indeed. Only when you literally take the object out of the flow (or emulate that by having absolute at root), can you do some limited things to the object.
> You claim you want to exit the regular HTML flow, and rendering semantics, and when you do, you complain that you've exited the regular HTML flow, and rendering semantics. That's just circular reasoning
It's not. HTML and CSS are extremely high-level. Canvas is extremely low-level. And there's literally nothing in between.
What if I want to take over the rendering of a single table cell? Or, better still, over just items in a select?
> It has never been as powerful
Powerful? At which point is it at all powerful?
> State your specific issues, and I'll state a specific solution.
How about:
- constraint-based layouts
- 60fps animations on actual HTML elements. And by animations I don't mean "only use animations that don't trigger reflows, or you're screwed". Things like "animate a list item being removed from a list" (and you're not allowed to say things like "we know the height of the item beforehand")
- customisation of built-in components like selects
- almost literally anything from Sencha's/ExtJS' kitchen sink: https://examples.sencha.com/extjs/7.4.0/examples/kitchensink... Modular, componentised, customisable. There's a reason every single "css or ui framework" on the web reimplements the same few components over and over (tabs, alerts, maybe selects) and rarely has the manpower to do anything more complex (virtual lists and tables, complex grids, treeviews, etc. Hell, even a calendar is often too big of an undertaking.)
Oh yes, some of them can be made at great expense of time and manpower. And some of them have become easier to do (some layouts like grids).
There are plenty of demos reaching 120fps animations either with CSS, or JS in DOM, or in canvas (with or without WebGL), so this issue doesn't sit.
Obviously a cross-platform solution is not as efficient as a platform-specific solution. But it's quite good these days.
> Things like "animate a list item being removed from a list" (and you're not allowed to say things like "we know the height of the item beforehand")
Look, JS is fully exposed to the DOM, so you don't get to tell me "you're not allowed" about features that the browser allows. We're not arguing whether the imaginary HTML in your head is capable of what you want, we're arguing about whether the real one is.
> customisation of built-in components like selects
Implemented by your next point:
> almost literally anything from Sencha's/ExtJS' kitchen sink
Those are libraries that run in a browser. So they count as something the browser can do. Your initial complaint was that we're so constrained that it's "nearly impossible" to do what you want. If Sencha and ExtJS does it, and you can just use it, your argument is invalid.
> Oh yes, some of them can be made at great expense of time and manpower. And some of them have become easier to do (some layouts like grids).
Uh-huh. So what is your complaint again? That it's too much effort to use this great expense of time and manpower by downloading it with your package manager?
Yup. Not native to the web, and IIRC jundreds of kilobytes of JS
> There are plenty of demos reaching 120fps animations either with CSS, or JS in DOM, or in canvas (with or without WebGL), so this issue doesn't sit.
Yup. "If I close my eyes, the problem will go away". Also, "if I ignore the actual content of the complaint, it will go away".
Because demos are just that: demos.
> Look, JS is fully exposed to the DOM
Ah yes. Suddenly it's no longer HTML and CSS, now we're bringing JS into the fold.
Do you know what it takes to actually properly animate what I requested?
> Implemented by your next point:
Ah, yes.
How it started: HTML is so powerful!
How it's going: Oh, look, all you have to do is spend thousands of man hours and write megabytes of Javascript to achieve what's available in other not-so-powerful UI kits.
Don't forget, what you implement will require orders of magnitudes more resources to run on what's essentially a supercomputer than almost literally anything else.
> Your initial complaint was that we're so constrained that it's "nearly impossible" to do what you want. If Sencha and ExtJS does it, and you can just use it, your argument is invalid.
I can also implement a web server in Brainfuck. Does it mean that Brainfuck is powerful and any complaints about it are invalid?
> That it's too much effort to use this great expense of time and manpower by downloading it with your package manager?
That things that are available out of the box almost literally everywhere else are actually incaccessibly to those who can't spend the effort on reimplementing them, from scratch, every single time.
There's a reason why Sencha costs $1295 per developer and even smaller projects like handsontable easily charge hundreds of dollars for their use. I mean, for things that are either available out of the box everywhere else, or are rather trivial to implement, once again, everywhere else.
You started complaining that all you want it is the ability to have custom layout & drawing logic and HTML doesn't let you escape the tree.
And currently you've given up this entire premise, and you're on a loop whining about how FOSS and professional UI libraries that have custom layout & drawing logic, which WORKS JUST FINE IN EVERY BROWSER take hundreds of kb (which is nothing) and some of them cost money (which is absolutely irrelevant).
You wanted to express "arbitrary relationships". This requires libraries implementing "arbitrary logic" with access to the presentation layer. You got it. Now you're whining about the fact these libraries exist.
Ok. Let's be very coherent. Let's talk about one single thing.
Not so long ago Twitter redesigned their website. Mind you, Twitter is far from being a complex app UI-wise. It's basically text plus images. All they did was re-implement infinite scrolling using a well-known paradigm called a virtual list (or a virtual table).
Note: I implemented a similar functionality in C++ Builder circa 2004 and in Qt circa 2005. This entire functionality is either available right out of the box, or will take a first-year CS student a day or two to implement by following a simple tutorial (because virtual lists are a thing available in all UI kits since probable early 80s).
It took Twitter close to a year to fix this functionality.
Now, tell me: why is it that such a powerful platform:
a) doesn't have this functionality out of the box
b) requires a company the size of Twitter almost a year to implement somewhat satisfactorily
c) why didn't Twitter just "go ahead and download a package" that implements this trivial primitive functionality that is so readily available, once again, everywhere else.
From here on we can discuss all the other trivial and primitive things that require you to depend on someone to spend untold man-powers to implement them in the "so powerful a platform".
And from there on we can move on to discussing why these trivial and primitive things require orders of magnitudes more resources to run to do a fraction of a fraction of the things available, you know, everywhere else.
How's that for coherency?
Edit: In a comment elsewhere I actually linked to a nice example. The Web is such a powerful platform that you can't even animate shadows without thinking hard and long about causing page repaints: https://tobiasahlin.com/blog/how-to-animate-box-shadow/ MacOS did shadows almost 20 years ago on hardware that's probably 100 times less powerful than now.
So an app had a bug and almost a year later they fixed it.
You're right. This scenario never happened outside the web. /s
Partial rendering of lists/tables is trivial when the items are not dependent on one another (flow) or you have fixed or easy to compute height (assuming vertical scroll). When that height is determined by thousands of variables, bugs can happen, and what platform you use doesn't matter. But I suspect Twitter's issue is elsewhere entirely and both you and I are forced to speculate POINTLESSLY I MIGHT ADD, on a fixed bug we can't debug the cause of.
And saying Twitter is "just text and images" is both terrible oversimplification (it has text in multiple styles, also videos, polls, retweet panels, info cards etc. etc. etc.), and just sounds ignorant. "Just text"? Do you have a clue how varied and complicated multilingual Unicode is at all, not to mention mixed RTL and LTR and so on. You get to say "just text" if you're rendering the visible range of ASCII in a monospace font only.
You did it more easily in your toy scenario most likely because your toy scenario had LESS complexity, not because HTML has less capability. You see, there's a reason why people often embed HTML in their apps to show so-called "rich text" in it. It's something that's not trivial to achieve at all in your typical UI kit (beyond basics like color, font-family and size).
And unfortunately your coherency remains low, as you're still arguing about things that have nothing to do with your initial thesis that HTML doesn't allow you to do what you want.
If HTML has a problem, is that it does too much, not too little. If you take Qt "circa 2005" and try to replicate the exact visual presentation of Twitter.com you'd quickly realize how much HTML gives you that Qt wouldn't. In fact, Qt's own rich text support is a tiny, tiny subset of HTML.
Oh, by the way, you don't get to use Qt. You only get to use whatever comes with your OS, because BY YOUR OWN STANDARDS you're very filesize conscious, and "hundreds of kilobytes" was too much for a UI library to use in your web app. Well Qt is several megabytes.
You forgot you were whining about kilobytes, right. Low coherence.
> So an app had a bug... terrible oversimplification... your toy scenario...
Life is so easy when you bury your head in the sand and pretend problems don't exist.
> trivial when the items are not dependent on one another (flow) or you have fixed or easy to compute height
Funny how "so powerful a platform" makes this "trivial and easy" only if you babysit it and give it rigid fixed dimensions.
> because BY YOUR OWN STANDARDS you're very filesize conscious, and "hundreds of kilobytes" was too much for a UI library
A modern browser is about 10 million lines of code, give or take. That's ~20% of the entirety of Windows 10. That's the size of Windows NT, and only slightly smaller than the size of Android.
And this "powerful system" still can't display more than very primitive UI elements, and needs additional megabytes of code to do the most trivial of UI things.
Oh, and it requires magnitudes more resources to display all that, and needs ridiculous things like "oh you must have fixed height" to do the most trivial of things.
But sure, to you it's "so powerful". That betrays your ignorance, and I'm tired of this conversation.
We'll always have relationships on top of (and independent of) the tree. I think we shouldn't underestimate what the tree gives us. I.e. in small fraction of cases the tree is maybe a hindrance. But if that hindrance doesn't go away but multiplies without the tree, our hindrance is likely coming from the complexity of our problem, rather than from the tree.
By the way notice the tree keeps reoccurring in other case of interfaces:
- All computer languages are code, which expresses a set of nested statements and expressions (which form a syntax tree).
- While XML was replaced with JSON for data exchange, that's also a tree, not a graph (some implementations exist to describe a graph, but I'd argue that doesn't help serialization etc. concerns).
There's something about a tree that makes it very suitable both for computer and human comprehension.
OF COURSE, all those trees end up describing graphs. Say our "syntax tree" at runtime is an object graph and so on. But it's notable that we describe that object graph by encoding it into a tree of rules.
To access elements outside of the tree structure. You can even watch HTML moving in this direction. Forms are a great example. It used to be that the form element would group related input controls. However that now meant that you were stuck linking layout and a form together. The for attribute on input has made HTML forms less tree and more graph-like since you can link input elements to a form outside of the tree.
The problem with forms is that they combine presentation with business logic. In any decent architecture, your UI has no business directly encoding API requests and directly submitting them to the server.
But of course, this was necessary in the early "thin client" days of HTML, before we had a well-developed client-side platform to encode client-side concerns independently of their presentation.
Case in point I rarely use <form> elements at all in my applications. I use form controls, of course. But all form data is collected, transformed in a FormData instance and sent via XHR. This is infinitely better and provides great opportunities for UI component reuse independent of what your server-side API shape happens to be. It also means no more "hidden inputs". Which is non-sense if you think about it. If the user can't edit it, or even just see it, what is it doing in the HTML form? Again, in the 90s it made sense. In 2020 it makes no sense.
HTML today is UI even more than it ever was. That's good. And UI is a tree, because it's a visual hierarchy. And that's all your need. HTML is not your entire application. And the rest of your application is already a graph.
But the for attribute now gives us the best of both worlds. I still use form tags, but always make them close immediately are style them to not display. This preserves functionality without JS while also separating business logic and display.
EDIT: I don't know why you're being downvoted, I get what you're saying. For example encoding the form URL in the HTML is a violation of separating business logic and display since you may want the submittal link to be dynamic based on the values in the form, and using JS to update the form action attribute doesn't really solve anything, but I feel like using for is a pragmatic compromise between the reality and history of HTML and a more ideal architecture.
HTML has a few kludges here and there that seem questionable on close inspection. Sure, having the "id" attribute and then referring to this id from anywhere else allows you to build an arbitrary directed graph of relationships independent of the DOM tree.
And that's useful in CSS selectors and from JS and so on.
Within HTML itself, the "for" attribute on a label has two behaviors... One is to read out the label for a given input for visually impaired users, and the other is to focus the input when you click the label.
The focus behavior is kinda useless, most people click the input, not the label. But OK, it's harmless, and nice to have. The accessibility feature makes more sense but also highlights the fact that a control and its label are intrinsically one unit. And in many UI frameworks they are one unit.
So why aren't they in HTML? Because INPUT existed in HTML far before accessibility was a concern, and people were writing out labels outside the inputs. So later versions of HTML had to deal with the status quo, and added LABEL to "patch" the problem without disrupting the existing form control behavior.
So this particular case is a historical quirk. Would HTML be redesigned, the label would be in the input, and you'd probably be styling it with a pseudo-selector, like you do :placeholder etc.
> I'm always surprised when people show what modern CSS and HTML5 is capable of doing.
There are web servers written in Brainfuck and Bash. They are capable of it, you can be surprised by it, but it doesn't mean that this is useable or applicable in real life.
What CSS lacks? Take what Sass offers, go through feature by feature, and you'll find so many things lacking. Some of them are slowly making their way into CSS, with emphasis on slowly: variables are in, nesting has been debated for 6 years now.
What else CSS lacks, and will lack forever due to the core nature of HTML and CSS? Actual useful animations. Where you can animate a height: auto, or a list item being removed from a list.
That would be a drastic shift of the philosophy of CSS.
Which currently is:
(1) CSS holds no mutable state
(2) CSS selectors are all based on existing DOM/device state.
"On-click" is not a state, it's an event. CSS can't select an event. And toggling classes is new mutable state. CSS can't have mutable state.
Also you may be overstating the problem with this "so many needless use of JS". It's a tiny snippet you can add once and reuse it everywhere in your document.
document.addEventListener('click', e => {
let n = e.target;
do if (n.getAttribute?.('data-toggle') !== undefined) n.classList.toggle('on-click');
while (n = n.parentNode);
});
CSS hold mutable state see e.g CSS counters.
It's not just about concision, it's also about convenience (not need to do js at all) and about performance (no need to call the v8 engine, which is executed after css and has inherent, avoidable overhead)
You're talking about the performance of a click action. How many clicks a second do your users do? Millions?
Also counters aren't mutable state in the sense of a value changing in time. The "increment" name was chosen so it's intuitive. They're more like the nth-child selectors, where an attribute's value is determined by its position in a list of matching nodes (where the match is determined by the increment being specified in those elements).
I will never like CSS and cannot share any fond memories of it's development.
Modern CSS is bearable with features like Flexbox and Grid, but CSS will never be able to hide how inelegant, clunky and sprawling it is. You could write an entire book on CSS 'gotchas' - from specificity to box-sizing to inheritance. The list of topics is endless.
There are also dozens of different ways of writing CSS (by design) which is why you never see two or more people write it in the same way.
Why did a "style sheet" language incorporate animation into its already bloated feature set? (Not convinced by the argument that animation = appearance and thus fits into the scope of CSS.)
It's a bit ironic that modern CSS features let you finally drop horrible CSS hacks from the past like floats. And yet, developers are not taking advantage of modern CSS features like Grid (which greatly simplifies layout). CSS frameworks often don't take advantage of these modern features either.
In fact, modern CSS makes it easier to write plain CSS without the use of a CSS framework. But is there anyone left who isn't using a framework?
Floats were never a 'hack'. There were hacks that used floats to achieve layouts they weren't intended for. But the flowing of text around a floated element was a required tool that floats enabled.
Devs will catchup with the whole we don't need frameworks thing, but it'll take a few years. I'm not going to go and rip the frameworks out of my existing apps just because I don't need them now, that doesn't really generate any value.
It's like jQuery, it was easily 5 years between when we no longer needed it and when we finally started dropping it.
I don't know why you're not convinced about animation = appearance, but I do agree about frameworks. I've never used one enough, partly because I immediately found they sucked for replacing anything I could much more easily do manually, such as grid.
After the dot-com crash I found myself coding again, and fell into CSS with his book, and managed to carve out a spot for myself as a bit of an early CSS guru in my professional network. Doing that saved my house, quite literally.
CSS can be gnarly and frustrating. This was even MORE true back then when you basically had to create parallel implementations of the same layout to support IE's willfully wrong interpretations of the box model (oh, and its bugs). But it beat the everliving crap out of what came before.
I've long since left that part of my career -- I mostly talk and tell people what to do now -- but I'll always love CSS a little for that period of my life.