Условный border-radius в CSS

0 235

И поделился следующим твитом об этом открытии. Затем, я получил такой ответ от Мириам Сюзанн:

Через несколько часов, Фрэнк Ян из Facebook подтвердил, что это условный оператор, чтобы изменить 8px на 0px, когда карточка занимает всю ширину окна просмотра. Разве это не потрясающе?

Сначала я подумал, что это какая-то ошибка. К счастью, нет. В этой статье я постараюсь осветить проблему и объяснить, как работает ее решение.

Проблема

У нас есть карточный компонент с border-radius равным 8px. Когда карточка не имеет поля или занимает всю ширину области просмотра, мы хотим изменить ее border-radius на 0.

Условный border-radius в CSS

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Условный border-radius в CSS

Это можно сделать, удалив border-radius с помощью медиа-запроса CSS, подобного такому:

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

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

В некоторых случаях это ограничение. Если по какой-то причине мы хотим активировать border-radius, когда размер области просмотра меньше 450px, нам нужно будет создать вариативный класс CSS и снова использовать медиа-запрос.

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

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

Решение

Это умный пример, сделанный командой Facebook. Он имитирует следующую логику:

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

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

Чтобы реализовать эту логику в CSS, нам нужно сравнить два значения с помощью функции сравнения CSS. Решение вдохновлено статьей Хейдона Пикеринга «Священный альбатрос Flexbox». Наман Гоэл из Facebook адаптировал его для работы с border-radius.

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

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

Давайте подробно рассмотрим приведенный выше CSS.

У нас есть функция max(), которая сравнивает 0px с вычисленным значением min(). Она выберет большее значение.

Функция min() сравнивает между 8px и вычисленным значением из calc((100vw — 4px — 100%) * 9999). Результатом будет очень большое положительное или отрицательное число.

Большое число 9999, заставляет значение быть либо 0px либо 8px.

Давайте объясним волшебство calc()! Волшебство происходит в значении 100%. Оно может отличаться в зависимости от двух разных сценариев:

Оно может быть равно 100% содержащему его элементу (родительский элемент / оболочка .. или как он там называется в вашем CSS).

Или оно может быть равно 100vw, если карта занимает всю ширину области просмотра (например, в мобильном телефоне).

Условный border-radius в CSS

Зачем Использовать 9999?

Это не потому, что это точное число имеет суперсилу или что-то в этом роде. Речь идет о том, чтобы избежать крайнего случая. Предположим, что ширина области просмотра равна 375px, а контейнера — 365px. Если подставить эти значения в уравнение, оно будет выглядеть так.

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

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

Условный border-radius в CSS

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

На основании вышеизложенного, браузером будет выбрано значение 6px. Мы этого не хотим. Вместо этого радиус должен быть либо 0px либо 8px. Для этого мы можем умножить результат на большое число, например 9999.

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

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

Исходя из этого, браузер выберет значение 8px из функции min, а затем то же значение из функции max(). Возьмем пример, основанный на первом сценарии. У нас есть окно просмотра шириной 1440px, а компонент карты находится внутри контейнера 700px.

Условный border-radius в CSS

Умножение полученного значения на 9999 приведет 7359264 что является большим случайным числом. В этом случае CSS для браузера будет выглядеть следующим образом:

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

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

Поскольку у нас есть min(), будет выбрано наименьшее из имеющихся значений -8px. При сравнении с max(), тоже будет выбрано 8px. Это первый вариант использования такого CSS.

CSS .card { border-radius: 8px; }

123 .card {    border-radius: 8px;}

Второй, когда карта занимает всю ширину области просмотра. Это можно увидеть в мобильном окне просмотра. Обратите внимание, что ширина контейнера и области просмотра одинакова.

Условный border-radius в CSS

Умножение значения на 9999 приведет к отрицательному значению -39996px. Браузер прочитает это так:

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

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

А теперь самое интересное! Браузеру нужно задать два вопроса:

Какое значение меньше? 8px или -39996px? Результат -39996px.

Какое значение больше? 0px или -39996px? Результат 0px.

CSS .card { border-radius: 0px; }

123 .card {    border-radius: 0px;}

Вы видели, как это произошло? Меня все еще удивляет такое умное использование функций сравнения CSS. Мы также можем вывести это на новый уровень, используя CSS clamp(). Я думаю, что команда Facebook не использовала его, поскольку он не поддерживается в более старых версиях Safari (например, v12).

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

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

Проверьте это на Codepen. Надеюсь, вам понравилась статья. Спасибо за чтение!

Автор: Ahmad Shadeed

Источник: webformyself.com

Оставьте ответ

Ваш электронный адрес не будет опубликован.