вторник, 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

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

понедельник, 5 октября 2009 г.

Двухколоночный макет тянущийся по вертикали (CSS only)

О чем это он? о_0

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

Вступление

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

К сожалению я не любитель такой верстки - верстки таблицами... это конечно семантически корректно и очень просто, но все же я задался целью сделать это DIV'ами.

Проблема

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

two column layout problem

Видите? Я поставил немного переносов строк и получилось вот ЭТО. Никуда не годится.. то же самое получается и с другой колонкой...

Цель

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

Приступим

Для начала, как я всегда делаю, представлю Вам HTML код:


<div class="page">
<div class="leftcol">
LEFT COLUMN HERE
</div>

<div class="rightcol">
<div class="content">
RIGHT COLUMN HERE
</div>
</div>
</div>

Как Вы можете наблюдать, я создал общий контейнер для моих колоночек :). Они живут в страничке, у них статическая длинна и они разноцветные. Вот кстати нужный нам CSS код:


.page { background:#ffff66; width:500px; overflow:hidden; }
.leftcol {
float:left; background:#ccff66;
width:350px; border-right:1px solid #ff9900;
}
.rightcol { padding-left:350px; background:#ccff66; }
.rightcol .content {
background:#ffff66; border-left:1px solid #ff9900;
}

Все и без меня ясно, но я вставлю свои пять копеек. Главному контейнеру (page) мы ставим фон желтого цвета, это на тот случай если наша правая колонка будет короче левой.
Левая колонка принимает свойства float со значением left и фон, свой собственный фон - зеленый, длинна - 350 пикселей.
Правой колонке установим значение padding-left равным длинне левой колонке - 350 пикселей и ЗЕЛЕНЫЙ фон. ВАЖНО установить именно padding, а не margin, так как наша колонка не будет страховать левую в том случае если та будет короткой.
Внутри контейнера с правой колонкой я создал еще один блок, который и будет иметь свой правильный ЖЕЛТЫЙ фон.
Не забудьте про overflow:hidden у элемента .page. Это исправляет неправильное вычисление браузером высоты этого блока. В противном случае все будет как на предыдущем скриншоте.

two column layout good

Вот и он!!! Попробуйте подобавлять немного содержимого куда-либо.. все будет отлично! Кстати, я совсем не упомянул о бордере.. На левую колонку ставим border-right, на вложенный блок правой - border-left. Верстка кроссбраузерная (ИЕ6 тоже)!!! Никаких таблиц и javascript'a.

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