XUL layout removal progress

770 views
Skip to first unread message

Emilio Cobos Álvarez

unread,
Oct 17, 2022, 6:22:40 PM10/17/22
to dev-pl...@mozilla.org, firef...@mozilla.org
Just FYI, bug 1790616 and dependencies are on autoland (and hopefully
will stick).

That bug turns on flexbox emulation for browser.xhtml, which means that
(almost, see below) all the browser UI will be rendered using flexbox
rather than XUL layout, including the tab bar, toolbar, popups...

If you see any odd layout regression with the tab bar or toolbar
customization, etc, please file bugs and needinfo me, they're usually
trivial to fix and I'm happy to fix them of course :)

Things that are already using XUL emulation before this patch include
about:preferences, DevTools, the profile chooser dialog, and the tab
area of the browser. It's expected that browser.xhtml is the hardest, so
eventually we should flip the default, but step-by-step...

Btw, thanks to Gijs / Dao / Julian Descottes / Itiel / Shane (and
probably others, I always miss someone, sorry!) for all their help with
reviews, it's been invaluable!

# What does it mean?

What it means in practice is that these things should work now where
they didn't work consistently or at all before:

* Percentages on sizing properties ({min-,max-,}{width,height}).
* Absolute / fixed positioning.
* Negative margins.
* Should interact properly with other kinds of CSS layout.
* Probably a long list of etceteras, these are just off the top of my
head.

This also means that writing test-cases or porting browser UI to
actually use display: flex rather than display: -moz-box should be
trivial-ish. The property mapping works as follows:

* display: -moz-box -> display: flex
* -moz-box-flex: N -> flex-grow: N; flex-shrink: N
* -moz-box-align -> align-items:
* stretch -> stretch
* start -> flex-start
* center -> center
* baseline -> baseline
* end -> flex-end
* -moz-box-pack -> justify-content:
* start -> flex-start
* center -> center
* end -> flex-end
* justify -> space-between
* -moz-box-orient + -moz-box-direction -> flex-direction
* vertical + normal -> column
* vertical + reverse -> column-reverse
* horizontal + normal -> row
* horizontal + reverse -> row-reverse
* -moz-box-ordinal-group: N -> order: N

Porting to flexbox allows you to use all the goodies
(align/justify-self, flex-basis, ...).

# Behavior differences

While it's very close (that's why this is feasible to begin with), flex
emulation is not an exact replica of our old XUL layout.

Here are the things that are more likely to cause changes, and how to
(usually) fix them, along with examples.

These are the ones that come to mind, if they're useful I can put them
up in the in-tree docs or so.

## width/height are more frequently honored

With XUL, something like width: 100px wouldn't quite do what it says. If
it had content that was wider than that it'd expand over that size, if
the container was bigger it'd flex over it.

What it means in practice is that a bunch of explicit width/heights need
to become min-width/heights.

An example of this could be <https://bugzil.la/1795339>.

## Scrollable elements contribute more to the flex min size

(This is a rather annoying behavior with modern flexbox, IMO)

If you have an element which is flexible, but has scrollable overflow
(overflow: auto/hidden/scroll), it might still grow the surrounding flex
container based on the scrolled contents, rather than scroll.

