Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
How Browsers Lay Out Web Pages (browser.engineering)
269 points by pavpanchekha on April 6, 2021 | hide | past | favorite | 50 comments



This is excellent. However much effort I've put in I've always found HTML or rather CSS impenetrable. When doing something a little more complex I will often end up with something that works (or breaks) without fully understanding why.

Are there any other good references that give a good underlying understanding of HTML/CSS without just giving examples of the various elements?


>Are there any other good references that give a good underlying understanding of HTML/CSS without just giving examples of the various elements?

Yeah. The W3C spec.

A few years ago (before css flexbox and grid were really a thing), I was in your shoes. Anytime I needed to do something non trivial, I'd have to find some snippet from some tutorial site that would kind of fit with what I was looking for. At some point I got tired of that and just read the W3C specification. That's when I finally got the CSS layout manager. The specification was very accessible and explained exactly the layout rules. For example, here's the spec on the CSS box model: https://www.w3.org/TR/css-box-3/

Now that flexbox and grid are universally supported in modern browsers, css is actually quite easy.


Don't have any references for you but maybe I can give some perspective on it.

The things that still trip me up with CSS after a few years of full time frontend work are the following:

1. Dynamic 2D stuff

CSS kinda sucks for most 2D dynamic layouts. Especially when you have heights that are dependent on widths or the other way around. With CSS grid and the upcoming aspect-ratio things are better but I still run into some limitations in especially dynamic web apps / data visualizations I make and I usually resort to calculating the widths/heights in javascript so I can have full control.

2. Going into the third dimension

I'm not a big fan of the z-index / position absolute / relative stuff going on in css. I'm not sure what a better way would look like, but every so often I run into weird issues where a parent somewhere is relative and it messes up an element I'm trying to absolutely position.

Most things can be worked around but it's still annoying and usually take longer than what I feel they should.

Apart from these, most of the quirks of CSS are very mild and can be worked around easily. I actually find writing CSS quite enjoyable day to day.


Author here. Unfortunately, a lot of this "conceptual" content doesn't really exist, just because there aren't that many people who work on web browsers, plus it takes a lot of work to get a comprehensive view.

I wrote up this guide about CSS floats, for example: https://pavpanchekha.com/blog/css-floats.html It is just about complete, but it also took me about a year of work to get that understanding (from reading the spec, reading browser code, trying many many examples) and it lead to a published paper. And even then, it doesn't talk about negative top margins or refer to actual implementations!


I'd say a good start would be:

* Stacking context [1] — how individual layers interact with eachother to form a layout.

* Box model [2] — the most important properties that give an individual element its dimensions.

[1]: https://tiffanybbrown.com/2015/09/css-stacking-contexts-wtf/

[2]: https://css-tricks.com/the-css-box-model/


CSS The Definitive Guide by Eric Meyer is a deep dive book into all aspects of modern CSS by an expert.


For those wanting to dive deeper, the layout code in Chromium is surprisingly easy to read considering its a 20+ year old codebase.

This is a good starting point:

https://source.chromium.org/chromium/chromium/src/+/master:t...


Author here. Yes, the Chromium code is very good, and I learned a lot from reading the Servo code as well. We hope to do some more advanced chapters at the end of the book that reference real browser code bases more directly—if we can find an interesting way to write them, anyway.


How much diverged is this code from WebKit? 20 years ago Blink didn't even exist, right?


Most of it. The main changes from WebKit to blink are a different approach to memory allocation (oilpan) and object lifetimes to help security.

Most of the main files still say Copyright 1999 **@kde.org showing the origin of the original codebase that hasn't changed much to today.

It's now so huge and complex that a major redesign/rewrite is pretty much out of the question.

It's still mostly single threaded and all the main objects aren't thread safe. JavaScript shares that thread too. Parts of the rendering are multiththreaded and async, but that's it.


This tutorial looks amazing. I know what I'm going to be doing the next few weekends.


It’s such a great idea for a book!

I quite like Python but really I want a version all written in NodeJS, so it’s javascript all the way down :)


