border-radius в CSS: скругление углов и формы
Порядок четырёх значений, синтаксис со слэшем, px против %, рецепты круга и «таблетки» и почему браузер уменьшает слишком большой радиус.
border-radius принимает до четырёх значений, и они идут по часовой стрелке от левого верхнего угла: верхний левый, верхний правый, нижний правый, нижний левый. Всё остальное — проценты, слэш, трюк с «таблеткой» — вариации этого одного правила.
/* ВЛ ВП НП НЛ */
border-radius: 8px 24px 40px 4px;
Сколько значений писать
Краткая запись сворачивается ровно как у margin и padding:
| Значений | Пример | Что скругляется |
|---|---|---|
| 1 | border-radius: 12px | все четыре угла |
| 2 | border-radius: 12px 4px | 12px — верхний левый и нижний правый, 4px — два других |
| 3 | border-radius: 12px 4px 8px | верхний левый 12px, верхний правый и нижний левый 4px, нижний правый 8px |
| 4 | border-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 v4 | Bootstrap 5 | Material Design 3 |
|---|---|---|---|
| Без скругления | rounded-none — 0 | rounded-0 — 0 | 0 |
| Очень маленькое | rounded-xs — 2px | — | 4px |
| Маленькое | rounded-sm — 4px | rounded-1 — 4px | 8px |
| Базовое | rounded-md — 6px | rounded — 6px | 12px |
| Крупное | rounded-lg — 8px | rounded-3 — 8px | 16px |
| Очень крупное | rounded-xl — 12px | rounded-4 — 16px | 28px |
| 2XL | rounded-2xl — 16px | rounded-5 — 32px | — |
| 3XL | rounded-3xl — 24px | — | — |
| Полное | calc(infinity * 1px) | rounded-pill — 50rem | full |
Если макет отдали в пикселях, а в стилях приняты 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, генератор градиентов и проверка контраста цветов.