The right fix is to have min-{width,height}: 0 on the flex item(s), or
alternatively contain: {size,inline-size}. contain is a simpler fix (you
don't need to specify min-{width,height} on all flex items), but is a
bit more aggressive.

Examples of this could be <https://bugzil.la/1794499> or
<https://bugzil.la/1793505>. <https://bugzil.la/1795286> is an example
of the contain vs. min-* behavior making a difference.

## Minimum sizes are slightly different

On XUL, automatic minimum sizes of flex items are roughly calculated by
recursively adding all margin/border/paddings and min-{width,height} of
descendants.

On flexbox, the automatic content sizes actually lay out the element
(ignoring percentages, etc).

In practice the new behavior should be more intuitive (except for
scrollers as mentioned above), but sometimes it may make stuff grow
where it didn't before.

# What's missing?

At the beginning of the email there's a tricky _almost_. While almost
every XUL element has been ported to respect `display` (and thus use
modern flexbox when enabled), there are a few that aren't still ported.

My priority with this work is first making the front-end team's life
easier, then (eventually) make the layout team's life easier by removing
a lot of poorly-maintained code.

Given that, I plan to prioritize fixing first the elements that will
save paint to front-end devs.

My current order of priorities is:

## Menus

That is, <menulist>/<menupopup>/<panel>/<menu>/<button type=menu>.

These have a bunch of event handling code in layout code, which is
non-trivial to port. I'm hoping to just switch them all to modern
flexbox in one sweep by changing the layout class inheritance in
<https://bugzil.la/1551637>.

If that somehow doesn't work I'll do the actual work to move all of them
to the DOM like buttons (<https://buzil.la/1790920>), ideally also
simplifying some of the layout code.

This is the biggest source of weirdness coming from XUL layout that I
expect, and the most complex chunk of work, so I hope to address it
ASAP.

## Some label / description elements

The ones with `value` attribute in particular. The only requirement that
I'm aware of that CSS layout doesn't have is middle-cropping (which is
used e.g., for filenames in the downloads panel).

I haven't figured out a great solution for that just yet. We do have
some middle-cropping support for the file input element, so maybe I just
reuse that.

These are not particularly problematic since they are just one line, so
weird sizing issues are not expected to happen.

## XUL image elements

These use list-style-image etc, and are not particularly hard to port to
regular HTML layout, or convert to HTML img elements (or use content:
url()).

Same as above, these aren't expected to be problematic because they're
leafs and they behave pretty much like any other HTML replaced element
already. Given that, not the highest priority to remove to achieve the
first, but if you want a fun layout project please let me know, should
be a good clean-up.

## Scrollbars

These have been using XUL since ~forever, and right now keep doing so.
These are definitely not expected to cause trouble because they are very
special already, and we use the XUL in HTML. Probably one of the last
few things to go away.

## XUL treebody

This still uses XUL layout. In practice it doesn't seem to interact
poorly with flex emulation, so I haven't dug into porting it just yet.

Thanks for reading till the end, if you made it. Let me know if you have
any questions or so, happy to help!

Cheers,

-- Emilio

Mike Conley

unread,
Oct 18, 2022, 11:49:52 AM10/18/22
to Emilio Cobos Álvarez, dev-pl...@mozilla.org, firef...@mozilla.org
As someone who's dealt with my fair share of XUL layout quirks and frustrations (especially when intermingled with things using the CSS layout engine), this makes me so so so happy.

Thanks so much Emilio - I'd say there's a high likelihood that you're saving us a ton of future debugging time.

-Mike

--
You received this message because you are subscribed to the Google Groups "firef...@mozilla.org" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firefox-dev...@mozilla.org.
To view this discussion on the web visit https://groups.google.com/a/mozilla.org/d/msgid/firefox-dev/52038aac-e1ec-0e5d-3009-8da7ac8214f4%40mozilla.com.

Brian Grinstead

unread,
Oct 18, 2022, 7:52:52 PM10/18/22
to Mike Conley, Emilio Cobos Álvarez, dev-pl...@mozilla.org, firef...@mozilla.org

+1. And having been involved in efforts to remove similar stuff from Firefox, I wanted to take the opportunity to reflect on the fact that features like this are actually a success story for the web in their own way.


XUL layout had to be invented because there wasn't an equivalent on the web platform at the time - I don't know the background of flexbox as well as XBL but as best I can tell the first commit for "box layout system" was in March 1999.


10 years later CSS flexbox was drafted as a spec after what I’m sure was lots of learning about the good and bad parts of XUL (https://www.w3.org/TR/2009/WD-css3-flexbox-20090723/):


> This model is based on the box model in the XUL user-interface language used for the user interface of many Mozilla-based applications (such as Firefox).


It did have a bumpy onramp (documented in https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox) with a breaking syntax update in 2012 (https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/) and then a non-vendor-prefixed version finally releasing in most browser during 2013-2015 (https://caniuse.com/flexbox).


But by now there’s a whole ecosystem around flex and other modern layout features, like good tools (https://firefox-source-docs.mozilla.org/devtools-user/page_inspector/how_to/examine_flexbox_layouts/index.html), docs (https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox / https://css-tricks.com/snippets/css/a-guide-to-flexbox/), and lots of people who know how to use them.


So when we look at XUL flex today by comparison it’s poorly documented, not as capable, lacks tooling support, and requires difficult onboarding for frontend developers. But the good part is that a better set of technologies for layout emerged from it, and we can use them instead.


Not to mention the fact that we can reliably use position absolute now - my own personal pet peeve :). Thanks Emilio for pushing this forward.


Brian


You received this message because you are subscribed to the Google Groups "dev-pl...@mozilla.org" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dev-platform...@mozilla.org.
To view this discussion on the web visit https://groups.google.com/a/mozilla.org/d/msgid/dev-platform/CA%2B3p4uZi66dEadghpM9at%3DnTB2DJg6ctN5OHMvPSxndM9QpkwA%40mail.gmail.com.

Emilio Cobos Álvarez

unread,
Mar 30, 2023, 1:33:42 PM3/30/23
to dev-pl...@mozilla.org, firef...@mozilla.org
Just wanted to do a quick update here.

This is done, all the XUL-box layout code in the tree is gone. Most of
it went away in:

* https://hg.mozilla.org/mozilla-central/rev/c134b1c8a8ed
* https://hg.mozilla.org/mozilla-central/rev/0e21add6bf2c

I wrote a bit about what it took, and the process, and some history,
before it evaporates from my poor memory:

* https://crisal.io/words/2023/03/30/xul-layout-is-gone.html

Thanks to everyone that helped with this effort!

Cheers,

-- Emilio

Mike Conley

unread,
Mar 30, 2023, 1:45:10 PM3/30/23
to firef...@mozilla.org
This is wonderful! Thank you so much for driving this over the line, Emilio!
OpenPGP_0x58722F55DDDB00CE.asc
OpenPGP_signature
Reply all
Reply to author
Forward
0 new messages