Hi mjgs. I'm one of the book's authors, and we debated this quite a bit. The reasoning for using Python is written up here: https://browser.engineering/blog/why-python.html

That said, it's pretty easy to follow along in JS if you really want and in fact... Stay tuned, there'll be an update in this space very soon.


Thanks for the reply. I like that you’ve chosen a scripting language, it makes the book much more accessible. If it were in c / c++ / rust etc, I would never read it.

Thanks for sending the writeup of why you chose Python.

As for javascript readability issues, IMO those are non-issues and actually in some ways beneficial to have one language, no need to context switch.

The web workers issue is perhaps a problem, but maybe it makes the implementation easier, even if it doesn’t look much like real browsers?

I don’t understand the networking issue you highlight, you can build any networking functionality using NodeJS, it’s actually very good in networked application settings.

With so many people that write code online in javascript, the book would be so much more accessible. It would be a great compliment to the Python version or any C / C++ version.

I’m interested to hear your update, what’s the best way to get that automatically?


One other thing...this passed by in my feeds last week, I’m not an expert in web workers or browser threads etc, but it seems like it might be relevant, so sharing it just in case:

“A fast, efficient Node.js Worker Thread Pool implementation”

https://github.com/piscinajs/piscina


Right! I'm working with the web since 2006 but still I find this book a must to read.


Yes! Apparently it's still being written.... and I NEED them to get to the CSS bits.


Book author here. A basic styling engine is the very next chapter, so it should be out in about two months, depending on how the writing process goes.


Incredible, thank you!

I believe expanding the simple version into a decently robust rendering engine will be the ultimate way for me to learn CSS.

Thanks so much again!


No doubt I'll do something crazy, that is, try to implement this in C.


I was going to > inb4 rust!, but, isn't Gecko built in Rust?


Gecko is (mostly, at least) traditional C++. Servo is written in Rust.


Would Rust be the best choice of language, given all the back pointers (previous, parent)?


Trees are not that bad in Rust, it's when you have a cyclical structure that Rust is really difficult.


Yes, that's what I meant by "back pointers". In the article, every node has a parent pointer and a child pointer (or several). You can't have both of these pointers without introducing cycles.


The style parts are in Rust, but layout is C++, I believe. servo does have an experimental layout engine (or two? layout 2020?) in Rust, but I don't think that ever reached a point where Mozilla were seriously considering replacing Gecko's with it.


I think Servo is basically a proving ground for replacing components in Firefox with Rust equivalents.


This is excellent, but I also recommend the following that describes how text is laid out of the screen:

https://raphlinus.github.io/text/2020/10/26/text-layout.html


I wish this web page used a smaller font, 24px (18pt) is really, really large. (HN comments are 9pt.)

The page's ToC uses 60% of the body font, which is ~10pt.


Hit "CTRL" and "-"! You will be amazed to find the page shrink, and the font alongside it!

I personally like it around 67%.

I'd prefer most sites have smaller fonts; there's no need to complain about it, though, because browsers allow you to make text smaller pretty easily, as long as the site doesn't go out of its way to deny you that.


Definitely; I often increase the size of fonts when they're too small for my liking. I have HN at 125%.

The important part is not so much getting the right font size, but making sure the user's browser can change it well enough.


Plus add line-height: 134%; and you are set! :)


It's funny you say that, I usually view Hacker News zoomed in at 250% (on desktop) because the font is tinier than I'd like.


Yup - I increase the font size a lot these days, especially on mobile.

I haven’t looked into the best way to write web pages that accommodate zooming, but there is a huge variety in how pages perform as you zoom.

Loads of sites don’t do it properly, where you zoom and all the text and images get squashed in the middle of the page, or where the elements disappear off the side of the page. The other horrid thing is when you zoom and then the text is the right size but you end up having to scroll left to right to read the text.

The best sites perform perfectly at every zoom level, with all the content resizing properly so the reading experience is always pleasant.

