вторник, 6 октября 2009 г.

CSS закругленные уголки/углы без абсолютного позиционирования (css round corners NO absolute position)

Доброго времени суток. Вот решил еще однин пост написать. Давайте сразу к делу.

В чем минусы position:absolute?

Я уже писал на своем блоге о методе верстки закругленных уголков. В тот раз они строились с помощью абсолютного позиционирования. Мы расставляли каждый уголок по уголкам о_0. Видите? Тавтология - уже минус. Также нам надо было фиксить проблему с ИЕ6 с помощью expressions (баг - bottom:0; not on the bottom). Зачем же эта ерунда если можно обойтись без этого?

Что будем верстать?

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

round green block

В основе данного метода верстки лежит спрайт. Он будет включать в себя 6 элементов нашего круглого блока: 4 угла + верхняя и нижняя части, захватывающие бордер.

Начнем нашу верстку

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

elements sprite

Мои элементы получились размером в 11 пикселей. Разместить их нужно именно вертикально один за другим (расскажу позже почему именно так).

Перейдем к представлению HTML кода:

<div class="roundblock">
<div class="head"><span><span></span></span></div>
<div class="body">
<div class="content">
Никакого абсолютного позиционирования
</div>
</div>
<div class="foot"><span><span></span></span></div>
</div>

Что у нас тут:

  • 3 части основного блока
  • вложенный span в елемент класса head и foot
  • еще один span в span'е
  • body для зеленого бордера
  • content в body для белого бордера

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

Давайте взглянем на CSS код:

.roundblock { width:200px; margin:200px auto; }
.roundblock .head {
background:url("corners-sprite.png") 0 -44px repeat-x;
height:11px;overflow:hidden;
}
.roundblock .head span {
background:url("corners-sprite.png") left 0 no-repeat;
height:11px; display:block;
}
.roundblock .head span span { background-position:right -11px; }

.roundblock .body {
border-width:0 1px; border-style:solid;
border-color:#6cb700;
}
.roundblock .body .content {
border-width:0 1px; border-style:solid;
border-color:white; background:#6cb700;
padding:10px; color:white;
}

.roundblock .foot {
background:url("corners-sprite.png") 0 -55px repeat-x;
height:11px; overflow:hidden;
}
.roundblock .foot span {
background:url("corners-sprite.png") left -33px no-repeat;
height:11px; display:block;
}
.roundblock .foot span span { background-position:right -22px; }

Давайте рассмотрим все по порядку:

  1. Первым делом мы опишем стили класса head. Обязательно следует указать ему высоту. В моем случае это 11 пикселей. Далее задаем фоновую картинку с урлом на наш ранее созданный спрайт. Устанавливаем позицию на элемент верхней части блока и тянем его по оси Х. Если ваши уголки меньше чем 20 пикселей, то следует поставить overflow:hidden, так как ИЕ6 не любит блочные элементы меньше 20-ти пикселей. Можете проверить что получилось открыв документ в браузере.
  2. Переходим к вложенному элементу span. Сразу же делаем его блочным (display:block) чтобы он тянулся по всей ширине контейнера. Устанавливаем картинку фона отказываясь от повторения (no-repeat). Так как это наш первый уголок и в картинке он у нас сверху, устанавливаем значение позиции Х равное left и значение Y равное 0. Проверяем в браузере и видим уголок слева.
  3. Переходим к span'у что поглубже. Он тоже должен быть блочным. Все так же только следует изменить позицию Х на right и сменить позицию спрайта по Y. Как и обещал, возвращаюсь к пояснению о вертикальной расстановке элементов в нашем спрайте. Как Вы могли заметить span у нас блочный и задавать ширину ему нельзя, так как вложенный в него span для другого уголка не будет в нужном месте. Если мы разместим элементы спрайта горизонтально, мы не сможем контролировать ширину, а в нашем случае она вычисляется окончанием рисунка.
  4. Далее сам контейнер с содержимым - body. Это промежуточный элемент, созданный для того, чтобы отобразить 2 бордера по бокам. Ставим ему зеленый бордер. А вот внутренний элемент с классом content послужит нам не только элементом с боковыми белыми линиями, но также создаст продолжение верхнего и нижнего фона.
  5. С foot'ом у нас все также как и с head. Меняем позицию спрайта соответствующих элементов и все готово.

В результате у Вас должно получиться это:

block ready

Помните, что если Вы не хотите блок с белым бордеров внутри, просто используйте background:#color; вместо backround:url('image'); у элементов head и foot. А в центре будет достаточно одного элемента с классом content.

Поэксперементируйте с данной версткой и Вы сможете легко создать что-то вроде этого:

round block with gradient

Спасибо. Буду рад любым комментариям и исправлениям.

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

Анонимный комментирует...

Спасибо за пример,
выглядит красиво.
Но есть два минуса.

1-й: Не валидный для XHTML код.
Внутри блока span не должно быть других блочных элементов.

2-й: Не семантично. Куча
'лишних' тэгов и контейнеров только для разметки.

P.S. Не сочтите за критику, всего лишь мнение.

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

Спасибо за Ваш комментраий.. всегда уважаю чужое мнение и критику...

Отвечу по порядку:

1-е: вместо тега span всегда можно использовать div.. в данном примере я использовал span чтобы все не сливалось и было более ли менее нагляднее..

2-е: опять же уникален данный пример.. если мы не используем бордер, то нам достаточно только одного контейнера для содержимого.. + для верхней и нижней частей достаточного одного вложенного элемента... верстка закругленных уголков будет несемантичной до тех пор, пока не умрет ИЕ и border-radius это не заменит... тогда с семантичностью не поспоришь..

Анонимный комментирует...
Этот комментарий был удален администратором блога.
walma комментирует...

Эй, я могу тут комментировать?

Неудобная формочка для комментовЁ