belun.app Блог
EN
· обновлено

border-radius в CSS: скругление углов и формы

Порядок четырёх значений, синтаксис со слэшем, px против %, рецепты круга и «таблетки» и почему браузер уменьшает слишком большой радиус.

Веб-дизайнер настраивает скруглённые углы макета интерфейса на экране компьютера

border-radius принимает до четырёх значений, и они идут по часовой стрелке от левого верхнего угла: верхний левый, верхний правый, нижний правый, нижний левый. Всё остальное — проценты, слэш, трюк с «таблеткой» — вариации этого одного правила.

/*             ВЛ   ВП   НП  НЛ  */
border-radius: 8px 24px 40px 4px;

Сколько значений писать

Краткая запись сворачивается ровно как у margin и padding:

ЗначенийПримерЧто скругляется
1border-radius: 12pxвсе четыре угла
2border-radius: 12px 4px12px — верхний левый и нижний правый, 4px — два других
3border-radius: 12px 4px 8pxверхний левый 12px, верхний правый и нижний левый 4px, нижний правый 8px
4border-radius: 12px 4px 8px 2pxверхний левый, верхний правый, нижний правый, нижний левый

Именно двухзначная форма сбивает с толку: она объединяет углы по диагонали, а не «верх и низ», как margin объединяет стороны. Если нужно скруглить верх иначе, чем низ, придётся писать все четыре значения или два отдельных свойства.

Если нужен просто готовый код — в Генераторе border-radius есть ползунок на каждый угол, а строка собирается в кратчайшую валидную форму. Дальше — что эти значения означают.

Отдельные свойства для каждого угла

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

СвойствоУгол
border-top-left-radiusверхний левый
border-top-right-radiusверхний правый
border-bottom-right-radiusнижний правый
border-bottom-left-radiusнижний левый
/* Скруглить только верх — шапка карточки, вкладка, верх модалки */
border-top-left-radius: 12px;
border-top-right-radius: 12px;

/* То же самое краткой записью */
border-radius: 12px 12px 0 0;

Есть и логический набор, который следует направлению письма, а не экрану: border-start-start-radius, border-start-end-radius, border-end-start-radius, border-end-end-radius. На странице слева направо border-start-start-radius — это верхний левый угол, а в RTL-вёрстке он сам переезжает в верхний правый. Все три движка поддерживают их с 2021 года.

Слэш: два радиуса на угол

Каждый угол на самом деле — четверть эллипса, у него есть горизонтальный радиус и вертикальный. Обычная запись просто задаёт им одинаковое число. Слэш разделяет их: до слэша идут горизонтальные радиусы, после — вертикальные.

border-radius: 50% / 20%;

Читается так: каждый угол загибается на 50% ширины элемента по горизонтали и на 20% его высоты по вертикали. В полной форме с каждой стороны слэша можно указать до четырёх значений — это и есть та «каша из восьми процентов», которую выдают генераторы органических форм:

border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;

Формальный синтаксис — <length-percentage>{1,4} [ / <length-percentage>{1,4} ]?, причём две половины раскрываются независимо друг от друга. Запись border-radius: 10px 5% / 20px 25px 30px 35px даёт верхнему левому углу горизонтальный радиус 10px и вертикальный 20px, верхнему правому — 5% и 25px, и так далее.

Отдельные свойства принимают ту же пару без слэша: border-top-left-radius: 40px 20px — это один широкий и пологий угол.

px и % — разные инструменты

Радиус в пикселях абсолютный. 16px выглядят одинаково на маленькой кнопке и на карточке во всю ширину — обычно дизайн-системе нужно именно это.

Процентный радиус масштабируется вместе с элементом и вычисляется по каждой оси отдельно: горизонтальный — от ширины бордер-бокса, вертикальный — от высоты. На карточке 300×100 запись border-radius: 50% даёт каждому углу дугу 150px по горизонтали и 50px по вертикали. Это четверть эллипса, а не круга — поэтому 50% на широкой кнопке даёт «линзу», а не «таблетку».

ЭлементЧто даст border-radius: 50%
квадрат 100 × 100идеальный круг
карточка 300 × 100эллипс (углы 150px × 50px)
аватар 40 × 40идеальный круг
кнопка 200 × 40линза, а не таблетка

У процентов есть ровно одна типовая задача: квадратный элемент, который должен стать круглым. Аватары, точки, бейджи. 50% — и всё. На квадрате 50% и 100% выглядят одинаково: браузер всё равно ограничивает радиус половиной стороны.

Готовые формы

ФормаCSS
Круг (на квадратном элементе)border-radius: 50%
«Таблетка», кнопка со скруглением на всю высотуborder-radius: 9999px
Обычная карточкаborder-radius: 12px
Только верхние углыborder-radius: 12px 12px 0 0
Только левая сторонаborder-radius: 12px 0 0 12px
Пузырь чата (один угол острый)border-radius: 16px 16px 16px 4px
Листborder-radius: 0 32px 0 32px
Яйцоborder-radius: 50% 50% 50% 50% / 60% 60% 40% 40%
Органическая «капля»border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%
Почти сквирклborder-radius: 30% на квадрате

«Таблетка» и почему она работает

Чтобы получить кнопку-таблетку, ничего измерять не нужно:

border-radius: 9999px;

Работает это из-за правила перекрытия из спецификации CSS Backgrounds and Borders: если радиусы двух соседних углов вместе больше стороны между ними, браузер пропорционально уменьшает все радиусы одним и тем же коэффициентом, пока они не поместятся. Радиус 9999px на кнопке высотой 40px сожмётся до 20px на угол — ровно половина высоты, ровно таблетка, при любой высоте и без медиазапросов. В Tailwind v3 это был rounded-full: 9999px, в v4 — calc(infinity * 1px), та же идея, доведённая до предела.

То же правило объясняет вторую классическую неожиданность. Поставьте радиусы 100px на блоке высотой 120px: двум углам на каждой вертикальной стороне понадобилось бы 200px, а есть 120px — и всё сожмётся до 60px. Радиус не сломан, его ограничили. Коэффициент — это наименьшее из отношений «длина стороны ÷ сумма двух радиусов на этой стороне» по всем четырём сторонам, и поскольку он одинаков для всех углов, несимметричная форма при сжатии сохраняет пропорции.

Типовые значения в дизайн-системах

Полезно, когда нужно попасть в уже существующий стиль, а не придумывать свой:

Шаг шкалыTailwind v4Bootstrap 5Material Design 3
Без скругленияrounded-none — 0rounded-0 — 00
Очень маленькоеrounded-xs — 2px—4px
Маленькоеrounded-sm — 4pxrounded-1 — 4px8px
Базовоеrounded-md — 6pxrounded — 6px12px
Крупноеrounded-lg — 8pxrounded-3 — 8px16px
Очень крупноеrounded-xl — 12pxrounded-4 — 16px28px
2XLrounded-2xl — 16pxrounded-5 — 32px—
3XLrounded-3xl — 24px——
Полноеcalc(infinity * 1px)rounded-pill — 50remfull

Если макет отдали в пикселях, а в стилях приняты rem, пересчитать шкалу поможет конвертер px в rem — с любым корневым размером шрифта.

Концентрические углы: формула внутреннего радиуса

Когда одна скруглённая коробка лежит внутри другой — карточка в контейнере, картинка в рамке с отступом, — одинаковый радиус у обеих смотрится неправильно: внутренняя дуга кажется слишком тугой. Лечится одним вычитанием:

внутренний радиус = внешний радиус − отступ

где отступ — это padding (или толщина рамки) между двумя краями. Карточке с border-radius: 16px и padding: 8px нужен border-radius: 8px на вложенном элементе. В CSS это можно записать прямо:

.card {
  --radius: 16px;
  --pad: 8px;
  border-radius: var(--radius);
  padding: var(--pad);
}
.card > img {
  border-radius: calc(var(--radius) - var(--pad));
}

