Илья Бирман. Дизайн транспортных схем. Глава «Изгибы»

В своей мегакниге о дизайне транспортных схем Илья Бирман подробно описал, в чём проблема с обычными радиальными скруглениями:

Илья Бирман. Дизайн транспортных схем. Глава «Изгибы»

«При ради­аль­ном скруг­ле­нии линия состав­ля­ется из трёх при­став­лен­ных друг к другу фраг­мен­тов: отрезка пря­мой, дуги окруж­но­сти, снова отрезка пря­мой. Это про­ти­во­есте­ственно, реаль­ные объ­екты так не гнутся. Если согнуть сталь­ной прут или душе­вой шланг, радиус кри­визны будет плавно воз­рас­тать в направ­ле­нии от цен­тра изгиба. Точно ука­зать точку, где изгиб закан­чи­ва­ется, будет невозможно.

Линии, скруг­лён­ные ради­у­сом, тоже в каком‑то смысле сло­маны — доста­точно один раз уви­деть места, где дуга окруж­но­сти «при­де­лы­ва­ется» к пря­мым отрез­кам, и раз­ви­деть их уже не получится».

Раньше сгладить скругления в вёрстке можно было только малонадёжными костылями. В 2025 у нас наконец‑то появилось специальное свойство — corner-shape с мелодичным значением squircle.

.btn {
  /* … */
  border-radius: 20px;
}

.btn.smooth {
  corner-shape: squircle;
}

Но пока есть два нюанса.

corner‑shape. Can I Use

Во‑первых, свойство поддерживается в большинстве, но ещё не во всех браузерах. Где не поддерживается — скругления останутся без сглаживания.

corner‑shape. Can I Use

Во‑вторых, при одинаковом значении border-radius, визуально скругление со squircle получится сильно меньше. Это заметно в примере выше.

Чтобы сохранить размер скругления при сглаживании, значение border-radius придётся сильно увеличивать. И если при этом браузер не поддерживает сглаживание, вы получите элемент с неадекватным скруглением:

.btn {
  /* … */
  border-radius: 20px;
}

.btn.smooth {
  border-radius: 45px;
  corner-shape: squircle;
}

Поэтому сейчас при работе со сглаживанием лучше использовать выражение @supports. Оно проверяет поддержку сглаживания в браузере и только в этом случае применяет указанные свойства:

.btn {
  border-radius: 20px;
}

@supports(corner-shape: squircle) {
  .btn.smooth {
    corner-shape: squircle;
    border-radius: 45px;
  }
}

А если у вас в проекте есть препроцессоры стилей, всю эту конструкцию можно вынести в миксин и частично автоматизировать. Например, так:

/* Пример в препроцессоре SCSS*/
@mixin smooth-br($br) {
  border-radius: $br;

  @supports (corner-shape: squircle) {
    corner-shape: squircle;
    border-radius: calc($br * 1.85);
  }
}

@include smooth-br(20px);

P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Веб‑разработка
Отправить
Поделиться
Запинить

Комментарии

Мы придумали неплохое временное решение для остальных браузеров, вот тут https://intuition-tech.github.io/ids/, в самом‑самом конце

26 мар 2026
Намор Вотилав

Ну или вместо вычисления радиуса для squircle нащупать нужное значение с помощью corner‑shape: superellipse(N); Я нашёл N=1.6, которое оставляет радиусы близкими несглаженным, и получить плавный спад.

26 мар 2026

Как будто 20 × 1,85 = 37px, а не 45px.

Какая‑то разсогласованность между css и миксином scss.

И почему 1,85? Что за магическое число?

Может действительно есть магическое число которое позволит забыть о подборе подходящего радиуса, а просто кидать в миксин и там всегда будет высчитываться идеальное число?

Погуглил, волшебной константы нет, но есть примерное число от 1,7 до 2,0. То есть в примере указано среднее скругление (×1,85).

Предлагаю обновлённый вариант миксина:

@mixin smooth-br($br, $k: 1.85) {
    border-radius: $br;

    @supports (corner-shape: squircle) {
        corner-shape: squircle;
        border-radius: calc($br * $k);
    }
}

Погонял нейронку над формулами максимально приятными глазу, получился коэфициент 1,87.

Но тут есть момент, что у мелких объектов этот коэфициент должен быть меньше, а у крупных больше. Прикрепил таблицу.

Но если копнуть глубже, то появляется:
— константа 1. Порог различимости кривизны: 0,1 (10%), Just Noticeable Difference (JND) ≈ 7–12%;
— константа 2. Приближённая средняя ширина визуального объекта в вебе 400px, а это значит радиус ~ 40px.

А это уже основа для ещё одного обновления миксина:

// Функция адаптивного множителя
// $r — обычный border-radius
// $max-br — максимальный радиус, после которого глаз перестаёт различать изменения
// по умолчанию 40px
@function squircle-k($r, $max-br: 40px) {
    // нормализуем радиус в диапазон 0–1
    $t: clamp(0, $r / $max-br, 1);

    // интерполяция между 1.75 и 2.05
    @return 1.75 + (0.30 * $t);
}

// Миксин сглаживания
@mixin smooth-br($br, $max-br: 40px) {
    border-radius: $br;

    @supports (corner-shape: squircle) {
        $k: squircle-k($br, $max-br);
        corner-shape: squircle;
        border-radius: calc($br * $k);
    }
}

Вызовы:
— Средний
@include smooth-br(20px);

— Если дизайн‑система с большими радиусами
@include smooth-br(32px, 48px);

— Если хочешь более мягкие углы
@include smooth-br(16px, 32px);

В общем, 32px — естественная нижняя граница, а 40px — комфортный дефолт.

Функция squircle-k() берёт твой радиус, определяет насколько он «крупный», и подбирает множитель от 1,75 до 2,05, чтобы squircle выглядел естественно для глаза.

26 мар 2026

Рекомендуем другие советы