- PVSM.RU - https://www.pvsm.ru -
Иногда кажется, что дизайнеры придумывают интерфейсные паттерны, чтобы поиздеваться над разработчиками. Впуклый угол — один из них.
«Инвертированный», «вогнутый», «впуклый» угол, а также negative border radius или inverted border radius. Когда слышите это — знайте, дальше будут страдания.
Проблема в том, что приём выглядит просто, но нативного способа сделать такой угол в CSS нет. Поэтому в ход идут тучи дополнительных обёрток и море стилей для их позиционирования. И всё это ломается на неоднородном фоне.
В этой статье я покажу простой способ создания впуклых углов с помощью опенсорсной CSS‑библиотеки, которую я разработал специально под эту задачу.
Знакомьтесь с нашим героем на скриншоте:
Самый популярный способ реализации выглядит примерно так:
добавляем дополнительные обёртки и псевдоэлементы;
абсолютно позиционируем кусочки;
подгоняем радиусы, размеры и отступы.
На практике получаем море кода на каждый угол и хрупкое решение, которое сложно изменять.
Ниже скриншот одного из популярных роликов про реализацию впуклого угла. На скриншоте видна примерно одна пятая от общего объёма кода реализации.
Типовые решения работают только на сплошных фонах. Как только появляется неоднородный фон, нужно использовать SVG. И CSS‑боль превращается в SVG‑боль.
О чём мечтает разработчик, когда видит впуклый угол:
простое решение на чистом CSS;
работающее из коробки, в том числе на неоднородных фонах;
с возможностью нативной кастомизации размеров и формы углов.
И такое решение существует! Это библиотека nebo.css, с которой мы познакомимся в этой статье. Название происходит от названия паттерна — negative border radius.
nebo.css — это один CSS‑файл, по духу очень похожий на normalize.css: подключил — и используешь. Внутри нет JavaScript, всё сделано на чистом CSS.
<link rel="stylesheet" href="nebo.css">
Этого уже достаточно, чтобы начать.
Чтобы добавить инвертированный угол, элементу нужен базовый класс nebo. По умолчанию угол появляется снизу справа.
<article class="card nebo">...</article>
Результат:
Сторона задаётся модификаторами:
nebo--tr — сверху справа,
nebo--tl — сверху слева,
nebo--bl — снизу слева,
nebo--br — снизу справа.
<article class="card nebo nebo--tr">...</article>
Результат:
На этом этапе уже видно важную вещь: угол корректно работает даже на неоднородном фоне, без дополнительных ухищрений.
Все параметры nebo.css настраиваются через нативные CSS‑переменные, которые подчиняются обычному каскаду.
Эта переменная управляет радиусами скруглений в угле. Значение по умолчанию — 20px. Немного уменьшим его.
.nebo {
--nb-r: 16px;
}
Эти переменные задают дополнительные смещения между внутренним и внешними радиусами.
.card--cat1 {
--nb-w: 42px;
--nb-h: 16px;
}
Результат:
Так как мы работаем с обычным каскадом, каждый элемент можно настраивать по‑своему:
.card--cat1 { --nb-w: 42px; --nb-h: 16px; }
.card--cat2 { --nb-w: 32px; --nb-h: 42px; }
.card--cat3 { --nb-w: 64px; --nb-h: 42px; }
.card--cat4 { --nb-w: 42px; --nb-h: 16px; }
Результат:
Кстати, углы корректно отображаются даже при нулевых значениях (0px) — главное не забывать единицы измерения.
nebo.css изначально решает одну задачу: один элемент — один угол. Но если нужно несколько углов, в ход идёт проверенный приём — дополнительная обёртка.
<div class="card-wrapper nebo nebo--bl">
<article class="card nebo nebo--tr">...</article>
</div>
Результат:
Каждый уровень можно настраивать отдельно через CSS‑переменные. Можно собрать и три, и четыре угла — просто добавляя обёртки.
Общий радиус для всех скруглений, который задаётся с помощью переменной --nb-r, можно переопределить для каждого из трёх скруглений: двух внешних и одного внутреннего. Причём можно отдельно задать как вертикальные, так и горизонтальные радиусы. Это делается с помощью шести дополнительных CSS-переменных:
--nb-cor1-rw,
--nb-cor1-rh,
--nb-cor2-rw,
--nb-cor2-rh,
--nb-curve-rw,
--nb-curve-rh,
Благодаря этим переменным можно получать впуклые углы очень сложных форм. Например:
.card--cat1 {
--nb-r: 30px;
--nb-w: 0px;
--nb-h: 0px;
--nb-curve-rw: 120px;
--nb-curve-rh: 90px;
--nb-cor1-rw: 90px;
--nb-cor1-rh: 90px;
--nb-cor2-rw: 60px;
--nb-cor2-rh: 60px;
--_nb-smooth: 99.5%;
}
Результат:
Теперь посмотрим на более жизненный кейс — карточку, состоящую из верхнего блока с изображением и нижнего блока с информацией.
<div class="card">
<div class="card-header"></div>
<div class="card-body">
<div class="price">$114,000</div>
...
</div>
</div>
<div class="card-header nebo nebo--bl"></div>
<div class="card-body nebo nebo--tr">...</div>
В примере использован быстрый грязный приём с отрицательным маргином, чтобы подтянуть блок с картинкой к блоку с описанием. Но цель была — показать простоту создания вырезов.
.card-header {
--nb-r: 10px;
--nb-w: 130px;
--nb-h: 44px;
margin-bottom: -54px;
}
.card-body {
--nb-r: 10px;
--nb-w: 160px;
--nb-h: 44px;
}
Результат:
Обратите внимание, что всё отлично работает с неоднородным фоном.
nebo.css — это бесплатная опенсорсная библиотека, разработанная автором. Лежит на GitHub.
Репозиторий:
https://github.com/htmlacademy/nebo.css [1]
Библиотеку можно просто подключить отдельным файлом или скопировать код прямо в свои стили. Пользуйтесь и наслаждайтесь!
Подписывайтесь на мой телеграм‑канал [2] «CSS Боль». Там собраны все материалы, видеоролики, ссылки на интерактивные пошаговые демки
Автор: AlexPershin
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/css/442714
Ссылки в тексте:
[1] https://github.com/htmlacademy/nebo.css : https://github.com/htmlacademy/nebo.css
[2] телеграм‑канал: https://t.me/cssbol
[3] Источник: https://habr.com/ru/articles/987944/?utm_source=habrahabr&utm_medium=rss&utm_campaign=987944
Нажмите здесь для печати.