Скруглённые углы на чистом CSS для Opera 9.5, FF 1.5, IE 5, Konqueror и Safari3

Всё, надоело. Никто не использует VML и SVG? Почему все делают скруглённые углы только кучей картинок или через CSS3-свойства? В общем, представляю код, который работает для Opera 9.50 и выше (через SVG background), IE5.0 и выше (через VML), на FireFox 1.5, Safari3 и Konqueror (через свойства CSS3). Та-да:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- подключаем пространство имён VML для IE -->
<!--[if vml]>
	<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v"/>
	<style> v\:* { behavior: url(#default#VML); display: block; } </style>

<![endif]-->

<title>Скруглённые углы</title>

<style type="text/css">
	*    { padding: 0; margin: 0; }
	body { background: white; color: black; font: 12px Arial, sans-serif; }

	.rounded { margin: 100px auto; text-align: center; width: 50%; position: relative; padding: 10px; }

/*
Нижеприведённые background-image работает только в Opera 9.50 и представляет собой закодированный алгоритомом base64
код SVG-картинки:

<svg xmlns="http://www.w3.org/2000/svg">
<mask id="mask">
   <rect width="100%" height="100%" rx="10" ry="10" fill="white" stroke="black" stroke-width="2"/>
</mask>
<rect stroke="black" fill="white" stroke-width="4" mask="url(#mask)" width="100%" height="100%" rx="10" ry="10"/>
</svg>


В этой картинке подготавливается бакграунд со скруглёнными углами
*/
	noindex:-o-prefocus, .rounded-svg {
		background-image: url(data:image/svg+xml;base64,cюда нужно положить base64-кодированную картинку);
		border: none !important;
	}

	/* для разных браузеров указываем rounded corner через CSS3-свойство */
	.rounded-css3 {
		border: 1px solid black;
		-moz-border-radius: 1em;     /* mozilla 1.5 */
		-webkit-border-radius: 1em;  /* safari 3 */
		-khtml-border-radius: 1em;   /* Konqueror */
		border-radius: 1em;          /* CSS3 */
	}
</style>

</head>

<body >
	<!--[if vml]><v:roundrect class="rounded" strokecolor="black" strokeweight="1px" arcsize="0.25" ><![endif]-->
	<!--[if !vml]>--><div class="rounded rounded-css3 rounded-svg"><!--<![endif]-->
		<p>Вот эти ребята!</p>
	<!--[if !vml]>--></div><!--<![endif]-->
	<!--[if vml]></v:roundrect><![endif]-->
</body></html>
В коде есть несколько хаков. В частности, для «Оперы» я использую background, вставленный как SVG-изображение, через data URL. Поэтому приходится выключать border, иначе он закрывает края background. SVG закодировано в base64 (функция base64_encode в PHP), потому что оно занимает так меньше, чем в URL encoded.

Далее. Для IE включается VML, это, если кто не знает, появившаяся ещё до SVG технология построения векторных изображений. Более мощная, чем SVG, кстати. Весь VML включается через условные комментарии и другие браузеры этого безобразия не видят, в том числе их не увидит и валидатор (хотя ему и без VML тут есть на что поругаться).

Для остальных браузеров используются их префиксное свойство border-radius, которое включено в CSS3.
18 июля 2008 15:08

hshhhhh.name (hshhhhh.name)
18 июля 2008, 15:37

опера 9.50 у меня на работе не подхватила, попробую ещё из дома.
сафари, фф и ие таки да, показали ).
болк крутой!

Free, Anonymous OpenID by http://www.jkg.in/ (www.jkg.in/openid/qfzh43mc)
18 июля 2008, 15:39

<link rel="stylesheet" href="css/opera.css" type="opera/css" media="screen" />

bolk (bolknote.ru)
18 июля 2008, 15:41

Не работает на моей Opera 9.51

blog.ad.by (blog.ad.by)
18 июля 2008, 15:45

Ну почему никто, используют люди.
Например http://cssing.org.ua/2008/06/23/rounded-corners-unusual-approach/#comment-12678
Другое дело, что этот товарищ на меня сослался, но у меня SVG нет, только VML. Что ему мешало выкатить свой пример с SVG, я лично не совсем понимаю.

Про -khtml-border-radius не знал, спасибо. И вообще - отличная работа.

bolk (bolknote.ru)
18 июля 2008, 16:07, ответ предназначен blog.ad.by:

Спасибо!

Кстати, в поисках лучшего решения для «Оперы» (тут требовалось отрубить border), нашёл-таки CSS hack для 9.50, упоминания о нём есть changelogs на их сайте.

morozov.livejournal.com (morozov.livejournal.com)
18 июля 2008, 16:18

Грязновато выглядит (смотрел в Опере и FF): визуально толщина скругленного участка границы кажется толще и шумит/шипит.

bolk (bolknote.ru)
18 июля 2008, 16:18, ответ предназначен morozov.livejournal.com:

Ничего такого не вижу.

bolk (bolknote.ru)
18 июля 2008, 16:19, ответ предназначен morozov.livejournal.com:

Можно screenshot?

blog.ad.by (blog.ad.by)
18 июля 2008, 16:55, ответ предназначен bolk (bolknote.ru):

В принципе, можно использовать SVG как фон и в Safari, но ограничения там дурацкие:
1) Начиная с Safari 3.1
2) Размер SVG должен совпадать с размером блока
http://ad.by/svg-test/svg_rounded_corner_safari31.html

