Глава 2.5. Позиционирование элементов

2.5.1. Общие положения

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

В процессе отображения документа для каждого элемента обозреватель генерирует нуль или более объемлющих прямоугольников. Внешний вид и расположение этих прямоугольников определяется следующими параметрами:

  • размерами прямоугольника, которые задаются свойствами границы, заполнителя и рамки;
  • типом прямоугольника, который задается свойством display;
  • схемой позиционирования элемента, которая задается свойством position;
  • взаимоотношениями элементов в дереве документа;
  • внешней информацией (например, размером окна отображения, собственными размерами графических образов и т. п.).

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

2.5.2. Типы объемлющих прямоугольников: свойство display

Синтаксис:  display: inline | block | list-item | run-in | compact | marker | table |
                     inline-table | table-row-group | table-header-group |
                     table-footer-group | table-row | table-column-group | table-column |
                     table-cell | table-caption | none | inherit
Начально:   inline
Применимо:  ко всем элементам
Наследуемо: нет
Проценты:   не используются
Устройства: все
Поддержка:  Internet Explorer Поддерживает только inline, block, list-item, none (4.0+),
               table-header-group и table-footer-group (5.0+)
            Netscape Navigator Поддерживает только inline, block, list-item и none (4.0+)

Свойство display задает тип объемлющего прямоугольника для данного элемента. CSS поддерживает следующие типы прямоугольников:

block Блочный элемент. Соответствует блочным элементам HTML, т. е. отображается как отдельный абзац. При его отображении генерируется главный прямоугольник блока, в котором располагаются объемлющие прямоугольники потомков данного элемента.
inline Текстовый элемент. Соответствует текстовым элементам HTML, т. е. отображается как текстовые строки внутри текущего абзаца, точнее внутри главного прямоугольника соответствующего блока.
list-item Элемент списка. Отображается как блочный элемент с добавлением к нему маркера элемента списка (подробнее см. п. 2.11.5).
marker Маркер. Подробности см. в п. 2.11.4.
run-in Присоединяемый элемент. Если следующий за данным элемент является блочным, то данный элемент форматируется как его первый текстовый элемент. В противном случае отображается как обычный блочный элемент.
compact Компактный элемент. Если следующий за данным элемент является блочным, то данный элемент форматируется как однострочный текстовый элемент, и если он помещается на левой или правой границе последующего блока (граница задается свойством direction вмещающего блока), то на ней он и отображается. В противном случае отображается как обычный блочный элемент.
none Элемент и все его потомки игнорируются при отображении.
table Блочная таблица. Подробности см. в п. 2.10.1.
inline-table Текстовая таблица. Подробности см. в п. 2.10.1.
table-row-group Группа строк таблицы. Подробности см. в п. 2.10.1.
table-header-group Группа надзаголовков таблицы. Подробности см. в п. 2.10.1.
table-footer-group Группа подзаголовков таблицы. Подробности см. в п. 2.10.1.
table-row Строка таблицы. Подробности см. в п. 2.10.1.
table-column-group Группа столбцов таблицы. Подробности см. в п. 2.10.1.
table-column Столбец таблицы. Подробности см. в п. 2.10.1.
table-cell Ячейка таблицы. Подробности см. в п. 2.10.1.
table-caption Заголовок таблицы. Подробности см. в п. 2.10.1.

Хотя начальное значение этого свойства inline, таблица стилей обозревателя, принятая по умолчанию, может подменять это значение для отдельных элементов. Подробности см. в Рекомендуемой таблице стилей для HTML. Примеры задания типов отображения для некоторых элементов:

P   { display: block }     /* Блочный элемент */
EM  { display: inline }    /* Текстовый элемент */
LI  { display: list-item } /* Элемент списка */
IMG { display: none }      /* Не отображать графические образы */

2.5.3. Схема позиционирования: свойство position

