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

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

пятница, 27 марта 2009 г.

Использование CSS Sprites (Спрайты)

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

Главное преимущество спрайтов - это уменьшение количества HTTP запросов к серверу для получения картинок. Это конечно незначительно уменьшает скорость загрузки страницы, но представте, что у вас 100 маленьких картинок(допустим, иконок). Объеденив их, например в 4 картинки включающие по 25 иконок, Вы уменьшаете количество запросов в 25 раз, а это уже что-то.

Ну давайте наконец перейдем к делу.
Предлагаю небольшой пример с использованием 8-ми картинок объедененных в одну.



Давайте отобразим 4 верхних смайлика и установим ховер (hover) на каждый из них. Псевдокласс будет менять каждый смайлик на нижестоящий.

Вот HTML конструкция:
<ul>
<li><a class="happy" href="#"></a></li>
<li><a class="green" href="#"></a></li>
<li><a class="punk" href="#"></a></li>
<li><a class="sad" href="#"></a></li>
</ul>
А вот фрагмент CSS кода:
ul li { list-style:none; float:left; }
ul a { display:block; display:block; height:96px; width:96px;
background:url("smileys.png") no-repeat; float:left;
}
Как Вы заметили, я задал всем элементам "а" фон с картинкой smileys.png которая показана выше. Должно получится следующее:


Теперь немного пояснения. Размеры наших элементов "а" - 96х96 пикселей. Свойство background-position по умолчанию имеет значение 0. Это значит, что фон для элемента будет начинаться с верхнего левого угла нашей картинки. Вот почему все 4 смайлика будут одинаковыми.

Теперь попробуем изменить 3 последних смайлика используя ту же картинку.

ul a.happy { } /* с первым у нас и так все нормально */
ul a.green { background-position:-96px 0; }
ul a.punk { background-position:-192px 0; }
ul a.sad { background-position:-288px 0;}
Заметьте, что я установил именно отрицательное значение по оси Х. Это потому, что мы двигаем не элементы по фону, а сам фон под элементом. Допустим, для зеленого смайлика нам необходимо сдвинуть фон влево ровно на 96px. Должно отображаться следующее:



Ну а теперь добавим псевдокласс hover для каждого элемента "а":
ul a.happy:hover { background-position:0 -96px; }
ul a.green:hover { background-position:-96px -96px; }
ul a.punk:hover { background-position:-192px -96px; }
ul a.sad:hover { background-position:-288px -96px; }
Теперь я сдвинул background вниз на 96 пикселей для каждого из классов, а значение Х оставил прежним. В конечном результате у вас должно получиться следующее:

Рабочий пример








Вот так можно удобно пользоваться спрайтами. Главное правильно расположить картинки чтобы в дальнейшем их возможно было использовать. Например, для кнопки состоящей из 3-х картинок (предыдущая статья) можно использовать такой спрайт:



Сверху расположены правая и левая часть кнопки, снизу - середина.

Надеюсь, что моя статья была вам интересна и вы что-то из нее почерпнули. Если нет, то смайлики определенно должны были вас порадовать :).

вторник, 17 марта 2009 г.

CSS кнопка (кроссбраузерная)

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

Я нарисовал свою собственную кнопку которая напоминает стиль Windows Vista Button:


Для того чтобы сверстать такую кнопку я использую следующую конструкцию:

<a class="button" href="#">
<img class="head" src="blank.png" /><input type="submit" value="Button"/><img class="tail" src="blank.png" />
</a>

Я не зря обрамил три элемента именно в тег <A>. IE6 понимает псевдокласс hover только для этого элемента, поэтому если в дальнейшем мы захотим чтобы кнопка изменяла свой вид при наведении на нее мышкой - это будет какраз кстати. Также учтите, что все элементы являются инлайновыми(inline) и любой пробел или перенос строки между ними приведет к возникновению пустого пространства, а нам этого не надо. Поэтому сохраните форматирование именно так (все 3 внутренних элемента в одной строке).