muxa-ru.livejournal.com (muxa-ru.livejournal.com)
18 июля 2008, 16:59

Почему все делают скруглённые углы только кучей картинок или через CSS3-свойства?
Потому что качество лучше и ровнее.

bolk (bolknote.ru)
18 июля 2008, 17:00, ответ предназначен blog.ad.by:

Ну а тогда зачем? :) Прямой путь — это border-radius.

bolk (bolknote.ru)
18 июля 2008, 17:01, ответ предназначен muxa-ru.livejournal.com:

Где именно лучше и равнее и по сравнению с чем? У меня всё кругло и ровно.

xcellnt.livejournal.com (xcellnt.livejournal.com)
18 июля 2008, 17:16

Вообще то "Konqueror", даже в коде это написано :) *на правах зануды*.

bolk (bolknote.ru)
18 июля 2008, 17:28, ответ предназначен xcellnt.livejournal.com:

Я это слово без словаря не напишу :)

muxa-ru.livejournal.com (muxa-ru.livejournal.com)
18 июля 2008, 17:55, ответ предназначен bolk (bolknote.ru):

Где именно лучше и равнее и по сравнению с чем?
Лучше "с картинками". Качество скруглений не зависит от модели браузера и потому ровнее.

http://muxa.ru/img/bolk-round.jpg

Да и само по себе, качество скругления полученого из графического редактора будет выше чем сделает браузер. Специализация.

З.Ы. а теперь всё тоже самое плюс:
- залить цветом
- залить цветом и положить вертикальный градиент у верхней границы
- залить цветом и положить горизонтальный градиент у левой границы
- залить цветом и положить фоновую картинку прижатую в верхний-левый угол

muxa-ru.livejournal.com (muxa-ru.livejournal.com)
18 июля 2008, 17:58

З.З.Ы. под "качество ровнее" подразумевалось что скругления выглядят одинаково в разных браузерах, а не длина полученых блоков :)

muxa-ru.livejournal.com (muxa-ru.livejournal.com)
18 июля 2008, 18:02

Кстати, люди добрые. Сам я не местный, из-за злого BoЛka и его опытов поставил себе злостобучую Оперу 9.51. А типа "стилизована под хрен знает что". Как в ней вернуть нормальный вид?

zencd.livejournal.com (zencd.livejournal.com)
18 июля 2008, 18:07

Вот рендеринг от четырёх бро:
http://www.picamatic.com/view/640057_rounds/

На мой взгляд приемлим только сафарийский вариант.

zencd.livejournal.com (zencd.livejournal.com)
18 июля 2008, 18:10, ответ предназначен muxa-ru.livejournal.com:

http://habrahabr.ru/blog/opera/44411.html

savintsev.ru (savintsev.ru)
18 июля 2008, 18:27

Круто!
Болк молодец

muxa-ru.livejournal.com (muxa-ru.livejournal.com)
18 июля 2008, 18:31, ответ предназначен zencd.livejournal.com:

О да-а-а-а!!!!!!!!!! Спасибо.

Ray T. Kerrygun (kerrygun.ru)
18 июля 2008, 18:58

<blockquote>З.Ы. а теперь всё тоже самое плюс:
- залить цветом
- залить цветом и положить вертикальный градиент у верхней границы
- залить цветом и положить горизонтальный градиент у левой границы
- залить цветом и положить фоновую картинку прижатую в верхний-левый угол <blockquote>

И тенющечки, тенюшечки чтоб были.

Ray T. Kerrygun (kerrygun.ru)
18 июля 2008, 18:59

Полупрозрачные.

arty (arty.name)
18 июля 2008, 19:46, ответ предназначен muxa-ru.livejournal.com:

чтобы вернуть опере прежний вид: меню - tools - appearance - skin - classic
ну или http://my.opera.com/spybot2d/blog/2008/06/07/classic-skin-for-opera-9-5-10051

blog.ad.by (blog.ad.by)
18 июля 2008, 20:06, ответ предназначен bolk (bolknote.ru):

Слушай, а ты -khtml-border-radius проверял? Он вообще работает?
Я пробовал Konqueror 4.00.83 (win32) и Konqueror 3.4.0 (cygwin) - не работает совсем. И в бинарниках не находится.

bolk (bolknote.ru)
18 июля 2008, 20:22, ответ предназначен muxa-ru.livejournal.com:

Дотюнить по размерам — дело несложное, это не так важно. Качество скругления мне на глаз кажется одинаковым.

Положить градиент картинкой совсем несложно, не понимаю в чём тут затруднения.

bolk (bolknote.ru)
18 июля 2008, 20:23, ответ предназначен muxa-ru.livejournal.com:

Она не стилизована под «хрен знает что», это новый скин и именно в нём будут все новые измененения происходить :)

bolk (bolknote.ru)
18 июля 2008, 20:23, ответ предназначен Ray T. Kerrygun (kerrygun.ru):

Положить градиент картинкой совсем несложно, не понимаю в чём тут затруднения.

bolk (bolknote.ru)
18 июля 2008, 20:24, ответ предназначен Ray T. Kerrygun (kerrygun.ru):

тенюшечки — через shadow или положить картинкой, тоже мне фокус :)

bolk (bolknote.ru)
18 июля 2008, 20:24, ответ предназначен blog.ad.by:

Не проверял, негде мне. В интернетах нашёл.

simonov.myopenid.com (simonov.myopenid.com)
19 июля 2008, 09:11

в бете ie8 вообще не показывает.

bolk (bolknote.ru)
19 июля 2008, 10:12, ответ предназначен simonov.myopenid.com:

В бете IE8 ничего смотреть нельзя.

ELV1S (elv1s.ru)
20 июля 2008, 22:23, ответ предназначен blog.ad.by:

Мне мешала лень. Вот пример: http://elv1s.ru/files/html+css/vector-corners.html
Получилось почти как у Болка. Правда у него хаки другие и SVG вставлено через base64.

ELV1S (elv1s.ru)
20 июля 2008, 22:26, ответ предназначен bolk (bolknote.ru):

У меня в ссылке опять «+» заменяется на «%20» :-(

bolk (bolknote.ru)
20 июля 2008, 22:42, ответ предназначен ELV1S (elv1s.ru):

У тебя же файлы сегодня созданы ;) http://elv1s.ru/files/html+css/

ELV1S (elv1s.ru)
21 июля 2008, 01:20, ответ предназначен bolk (bolknote.ru):

vector-corners.html сегодня был изменён и закачен. Ну, естественно это не актуально, после того-то как ты всё хорошо расписал уже.

0range (0range.ru)
23 июля 2008, 17:18

эххх если б не опера мона была бы юзать border-radius :/
правда border-radius пока что через жопу реализован в сафари и лисе, но все же поддержка оперы не помешала
и вообще w3c тянет и тянет резину с css3 :(((((( пора им что то менять иначе css3 в полной форме выйдет лишь лет через 6-7

bolk (bolknote.ru)
23 июля 2008, 18:21, ответ предназначен 0range (0range.ru):

Если бы не «Опера» и не IE

0range (0range.ru)
29 июля 2008, 12:59, ответ предназначен bolk (bolknote.ru):

да ие безнадежен или gracefull degradation для него или через экспрешены

bolk (bolknote.ru)
4 августа 2008, 15:04, ответ предназначен 0range (0range.ru):

В этом вопросе безнадёжна «Опера», в IE всё-таки что-то можно сделать.

faxenoff.livejournal.com (faxenoff.livejournal.com)
17 августа 2008, 11:51

А возможно ли скриптом переконвертить обычный <div class="rounded" /> в <v:roundrect class="rounded />? Посмотрел через DOM, вроде обычная нода, только есть отличия в scopeName,tagUrn и nodeName. Вот как раз последнее я и не знаю как менять, если только не как обычно - сделать новую ноду, внутренности скопировать, старую грохнуть. Но это как то...

bolk (bolknote.ru)
18 августа 2008, 10:38, ответ предназначен faxenoff.livejournal.com:

Можно и переконвертить. На MSDN есть примеры работы.

faxenoff.livejournal.com (faxenoff.livejournal.com)
18 августа 2008, 14:06

Ну тогда алгоритм более-менее вырисовывается. В отдельном ie.css пишем в expression функцию конверчения, а в нужных селекторах её вызываем с параметрами цвета, радиуса уголков и прочим. Хорошо бы ещё и градиент сделать возможным. Там же обнуляем svg-бэгкраунд во избежание недоразумений.

+ Без кондишен коментариев.
+ Всё в css
+ Можно применять к чему угодно - названия классов не зашиты в функцию
- Ну скрипт, ну так что же?

ps. Пока некогда самому, но если кто-то быстро реализует - отпишитесь здесь.

faxenoff.livejournal.com (faxenoff.livejournal.com)
21 августа 2008, 14:38

Нарисовывается достаточно простое решение, без всяких if vml.
Объявляем ns:v и спокойно делаем <v:roundrect /> в Opera & FF. Оформляем их через css как v\:roundrect{}.

В xhtml+xml режиме Opera&FF работает как-то странно и приходится включать в css:
@namespace v "urn:schemas-microsoft-com:vml"; и использовать v|roundrect{}, но при этому всё равно какие-то глюки происходят.

Понадобилось сразу же сделать скруглённые уголки у картинок.
В IE всё решилось добавкой в
<v:roundrect>
    <v:fill type="frame" src="image.jpg" ></:fill>
</v:roundrect>

В FF и так всё хорошо.

В Opera возникла проблема - прописанный в svg <image /> работает отлично, но зачем нам такое нужно, плодить svg, особенно если используется cms?

К <img> SVG background-image применяется без успеха. Поэтому сейчас стоит проблема сделать сниффер изнутри svg, который бы определял src тэга <v:fill/> и вставлял его как src для <svg:image /> (внутри svg-файла). Пока у меня почему-то не получается добиться даже alert() из SVG вставленного как картинка (в режиме страницы text/html). Что-то мне кажется что и не получиться. 8-(

Может есть какие-то методы передать url как параметр в svg?

faxenoff.livejournal.com (faxenoff.livejournal.com)
21 августа 2008, 15:55

Конкретнее по xhtml+xml режиму в Опера и FF:

Проблема в том, что на <v:roundrect> не действуют в css-ные правила через class & id. И даже аттрибут style не действует. Но по тэгу "v|roundrect" - всё работает. Видимо надо допрописывать DTD для <v:roundrect>.

Т.е. для окончательного решения вопроса требуется:
1. Найти как заставить <v:tags> подчиняться css через классы.

2. Достать src картинки из SVG, которое можно заранее прописать как атрибут <v:tags src="..."> скриптом из svg (как-то надо пробиться к объекту, содержащему svg).

3. Если 1 получилось, а 2 не получается - прописать в каждом <v:tags> свой style="background-image:url(round.svg?myimage.jpg);" и внутри SVG скриптом определять параметр и использовать его на <image xlink:href="top_logo_bg.jpg" />

И всё это только ради Оперы. 8-(

bolk (bolknote.ru)
21 августа 2008, 17:13, ответ предназначен faxenoff.livejournal.com:

Посмотрите мою посленюю заметку, решение сразу найдётся. По поводу того как передать в SVG картинку сказать не могу, да и не надо это. Не понимаю чем плохо внедрять SVG в CSS.

bolk (bolknote.ru)
21 августа 2008, 17:14, ответ предназначен faxenoff.livejournal.com:

Тем более, что SVG это вектор, а JPEG — растр. Именно поэтому я применяют svg background.

faxenoff.livejournal.com (faxenoff.livejournal.com)
21 августа 2008, 18:22

Задача1: Множество разноцветных скруглённых блоков с разными id и class.
В IE+FF решаема без проблем. Я сразу отказался от [if vml] и сделал namespace:v для этих целей. А в Опере для каждого блока потребуется отдельный SVG. Хотелось бы использовать одну svg-маску, а фон менять стилями или скриптом (но тоже из стилей) - это же как-то должно делаться, ведь там везде xml. Внедрение svg как mime в css действительно наименьшее зло, но это неудобно.

Задача2: Скругление уголков у картинок (как пример: новостная лента или аватары)
Например при генерации кода, конечно же мы знаем адрес картинки и можем использовать его в html. Для того чтобы скруглить в Опере уголки у картинки, пока есть один способ - сделать svg с картинкой и маской и применить его как background-image. Но на все новостные картинки, мы, миллионы svg c бэграундами - не напасёмся.

p.s. Не забываем, что у мы используем всё только на блоках <v:roundrect> для интеграции с IE и забываем о замене его на div или на svg, чтобы не усложнять вёрстку.

p.p.s. Фон для картинок может быть любым и неоднородным. Обработка картинок на сервере не подходит.

-----------------
Сейчас я всё же делаю отдельные svg для каждого блока и применяю их через враппер (или просто через родительский блок) #wrapper v|roundrect{...} так как class на объекты из инопланетянского namespace не работает!

gr1b0k.livejournal.com (gr1b0k.livejournal.com)
1 сентября 2008, 11:29

первый раз услышал о "noindex:-o-prefocus"
в спецификации указано что-то типа "если попадается незнакомый селектор- не парсить правило вообще"?

gr1b0k.livejournal.com (gr1b0k.livejournal.com)
1 сентября 2008, 12:07

http://blog.ad.by/2008/08/easy-way-to-embed-transparent-png24.html
>Кстати, валидатор от W3C таки научился понимать
>пространства имен. Это позволяет не использовать
>условные комментарии для включения VML.

bolk (bolknote.ru)
1 сентября 2008, 14:14, ответ предназначен gr1b0k.livejournal.com:

Да, именно так в спецификации и написано. noindex — это просто тег, можно написать «xxx» или что-то другое.

tnq.livejournal.com (tnq.livejournal.com)
10 сентября 2008, 21:46

по моему есть один недочет у этого способа - при большом количестве содержимого в блоке также и увеличиваются скругления в ИЕ, ведь рисует он их в зависимости от размеров блока. Для ЦСС3 можно в пикселях задать скругление, для СВН - тоже, а вот с ИЕ облом.

bolk (bolknote.ru)
11 сентября 2008, 09:56, ответ предназначен tnq.livejournal.com:

Не пробовал на больших блоках, видимо зря. Так как схему утянули в несколько мест без указания источника, думаю, заниматься ей я не буду. Пусть занимаются те, кто утянул.

Мне-то самому скруглённые углы уже начинают надоедать.

romchus.livejournal.com (romchus.livejournal.com)
9 декабря 2008, 19:26

Лучше уж по старинке, слишком все заморочено и крайне не гибко... но прикольно...

Вообще только и мечтаю чтобы давно уже все браузеры перешли на css3 сидим блин в каменном веке и наслаждаемся фоксом

bolk (bolknote.ru)
9 декабря 2008, 22:07, ответ предназначен romchus.livejournal.com:

А FF каким-то прорывом является? Браузеры все более-менее борятся за функционал. Вряд ли кого-то можно выделить.

poltoraivana.ru (инкогнито)
7 сентября 2013, 16:39

Да уж отличная статья. Только в вот в HTML вставлять SVG как то не корректно. Там всё проще картинками обыграть.

Евгений Степанищев (bolknote.ru)
7 сентября 2013, 19:15, ответ предназначен poltoraivana.ru

Кто это вам сказал, что некорректно?

бдбдбдб (инкогнито)
10 октября 2013, 09:17

Откройте ссылку та-да в ie8 посмотрите там нет углов только текст

Евгений Степанищев (bolknote.ru)
10 октября 2013, 16:46, ответ предназначен бдбдбдб

Ну так поправьте, чтобы в IE8 работал VML, тоже мне проблема. SVG в HTML появилось только в IE9. Ничего некорректного в этом нет.

Некорректно комментировать статью пятилетней давности. Откройте какую-нибудь более современную.

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)