Flexbox Holy Albatross
In their post-lunch talk at Patterns Day 2019, Heydon talked about the flexbox holy albatross layout pattern.
The Flexbox Holy Albatross
The Flexbox Holy Albatros, breaking it down:
- Flexbox, the CSS layout. A way of arranging boxes inside of other boxes.
- We also have grid, but flexbox is not superseded by grid
- Holy, as in Holy Grail, wanted to find a solution to a specific layout problem in web development
- Albatross, an allusion to a famous rap by Sammy C. It’s in the name, because it took a long time to solve the problem.
- The problem, a basic layout with a parent that has child elements, where flexbox fills the space with the child.
- When you create a basic flexbox layout, you have
flexbox: wrap;by default where a widow child element would fill the rest of the available space.
- The problem is, that
flexbox: wrap;the child item, to a user, is treated differently, because it looks different.
- What if we could bypass the stage, where a widowed child element takes the full-width, but without breakpoints.
“Why not use breakpoints?”
- Pertinently, media queries are a hack. They don’t work with design systems, they don’t need to be in design systems.
- The media is constant, but with media queries but the context is not.
- What about using container queries? Nope.
- We could use JengaScript, named because of it’s way of handling errors. If you write an error, or somebody else does - it won’t work.
- There could be use of resize observer, note - this only handles pixels. not ems, rems, ch, etc.
The Flexbox Holy Albatross Reincarnated
- The layout has to make the decision, kinda like a boolean, which CSS doesn’t have. This can be done with CSS custom properties and the cascade which can “turn things off and on”.
- max-width always beats width, similar with min-width and width.
- If you have a negative flex-basis - it will default to zero.
- if we wanted gutters we could use
gapbut this is (currently) only supported in FireFox.
- You could create gutters with margins, but this could break unless you add more declarative rules.
- So, add margins to everything, and then you can remove from it, as you’re surprising the negative values.
- Bonus: we can use quantity queries. This allows the browser to work out what it needs to do with styling child elements, but without using media queries.
“You want to be your browsers mentor, not it’s micro manager”
- simple layouts, that can be built upon each other to create a component.
- the layouts are using Web Components, so you can drop them into things like Vue, Preact, etc.
- they feature ‘getters’ and ‘setters’, sensible defaults with composition over inheritance.
- Web Components doesn’t show its CSS to the DOM - there is a fork of JSDOM that can do this using a transform in 11ty, and you need to remove ShadowDOM > creates a unique string of all the styles and that can be added to the HTML.