Синтаксис:  position: static | relative | absolute | fixed | inherit
Начально:   static
Применимо:  ко всем элементам, кроме генерируемого оглавления
Наследуемо: нет
Проценты:   не используются
Устройства: визуальные
Поддержка:  Internet Explorer Поддерживает только static, relative и absolute (4.0+)
            Netscape Navigator Поддерживает только relative и absolute; реализовано с ошибками (4.0+)

Свойство position задает схему позиционирования данного элемента. CSS поддерживает следующие схемы позиционирования:

static Статический элемент. Не имеет специального позиционирования, отображается в обычном потоке элементов.
relative Относительно позиционируемый элемент. Для него сначала генерируется объемлющий прямоугольник в обычном потоке элементов, а затем смещается на величины, заданные свойствами left и top.
absolute Абсолютно позиционируемый элемент. Позиция элемента вычисляется относительно позиции его ближайшего позиционированного предка (или относительно элемента BODY, если все предки не позиционированы) на основании свойств left и top. Помимо позиции элемента можно задать и его размер свойствами right и bottom.
fixed Фиксированный элемент. Этот элемент является абсолютно позиционированным, но дополнительно зафиксирован относительно некой отправной точки. Для непрерывных устройств отображения его позиция зафиксирована относительно окна обозревателя, т. е. он остается неподвижным при прокрутке окна. Для страничных устройств его позиция фиксируется относительно страницы.

Абсолютно позиционированные элементы выпадают из обычного потока отображения элементов документа. Их позиция не зависит от окружающих объектов, а определяется относительно ближайшего позиционированного предка. Если заданная позиция уже занята другим элементом, то оба элемента будут отображаться в одном месте, перекрывая друг друга. То, какой из элементов находится выше, а какой ниже, задается свойством z-index. Абсолютно позиционированные элементы не имеют границ, но имеют заполнители и рамки. Пример абсолютно позиционированного графического образа внутри относительно позиционированного элемента DIV:

<DIV style="position: relative; left: 0; top: 0; height: 50px">
  <P>Часть текста будет скрыта рисунком, потому что он позиционирован поверх текста.</P>
  <IMG src="images\leaf.gif" style="position: absolute; left: 300px; top: 0">
</DIV>

Этот пример будет отображаться так (Netscape Navigator 4.x отображает этот пример неверно!):

Часть текста будет скрыта рисунком, потому что он позиционирован поверх текста.

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

<P>Пример вывода текста в верхнем индексе:
  <SPAN style="position: relative; top: -3px">xyz</SPAN>.</P>

Этот пример будет отображаться так:

Пример вывода текста в верхнем индексе: xyz.

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

2.5.4. Задание позиции элемента

Если элемент не является статическим, то его позиция должна быть задана явно. Для этого используются четыре свойства: left, top, right и bottom, которые задают относительное смещение элемента. Если они не заданы, то положение и размер объемлющего элемент прямоугольника вычисляется автоматически. Эти свойства имеют тип <смещение>, который определяется следующим образом:

<смещение> = <размер> | <процент> | auto
  <размер>
    Задает фиксированное смещение.
  <процент>
    Вычисляется относительно высоты или ширины вмещающего блока.
  auto
    Положение элемента по умолчанию в обычном потоке элементов. См. 2.6.2 и 2.6.5.

2.5.4.1. Верхняя позиция: свойство top

Синтаксис:  top: <смещение> | inherit
Начально:   auto
Применимо:  ко всем позиционированным элементам
Наследуемо: нет
Проценты:   Вычисляется относительно высоты вмещающего блока.
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (4.0+)
            Netscape Navigator Соответствует стандарту (4.0+)

Свойство top задает смещение позиционированного элемента относительно верхнего края вмещающего блока. Пример:

<IMG src="sample.gif" style="position: absolute; left: 300px; top: 0">

2.5.4.2. Левая позиция: свойство left

Синтаксис:  left: <смещение> | inherit
Начально:   auto
Применимо:  ко всем позиционированным элементам
Наследуемо: нет
Проценты:   Вычисляется относительно ширины вмещающего блока.
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (4.0+)
            Netscape Navigator Соответствует стандарту (4.0+)

Свойство left задает смещение позиционированного элемента относительно левого края вмещающего блока. Пример:

<IMG src="sample.gif" style="position: absolute; left: 300px; top: 0">

2.5.4.3. Нижняя позиция: свойство bottom

Синтаксис:  bottom: <смещение> | inherit
Начально:   auto
Применимо:  ко всем позиционированным элементам
Наследуемо: нет
Проценты:   Вычисляется относительно высоты вмещающего блока.
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (4.0+)
            Netscape Navigator Соответствует стандарту (4.0+)

Свойство bottom задает смещение позиционированного элемента относительно нижнего края вмещающего блока. Пример:

<IMG src="sample.gif" style="position: absolute; right: 20px; bottom: 50px">

2.5.4.4. Правая позиция: свойство right

Синтаксис:  right: <смещение> | inherit
Начально:   auto
Применимо:  ко всем позиционированным элементам
Наследуемо: нет
Проценты:   Вычисляется относительно ширины вмещающего блока.
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (4.0+)
            Netscape Navigator Соответствует стандарту (4.0+)

Свойство right задает смещение позиционированного элемента относительно правого края вмещающего блока. Пример:

<IMG src="sample.gif" style="position: absolute; right: 20px; bottom: 50px">

2.5.5. Порядок отображения элементов: свойство z-index

Синтаксис:  z-index: auto | <целое> | inherit
Начально:   auto
Применимо:  к позиционированным элементам
Наследуемо: нет
Проценты:   не используются
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (4.0+)
            Netscape Navigator Поддерживается только для слоев (layers) (4.0+)

Как уже отмечалось выше, позиционирование элементов часто приводит к тому, что объемлющие прямоугольники нескольких элементов перекрываются, т. е. при отображении эти элементы накладываются друг на друга. При этом элементы образуют стек, расположенный по оси координат Z. Чем больше индекс элемент в стеке, тем выше он расположен, т. е. лучше видим пользователем. Элементы с одинаковым индексом располагаются по обычному правилу наполнения стека: чем раньше элемент расположен в тексте документа, тем глубже он находится.

Свойство z-index позволяет явно задать индекс элемента в этом стеке и тем самым управлять порядком наложения элементов друг на друга при отображении. Оно может принимать следующие значения:

<целое> Явно задает индекс элемента в стеке.
auto Индекс элемента принимается равным индексу его отца.

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

<DIV style="position: relative; top: 0; left: 0; width: 100%; height: 60px">
  <P style="position: absolute; top: 10px; left: 100px; z-index: 2;
    background: purple; color: white">Текст</P>
  <IMG src="images/leaf.gif" style="position: absolute; top: 10px; left: 100px;
    z-index: 1">
</DIV>

Приведенный фрагмент будет отображаться так (Netscape Navigator 4.x отображает этот пример неверно!):

Текст

2.5.6. Плавающие элементы: свойство float

Синтаксис:  float: left | right | none | inherit
Начально:   none
Применимо:  ко всем элементам, кроме позиционированных и генерируемого оглавления
Наследуемо: нет
Проценты:   не используются
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (4.0+)
            Netscape Navigator Соответствует стандарту; реализовано с ошибками (4.0+)

Свойство float со значением left или right указывает, что элемент является плавающим и задает его выравнивание влево или вправо. По умолчанию это свойство имеет значение none, что означает, что элемент не является плавающим.

Плавающий элемент всегда считается блочным, т. е. его свойство display игнорируется. Плавающий элемент смещается влево или вправо до тех пор, пока не встретит рамку, заполнитель или границу другого блочного элемента. Элементы, следующие за плавающим элементом, сдвигаются относительно его позиции и как бы обтекают его соответственно справа или слева (см. также описание свойства clear). Так, использование плавающих абзацев позволяет выводить их бок о бок, например (Netscape Navigator 4.x отображает этот пример неверно!):

Это абзац, выровненный влево.

А это абзац, выровненный вправо.

Для вывода этого примера использован следующий фрагмент:

<P style="float: left; width: 50%">Это абзац, выровненный влево.</P>
<P style="text-align: right"> А это абзац, выровненный вправо.</P>

Плавающий элемент должен иметь явно заданную ширину. Она задается либо свойством width, либо самим элементом, если это, к примеру, графический образ.

В следующем примере абзац состоит из текста и двух плавающих графических образов, выровненных соответственно влево и вправо:

<P>
  <IMG src="images/left.gif" alt="Стрелка влево" style="float: left">
  <IMG src="images/right.gif" alt="Стрелка вправо" style="float: right">
  Это текст абзаца, который будет расположен между плавающими образами.
</P>

Этот фрагмент будет отображаться так (Netscape Navigator 4.x отображает его неверно!):

Стрелка влевоСтрелка вправо Это текст абзаца, который будет расположен между плавающими образами.

2.5.7. Управление обтеканием текста: свойство clear

Синтаксис:  clear: none | left | right | both | inherit
Начально:   none
Применимо:  к блочным элементам
Наследуемо: нет
Проценты:   не используются
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (4.0+)
            Netscape Navigator Соответствует стандарту; реализовано с ошибками (4.0+)

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

none Разрешает обтекание плавающего элемента с обеих сторон.
left Запрещает обтекание плавающего элемента слева.
right Запрещает обтекание плавающего элемента справа.
both Запрещает обтекание плавающего элемента с обеих сторон.

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

<P>
  <IMG src="images/left.gif" alt="Стрелка влево" style="float: left">
  <IMG src="images/right.gif" alt="Стрелка вправо" style="float: right">
  Это текст абзаца, который будет расположен между плавающими образами.
  <SPAN style="clear: both">Этот текст будет выведен ниже остального фрагмента.</SPAN>
</P>

Этот фрагмент будет отображаться так (Netscape Navigator 4.x отображает этот пример неверно!):

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

2.5.8. Направление вывода текста

Всем символам в кодировке Unicode приписано направление, с тем, чтобы текст отображался правильно. Так, латинские и русские буквы выводятся слева направо, а еврейские и арабские – справа налево.

Unicode определяет двунаправленный алгоритм, который должен применяться всякий раз, когда документ содержит символы, выводимые справа налево. Хотя обычно этот алгоритм дает правильное изображение текста, существуют ситуации, когда направление вывода текста приходится задавать явно с помощью свойств direction или unicode-bidi.

2.5.8.1. Задание направления вывода текста: свойство direction

Синтаксис:  direction: ltr | rtl | inherit
Начально:   ltr
Применимо:  ко всем элементам
Наследуемо: да
Проценты:   не используются
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (5.0+)
            Netscape Navigator Не поддерживается

Свойство direction определяет направление вывода текста элемента: слева направо (ltr, принято по умолчанию) или справа налево (rtl). При этом оно перекрывает двунаправленный алгоритм Unicode. Кроме того, оно задает направление вывода столбцов таблиц, направление горизонтального переполнения (см. overflow) и положение последней неполной строки в блоке со свойством "text-align: justify".

Для того, чтобы это свойство оказывало влияние на отображение текстовых элементов, значение свойства unicode-bidi должно быть равно embed или override.

2.5.8.2. Управление двунаправленным алгоритмом Unicode: свойство unicode-bidi

Синтаксис:  unicode-bidi: normal | embed | bidi-override | inherit
Начально:   normal
Применимо:  ко всем элементам
Наследуемо: нет
Проценты:   не используются
Устройства: визуальные
Поддержка:  Internet Explorer Соответствует стандарту (5.0+)
            Netscape Navigator Не поддерживается

Свойство unicode-bidi задает уровень вложения для двунаправленного алгоритма Unicode. Оно может принимать следующие значения:

normal Элемент не открывает нового уровня вложения.
embed Элемент открывает новый уровень вложения, который задается свойством direction и двунаправленным алгоритмом.
bidi-override Элемент открывает новый уровень вложения, направление вывода текста задается только свойством direction; двунаправленный алгоритм игнорируется.

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