пятница, 24 октября 2008 г.

CSS и закругленные углы (round corners)

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


Есть много способов данной верстки. Я же расскажу вам как сверстать закругленные углы с помощью абсолютного позиционирования. Этот способ позволит тянуться нашей области как по горизонтали, так и по вертикали.

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

<div class="roundblock">
<div class="corners"><s></s><b></b><u></u><i></i></div>
ROUND BLOCK
</div>

Внутрь элемента с классом 'corners' я поместил 4 элемента (s, b, u, i) которым позже поставлю background image.

И так начнем. Опишим стили для нашего контейнера (roundblock).

.roundblock {
background:#ae2d00;
padding:16px; width:300px;
position:relative;
}
Цвет заднего фона ставим такой же как и цвет нашего закругленного блока. В моем случае размер картинок с уголками получился 16 на 16 пикселей. Поэтому ставим внутренний отсуп 16 пикселей. И конечно же ставим position:relative. Теперь элементы которые находяться внутри этого блока и позиционируются абсолютно(position:absolute) будут размещаться не относительно всего документа, а именно относительно нашего блока.

Подошла очередь к нашим углам.

Всем элементам ставим абсолютное позиционирование. Высоту и ширину утсанавливаем равную 16-ти пикселям, именно такие размеры у наших картинок.
.roundblock .corners * { position:absolute; height:16px; width:16px; display:block; }
Теперь на задний фон какждого из элементов устанавливаем наши картинки-уголки и расставляем их по углам нашего блока-контейнера.
.roundblock .corners s {
background:url( "corner-tl.png" ) no-repeat;
left:0;
top:0;
}
.roundblock .corners b {
background:url( "corner-tr.png" ) no-repeat;
right:0;
top:0;
}
.roundblock .corners u {
background:url( "corner-br.png" ) no-repeat;
right:0;
bottom:0;
}
.roundblock .corners i {
background:url( "corner-bl.png" ) no-repeat;
left:0;
bottom:0;
}
Вот собственно и все. Это работает во всех браузерах. Правда в IE6 возникают некоторые проблемы. Картинки не правильно отображаются. Чтобы этого избежать добавьте свойство overflow:hidden; для каждого уголка.

Но и это еще не все. Есть проблема посерьезнее. В свое время я потратил на ее решение около 3-х часов. Вернее на само решение проблемы у меня ушло около 20-ти минут. Сложность состояло в том чтобы выяснить в чем собственно дело. А проблема заключалась в следующем:

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




Чтобы решить эту проблему я воспользовался командой 'expression' которую прописал прямо в стилях. Expression позволяет назначить CSS-свойству Javascript-выражение. И так мы знаем что проблема в размере углов, если кратно 2-м - позиционировать надо ниже на один пиксель. Выглядить CSS в конечном итоге должен так:
.roundblock .corners * {
position:absolute;
height:16px;
width:16px;
overflow:hidden;
display:block;
}
.roundblock .corners s {
background:url( "corners-tl.png" ) no-repeat;
left:0;
top:0;
}
.roundblock .corners b {
background:url( "corners-tr.png" ) no-repeat;
right:0;
top:0;
_right: expression((this.offsetParent.clientWidth % 2) ? '-1px' : 0);
}
.roundblock .corners u {
background:url( "corners-br.png" ) no-repeat;
right:0;
bottom:0;
_bottom: expression((this.offsetParent.clientHeight % 2) ? '-1px' : 0);
_right: expression((this.offsetParent.clientWidth % 2) ? '-1px' : 0);
}
.roundblock .corners i {
background:url( "corners-bl.png" ) no-repeat;
left:0;
bottom:0;
_bottom: expression((this.offsetParent.clientHeight % 2) ? '-1px' : 0);
}
Подчеркивание перед свойством (_right: ....) делает его активным только в IE6, поэтому он перекрывает предидущие стили.

Вот и все. Наслаждайтесь кроссбраузерными закругленными уголками которые растягиваются в зависимости от внутреннего контента.

3 комментария:

Yvelious комментирует...

Рещение проблемы с неправильным позиционирование в ie6 cправа и внизу можно решить и без экспрешен.
решение у лебедева на сайта в разделе техногред. К тому же если уже используется хак подчеркивания "_" почему бы просто не поставить -1px а не писать експрешен?
Еще один важный момент - это невозможность при таком способе использовать спрайт и одновременно пнг24 с полупрозрачностью! Ну а в целом долгое время сам пользовался таким способом, но в итоге перешел на другой

Razor комментирует...

Просто поставить подчеркивание и везде установить значение -1px не получится так как проблема с позиционированием проявляется не всегда, а зависит от размеров контента. Именно по этому я использую икспрешн.

з.ы. Лебедев - это далеко не показатель.

Razor комментирует...

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

Проблема с пнг фиксом мне известна. Приходится жертвовать чем-то если хочется красоты в ИЕ6, такие уж они - дядьки из Майкрософт.