Sign in

Andreu Botella

@andreubotella.com
142 followers 14 following 68 posts

Browser engineer at @igalia.com. I work on things ranging from CSS and layout in browsers, to Javascript language features, to interoperability between browsers and server-side runtimes as part of WinterTC. They/them

PostsRepliesMedia
Andreu Botella @andreubotella.com · 26/05/2026
Brian's blog post goes in more depth on line-clamp, but it gets rid of the 3-property cruft you need before -webkit-line-clamp will do anything, and it also adds a `line-clamp: auto` syntax to be able to clamp to whatever content fits a given height. It even lets you animate that height!
131
Andreu Botella @andreubotella.com · 02/04/2026
Meanwhile, today in the CSS Working Group:
IRC screenshot (TabAtkins is scribing the meeting in IRC):

TabAtkins: emilio: maybe scroll-snap-align-rect?
TabAtkins: astearns: -basis?
TabAtkins: how about scroll-snap-align-decide-in-two-weeks
*kbabbit pulls up Keith Cirkel's game to look for ideas*
020
Andreu Botella @andreubotella.com · 22/02/2026
Signal message from me:

once again I'm yelling out load to a veritasium video, "no, it's fucking capitalism! enough capital can break down all regulations and make them useless!"
021
Andreu Botella @andreubotella.com · 22/02/2026
My trans friend group:
Screenshot of a Signal conversation. Some names are redacted with colors.

Pichu: Alpine Linux or Not Alpine Linux, the only two genders.
Me: where does gentoo fit in that
Pichu (in response to my "where does gentoo fit in that"): Yes.
Green (in response to Pichu's "Alpine Linux or Not Alpine Linux, the only two genders."): glibc or musl
Green (in response to my "where does gentoo fit in that"): clearly not alpine
Pichu (in response to Green's "clearly not alpine"): Void is Non-Binary.
Me: what if you install gentoo in the alps?
Pichu: It has bot- wait no it doesn't.
Green (in response to Pichu's "Void is Non-Binary."): wdym it's clearly not alpine
Pichu: Which was that ONE (1) Distro that gave you the option between musl and glibc?
Me: distros are a social construct anyway
Pichu: Void let's you pick your init system definitely not the libc though.
Magenta (in response to my "distros are a social construct anyway"): wait this is kinda a good metaphor....
100
Andreu Botella @andreubotella.com · 27/01/2026
Today in the CSS face-to-face meeting we're discussing line-clamp, which is something I've been working on fixing for years. The meeting is in Apple's offices in Cupertino, California, so I'm not attending in person because fuck traveling to the US. This is gonna be my camera feed though:
Photo taken in my office with my webcam, of me wearing a maroon dress, with nails painted purple, and a purple bracelet. I have hair by the shoulders, and also a bit of a short beard.
100
Andreu Botella @andreubotella.com · 27/08/2025
The behavior I would have expected would be something like this: 0% means 1 line, 100% means the full number of lines, and everything is evenly spaced. So clamping by `floor(1 + (percentage / 100) * (numLines - 1))`.
0% -> line 1
25% -> line 2
50% -> line 3
75% -> line 4
100% -> line 5
100
Andreu Botella @andreubotella.com · 27/08/2025
This is the smallest values that trigger clamping by that many lines, on a test with 5 lines. From what I can tell, it behaves like clamping by `max(1, floor((percentage / 100) * (numLines + 1)))` lines. The `numLines + 1` multiplier means you can clamp by the full number of lines (5 here) with 84%
0% -> line 1
34% -> line 2
50% -> line 3
67% -> line 4
84% -> line 5
100
Andreu Botella @andreubotella.com · 06/05/2025
I'm pumped about the enum JS proposal, (that makes enums part of core JS, not just TS) -- not so much because of the proposal itself, but because one of the possible future directions for it would finally let JS evolve to crab. 🦀
A slide, titled "Algebraic Data Type Enums":

- Algebraic Data Type (ADT) enums are structured objects with some form of discriminant property.
- ADT enums would tie in nicely with Extractors and Pattern Matching

A code sample follows:

enum Option {
  Some(value),
  None()
}

enum Result {
  Ok(value),
  Error(reason)
}

match (opt) {
  Option.Some(let value): console.log(value);
  Option.None(): console.log("<no value>");
}
020