пятница, 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. Ну а если Вам это так необходимо, просто добавьте приставку значению имени или айди определенного элемента или же учитывайте порядок поиска "сверху вниз".

вторник, 24 февраля 2009 г.

Новые возможности CSS3

Конец эры интенсивного использования CSS2.1 не за горами. Вскоре CSS дизайнеры позабудут о проблемах верстки в IE6, перестанут вырезать картинки чтобы создать блоки с закругленными уголками, задавать float:left блочным элементам дабы те выстроились в нужное количество колонок и ложить два background'а на разные элементы когда так хочется установить их на один. Совсем чуть-чуть и мы наконец сможем задействовать всю мощь CSS3 так как нам этого захочется.

Сейчас современные браузеры такие как Opera 9.63, Mozilla 3.06 и Internet Explorer 6 :) активно внедряют CSS3. Конечно понимают они не все нововведенные свойста. Вот например случай с закругленными углами:

border-radius:10px;  /*одно свойство и кругые углы в 10 пикселей готовы*/

...к сожаление такое нигде не работает. Mozilla использует свой прием. Добавляет приставку -moz- почти ко всем свойствам CSS3 и все начинает работать. Safari добавляет приставку -webkit-.

Уверен, что в новых браузерах таких как Opera 10, Mozilla 3.1 и IE8 все будет хорошо

Немного подкрепления от CSS3

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

  • Очень понравилась возможность устанавливать несколько фоновых рисунков на элемент, это очень упрощает жизнь хотябы с теми же закругленными краями. Хотя сразу вспоминаешь, что это уже не проблема.
    background: url(body-bottom.gif) bottom left no-repeat,
    url(body-middle.gif) left repeat-y;
  • Возможность установить рисунок на border (Safari, Firefox 3.1 alpha)
    border-top-image:url("image.png");
    .
  • Очень классная вещь с добавлением падающей тени от текста(Opera 9.5+):
    text-shadow:10px 5px yellow;
  • Мультиколоночный лейаут с помощью всего нескольких свойств:
    -moz-column-count: 3;
    -moz-column-gap: 1em;
    -moz-column-rule: 1px solid black;
  • Закругленные углы (round corners) теперь под силу всем:
    -moz-border-radius:0 15px 0 15px;

Это конечно же только малая часть возможностей CSS3 и перечеслять их можно еще долго. Нам остается только ждать новых версий браузеров, а пока справляемся как можем :).

четверг, 19 февраля 2009 г.

Кроссбраузерный XmlHttpRequest (xhr)

Сегодня немного отдалимся от CSS и HTML и перейдем к Javascript. Речь пойдет о XmlHttpRequest.

XmlHttpRequest - это апи для пересылки различных данных между браузером и веб-сервером по Http-протоколу. Вообщем вы можете слать запрос на удаленный сервер не перегружая страницу. Очень удобная вещь.

Работая над одним проектом, я столкнулся с проблемой кроссбраузерности при использовании XHR.. как Вы думаете о чем это я? Конечно же о полюбившимся мною IE6 :). С ним всегда все наперекосяк. Вот я и решил написать свою реализацию XmlHttpRequest, точнее описать что-то вроде класса который бы все делал сам, был бы легок в эксплуатации.

И так представляю вашему вниманию функцию создающую кроссбраузерный XmlHttpRequest:

function Xhr(options) {
this.method = 'post';
this.onSuccess = function() {
};
this.onFailure = function() {
};

if (options) {
for (var o in options)
this[o] = options[o];
}
if (window.XMLHttpRequest) this.request = new XMLHttpRequest();
else if (window.ActiveXObject) this.request = new ActiveXObject("Microsoft.XMLHTTP");

this.onreadystatechange = function() {
if (this.request.readyState == 4)
if (this.request.status == 200) {
this.onSuccess(this.request.responseXML, this.request.responseText);
}
else this.onFailure();
};

var xhr = this;
this.request.onreadystatechange = function() {
xhr.onreadystatechange();
};

this.send = function(url, data) {
this.request.open(this.method, url, true);
if (this.method == 'post') {
this.request.setRequestHeader('Content-type','application/x-www-form-urlencoded');
this.request.setRequestHeader('Content-length', data.length);
}
this.request.send(data);
};
}

Теперь мне стоит немного рассказать об этом коде. И так Вы видите функцию, которой на вход передаются параметры (опции), относительно которых и будет строиться наш XHR. Пойдем по порядку

  • method - метод передачи данных, может быть POST или GET.
  • onSuccess - это функция которая будет выполняться при удачном выполнении запроса.
  • onFailure - функция которая будет выполняться при возникновении ошибки(можно выводить какое-то сообщение).
Ну вот все нужные параметры переданы, а дальше идет проверка на ActiveX. Если таковые компоненты присутствуют значит это никто иной как Internet Explorer 6.

Теперь небольшой примерчик использования.

Допустим у Вас есть текстовое поле(textarea) в котором люди пишут свои комментарии.

<textarea rows='5' cols='100' name='comment' id='comment'></textarea>
<input type='button' name='send' value='Отослать' onclick='send();'/>

Наша задача принять значение текстового поля и передать их на сервер не перегружая страницу. Создадим функцию которую сможем поместить в виде события(event) на нашу кнопку отправки.

function send() {
var xhr = new Xhr({
method:'post',
onSuccess:function() { alert('Спасибо за комментарий'); },
onFailure:function() { alert('Произошла ошибка!!!'); }
});
var commentValue = document.getElementById('comment').value;
xhr.send('/commented', 'commentText=' + commentValue);
}

Метод send у XHR шлет запрос на сервер по урлу '/commented' и передает параметр 'commentText' - это текст комментария. А на сервере мы просто получаем параметры и используем их в своих целях.

Хух! Вот и все. Напомню, что этот XmlHttpRequest работает во всех браузерах. Удачного использования.