Hacker News new | ask | show | jobs
by svl 2135 days ago
The complexity in supporting CSS does not come (primarily) from its individual properties, no matter how obscure. It comes from things like margin collapse, from correctly determining the stacking context, and about a gazillion other things like that.

These aren't things where you can just scan the CSS of the top websites to find out if they're being used. These are things where you'd have to do visual comparisons to the output of at least two other browser engines to determine if you end up with the same result.

Building a browser engine from scratch is imho more doable now than it's ever been before (excepting EME), due to the insane effort by the WHATWG standards to truly describe what is actually happening in browsers (rather than coming up with some theoretically pure description of what is envisioned to happen), and the similar level of detail on the CSS side to the myriad interactions between properties, along with the huge set of testcases for all of that.

Yes, there's _a lot_ - but compared to how loosely specified it all was in the past, when the instruction for building a browser engine was: "reverse engineer the bugs the dominant browser engine of today made in reverse engineering the bugs of the dominant browser that came before, and emulate that to your best ability", anyone starting from scratch nowadays has a way better chance at succeeding.

4 comments

My favourite example of the thousand-yard-stare horror of web specs is Manish's "Font-size: An Unexpectedly Complex CSS Property". It's awful and hilarious and just keeps getting worse and worse and worse.

https://manishearth.github.io/blog/2017/08/10/font-size-an-u...

Yeah so this is exactly the kind of thing I'm talking about:

-----------------

The syntax of the property is pretty straightforward. You can specify it as:

- A length (12px, 15pt, 13em, 4in, 8rem)

- A percentage (50%)

- A compound of the above, via a calc (calc(12px + 4em + 20%))

- An absolute keyword (medium, small, large, x-large, etc)

- A relative keyword (larger, smaller)

The first three are common amongst quite a few length-related properties. Nothing abnormal in the syntax.

The next two are interesting.

-----------------

I've been doing front-end web dev for nearly ten years, and I've never even heard of those last two, much less used them. That's the kind of thing a new browser could defer support for until after the MVP, while barely detracting from the average user's experience.

Though this does remind me that i18n is a thing, and how gnarly of a problem it must be for a piece of software so concerned with text flow/layout, and ideally it's not something that a theoretical upstart browser would punt on.

If people feel the need to use text inside their <canvas> elements, I've done some (not very rigorous) research on how JS engines interpret font size instructions in their canvasRenderingContext2d environments:

- Absolute size keywords ('xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', 'xxx-large') may-or-may-not work — and the resulting size may-or-may-not have a relationship to the <canvas> elements surrounding environment.

- Relative size keywords ('larger', 'smaller') can be hit-and-miss too.

- Absolute length values, defined with px, pt, in, cm, mm, pc, will usually work as expected.

- Viewport lengths (vw, vh, vmax, vmin) will often work; note that these lengths are set on creation and don't automatically resize when the viewport dimensions change.

- For lengths defined by the font itself, rem will use the root element's font size for its reference; %, em, ch can be less helpful. Again these won't automatically resize in a responsive environment.

- Of the rest, Q is not supported by Safari browsers, while cap, ic, lh, rlh, vb, vi are not supported by any browser. Avoid!

> I've been doing front-end web dev for nearly ten years, and I've never even heard of those last two, much less used them.

Huh, that's interesting to hear you say that. I hardly do any web development at all, but I was using both of those things for personal/toy web sites over a decade ago.

Just goes to show you that even rank amateurs can end up exposed to things that professionals haven't seen, for whatever reason.

While I think you're right that the last two are very uncommon, they are not a large contributor to the complexity of handling font sizing. Once you've done all the rest, I suspect you could add them with <5% more work.

Leaving out rare features to build a browser more quickly only makes sense if those features let you remove a lot of complexity from your implementation.

When it gets to the point of diving into the last two, the article literally says:

> Alright, this is where it gets complicated.

I haven't implemented any of the above myself, but the author at least seems to think the last two are where the complexity is concentrated.

Sorry, you're right. I've gone back and read the article and there was complexity in those two that I had completely forgotten about.
> These aren't things where you can just scan the CSS of the top websites to find out if they're being used.

I guess I was drawing a distinction between a certain subset of functionality that's definitely being used constantly everywhere, like the core box model, vs new features that have gotten layered-on over time and specifically designed not to interfere with or change what came before. For example, the CSS Grid standard has zero effect on any part of page layout unless it is explicitly invoked with "display: grid". These hard barriers were drawn to maintain backwards-compatibility, but they could be leveraged to carve out pieces of functionality to not support, or at least defer support for.

> Building a browser engine from scratch is imho more doable now than it's ever been before

I agree. And I would actually add Rust as a factor for that. Don't forget, Rust was literally purpose-built for building a web browser. With its focus on memory safety and safe concurrency, I'd bet it will act as a very real force-multiplier when it comes to a project like this. Devs will spend that much less time chasing down race conditions and memory errors, while at the same time getting something highly parallel and performant.

“due to the insane effort by the WHATWG standards to truly describe what is actually happening in browsers”

I wonder whether one could reuse testcases from other browsers. Might be easier than having humans translate those WHATWG descriptions, written for humans, into a form that computers running tests can use.

And nitpick: it isn’t easier than ever. It was a lot easier for Tim Berners-Lee and the first few other browser writers, before there was a lot of agreement on how a browser was supposed to behave. Certainly, before JavaScript and css, SVG, XML, etc. The scope was a lot smaller.

> I wonder whether one could reuse testcases from other browsers.

Even better: there is a shared set of test cases and infrastructure that the web standards and compatibility folks have built: https://wpt.fyi

Maybe it's time we create a new html rendering engine by training a ML model using w3c specs and tests as input.
Hmm, you might be onto something here. Someone created a react layout generator using gpt3 that translates natural language description into actual layout. Maybe some ml models can be developed to render a layout from HTML content. No need to perfectly render it, just 80% approximate would already impressive enough.