Some time in the past, I used to be inspecting fb.com residence web page feed to study and see how they construct issues out. I’m all the time curious to see how folks write CSS. I seen a really, very fascinating border-radius worth for the cardboard part in the primary feed.

I shared the next tweet about this little discovery. Then, I acquired this reply from Miriam Suzanne:

is it all the time 8px? That math seems to be like a toggle to me, the place at a sure level ((100vw – 4px) – 100%) could possibly be detrimental, toggling 9999 to -9999? Which might flip the worth to 0? Principally: if we’re inside 4px of the total viewport measurement, take away the border radius.

After a couple of hours, Frank Yan from Fb (Yay!) confirmed that it is a conditional assertion to flip 8px to 0px when the cardboard is taking the total viewport width.

Isn’t that simply wonderful?

At first, I believed that it is a sort of bug or one thing that was accomplished by mistake. Fortunately, I used to be mistaken. On this article, I’ll attempt to spotlight the issue, and clarify how the options work.

The issue

We’ve got a card part with a border-radius of 8px. When the cardboard doesn’t have margin or is taking the total viewport width, we wish to flip the border-radius to 0.

This may be accomplished by eradicating the border-radius with a CSS media question like this.

@media (min-width: 700px) {
    .card {
        border-radius: 8px;    
    }
}

In some instances, that’s limiting. If for some cause we wish to activate the border-radius when the viewport measurement is lower than 450px, we might want to create a variation CSS class and use media question once more.

@media (max-width: 450px) {
    .card--rounded {
        border-radius: 8px;
    }
} 

The answer

It is a intelligent one which was accomplished by the workforce Fb. It mimics the next logic:

if (cardWidth >= viewportWidth) {
    radius = 0;
} else {
    radius = 8px;
}

To implement that logic in CSS, we have to evaluate between two values by utilizing CSS comparability features. In case you don’t know them, I like to recommend studying this text by yours really.

The answer is impressed by the article The Flexbox Holy Albatross by Heydon Pickering. It was tailored by Naman Goel from Fb to work with border-radius.

.card {
   border-radius: max(0px, min(8px, calc((100vw - 4px - 100%)
    * 9999)));
}

Let’s stroll by way of the above CSS intimately.

  1. We’ve got a max() perform that compares between 0px and the computed worth of the min(). It is going to choose the bigger worth.
  2. The min() perform compares between 8px and a computed worth from calc((100vw - 4px - 100%) * 9999). This may end result with a really giant constructive or detrimental quantity.
  3. The 9999 is a big quantity to power the worth to be both 0px or 8px.

Let’s clarify the calc() magic!

The magic occurs within the 100% worth. It may be totally different based mostly on two totally different eventualities:

  • It may be equal to 100% of its containing component (The dad or mum/wrapper.. or no matter it’s known as in your CSS).
  • Or, it may be equal to the 100vw, in case the cardboard is taking the total viewport width (E.g: in cell).

Why to make use of 9999?

It’s not as a result of this precise quantity has superpower or one thing. It’s about avoiding an edge case. Due to Temani Afif for reminding me of that.

Let’s suppose that the viewport width is 375px, and the container is 365px. If we substitute these values within the equation, it should seem like this.

.card {
    border-radius: max(0px, min(8px, calc(375px - 4px - 365)));
    /* will end result to */
    border-radius: max(0px, min(8px, 6px));
}

Based mostly on the above, the worth 6px can be picked by the browser. We don’t need that. As an alternative, the radius ought to be both 0px or 8px. To perform that, we will a number of the end result by a big quantity that’s much less most likely for use in CSS, like 9999.

.card {
    border-radius: max(0px, min(8px, calc((375px - 4px - 365)
     * 9999)));
    /* will end result to */
    border-radius: max(0px, min(8px, 59994px));
}

Based mostly on that, the browser will choose the 8px from the min perform, after which the identical worth from the max() perform.

Let’s take an instance based mostly on the primary situation. We’ve got a viewport with a width of 1440px, and the cardboard part lives inside a 700px container.

Multiplying the resulted worth by 9999 will end in 7359264, which is a big random quantity. In that case, the CSS will seem like this for the browser:

.card {
    border-radius: max(0px, min(8px, 7359264px));
}

Since we’ve got min(), it should choose the smallest worth which is 8px. When in comparison with the max(), the 8px will win too. That’s the primary use-case of this intelligent CSS.

.card {
    border-radius: 8px;
}

Subsequent, is when the cardboard is taking the total viewport width. That may be seen in a cell viewport. Discover that the container and viewport width are the identical.

Multiplying the worth with 9999 will end in -39996px, which is a detrimental worth. The browser will learn it like the next:

.card {
    border-radius: max(0px, min(8px, -39996px));
}

Now to the enjoyable! The browser has two inquiries to ask:

  • Which worth is smaller? 8px or -39996px? The result’s -39996px.
  • Which worth is bigger? 0px or -39996px? The result’s 0px.
.card {
    border-radius: 0px;
}

Did you see how that occurred? I’m nonetheless stunned by such a intelligent utilization of CSS comparability features.

We are able to additionally take this to the following stage by utilizing CSS clamp() as steered by Temani Afif and Liad Yosef. I believe workforce Fb didn’t use it because it’s not supported in older variations of Safari (e.g: v12).

.card {
    border-radius: clamp(0px, ((100vw - 4px) - 100%) * 9999, 8px);
}

Test it out on Codepen.

I hope you loved the article. Thanks for studying!

#Conditional #Border #Radius #CSS

Leave a Reply

Your email address will not be published. Required fields are marked *