7. Пример 3

На этой странице:

Вверх Постановка задачи

Построим “резиновую” страницу с двумя колонками, заголовочной частью и подвалом.

Макет страницы

Заголовочная часть (блок header) и подвал (блок footer) должны растягиваться по текущей ширине окна.

Основное содержание (блок content) и боковая панель (блок sidebar) должны делить ширину окна в пропорции 65%:35%.

Вверх Модель вёрстки

Модель вёрстки

Все блоки, кроме sidebar, оставим в потоке. Для content зададим внешний отступ справа шириной в 35% (от BODY) и в образовавшийся промежуток поместим абсолютно позиционированный блок sidebar шириной в те же 35%.

Вверх Без CSS

Запишем HTML-код будущей страницы:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
  "http://www.w3.org/TR/html4/loose.dtd">
<HTML lang="ru">
  <HEAD>
    <META http-equiv="Content-Type" 
          content="text/html; charset=windows-1251">
    <LINK rel="stylesheet" type="text/css" href="main.css">
    <TITLE>Роботландия</TITLE>
  </HEAD>

  <BODY bgcolor="white" text="black">

    <DIV class="header"><H1>Роботландия</H1></DIV> 

    <HR class="none">

    <DIV id="content">Содержание</DIV> 

    <HR class="none">

    <DIV id="sidebar">Боковая панель</DIV> 

    <HR class="none">

    <DIV id="footer">Подвал</DIV> 
  </BODY>
</HTML>
     

Без CSS

Посмотреть

Так это выглядит без CSS. Горизонтальные линии введены для браузеров, которые CSS не поддерживают — они разделяют страницу на логические части.

Для класса none, которым помечены HR'ы, запишем правило display:none, и линии в браузерах с CSS будут удалены из документа.

Вверх CSS

В соответствие с макетом построим набор CSS-определений:

HTML {background:white;}

BODY
{
  position:relative; /* Будем позиционировать от BODY */
  margin:10px; padding:0;      
  font:small Georgia, serif; 
  color:#2A3D34;            
  border:1px solid #638F7B;  
}

/* Заголовок */
.header 
{ 
  border-bottom:1px solid #638F7B;
}
.header H1 
{ 
  color:#a68400;
  margin:0;padding:0;
  padding-left:180px;
  font:bold 70px Georgia,serif;  
  letter-spacing:2px; 
  line-height:110px;
}

/* Содержание */
#content 
{ 
  margin-right:35%;
  padding:10px;
}

/* Боковая панель*/
#sidebar
{
  position:absolute;
  right:0; top:110px;
  width:35%;
}

/* Подвал */
#footer 
{ 
  padding:5px 10px;
  border-top:1px solid #638F7B;
  white-space:nowrap;
  font:0.7em Tahoma,sans-serif;
  color:white;
  background:#828377;
}

/* Для устранения элементов при включённом CSS */
.none {display:none;}
     

Вместе с CSS

Посмотреть

Так это выглядит в окне шириной 780 пикселов.

В окне шириной 1100 пикселов

Посмотреть

А так — в более широких окнах. Страница, действительно, обладает “резиновым” характером.

Для блока основного содержания задан внутренний отступ в 10 пикселов, а для боковой панели — нет. Вот чем объясняется разное положение текста в этих блоках.

Нельзя задавать для sidebar ни рамку, ни отступы, если мы хотим уместить его в отведённые 35%.

Для sidebar нельзя указывать отступы. Для этого блока задана ширина width:35% которая относится по стандарту к области содержимого. Если добавить ещё и отступы, отведённого места не хватит и блок выйдет за границу окна (браузер включит “вечную” линейку прокрутки).

Посмотреть

Теперь всё в порядке. Правда, порядок установлен ценой дополнительного блока, который не имеет отношения к структуре, а введён для визуальных надобностей. Плохо. Увы, мы живём не в идеальном мире, и дополнительный блок появился из-за отсутствия нужных возможностей в текущей версии CSS.

Поступим так. Вложим содержимое sidebar в дополнительный блок wrap:

<DIV id="sidebar">
  <DIV class="wrap">
    Боковая панель
  </DIV> 
</DIV> 
     

Внутренние отступы укажем для блока wrap:

#sidebar .wrap
{
  padding:10px;
}
     

Вверх Заголовок

Заголовок H1 был заранее погружен в блок header:

<DIV class="header"><H1>Роботландия</H1></DIV> 
     

Причина — снова визуальная необходимость: желание прикрепить к заголовочной части две фоновые картинки. Одну картинку будем использовать как паркетную заливку в блоке header, другую — для показа логотипа в блоке H1:

.header 
{ 
  background:white url(pic/h1bg.gif); /* Паркетная заливка */
  border-bottom:1px solid #638F7B;
}
.header H1 
{ 
  background:url(pic/logo.png) no-repeat 10px 10px; /* Лого */
  color:#a68400;
  margin:0;padding:0;
  padding-left:180px;
  font:bold 70px Georgia,serif;  
  letter-spacing:2px; 
  line-height:110px;
  zoom:1;
}
    

Заголовок

Посмотреть

Фоновая заливка:

Фоновая заливка

Логотип:

Фоновая заливка

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

Конечно, логотип можно выводить не фоном, а при помощи элемента IMG, и тогда надобность во внешней оболочке header отпадает. Тем не менее, хочется продемонстрировать и вариант с фоном.

Обратите внимание на последнее правило в стилевом определении для H1.

Свойство zoom (масштабирование) понимает только браузер IE. Именно для него и записано это правило, которое ничего не делает по прямому назначению — ведь задано масштабирование 1.

По прямому назначению правило zoom:1 ничего не делает, зато часто помогает IE справиться с ошибками определения позиции элемента на экране. Без этого правила логотипа на экране в IE нет (с другими браузерами всё в порядке).

Практическая рекомендация: если во всех браузерах всё нормально, а в IE что-то не так, попробуйте применить к проблемному блоку одно из следующих “заклинаний”:

* HTML .block { height:1%; } 
.block { width: 100%; } 
.block { position: relative; } 
.block { zoom: 1; } 
          

Вверх Наполняем страницу содержимым

Наполним страницу реальным содержимым и опишем дополнительные оформительские стили.

Наполнение содержимым

Посмотреть

/* Приближаем заголовок 
   к своему абзацу */
H2, H3, H4, H5, H6 
{margin-bottom:0.2em;}
P {margin:0.2em 0 1em;}
/* Размеры заголовков */
H2 {font-size:1.4em;}
H3 {font-size:1.2em;}
/* Выделение */
EM {font-weight:bold;}
/* Рисованный маркер списка */
UL LI
{
  list-style-image:url(pic/marker.gif);
}
          

Вверх Ложные колонки

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

Дуглас Бауман (ссылка) и Эрик Мейер (ссылка) доработали идею Дэна Седерхольма (ссылка) для пропорциональных колонок и предложили (в 2004 году) способ, описанный ниже.

Ложные колонки

Общая длина фоновой полоски делается настолько большой, например, 2000 пикселов, чтобы она смогла покрыть ширину окна на огромном мониторе.

Полоска делится разными цветами в таком же процентном отношении, что и наши колонки (65%:35%). То есть для первого цвета в нашем случае отводится 1300 пикселов, а для второго — 700.

Для вывода полоски используется стилевое правило для BODY:

BODY
{
  position:relative; /* Будем позиционировать от BODY */
  margin:10px; padding:0;  /* Отступы */
  font:small Georgia, serif; /* Шрифт */
  color: #2A3D34;            /* Цвет текста */
  border:1px solid #638F7B;  /* Рамка */
  background:white url(pic/fon.png) 65% top repeat-y;
}
          

Две вертикали, одна на элементе, другая на картинке, проведённые в 65% от левого края (соответственно, элемента и картинки), будут совпадать при любой ширине BODY.

Это как раз то поведение, которое нам нужно для создания ложных колонок.

Суть метода в особенностях вывода фоновой картинки, положение которой задано в процентах. Подробности смотрите в описании свойства background (ссылка). Ниже приводится краткое описание этого алгоритма.

Если стартовое положение картинки (место с которого она размножается по фону) задаётся в процентах, картинка размещается так, чтобы совпали две точки, одна из которых расположена на картинке, другая на элементе. Положение обеих точек (отдельно для картинки, отдельно для элемента) вычисляется в заданном процентном отношении.

Пусть, например, для элемента задано:
background: url(pic.png) 50% 50%.
Стартовое положение определится таким образом, чтобы центр элемента совместился с центром картинки:

Окончательный вариант

Посмотреть страницу

Посмотреть файл CSS

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

Если это не так, боковая панель перекроет подвал и даже может вылезти вниз за пределы BODY — ведь блок sidebar абсолютно позиционирован, а значит, не подчиняется правилам потока.

В рамках используемой модели (с абсолютным позиционированием) решение проблемы возможно средствами JavaScript, иначе (если проблема критична для вашей страницы) для многоколонной вёрстки можно использовать плавающие блоки (ссылка).