Если разность уходит в минус — ставьте 0: острый внутренний угол выглядит лучше, чем несогласованная дуга.

Скруглённые углы не обрезают содержимое

Фон и рамка изгибаются, а <img> внутри карточки спокойно высунет свои квадратные углы за дугу. Добавьте скруглённому элементу overflow: hidden — содержимое обрежется по той же форме. overflow: clip делает то же самое, но без побочных эффектов скролл-контейнера.

Одно исключение стоит помнить: в некоторых версиях Safari потомок, создающий свой слой композитинга (transform, анимация), всё равно вылезает за обрезку. Если при наведении у скруглённой картинки на мгновение появляются квадратные углы — это оно; лечится тем, что тот же border-radius задаётся и самому потомку.

Что ещё повторяет дугу

  • box-shadow повторяет скруглённую форму автоматически, и внешняя тень, и inset.
  • outline повторяет радиус во всех актуальных браузерах, но только начиная с Chrome 94 (конец 2021 года). Если фокусная рамка на круглой кнопке рисуется квадратом — виноват старый браузер.
  • Фоновая картинка обрезается по дуге по умолчанию (background-clip: border-box).
  • <table> игнорирует border-radius на ячейках, пока не задано border-collapse: separate.
  • Отрицательные значения невалидны, и объявление целиком отбрасывается — случайный -4px молча оставит углы квадратными.

Частые вопросы

Что такое border-radius в CSS? Свойство, которое скругляет углы элемента, изгибая по четверти эллипса рамку, фон и фоновую картинку. Принимает длину (12px, 1rem) или проценты, от одного до четырёх значений, плюс необязательный второй набор после слэша.

В каком порядке идут четыре значения? По часовой стрелке от левого верхнего: верхний левый, верхний правый, нижний правый, нижний левый. Запись border-radius: 8px 24px 8px 24px скругляет верхний левый и нижний правый на 8px, а два других — на 24px.

Как сделать круг через border-radius? Задать элементу одинаковые ширину и высоту и поставить border-radius: 50%. На неквадратном элементе 50% даёт эллипс: процент считается отдельно от ширины и от высоты.

Чем отличаются 50% и 100%? На квадрате — ничем: оба ограничиваются половиной стороны и рисуют круг. На неквадратном элементе 100% — просто более вытянутый эллипс, чем 50%. Пишите 50%: так понятнее замысел.

Почему радиус выглядит меньше заданного? Потому что двум соседним углам не хватило стороны между ними, и браузер пропорционально уменьшил все радиусы. Это описанное в спецификации поведение, а не баг.

Зачем пишут border-radius: 9999px? Это радиус заведомо больше элемента, поэтому правило ограничения сжимает его ровно до половины меньшей стороны — таблетка на широкой кнопке, круг на квадратной, при любом размере. Для того же эффекта используют 50rem и calc(infinity * 1px).

Как скруглить только верхние углы? border-radius: 12px 12px 0 0 либо два свойства — border-top-left-radius и border-top-right-radius. Для любой другой стороны — та же схема со сдвигом значений.

Можно ли задать проценты только по одной оси? Да, единицы можно смешивать, в том числе по разные стороны слэша: border-radius: 20px / 50% даёт фиксированную дугу 20px по горизонтали и вертикальную, которая тянется вместе с высотой элемента.

Влияет ли border-radius на размер и вёрстку? Нет. Ширина, высота и положение блока не меняются — меняется только отрисовка углов. На попадание курсора влияет: клик за дугой в современных браузерах уже не считается кликом по элементу.


Собрать форму на глаз можно в Генераторе border-radius: свяжите четыре угла для симметричного скругления или разъедините для «листа» и «капли», переключите px и % и скопируйте кратчайшую валидную запись. Всё считается в браузере. Рядом пригодятся генератор box-shadow, генератор градиентов и проверка контраста цветов.

Попробуйте инструмент

Генератор border-radius →