Работа с фоном. Теория и практика CSS

Добавлено 26.12.2007 | CSS

Пожалуй, редко возникают ситуации, когда можно сверстать страницу без использования атрибутов и свойств для работы с фоном. Фон присутствует везде: цвет фона надо прописывать для элемента BODY, фоновые изображения часто применяются в навигационных панелях (руки бы таким дизайнерам пооборвать), фоном делаются цветовые выделения заголовков и т.д. Короче, если с фоном не умеете обращаться, то тяжело вам придется…

Древние реликты (HTML)

Для начала взглянем на фон с точки зрения HTML. Точка зрения, надо сказать, не самая лучшая, но будем соблюдать хронологию. Итак, для работы с фоном у нас имеется два атрибута:

  1. BGCOLOR - задает фоновый цвет элемента. Присутствует у элементов BODY, TABLE, TR, TH и TD. В спецификации HTML 4.01 помечен как нежелательный для использования;
  2. BACKGROUND - задает фоновое изображение для элемента. Согласно спецификации HTML 4.01 присутствует только у элемента BODY и помечен как нежелательный для использования, однако браузеры поддерживают данный атрибут для элементов TABLE и TD.

Естественно, набор крайне ограничен и морально устарел года два назад. Но страшно сказать, какой процент кодеров пользуется только этими двумя атрибутами! Я догадываюсь, чем это вызвано. Хороший кодер достаточно ленив по своей природе, так что из этой лени должна логичным образом вытекать оптимизация труда и сокращение времени на кодирование. То есть надо быть в курсе всех нововведений, которые это самое кодирование облегчают. Плохой кодер ленью не наделен, по этой причине он упорно использует устаревшие (но проверенные) методы, трудолюбиво прописывая теги и FONT по 6 часов в сутки (два часа остается на таблицы :). Очевидно, плохих кодеров гораздо больше, чем хороших, поэтому использование морально устаревших методов в вебе дело привычное.

Надеюсь, лень входит в число ваших достоинств, так что освоение нижеизложенного материала сократит время, которое вы проводите за кодированием, а времени на самообразование и Quake (Counter Strike, StarCraft, HMM 4 - нужное подчеркнуть) останется больше.

Альтернатива новой эры (CSS)

Я бы вообще не писал эту статью, если бы альтернативы не было. Альтернатива, как вы догадались, содержится в каскадных таблиц стилей (CSS). Вам будет приятно услышать, что в спецификации CSS-1 (второй уровень отложим до лучших времен) есть пять свойств для работы с фоном. Займемся ими, если не возражаете.

background-color

Задает цвет фона элемента. Главное отличие этого свойства от атрибута BGCOLOR в том, что с его помощью можно задать фоновый цвет для любого элемента. На первый взгляд, преимущество незначительное, однако после конкретного примера все становится на свои места. Допустим, нам надо сделать блок, в котором будет серый фон. С помощью HTML в таком случае без таблицы не обойтись, а вот с помощью CSS можно повесить стиль на элемент P, к примеру. Экономия кода налицо!