I’d love to read some tutorials on how to ensure your website performs in this way. In my opinion it’s one of the signs of a really skill-full developer.


Pages are perfect by default (except for a serif font being by default on some screens and the line length not being limited to something readable).

The less you do, the best the web page behaves.

The more you fight against default behaviors / layouts, the more things break.

But more specifically, be careful with margins, they grow with the zoom level, often more than wanted. Same for position. And be careful with sizes fixed using something else than percentages for the same reasons. If you don't want a block be larger than 100ish characters for readability, use max-width with a font related unit, not straight width and not some other kind of unit.


Me too, at 200%. My eyes are getting old.


My userstyle sets 13pt in a bigger font with lots of line-spacing, looks like I'm in the over 200% crowd :)

I can read smaller text for a bit in a single block, but when it's something like a comment section I need things a lot bigger to be able to skim through comments to spot things I'm interested in.


200% club aswell


I enjoy this page’s typography on a smaller mobile screen. Line lengths, line spacing, font size, everything seems great for a medium-length read.

HN is great too: an assortment of pieces of text, having varied lengths and organized into a tree-like hierarchy, warrants tighter typography.


Hi, book author here. All the typographic tips are lifted practically directly from Matthew Butterick's Practical Typography: https://practicaltypography.com


Hi Inityx—book author here. My eyesight is bad, hence the big font. It should respond well to browser zoom, or if you narrow the page there's a narrower layout with smaller fonts.


Generally that's meant to be a user setting not a content setting. E.g. if the user likes 1.5x content for their eyesite they either set the OS to 150% scaling as a whole (or the browser default to 150% scaling should that not be available for some reason). Now everything they use is exactly the right size for them the instant they view it.

If the content tries to do this on behalf of certain users then site X ends up being 1.5*1.5=2.25x zoomed while site Y ends up being 1.5*.66 = 1x zoomed effectively turning a single setting that solved the accessibility and preference problem for everyone into a per content-piece nightmare again. Font size/weight/settings in a design is meant to change relative proportions of a design (e.g. headers, emphasized words, side notes) not to act as the overall scaler for the user - that's already available out of the box.

If this post weren't how browsers lay out web pages I wouldn't be such a stickler but to ignore this is to throw out the main advantage of the sizing model browsers use.


Is there a good page about font sizes, spacings and all that?


Here's a fun tool someone shared with me for experimenting with different font params: https://mbarkhau.keybase.pub/readable-text/index.html


Awesome! Thank you


> Finally, functional languages tend to fight against large, mutually-linked, mutable data structures, yet the layout engine of a browser is all about that.

Is the DOM (and LayoutObject et al.) truly a case where imperative object-oriented programming shines? In pure FP operations like insertion, bidirectional traversal, and moving objects between parents can be cumbersome because there is no implicit identity for the objects.

Curious whether this is true, or is there a way to implement a DOM-like API with mostly immutable values?


Random thought: why do we still call them "web pages"? They're not hypertext pages anymore and browsers are not hypertext document browsers anymore.

(It should probably be called "VM for UI apps that run directly from URL and written in UI stack that has never been intended for UI apps, and has weird tabbed window manager")


> Elements like <body> and <header> contain blocks stacked vertically. But elements like <p> and <h1> contain text and lay that text out horizontally in lines. ( In European languages, at least! )

Another day, another features despite PDF not being perfect, is still miles ahead of HTML. I am not even sure if there are any intention to bring vertical Japanese subtext feature to HTML.



> I am not even sure if there are any intention to bring vertical Japanese subtext feature to HTML.

Perhaps not HTML itself, but the first draft for writing modes in CSS is over 10 years old: https://www.w3.org/TR/2010/WD-css3-writing-modes-20101202/

> This module specifies the text layout model in CSS and the properties that control it. It covers bidirectional and vertical text.

There have been numerous revisions in the subsequent years. In 2017 w3.org published this article specifically on using vertical text in paragraphs, forms, lists and tables: https://www.w3.org/International/articles/vertical-text/




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: