Ahmad Shadeed documents a bonafide CSS trick from the Facebook CSS codebase. The idea is that when an element is the full width of the viewport, it doesn’t have any border-radius
. But otherwise, it has 8px
of border-radius
. Here’s the code:
.card {
border-radius: max(0px, min(8px, calc((100vw - 4px - 100%) * 9999)));
}
One line! Super neat. The guts of it is the comparison between 100vw
and 100%
. Essentially, the border-radius
comes out to 8px
most of the time. But if the component becomes the same width as the viewport (within 4px
, but I’d say that part is optional), then the value of the border-radius
becomes 0px
, because the equation yields a negative (invalid) number.
The 9999
multiplication means that you’ll never get low-positive numbers. It’s a toggle. You’ll either get 8px
or 0px
and nothing in between. Try removing that part, resizing the screen, and seeing it sorta morph as the viewport becomes close to the component size:
Why do it like this rather than at a @media
query? Frank, the developer behind the Facebook choice, says:
It’s not a media query, which compares the viewport to a fixed width. It’s effectively a kind of container query that compares the viewport to its own variable width.
Frank Yan
And:
This is a more general purpose solution as it doesn’t need to know the size of the card. A media query would be dependent on the width of the card.
Naman Goel
The technique is apparently called the “Fab Four” Technique which is useful in emails.
Very neat and interesting. The
4px
part I think is for when you have a vertical scrollbar. Just confirmed it, the technique won’t work without it.It could also be replaced with a calculated value that is equal to the scrollbar width
The scrollbar is larger than 4px. I did some quick testing. In desktop Safari, the value needs to be at least 15px to produce a 0px border radius.
Neat trick! What I don’t understand is why it’s working on
border-radius
only? Padding, margin etc. all ignore values computed this way.Have you tried it with padding or margin? They never say it only works with border-radius, it’s just that is how Facebook uses it