Заметки веб-работника
30 января 2006

Закругляем уголки границ у блоков

Заглянул я как-то с Internet Explorer'ом на Opera Community и почувствовал – что-то здесь не то. Нет, сайт успешно открылся, не развалился, однако присутствовало ощущение какой-то неполноценности. Обратившись к «правильным» браузерам, я понял, в чем дело – все блоки имели границы с закругленными углами, в IE наделить той же особенностью страницы либо не удалось, либо, скорее всего, «не очень-то и хотелось». Я же решил попробовать.

В CSS3, одной из новых опций для границ, WWW-Консорциум предложил свойство border-radius. С его помощью как раз и можно будет создавать закругленные углы ..., когда-нибудь, но не сейчас. Сегодня, из передовых веб-проводников только у Mozilla реализована эта возможность (-moz-border-radius), что конечно хорошо, да только результат этой реализации пока выглядит не очень-то аккуратно.

Opera Community создавали аккуратно, поэтому в качестве уголков использовались полупрозрачные (с альфа-каналом) png-картинки. Вообще, применение в этом случае изображений, сегодня – одно из популярных решений. Как правило, это громоздкие html-конструкции на основе таблиц, либо букет из вложенных div'ов. Но неужели нельзя обойтись всего одним блочным тегом, все представление убрав в CSS? Звучит, конечно, заманчиво, только вот как внедрить сразу 4 изображения в один CSS-класс, ведь множественный фон в background-image ведущими браузерами пока еще не поддерживается? Все оказывается просто – можно воспользоваться псевдо-элементами :after и :before. Вот решение с Opera Community:

.rounded{
   border:1px solid #d1d1d1;
   background:#cfc;
   padding:10px;
}

.rounded:before{
   display:block;
   height:9px;
   background:transparent url(c2.png) top right no-repeat;
   content: url(c1.png);
   line-height:1px;
   font-size:1px;
   margin:-11px -11px 0 -11px;
}

.rounded:after{
   display:block;
   height:9px;
   background:transparent url(c4.png) bottom right no-repeat;
   content: url(c3.png);
   line-height:1px;
   font-size:1px;
   margin:1px -11px -11px -11px;
}

Теперь блоки с классом rounded приобретут необходимый вид. Правда произойдет это только в браузерах, поддерживающих вставку генерируемого содержимого при помощи CSS, а это значит, что представленный ниже блок 1 в Internet Explorer сохранит прямоугольную рамку.

Блок 1
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

Эта же идея вполне применима и для IE, пусть браузер и не поддерживает многие стандарты CSS2, он сполна компенсирует это своими уникальными возможностями. Воспользуемся способностью веб-проводника обращаться к объектам документа через expression() и разместим внутри подопытного блока дополнительный html-код: два div'а, содержащих по два изображения. Строка behavior: expression(!this.rounded ? this.rounded = this.innerHTML = '<div class="rounded_before"><img src="c2.png" class="right"><img src="c1.png"></div>' + this.innerHTML + '<div class="rounded_after"><img src="c4.png" class="right"><img src="c3.png"></div>': '' );, добавленная к описанию класса rounded позволит сделать это. После чего остается лишь дополнить CSS-код новыми классами:

.rounded{
   border:1px solid #d1d1d1;
   background:#cfc;
   padding:10px;
   behavior: expression(!this.rounded ? this.rounded = this.innerHTML = '<div class="rounded_before"><img src="c2.png" class="right"><img src="c1.png"></div>' + this.innerHTML + '<div class="rounded_after"><img src="c4.png" class="right"><img src="c3.png"></div>': '' );
}

.rounded:before, .rounded_before{
   display:block;
   height:9px;
   background:transparent url(c2.png) top right no-repeat;
   content: url(c1.png);
   line-height:1px;
   font-size:1px;
   margin:-11px -11px 0 -11px;
}

.rounded:after, .rounded_after{
   display:block;
   height:9px;
   background:transparent url(c4.png) bottom right no-repeat;
   content: url(c3.png);
   line-height:1px;
   font-size:1px;
   margin:1px -11px -11px -11px;
}

.rounded img.right{
   float:right;
   margin-right:-3px;
}

.rounded_before, .rounded_after{
   background:none;
   position:relative;
   z-index:1;
}

Теперь и в IE блоки с классом rounded имеют закругленную рамку.

Блок 2
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

На этом можно было бы поставить точку, если бы не одна маленькая неприятность – если у вас IE 5.x - 6.0 (Windows-версии), то у блока 2, в уголках, вместо прозрачности вы увидите серый фон. О сложных отношениях между Internet Explorer и форматом PNG сказано уже достаточно («прозрачность PNG в IE»), я не буду здесь подробно останавливаться на этом, тем более что к заявленной теме, указанная проблема имеет лишь косвенное отношение. Укажу лишь, что препятствие легко обойти, к примеру, просто отказавшись от PNG, а можно воспользоваться одним из известных решений. Метод с применением DHTML Behaviors и фильтра AlphaImageLoader видится мне наиболее оптимальным (правда, он не поддерживается IE 5.0). Для этого добавим класс png:

.png{
   *background-image:none ! important;
   visibility:hidden;
   behavior: url(pngfix.htc);
}
и укажем его в создаваемых изображениях: behavior: expression(!this.rounded ? this.rounded = this.innerHTML = '<div class="rounded_before"><img src="c2.png" class="png right"><img src="c1.png" class="png"></div>' + this.innerHTML + '<div class="rounded_after"><img src="c4.png" class="png right"><img src="c3.png" class="png"></div>': '' );

Файл pngfix.htc содержит следующий код:

pngfix.htc
<public:component>
   <script language="JavaScript">
      element.style.width = element.width;
      element.style.height = element.height;
      element.runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + element.src + '", sizingMethod="crop")';
      element.src = "0.gif";
      element.style.visibility = "visible";
   </script>
</public:component>

Блок 3 являет собой итоговый результат:

Блок 3
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

Рабочий пример можно также увидеть на отдельной странице здесь.


Теги: CSS

 

Комментарии (1)

_______

Вы можете оставить свой отзыв по данной статье:

  Имя
  E-mail (не публикуется)
  Веб-сайт

Комментарий (Теги форматирования не поддерживаются)