И так, как Вы уже заметили, кнопка состоит их трех основных элементов: элемент img который выполняет роль левой части, элемент img - правая часть и input, который будет растягиваться посредине. Для верстки нам понадобятся 3 составные картинки этой кнопки. Вырежьте их в каком-то графическом редакторе типа Photoshop или GIMP. У Вас должно получиться следующее:

     

ВАЖНО! Дополнительно вырежьте картинку размером 1x1 пикселя полностью прозрачного фона. Об этом чуть дальше.

Настало время для самой верстки:

.button { text-decoration:none; }
.button * {
border:0;
height:37px;
cursor:pointer;
vertical-align:middle;
}

.button img.head {
background:url("button-left.png") no-repeat;
width:7px;
}

.button img.tail {
background:url("button-right.png") no-repeat;
width:7px;
}

.button input {
background:url("button-bg.png") repeat-x;
color:#eee;
width:100px;
padding-bottom:2px;
font-size:15px;
}
Подробно рассмотрим каждый селектор:

.button * задает каждому элементу высоту в 37 пикселей, убирает бордер и устанавливает курсор в виде руки(это по желанию).

Далее опишем два класса head и tail. Установите на бекграунд заведомо вырезанные рисунки. Я устанавливаю их с помощью CSS опять же для hover'a. Теперь, как и обещал, вернемся к нашей прозрачной однопиксельной картинке. В этом примере я назвал ее blank.png и поставил ее на оба тега img. Это нужно сделать так как картинка без указанного атрибута src вовсе не будет отрисовываться.

Наконец устанавливаем CSS свойства для нашей кнопки. Ставим фоновый рисунок и растягиваем его по горизонтали. Задаем cерый цвет шрифта, верхний паддинг чтобы центрировать текст по вертикали и размер фонта 15 пикселей.

Ну вот и все. Кроссбраузерная CSS кнопка готова.

Если захотите установить hover, достаточно добавить всего 3 коротких селектора:
.button:hover .head { background:url("button-left-hover.png") no-repeat;}
.button:hover input { background:url("button-bg-hover.png") repeat-x; }
.button:hover .tail { background:url("button-right-hover.png") no-repeat;}

четверг, 5 марта 2009 г.

Метод getElementById() в IE или "при чем тут name?"

Здравствуйте! Если Вы читаете эту статью, возможно, вы столкнулись с той же проблемой что и я и находитесь в небольшом замешательстве. Я сам когда-то столкнулся с ситуацией когда javascript'овый метод getElementById() возвращал мне ссылку не на тот объект который я запрашивал. Пришлось потратить немного времени чтобы выяснить в чем же всетаки дело.

На сайте http://www.w3schools.com в разделе Javascript черным по белому написано определение метода getElementById(). Выглядит оно так:

The getElementById() method returns a reference to the first object with the specified ID.
Из данных слов понятно, что этот метод возвращает ссылку на обьект с указанным идентификатором. Так оно и есть конечно, не думайте что я пытаюсь это оспорить :). А вот ребята из Microsoft со своим Internet Explorer'ом оспорили.

getElementById возвращает ссылку на объект с указанным name?

Рассмотрим небольшой пример. Создадим несколько элементов у которых бы совпадали атрибуты id и name:
<textarea name="chooseMe"></textarea>
<div id="chooseMe" />

А теперь попробуем вывести на экран сообщение с именем нужной нам ноды (nodeName):

alert(document.getElementById('chooseMe').nodeName);

Выполнение данного скрипта судя по названию метода должно вывести на экран сообщение с текстом DIV во всех браузерах. Жаль что используя IE6 или IE7 мы увидим ничто иное как окошко с текстом TEXTAREA. А какая разница между именем или айди? IE думает, что никакой.

Будьте внимательны используя элементы с совпадающими именами и идентификаторами когда используете браузеры компании Microsoft. Ну а если Вам это так необходимо, просто добавьте приставку значению имени или айди определенного элемента или же учитывайте порядок поиска "сверху вниз".