← Back to context

Comment by mannyv

19 hours ago

One great thing about this book is the 'stuff I didn't do' part.

Layout is really hard. Just tables by themselves are hard, even without any css around them. CSS makes layout impossibly difficult. I challenge anyone to keep the whole CSS spec and its associated behaviors in their head.

At this point css + html + javascript have become a dynamic PDL, and probably is one of the most complex pieces of software today.

As an aside, video decoding is offloaded onto hardware, so it's not as battery intensive as it used to be.

For the absolutely massive amount of code one needs to implement for production-grade CSS layout, the Servo source code is illustrative and IMO quite cool to see. For instance, this file just implements block and inline contexts; there's a bit of Rust boilerplate here, but the vast majority of lines are "business logic" around various parts of the specification. And there's a whole folder of these. https://github.com/servo/servo/blob/main/components/layout/f...

But implementing a layout engine is doable. CSS is not magic; there's a spec that can be (meticulously) transformed into code. I've occasionally showed code like this to people frustrated that CSS seems arbitrary, just to show them that there is a logic to the execution environment. Granted, you're not going to regularly click into it the way you'd click into the implementation of a library, but it's no different from something like React in that regard. I think it helps!

  • FWIW, Pavel, one of the authors, has devoted considerable time into what is one of the very, very few attempts at a formal specification for CSS (the static/float layout fragment cf [1]). It's a Racket program generating Z3 SMT solver code for verifying an instance layout (which also looks like Scheme) so it's not for the faint-hearted ;) but maybe just what an FP fan on HN is looking for as a challenge.

    [1]: https://pavpanchekha.com/blog/css-floats.html

    • Wow, thanks, you always suspect no one has actually read the papers :) That was a crazy project... I eventually got it passing almost all of the WPT css2 fragment.

      I'm still working on CSS layout, with hopefully another paper coming soon.

      2 replies →

Yes, layout is difficult, especially because (I think):

1. The most "core" parts of layout, like CSS 2 stuff, is pretty poorly considered with a bunch of weird features that interact in strange ways. (Floats and clearance? Margin collapsing?) Some parts of this "core" were intended to be universal even though they're a bad fit for other layout modes. (Margin and padding, for example, don't have a clear purpose for say grid elements.)

2. It's not well-modularized the way JS APIs are. A JS API can often be implemented fairly stand-alone, but each layout module interacts with every other layout module since they can be nested in various ways. I think newer specs like grid are trying to be stricter with this but there are fundamental challenges: the actual 2D screen is a shared resource that different layout modes must split up.

Layout is so difficult that it made me quit using Common Lisp and ncurses to build my passion project and become the very thing I swore to destroy (a React developer).

I can't be the only one who wants a simpler layout language than CSS that's designed with two decades of hindsight to provide the maximum simplicity-expressiveness product. Are there any serious projects to engineer something like this, or has everyone given up and either embraced CSS3 (waiting for the LLVM backend) or gone back to plain text?

  • Author here, and I also teach web dev, including CSS, at the University of Utah (including this semester). Newer parts of CSS, like flex-box layout are both simple and powerful. Just use those! I think it's important to start thinking about learning all of the Web Platform like you'd think about learning all of the Windows APIs or all of the Linux system calls or all of your favorite programming language's features. People rarely do! (I have 15 years of Python experience, and I do not understand metaclasses or async.) There are lots of weird obscure corners, but you don't need to know those to build websites.

  • Constraint-based layouts. The world's most sophisticated UI system uses that (Apple's UIKit).

    • I was playing with Solvespace a few weeks ago, and the thought occurred to me that the constraint-based modeling approach is exactly what I want in a layout system, and it extends to 3d even. We're stuck with CSS for now, but this must be the future.

For React Native the facebook engineers just gave up and were like "all you get is flexbox layout" and people were quite okay with that (although some people grumble about lack of display grid)

https://github.com/facebook/yoga

  • It works great for small devices, but I prefer ios constraint layout (and I think android got it too). No need for spacers.

This Babylonian tower will crumble one day.

Layout does not have to be so complex. There are dozens of GUI frameworks with simpler layout system. Those are enough for applications everyone uses.

  • Actually, almost every GUI toolkit's scheme for layout has issues, and none of them are perfect.

    The ones that use absolute pixel positioning fail when using different resolution displays.

    The ones that use box packing fail when you need to deal with different sized displays.

    The ones that use constraint programming fail when you need to layout hundreds or thousands of widgets.

    CSS-style layout has its own pros and cons, but there is no alternative to it that is clearly better under all circumstances. If you doing layout and want to be resolution-independent, function on everything from phones to giant displays and have thousands of things to layout, CSS is actually likely better than any alternative.

  • And they all have massive issues, or just provide a worse version of CSS (QT's qss, for example, as it's just a less well documented, non standard and very sparsely talked about CSS implementation. Oh and it doesn't work for everything in QT)

  • Pixel positioning is so nice! I remember how easy it was to layout UIs with VB.

I did layout for a feature phone browser. WAP and mercifully XHTML-basic’s ideas of layout was simple enough that I could treat spans as a concave octagon - a rectangle with a bite out of the upper left and lower right corner. It made it at least an order of magnitude faster to paint and scroll a long document, and much simpler to think about.

In the years since I’ve used a lot of tricks for web app CSS that I’m not sure I’m smart enough to figure out. But then I’ve never thought as long and as hard about typesetting as I did at the time so who knows.

Modern CSS implementations are full blown geometric constraint solvers now. The only things approaching their algorithmic complexity are now other geometric constraint solvers like CAD kernels and silicon layout software.

Tables are trivial in comparison to floats. If you think the latter are easy --- there are many (literal) edge-cases to consider.

> As an aside, video decoding is offloaded onto hardware, so it's not as battery intensive as it used to be.

This is technically but not usefully true with most videos on the web today.

The video decode itself is accelerated, but each frame passes through JavaScript to be composited.

The only time video is fully hardware decoded is when it's a simple video element to a static video file.

  • > The video decode itself is accelerated, but each frame passes through JavaScript to be composited

    I don't think that's true, and it's even less true once DRM video is involved - it becomes very difficult to get other software on the machine to even see the video, at least on Windows. You can very occasionally see bugs where the hardware accelerated playback ends up in a different place to where the browser thinks the video should have been put, too.

    What does happen is the video data gets reassembled in Javascript (e.g. Video.js) because the native player doesn't support HLS. Not quite the same thing. It's just reformatting MPEG-TS to the similar but not identical MP4. Oddly, the browser in my LG TV does play HLS video natively, and I think Safari does?

  • > not usefully true with most videos on the web today

    > The only time video is fully hardware decoded is when it's a simple video element to a static video file.

    These seem in disagreement to me. The vast majority of videos on the web are simple video elements going to static video files. It is not usual for each frame to pass through JavaScript before being displayed.

    • Most of the things you think of as static video files (say youtube) are actually video segments operating more or less exactly the way live streams work.

  • I think by "JavaScript" here you mean rendering—that's partially true. In macOS and Windows these days (also I think Linux with GTK4 on Wayland, though only in a limited way), the window manager is itself composited and a window can send a small display list to that window manager for it to composite. In that case, it's possible to actually have the video decoding to happen entirely in hardware and never have the browser directly interact with decoded video bits. That said usually the window manager compositor is pretty limited and the browser will only do this when the stars align. The sort of things that can break it are any kind of weird clipping, transparency, or effects applied to the videos.

  • > each frame passes through JavaScript to be composited

    What do you mean by that? There is no Javascript doing the actual compositing, and the actual compositing is (usually) hardware accelerated.

> I challenge anyone to keep the whole CSS spec and its associated behaviors in their head.

Lol, no way.

People are always "guess what JS does, wut."

Doesn't hold a candle to Cascading Stylesheets.