HTML (101 знак) CSS (79 знаков)
<TABLE><TR><TD BGCOLOR=#666666>
<FONT COLOR=#FFFFFF>Белый текст на сером фоне</FONT>
</TD></TR></TABLE>
P {
background-color: #666; color: #FFF}
. . .
<P>Белый текст на сером фоне</P>

background-image

Задает графическое фоновое изображение элемента. Вообще если указывается фоновое изображение, то рекомендуется указывать и фоновый цвет, потому что рисунок может не загрузиться или пользователь отключит загрузку изображений. В этом случае текст может плохо читаться на фоне по умолчанию, так что лучше указывать приемлемый фон явно. Естественно, если устанавливать фоновое изображение для таблицы, то CSS не дает никаких преимуществ, однако с помощью CSS можно задать его для любого элемента.

HTML (112 знаков) CSS (89 знаков)
<TABLE><TR><TD BACKGROUND=img/bg.gif>
<FONT COLOR=#FFFFFF>Белый текст на фоновом рисунке</FONT>
</TD></TR></TABLE>
P {
background-image: url(img/bg.gif); color: #FFF}
. . .
<P>Белый текст на фоновом рисунке</P>

background-repeat

Если задано фоновое изображение, то определяет, будет ли повторяться это фоновое изображение и, если будет, то каким образом.

Значения:

  • repeat: изображение повторяется по горизонтали и по вертикали
  • repeat-x: изображение повторяется только по горизонтали
  • repeat-y: изображение повторяется только по вертикали
  • no-repeat: изображение не повторяется

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

Часто кодеры поступают следующим образом. Если надо, скажем, чтобы изображение не повторялось вообще, то делают рисунок таких размеров, чтобы его повторение не было заметно на любых мониторах. Это примерно 1600ґ1200 пикселей. Сами понимаете, что решение это корявое (увеличивается вес рисунка), но единственно возможное средствами HTML. С помощью CSS проблема решатся изящно и легко.

BODY {
background-image: url(img/bg.gif);
background-repeat: no-repeat}
. . .
<BODY>Содержимое страницы на фоновом неповторяющемся рисунке</BODY>

background-attachment

Задает, будет ли перемещаться фон вместе со всем содержимым страницы при скроллировании или нет. Вообще когда фон страницы не перемещается это несколько непривычно для посетителя сайта и иногда вызывает раздражение. Так что применяйте это свойство очень осторожно.

Значения:

  • fixed: фон будет оставаться неподвижным, а содержимое страницы будет перемещаться относительно него
  • scroll: фон будет перемещаться вместе с остальным содержимым. Значение по умолчанию.

В HTML нет атрибута, равнозначного данному свойству, а по умолчанию любой фон перемещается при скроллировании, то есть имеет значение scroll.

P {
background-image: url(img/bg.gif);
background-repeat: no-repeat;
background-attachment: fixed}
. . .
<P>Текст на фоновом неповторяющемся и неподвижном рисунке</P>

background-position

Задает позиционирование фонового изображения. С помощью этого атрибута можно смещать фоновое изображение относительно левого верхнего угла элемента. Свойство имеет два параметра: первый определяет смещение по вертикали, второй - смещение по горизонтали.

В качестве значений можно указывать длину как положительную, так и отрицательную. Например, правило:

P {
background-image: url(img/bg.gif);
background-position: -12px 50px}

смещает фоновое изображение на 12 пикселов влево и на 50 пикселов вниз от левого верхнего угла элемента P. Кроме того, можно указывать процентные соотношения. Проценты вычисляются относительно ширины и высоты блока элемента. Например, правило:

P {
background-position: 20% 40%}

смещает фоновое изображение на 20% вправо и на 40% вниз от левого верхнего угла блока элемента P. Значением по умолчанию является 0% 0%, что соответствует верхнему левому углу. Кроме того, можно вместо численных значений указывать выравнивание относительно элемента. Так для выравнивания по вертикали можно использовать три ключевых слова:

  • top: выравнивание по верхнему краю;
  • center: выравнивание по центру;
  • bottom: выравнивание по нижнему краю.

Для выравнивания по горизонтали можно использовать ключевые слова:

  • left: выравнивание по правому краю;
  • center: выравнивание по центру;
  • right: выравнивание по правому краю.

Таким образом, правило:

P {
background-position: 0% 0%}

эквивалентно правилу:

P {
background-position: top left}

В HTML нет атрибута, который бы соответствовал данному свойству, а значение по умолчания для фона, заданного средствами HTML, совпадает со значением по умолчания для фона, заданного с помощью CSS и составляет 0% 0%.

P {
background-image: url(img/bg.gif);
background-repeat: no-repeat;
background-attachment: fixed;
background-position: top center}
. . .
<P>Текст на фоновом неповторяющемся и неподвижном рисунке, который отцентрирован по горизонтали</P>

Теория работы с фоном на этом практически исчерпывается. По крайней мере, никаких существенных моментов я не упустил. Впереди незабываемая и неизбежная встреча с прикладным применением.

На практике применять все гораздо интереснее, чем читать нудные руководства, инструкции и рекомендации. Ясно дело, когда видишь результат своего труда, на душе становится веселей. Мы с вами сейчас узнаем, как использовать свойства фона по назначению.

Очевидно, чаще всего кодеры задают цвет фона, используя свойство background-image или же просто background. Вот с него-то мы и начнем.

Замечание
Для тех кто не знает, свойство background является сокращенной формой записи всех возможных свойств фона. Так, например, цвет фона можно записать так background-color: #FFF, а можно и так background: #FFF. Места экономит порядочно, особенно если свойств несколько.

Как задают цвет фона для всей страницы? Правильно, с помощью атрибута BGCOLOR тега BODY. Так вот меняйте свои привычки, чтобы не засорять тег BODY всякой гадостью. Вообще каскадные таблицы стилей конкретно помогают сделать код чище. Итак, вместо

<BODY BGCOLOR=#FFFFFF>

Надо написать в стилях

BODY {background: #FFF}

После чего безжалостно убрать все атрибуты BGOLOR из всех тегов BODY всех страниц сайта. Экономия и чистота кода складывается из мелочей подобного рода, так что не стоит ими пренебрегать.

Однако со строками и ячейками таблиц ситуация не такая однозначная. Здесь бывают разные ситуации. Первая. Вы верстаете сайт в три колонки, применяя табличную верстку. Левая колонка должна быть серой. Нет особого смысла делать для этого отдельный класс, в котором прописывать цвет фона для этой колонки. Вставлять BGCOLOR=#CCCCCC в этом случае легче, чем запоминать название класса и вставлять CLASS=left-col. Естественно, здесь еще присутствует проблема обновляемости. То есть, если вдруг понадобиться изменить цвет с серого на белый, придется перелопатить все странички/шаблоны. Однако в большинстве случаев такие глобальные изменения на сайте не делаются, разве что при редизайне, но тогда все перекодируется с нуля.

Вторая ситуация. У вас есть таблица, в которой чередуются светло-серые и серые строки. Тогда вы пишете так:

<TR BGCOLOR=#EEEEEE><TD>контент</TD></TR>
<TR BGCOLOR=#DDDDDD><TD>контент</TD></TR>
...

Для сокращения кода можно ввести два новых класса. Например, eee и ddd. Тогда код станет вот таким:

.ddd {background: #DDD}
.eee {background: #EEE}
...
<TR class=eee><TD>контент</TD></TR>
<TR class=ddd><TD>контент</TD></TR>
...

Собственно говоря, у каскадных таблиц стилей всегда есть один глобальный плюс: при их использовании поддержка сайта однозначно упрощается.

Рекомендация
Легко сообразить, что использование классов особенно полезно в тех случаях, когда они будут использоваться часто. Так что, если класс появится на странице один раз, особого смысла его вводить нет.

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

У неопытного кодера при этом возникают определенные проблемы. Допустим, это у нас блок новостей. Замечательно. Мы создаем класс таких блоков и с чистым сердцем называем его news, что вполне логично. Класс и блок будут, например, такими:

.news {color: #000; font-size: 12px; width: 200px}
...
<DIV class=news>
Самый настоящий блок новостей. Вы не подумайте ничего плохого, обычная новостная колонка.
</DIV>

На практике блок будет выглядеть так:

Самый настоящий блок новостей. Вы не подумайте ничего плохого, обычная новостная колонка.

Надо бы сделать вначале блока красненькую плашечку, ширина которой соответствовала бы слову НОВОСТИ (учитывая тот факт, что дизайнер, по всей видимости, одной плашечкой под новости не ограничился, хотелось бы универсальности, то есть чтобы ширина плашечки соответствовала ширине контента. Короче, чтобы изменялась при изменении слова). Смело колбасим класс title и пихаем его в начало блока:

.title {color: #FFF; background: #E50D0D; font: bold 14px Arial}
...
<DIV class=news>
<DIV class=title>НОВОСТИ</DIV>
Самый настоящий блок новостей. Вы не подумайте ничего плохого, обычная новостная колонка.
</DIV>

Вот что видим:

НОВОСТИ
Самый настоящий блок новостей. Вы не подумайте ничего плохого, обычная новостная колонка.

Оказывается, наш блок с названием растянулся на всю доступную ему ширину, то есть на 200 пикселей. Как нам согласовать ширину блока с шириной контента? А вот тяжело, потому что элемент DIV образует блоки структурные, а нам нужен блок строчный. То есть, если использовать DIV, то надо ему прописать display: inline, но многие браузеры (в частности IE5) это объявление не понимают. Выход очевиден, надо использовать элемент строкового уровня, например тот же SPAN.

<DIV class=news>
<SPAN class=title>НОВОСТИ</SPAN><BR>
Самый настоящий блок новостей. Вы не подумайте ничего плохого, обычная новостная колонка.
</DIV>

НОВОСТИ
Самый настоящий блок новостей. Вы не подумайте ничего плохого, обычная новостная колонка.

Еще один прием. Маловероятно, что внутри новостной колонки будут использоваться еще какие-либо теги SPAN. Поэтому можно применить контекстный селектор — убрать класс title и вместо него повесить стили на элементы SPAN, которые находятся внутри элемента с классом news. Делается это так:

.news {color: #000; font-size: 12px; width: 200px}
.news SPAN {color: #FFF; background: #E50D0D; font: bold 14px Arial}
...
<DIV class=news>
<SPAN>НОВОСТИ</SPAN><BR>
Самый настоящий блок новостей. Вы не подумайте ничего плохого, обычная новостная колонка.
</DIV>

Код слегка сократился, что приятно само по себе. На сегодня достаточно, а теперь обратимся к работе с фоновыми изображениями.

Повторение

В HTML для вставки изображения есть атрибут BACKGROUND. Все бы ничего, но вот повторялось изображение как хотело. То есть если у вас была таблица 200х200 и рисунок 100х100, то в таблице вы увидите ровно четыре одинаковых рисунка.

<TABLE WIDTH=200 HEIGHT=200 BACKGROUND="fon.gif">
<TR VALIGN=top><TD>четыре фоновых изображения</TD></TR>
</TABLE>

четыре фоновых изображения

Чтобы этого избежать, надо было сделать рисунок 200х200, загнать в верхний левый угол наше фоновое изображение, а остальную часть рисунка сделать прозрачной. Если же повторения надо было избежать для всей страницы, то рисунок приходилось делать 1200х900 и более. С появлением CSS проблема ушла в прошлое, сейчас для этих целей служит свойство background-repeat. Например, можно вообще запретить повторение изображения.

<DIV STYLE="width: 200px; height: 200px; border: 1px solid #000; background: url(fon.gif) no-repeat">
одно фоновое изображение
</DIV>

одно фоновое изображение

Повторение по одной из осей тоже очень полезная штука. Например, сделал дизайнер что-то вроде :

Верстается эта конструкция достаточно сложно. Во-первых, надо сделать градиент у красной полосы, во-вторых, каким-то образом реализовать хитрый переплет. Если верстать простыми таблицами, то ничего не выйдет. Переплет разделяется на две части. Нижняя часть все время находится на красном фоне, а вот верхняя часть то на красном, то на белом, то на желтом (его на скриншоте не видно). Но проблема не в этом, потому что можно сделать прозрачный гиф. Проблема в том, что дизайн резиновый, то есть колонки растягиваются, и возникнут проблемы со стыковкой переплета. Смотрите, если мы как положено сделаем таблицу и запихнем в нужные ячейки переплет в виде фонового рисунка, то он не будет стыковаться между ячейками при некоторых разрешениях. Короче выглядеть все будет вот так:

Резиновый дизайн обуславливает и то, что нельзя разбивать макет на отдельные таблицы, чтобы сохранить одинаковые ширины колонок при некоторых разрешениях. То есть вся страница заверстывается в одну большую таблицу. Как же решить проблему? Решение, как вы догадываетесь, есть. Надо сделать отдельный слой, в котором будет прописан background в виде одного элемента переплета. Слой должен накладываться на всю таблицу. Сперва мы верстаем таблицу так, словно никакого переплета нет, а затем позиционируем слой с переплетом на нужное нам место:

#to {
 position: absolute;
 top: 74px;
 left: 0px;
 width: 100%;
 color: #000;
 background: url(i/bgall.gif) repeat-x;
 z-index: 10}

. . .

<DIV id=two>
<IMG SRC=../i/css/0.gif WIDTH=1 HEIGHT=25 ALT="">
</DIV>

Позиционирование

Ну и напоследок давайте рассмотрим, зачем может понадобиться позиционирование фонового изображения. Допустим, надо сверстать что-то вроде этого:

Три колонки, между которыми есть разделительная пунктирная линия. Если верстать таблицами, то нам надо сделать пять столбцов. Если же верстать блоками, то надо сделать всего лишь три блока. Как же тогда реализовать разделители? Очень просто, с помощью background-position. У нас три блока примерно с таким кодом:

#left-col {
 width: 25%;
 float: left}

#main-col {
 width: 50%;
 float: left}

#right-col {
 width: 25%;
 float: left}

. . .

<DIV ID=left-col>
</DIV>
<DIV ID=main-tcol>
</DIV>
<DIV ID=right-col>
</DIV>

Чтобы создать разделитель, нам надо в графическом редакторе вырезать один элемент последовательности, то рисунок 1х5 пикселей, который будет состоять из одной черной точки и четырех белых. После этого надо его внедрить в блок #left-col и заставить повторяться только по вертикали. А затем позиционировать его на 100%, то есть максимально вправо:

#left-col {
 width: 25%;
 background: url(bg.gif) repeat-y; 
 background-position: 100% 0%;
 float: left}

Обратите внимание, что позиционирование фонового изображения производится относительно блока, то есть ширина блока у нас 25% относительно ширины экрана, а позиционируется он на 100% относительно ширины блока, то есть на 25% относительно ширины экрана. Совершенно аналогично поступаем с блоком main-col (для сокращения кода запишем все свойства фона в background):

#main-col {
 width: 50%;
 background: url(bg.gif) repeat-y 100% 0%; 
 float: left}

Собственно говоря, больше ничего сложного в работе с фоном нет. Для вас, я надеюсь, тоже.