Как стать автором
Обновить

Скругление углов на чистом CSS с анти-алисингом

Время на прочтение5 мин
Количество просмотров8.6K
Вношу свои 5 копеек в проблему скругления уголков. Хочу предложить метод, который не революционный, а просто несколько усовершенствует другой.

Многие знакомы с методом скругления уголков средствами CSS, который активно использует Гугл. Я лично познакомился с ним на сайте Шторкин.ру.

Метод сделан на чистом CSS, без картинок, без JS, полностью кроссбраузерный. Он спокойно тянется в ширину и высоту. Единственный его недостаток: отсутствие сглаженности (алиасинг). В принципе, все вполне поправимо.

Итак, в фотошопе сделан вариант со сглаживанием. Выясняется, что необходимо всего-то добавить 7 пикселей, из которых 4 цвета примерно наполовину светлее цвета блока, и 3 еще светлее, почти сливаются с фоном.

Берем за основу вариант со Шторкин.ру:



Исходный код:

<style>
.grc {padding: 5px 15px;}
.grc .e{display:block; position: relative;}
.grc .e *{display: block; overflow: hidden; position: relative; z-index: 2; font-size: 0px;}
.grc b.e b, .grc b.e i, .grc b.e u {height: 1px !important; background: #1d5198;}
.grc b.e b{margin: 0 5px;}
.grc b.e i{margin: 0 3px;}
.grc b.e u{margin: 0 2px;}
.grc b.e span{margin: 0 1px; height: 2px !important; background: #1d5198;}
.grc div{background: #1d5198; padding: 0 10px; color: white;}
</style>

<div style='width: 300px;'>
<div class='grc'>
<b class='e'><b></b><i></i><u></u><span></span></b>
<div>Вокруг этого блока углы скруглены без сглаживания.<br/>Вес кода 730 Kb.</div>
<b class='e'><span></span><u></u><i></i><b></b></b>
</div>
</div>

Как это работает?


Верхняя часть блока высотой в 5 пикселей состоит из четырех вытянутых в ширину блоков. 3 блока имеют высоту в один пиксель, и еще один блок высоту 2 пикселя. Блоки имеют отступы в 5, 3, 2 и 1 пиксель слева и справа и таким образом получается эффект скругления.


Добавляем первый полутоновый цвет


Дописываем не сложные свойства для всех наших вытянутых блоков:
.grc b.e b, .grc b.e i, .grc b.e u, .grc b.e span {border-left:1px solid #9eb4d3;border-right:1px solid #9eb4d3;}

а заодно уменьшаем отступы этих блоков на 1 пиксель. Получаем результат:



Что же, смотрится уже гораздо более сглажено, появился анти-алиасинг, так сказать. И код увеличился всего на 120 байт.


Добавляем второй полутоновый цвет


Слева два полутона в ряд — не лучший вариант, поэтому дробим блок высотой в 2 пикселя на два по 1 пикселю, и верхнему задаем новый цвет левого и правого бордера. Вот что получаем:



Код добавился всего на 80 байт, смотрится еще лучше.


Доводим нашу идею до логического конца


Раз уж ввели второй полутоновый цвет, то давайте доведем нашу идею до конца. Верхним двум слоям надо добавить дополнительный левый и правый бордер. Для этого создаем еще один блок, который помещаем внутрь двух верхних блоков. Уменьшаем отступы этих блоков еще на пиксель. И вот что получается:



Код увеличился на 400 байт, что по нашим временам не много. Сохранилась полная кроссбраузерность, отсутствие фоновых картинок и JS, нет ограничений по ширине и высоте блока. Смотрится скругление помягче, так, как будто уголок готовили в фотошопе.

Конечный код:

<style>
.grc {padding: 5px 15px;}
.grc .e{display:block; position: relative;}
.grc .e *{display: block; overflow: hidden; position: relative; z-index: 2; font-size: 0px;}
.grc b.e b, .grc b.e i, .grc b.e u, .grc b.e s, .grc b.e span, .grc b.e strong {height: 1px !important; background: #1d5198;}
.grc b.e b, .grc b.e i, .grc b.e s {border-left:1px solid #f1f4f9; border-right:1px solid #f1f4f9;}
.grc b.e u, .grc b.e b strong, .grc b.e i strong, .grc b.e span {border-left:1px solid #9eb4d3; border-right:1px solid #9eb4d3;}
.grc b.e b{margin: 0 3px;}
.grc b.e i{margin: 0 1px;}
.grc b.e u{margin: 0 1px;}
.grc b.e s{margin: 0;}
.grc b.e b strong, .grc b.e i strong {margin: 0;}
.grc b.e span{margin: 0;}
.grc div{background: #1d5198; padding: 0 10px; color: white;}
</style>

<div style='width: 300px;'>
<div class='grc'>
<b class='e'><b><strong></strong></b><i><strong></strong></i><u></u><s></s><span></span></b>
<div>Здесь применено углубленное двойное сглаживание.<br/>Вес кода 1 130 Kb.</div><br/>
<b class='e'><span></span><s></s><u></u><i><strong></strong></i><b><strong></strong></b></b>
</div>
</div>

Немного философии


В первом варианте, в котором есть небольшая «лесенка», создает примерно такое ощущение:



Взгляд, сталкиваясь с «лесенкой», а не с плавной линией, дорисовывает лишние зубчики. Но значит ли это, что сглаживание намного лучше? Вот, что дорисовывает взгляд, глядя на скругленную картинку:



Появляется ощущение небольшого блюра. Все это связано с тем, что пиксель на экране по прежнему является достаточно большим, и добиться четкости полиграфии еще не возможно, даже пользуясь фоновой картинкой.

Конечно, на картинках все утрированно, на реальных примерах это еле заметно.

Какой метод использовать, с лесенкой или со сглаживанием? Думаю, это зависит от общего настроения сайта. Гугл использует скругление с лесенкой, и это подчеркивает его аскетизм. На каком-нибудь сайте, посвященном постельному белью или подушкам лучше использовать сглаживание.


Недостаток №1 метода


Так ли все хорошо? Не совсем. Изначальный вариант спокойно ложиться на любой фон, на белый, на черный, на любой цвет или фоновый рисунок. А наш вариант красиво ляжет только на белый или светлый фон. Если фон будет черным или темным, то полутоновые цвета надо будет готовить исходя из других оттенков. А если на разных участках страницы фон разный, то придется писать отдельные стили.

Правда, тут есть нюанс. Вставлять сглаживание есть смысл, если только фон и блок очень контрастных цветов. Если контраст не сильный, то сглаживание не имеет смысла, легче применить исходный вариант.

Впрочем, можно попробовать поиграть со свойством opacity. Вместо бордеров создаем блоки высотой и шириной в 1 пиксель, и задаем им цвет блока и полупрозрачность 0.6 и 0.2. Получаем графиконезависимый код, но и тут не все гладко:

1. opacity не поддерживается ИЕ, при чем в 8-й версии тоже.
2. код резко разбухает и усложняется, добавляется сразу 7 дополнительных блоков. Стоят ли муки результата? На мой взгляд нет.


Недостаток №2 метода


Второй недостаток метода в том, что в нем сложно менять радиус. Здесь радиус визуально составляет 5-6 пикселей. Если увеличить радиус в двое, то блоков должно быть уже 10, различный полутонов необходимо будет ввести не меньше 5, но скорее всего 7-8, в коде легко запутаться.

А методы с использованием картинок или JS легко справляются с этой задачей.


Недостаток №3 метода


Как указали в комментариях foxweb, homm, SelenIT и reaferon главный недостаток: очень сложный код. С точки зрения семантики это не чистый CSS, а практически хак.


Авторство и лицензия


Код распространяется бесплатно, ничего супер-навороченного в нем нет. По сути это просто идея, которая не лицензируется. Пользуйтесь и модифицируйте на здоровье.

Автор текста и картинок Вадим Галкин. Автор исходного кода Семен «Шторкин» Орлов. При опубликовании статьи прошу ссылаться на мою персональную страницу.


Пост скрипт


На следующий день, после опубликования данного поста, XAMelleOH предложил вариант, который по сравнению с моим методом обладает рядом преимуществ:
— гораздо легче менять радиус,
— полупрозрачность,
— более простой код.

Рекомендую.


Пост скрипт 2015


Сейчас читаю эту статью и кажется, что писал ее не 6 лет назад, а до полета Гагрина. Как быстро меняется наша индустрия и инструменты! Тот, кто изучает CSS сейчас, думаю, уверен, что border-radius был всегда. Это же так очевидно!
Теги:
Хабы:
+57
Комментарии44

Публикации

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн