Делаем закругленные уголки с помощью псевдоэлементов :before и :after

Задача: сделать врезку с закругленными уголками с минимумом html-кода.

Все, наверное, сталкивались с врезками с закругленными уголками. Поскольку множественный бэкграунд современные браузеры (кроме Safari) не поддерживают, то такие вещи приходится делать несколькими элементами, вложенными друг в друга.

Но есть способ уже сейчас избежать подобных вещей.

html-код:


<div class="incut">
  Текст
</div>

css-код:

Задаем голубой фон врезки:


.incut{background: #dff7ff;padding: 20px;}

Четыре уголка навешиваем на элементы :before и :after


.incut:before{
    content:url(i/border_tl.gif);
    background: url(i/border_tr.gif) no-repeat 100% 0;
    height: 7px;
    display: block;
    margin: -20px -20px 13px -20px;
}

.incut:after{
    content:url(i/border_bl.gif);
    background: url(i/border_br.gif) no-repeat 100% 0;
    height: 7px;
    display: block;
    margin:13px -20px -20px -20px;
}

Это работает во всех современных браузерах кроме IE (проверялось в Firefox 1–2, Opera 7–9, Safari 3). Для IE аналогичный функционал навешиваем с помощью JS (лучше помещать в отдельный файл CSS, специальный для IE):


.incut{
    zoom:1;
    behavior:expression(!this.isInserted==true ? this.isInserted=(this.innerHTML = '<span style="background: url(i/border_tr.gif) no-repeat 100% 0;height: 7px;display: block;margin: -20px -20px 13px -20px;"><img src="i/border_tl.gif" alt="" /></span>' + this.innerHTML + '<span style="background: url(i/border_br.gif) no-repeat 100% 0;height: 7px;display: block;margin:13px -20px -20px -20px;"><img src="i/border_bl.gif" alt="" /></span>') : '');
}

Работает в IE 6—7. При отключеных скриптах пользователь ie увидит голубой фон у врезки, т.е.  ничего не сломается.

В результате имеем «пуленепробиваемую» врезку с минимумом html-кода. Заметьте, что вы можете указать ещё одну картинку у врезки, которая будет её бэкграундом.

Примеры смотрите здесь

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

Тигренок
30 ноября
Это, конечно, клево... но как быть, если нужны прозрачные уголки, например, при неоднородном заднике?
Василий Дьяков
3 декабря
>но как быть, если нужны прозрачные уголки, например, при неоднородном заднике?

Если я правильно понял, и нужна однородная врезка с закругленными уголками на каком-то фоне, то в принципе можно выкрутиться. Код изменится, и картинки тоже будут по-сложнее, но это сделать можно. Прийдется использовать технику «раздвижных дверей» для каждого из псевдоэлементов.
Негриенко Данил
23 декабря
В осле тоже работает если написать не
.incut:before{

а через пробел
.incut:before {

и соответственно
.incut:after {

(нужен пробел между селектором и открывающей фигурной скобкой)
Василий Дьяков
24 декабря
>В осле тоже работает если написать не .incut:before{ а через пробел .incut:before {

Не очень понятно что в ie работает таким способом?
Дима
26 декабря
а они были в IE? ну они, это before и after, конечно :-)
quaritexa
30 декабря
"Прийдется использовать технику «раздвижных дверей» для каждого из псевдоэлементов."

Как это в данном конкретном случае?
Василий Дьяков
9 января
>"Прийдется использовать технику «раздвижных дверей» для каждого из псевдоэлементов."

>Как это в данном конкретном случае?

Да, вы правы - не получится. Сложность в прозрачности.
Слава
28 января
Все сдалал, как написано, не работает в лисе, черный квадрат какой то выводится.
Василий Дьяков
29 января
Все сдалал, как написано, не работает в лисе, черный квадрат какой то выводится.
Работающие примеры смотрите здесь.
Максим
12 апреля
Добрый день!
Очень понравился предлагаемый вами способ реализации. Решил попробовать его у себя. Все получилось за исключением отображения в IE. Что я сделал:
В стилевой файл я добавил предлагаемый вами скрипт с *html
Так как сайт на Wordpress, в header добавил хак <!--[if IE]><stylе type="text/css"></style><![endif]--> но почему-то не в 6 не в 7 версии не работает. Так же пробовал играться с подключением отдельного файла - не помогло. Подскажите, как быть. Заранее спасибо.
Ром
20 апреля
а возможно ли таким способом реализовать блок с обводкой? Нпример - белый, с черной однопиксельной. Или придется все же вставлять внутрь блоки?
Дима
5 мая
А если я хочу сделать "резиновую" по высоте колонку с закруглёнными уголками и чтоб бэкграунд у неё был в виде градиента, как тогда?
Фитискин Александр
12 мая
Максим, style использовать не стоит. Все стили для IE лучше всего вынести в отдельный css файл.
Ваш код может не работать по одной из нескольких причин:
1. Иногда IE игнорирует условные комментарии составленные в несколько строк, попробуйте упаковать комментарий целиком в одну строку
2. Часто следует уточнить версию IE, с помощью кострукций lt, lte, gt, gte (подробнее можно поглядеть, к примеру, ). Попробуйте для начала убрать комментарий, если стили в IE применятся, значит ошибка именно в нем. Если же нет - следует искать ошибку где-то в другом месте
Фитискин Александр
12 мая
Ром, на сколько я понимаю вы имеете ввиду блок с однопиксельной скругленной в углах границей. К примеру такой:

.box1{padding: 20px;background-color:#fff;border: 1px solid #000;}
.box1:before{display: block;height: 19px;background: url(1_tr.gif) no-repeat 100% 0;content: url(1_tl.gif);margin: -20px -20px 1px -20px;}
.box1:after{display: block;height: 19px;background: url(1_br.gif) no-repeat 100% 0;content: url(1_bl.gif);margin: 1px -20px -20px -20px;}

В таком случае, нам необходимо "вытащить" уголки на border, то есть увеличить их сдвиг на ширину границы (в нашем случае 1px). Получим:

.box1{padding: 20px;background-color:#fff;border: 1px solid #000;}
.box1:before{display: block;height: 19px;background: url(1_tr.gif) no-repeat 100% 0;content: url(1_tl.gif);margin: -21px -21px 1px -21px;}
.box1:after{display: block;height: 19px;background: url(1_br.gif) no-repeat 100% 0;content: url(1_bl.gif);margin: 0px -21px -21px -21px;}

Вам остается только подготовить соответствующие картинки.
Фитискин Александр
12 мая
Дима, текущий вариант "резиновый" по высоте, так что первая из двух задач уже решена.
Что касается бэкграунда с градиентом: вам необходимо использовать полупрозначные уголки "контр-формы" (прозрачная часть на стороне плашки, чтобы градиент сохранялся).
Дэф
31 мая
Можно поступить совсем просто - использовать border-radius, но это свойство, увы, работает пока только для сафари и фокса.