CSS border-radius: краткая запись, проценты и круглые углы
Как на самом деле работает border-radius — порядок четырёх значений, px против %, рецепты круга и «таблетки» и почему браузер уменьшает большие радиусы.
border-radius выглядит самым простым свойством в CSS. Одно значение, углы округлились, готово. А потом вы пишете border-radius: 50% на кнопке и вместо «таблетки» получаете линзу. Или ставите 100px на небольшой карточке, а браузер молча рисует что-то ближе к 60px. Оба поведения прописаны в спецификации. Ни одно не очевидно.
Если нужен просто код — в Генераторе border-radius есть ползунок на каждый угол и кратчайшая готовая строка для копирования. А в этой статье разберём, что эти значения на самом деле означают.
Краткая запись читается по часовой стрелке
Четыре значения идут в порядке: верхний левый, верхний правый, нижний правый, нижний левый:
border-radius: 8px 24px 40px 4px;
Правила сворачивания те же, что у margin и padding. Нижний левый равен верхнему правому — его можно убрать, остаётся три значения. Нижний правый совпал с верхним левым — уже два. Все четыре одинаковые — одно.
Поэтому border-radius: 8px 24px означает «8px на верхнем левом и нижнем правом, 24px на двух других». Двухзначная форма сбивает с толку: она объединяет углы по диагонали, а не «верх и низ», как margin объединяет стороны. Я видел, как из-за этого разъезжалась вёрстка, — разработчик искал причину полчаса.
px и % — разные инструменты
Радиус в пикселях абсолютный. Скругление 16px выглядит одинаково на маленькой кнопке и на карточке во всю ширину — обычно именно это и нужно дизайн-системе. rounded-xl в Tailwind — это просто 12px везде.
Процентный радиус масштабируется вместе с элементом, и вот подвох: он считается по каждой оси отдельно. Горизонтальный радиус — от ширины, вертикальный — от высоты. На карточке 300×100 запись border-radius: 50% даёт каждому углу дугу 150px по горизонтали и 50px по вертикали. Это четверть эллипса, а не круга — та самая линза из начала статьи.
У процентов есть ровно один типовой сценарий: квадратный элемент, который должен стать идеально круглым. Аватары, точки, бейджи. 50% — и всё.
«Таблетка» без вычислений
Для кнопки-таблетки ничего измерять не нужно. Задайте фиксированный радиус заведомо больше, чем элемент может быть:
border-radius: 9999px;
Работает это из-за правила в спецификации CSS Backgrounds and Borders: когда радиусы соседних углов накладываются друг на друга, браузер пропорционально уменьшает их все, пока они не поместятся. Радиус 9999px на кнопке высотой 40px сжимается до 20px на угол — ровно половина высоты, ровно «таблетка». rounded-full в Tailwind — буквально это значение.
То же правило объясняет загадку из начала. Поставьте радиусы 100px на блоке высотой 120px — соседним углам понадобилось бы 200px общей стороны, которых нет, и всё уменьшается. Радиус не сломан, его просто ограничили.
Две вещи, которые аукнутся позже
Скруглённые углы не обрезают вложенные элементы. Фон и рамка изгибаются, а <img> внутри карточки спокойно высунет свои квадратные углы за дугу. Добавьте скруглённому элементу overflow: hidden — и содержимое обрежется по той же форме.
И про доступность: outline теперь повторяет скруглённую форму во всех современных браузерах, но только начиная с Chrome 94, то есть с конца 2021 года. Если в вашей аналитике ещё встречаются старые браузеры, проверьте, как выглядит фокусная рамка на круглых кнопках.
Покрутите ползунки в Генераторе border-radius: свяжите углы для симметричных форм или разъедините их для «капель» — и скопируйте готовую строку, когда результат понравится.