9 Модель визуального форматирования

Содержание

9.1 Знакомство с моделью визуального форматирования

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

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

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

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

9.1.1 Область просмотра

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

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

9.1.2 Контейнеры

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

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

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

9.2 Управление процессом создания блоков

В следующих разделах описаны различные типы блоков, которые можно создавать в CSS 2.1. Тип блока частично влияет на его поведение в рамках модели визуального форматирования. Тип блока определяется с помощью свойства 'display', описанного ниже.

9.2.1 Элементы уровня блока и структурные блоки

К элементам уровня блока относятся элементы исходного документа, которые визуально форматируются в виде неких структурных единиц текста (например, абзацев). Принадлежность уровню блока определяется значениями свойства 'display': 'block', 'list-item' и 'run-in' (часть из них; см. раздел, посвященный вставляемым блокам), а также 'table'.

Элементы уровня блока (кроме элемента 'table', который описан в следующем разделе) генерируют главный структурный блок, который содержит или только структурные блоки или только строковые блоки. Главный блок может участвовать в рамках любой схемы позиционирования и вместе с этим назначать контейнер для блоков, выступающих в качестве его потомков, и для генерируемого содержимого. Главные структурные блоки используются в контексте форматирования блоков.

Некоторые элементы уровня блока порождают дополнительные блоки за пределами главного: элементы 'list-item'. Дополнительные блоки размещаются относительно главного блока.

9.2.1.1 Безымянные структурные блоки

В документе типа такого:


<DIV>
  Некий текст
  <P>Больше текста
</DIV>

(и считая, что для элементов DIV и P установлено значение 'display:block') элемент DIV имеет два типа содержимого: и принадлежащего строке и принадлежащего блоку. Чтобы упростить процесс форматирования, предполагается, что надпись "Некий текст" заключена в безымянный структурный блок.

Рисунок, представляющий три типа блоков для приведенного выше примера   [D]

На рисунке, иллюстрирующем пример выше, изображены три типа блоков, из которых один – безымянный.

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

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

Пример(ы):

Такая модель в следующем примере будет применена, если следующие правила:


body { display: inline }
p    { display: block }

будут использованы с таким HTML-документом:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HEAD>
<TITLE>Безымянный текст, разорванный блоком</TITLE>
</HEAD>
<BODY>
Это безымянный текст, расположенный до элемента P.
<P>Это содержимое элемента P.</P>
Это безымянный текст, расположенный после элемента P.
</BODY>

Элемент BODY содержит отрывок (C1) безымянного текста, после которого следует элемент уровня блока, за которым, в свою очередь, следует другой отрывок (C2) безымянного текста. В результате будут сгенерированы безымянный структурный блок вокруг элемента BODY, который содержит безымянный структурный блок вокруг отрывка C1, структурный блок для элемента P и другой безымянный структурный блок вокруг отрывка C2.

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

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

Некоторые агенты пользователей реализуют границы в строковых контейнерах другими способами, например заключая такие вложенные блоки в "безымянные структурные блоки" и таким образом рисуя строковые границы вокруг таких блоков. Поскольку CSS1 и CSS2 не описывали такое поведение, агенты пользователя, поддерживающие только CSS1 и только CSS2, могут реализовывать такую альтернативную модель и все еще утверждать о соответствии их данной части CSS 2.1. Это не применимо к агентам пользователей, разработанным после выхода данной спецификации.

9.2.2 Элементы строкового уровня и строковые блоки

Элементы строкового уровня – это те элементы исходного документа, которые не формируют новых структурных единиц содержимого; содержимое выводится в строках (например, выделенные отрывки текста в абзаце, вложенные в строку рисунки и т.д.) Определенные значения свойства 'display' делают элемент принадлежащим строке: 'inline', 'inline-table', и 'run-in' (часть из них; см. раздел, посвященный вставляемым блокам). Элементы строкового уровня порождают строковые блоки.

9.2.2.1 Безымянные строковые блоки

В документе с разметкой HTML, таком как этот:


<p>Некоторый <em>выделенный</em> текст</p>

<p> порождает структурный блок, содержащий внутри несколько строковых блоков. Блок, содержащий слово "выделенный", является строковым блоком, порожденным строковым элементом (<em>), но остальные блоки, ("Некоторый" и "текст") являются строковыми блоками, порожденными элементом структурного уровня (<p>). Последние называются безымянными строковыми блоками, т.к. не существует элемента строкового уровня, который был бы связан с ними.

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

Содержимое с пустым пространством, которое было впоследствии сокращено в соответствии со свойством 'white-space', не генерирует никаких строковых блоков.

Если из контекста видно, какой тип анонимного поля имеется в виду, и безымянные строковые блоки и безымянные структурные блоки в этой спецификации просто называют безымянными блоками.

Больше типов безымянных блоков возникают при форматировании таблиц.

9.2.3 Вставляемые блоки

Вставляемый блок ведет себя следующим образом:

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

Блок 'run-in' оказывается удобным при вставке заголовков, как это показано в следующем примере:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Пример вставляемого блока</TITLE>
    <STYLE type="text/css">
      H3 { display: run-in }
    </STYLE>
  </HEAD>
  <BODY>
    <H3>Вставляемый заголовок.</H3>
    <P>И абзац текста, который
       следует за ним.
  </BODY>
</HTML>

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

  Вставляемый заголовок. И
  абзац текста, который 
  следует за ним.

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

Информацию о взаимодействии вставляемых блоков с генерируемым содержимым можно найти в разделе о генерируемом содержимом.

9.2.4 Свойство 'display'

'display'
Значение:  inline | block | list-item | run-in | inline-block | 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
Область применения:  все элементы
Наследование:  нет
Процентное задание значений:  Н/Д
Устройства:  все
Вычисляемое значение:  см. описание

Значения данного свойства имеют следующий смысл:

block
При этом значении свойства элемент порождает структурный блок.
inline-block
При этом значении свойства элемент порождает структурный блок, который сам перемещается как одиночный строковый блок, аналогично перемещаемому элементу. Изнутри блок inline-block отформатирован как структурный блок, а сам элемент отформатирован как строчный перемещаемый элемент.
inline
При этом значении свойства элемент порождает один или несколько строковых блоков.
list-item
При этом значении свойства элемент (например, LI в HTML) порождает главный структурный блок и строковый блок элемента списка (list-item). Информацию о списках и примерах форматирования списков можно найти в разделе о списках.
none
При этом значении свойства элемент не порождает ни одного блока в структуре форматирования (т.е. элемент никак не влияет на построение документа). Элементы-потомки тем более не будут порождать никаких блоков; такое поведение не может быть перезаписано установкой свойства 'display' у потомков.

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

run-in
Это значение в зависимости от контекста создают структурный или строковый блок. Свойства применяются к встраиваемым блокам основываясь на их окончательном статусе (inline-level или block-level).
table, inline-table, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, и table-caption
При этих значениях свойства элемент ведет себя как элемент таблицы (ограничения рассматриваются в главе о таблицах).

Вычисляемое значение то же, что и заданное значение, за исключением позиционируемых и перемещаемых элементов (см. Взаимодействия между 'display', 'position' и 'float') и корневых элементов. Для корневого элемента, вычисляемое значение выбирается как описано в разделе о взаимодействиях между 'display', 'position' и 'float'.

Примите во внимание, что хотя в качестве начального значения свойства 'display' используется значение 'inline', правила, содержащиеся в таблице стилей, принятой по-умолчанию в агенте пользователя, могут перезаписать это значение. См. информацию о простой таблицы стилей для HTML 4, приведенную в приложении.

Пример(ы):

Далее представлено несколько примеров использования свойства 'display':


p   { display: block }
em  { display: inline }
li  { display: list-item } 
img { display: none }      /* Не отображать рисунки */

9.3 Схемы позиционирования

В CSS 2.1 блок может размещаться согласно трем схемам позиционирования:

  1. Нормальный поток. В CSS 2.1 модель нормального потока включает форматирование блока структурного уровня, строковое форматирование строковых блоков, относительное позиционирование структурных или строковых блоков, а также позиционирование встраиваемых блоков.
  2. Перемещаемые объекты. Согласно этой модели блок сначала размещается в соответствии с нормальным потоком, а затем изымается из него и перемещаются влево или вправо настолько, насколько это возможно. Содержимое может располагаться по сторонам перемещаемого элемента.
  3. Абсолютное позиционирование. В модели абсолютного позиционирования блок полностью удаляется из нормального потока (и не влияет на последующие сестринские элементы), а затем ему назначается положение относительно контейнера.
Примечание. Схемы позиционирования, разработанные в CSS 2.1, помогают разработчикам делать свои документы более доступными, избавляя разработчиков от необходимости использовать различные приемы разметки (например, невидимые изображения) для управления отображением документа.

9.3.1 Выбор схемы позиционирования: свойство 'position'

Свойства 'position' и 'float' определяют алгоритм позиционирования CSS 2.1, используемый для определения положения блока.

'position'
Значение:  static | relative | absolute | fixed | inherit
Начальное значение:  static
Область применения:  все элементы
Наследование:  нет
Процентное задание значений:  Н/Д
Устройства:  визуальные
Вычисляемое значение:  как определено

Значения данного свойства имеют следующий смысл:

static
Данный блок является обычным блоком, позиционируемым в соответствии с нормальным потоком. Свойства 'top', 'right', 'bottom' и 'left' не применяются.
relative
Положение блока рассчитывается в соответствии с нормальным потоком (оно называется положением в нормальном потоке). Затем блок смещается относительно своего нормального положения. Когда для расположения блока B используется модель относительного позиционирования, тогда положение следующего блока рассчитывается так, как будто блок B не был смещен. Воздействие 'position:relative' на элементы table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, и table-caption – не определено.
absolute
Положение блока (возможно и размер) указывается с помощью свойств 'top', 'right', 'bottom', и 'left'. Они указывают величину смещения относительно контейнера блока. Абсолютно позиционируемые блоки изымаются из нормального потока. Это значит, что они не влияют на размещение последующих сестринских элементов. Следует заметить, что поля абсолютно позиционируемых блоков не перекрываются ни с какими другими полями.
fixed
Положение блока рассчитывается в соответствии с моделью абсолютного позиционирования, а затем он фиксируется относительно некоторого объекта. Как с моделью 'absolute', поля блока не накладываются на любые другие поля. При использовании handheld, projection, screen, tty и tv типов устройств блок фиксируется относительно области просмотра и не перемещается при прокрутке. При использовании типа устройства print, блок представляется на каждой странице, и фиксируется относительно блока страницы, даже если страница отображается в области просмотра (например, при предварительном просмотре печати). Для остальных типов устройств, представление не определено. Авторы могут сделать определение значения 'fixed' аппаратно-зависимым. Например, автор может сделать так, чтобы на экране блок всегда отображался в верхней части области просмотра на экране, но не в верхней части каждой распечатываемой страницы. Два объявления могут быть отделены друг от друга с помощью правила @media, как это показано ниже:

Пример(ы):

   
@media screen { 
  h1#first { position: fixed } 
}
@media print { 
  h1#first { position: static }
}

Агенты пользователей не должны разбивать на страницы содержимое фиксируемых блоков. Примите во внимание, что агенты пользователей могут распечатывать невидимое содержимое другими способами. См. "Содержимое за пределами блока страницы" в главе 13.

Агент пользователя может обрабатывать положение как 'static' в корневом элементе.

9.3.2 Смещение блоков: 'top', 'right', 'bottom', 'left'

Говорят, что элемент был позиционирован, если для свойства 'position' устанавливается значение, отличное от 'static'. Позиционированные элементы порождают позиционированные блоки, положение которых регулируется с помощью следующих четырех свойств:

'top'
Значение:  <длина> | <проценты> | auto | inherit
Начальное значение:  auto
Область применения:  позиционируемые элементы
Наследование:  нет
Процентное задание значений:  относительно высоты контейнера
Устройства:  визуальные
Вычисляемое значение:  для 'position:relative' – см. раздел Относительное позиционирование. Для 'position:static' – 'auto'. Иначе: если определено как длина – соответствующая абсолютная длина; если определено как процентное значение – заданное значение; иначе – 'auto'.

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

'right'
Значение:  <длина> | <проценты> | auto | inherit
Начальное значение:  auto
Область применения:  позиционируемые элементы
Наследование:  нет
Процентное задание значений:  относительно ширины контейнера
Устройства:  визуальные
Вычисляемое значение:  для 'position:relative' – см. раздел Относительное позиционирование. Для 'position:static' – 'auto'. Иначе: если определено как длина – соответствующая абсолютная длина; если определено как процентное значение – заданное значение; иначе – 'auto'.

Как и 'top', но задает на сколько правый край поля блока смещен влево от правого края контейнера блока. Для относительно позиционируемых блоков, смещение осуществляется относительно правого края самого блока. Примечание: Для абсолютно позиционированных элементов, чей контейнер основывается на элементе уровня блока, это свойство является смещением относительно краевой линии отступа такого элемента.

'bottom'
Значение:  <длина> | <проценты> | auto | inherit
Начальное значение:  auto
Область применения:  позиционируемые элементы
Наследование:  нет
Процентное задание значений:  относительно высоты контейнера
Устройства:  визуальные
Вычисляемое значение:  для 'position:relative' – см. раздел Относительное позиционирование. Для 'position:static' – 'auto'. Иначе: если определено как длина – соответствующая абсолютная длина; если определено как процентное значение – заданное значение; иначе – 'auto'.

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

'left'
Значение:  <длина> | <проценты> | auto | inherit
Начальное значение:  auto
Область применения:  позиционируемые элементы
Наследование:  нет
Процентное задание значений:  относительно ширины контейнера
Устройства:  визуальные
Вычисляемое значение:  для 'position:relative' – см. раздел Относительное позиционирование. Для 'position:static' – 'auto'. Иначе: если определено как длина – соответствующая абсолютная длина; если определено как процентное значение – заданное значение; иначе – 'auto'.

Как и 'top', но задает на сколько левый край поля блока смещен вправо от левого края контейнера блока. Для относительно позиционируемых блоков, смещение осуществляется относительно левого края самого блока. Примечание: Для абсолютно позиционированных элементов, чей контейнер основывается на элементе уровня блока, это свойство является смещением относительно краевой линии отступа такого элемента.

Значения этих четырех свойств имеют следующий смысл:

<длина>
Смещение задается фиксированным значением расстояния от исходной краевой линии. Отрицательные значения допускаются.
<проценты>
Смещение задается процентным соотношением относительно ширины (для свойств 'left' или 'right') или высоты (для свойств 'top' и 'bottom') контейнера. Отрицательные значения допускаются.
auto
Для неперемещаемых элементов, действие данного значения зависит от того, какие из свойств, близких по своему содержанию к рассматриваемым, также имеют значение 'auto'. Подробную информацию можно найти в разделах, посвященных ширине и высоте абсолютно позиционируемых, незамещаемых элементов. Для перемещаемых элементов, действие данного значения зависит только внутренних размеров перемещаемого содержимого. Подробную информацию можно найти в разделах, посвященных ширине и высоте абсолютно позиционируемых, перемещаемых элементов.

9.4 Нормальный поток

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

9.4.1 Контексты форматирования блоков

Перемещаемые объекты, абсолютно позиционируемые объекты, строковые блоки, ячейки таблиц, оглавления таблиц и элементы со свойством 'overflow' другие, чем 'visible' (кроме случаев, когда значение распространяется на область просмотра) устанавливают новые контексты форматирования блока.

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

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

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

9.4.2 Контекст форматирования строк

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

Ширина линейного блока определяется шириной контейнера и наличием перемещаемых объектов. Высота линейного блока регулируется правилами, описанными в разделе "Вычисления высоты строк".

Линейный блок всегда имеет высоту, достаточную для все содержащиеся в нем блоков. Однако он может быть выше, чем самый высокий блок, содержащийся в нем (если, например, блоки выровнены таким образом, что базовые линии текста находятся на одной оси). Если высота блока B меньше высоты линейного блока, содержащего его, то вертикальное выравнивание блока B внутри последнего определяется свойством 'vertical-align'. Если несколько строковых блоков не могут разместиться горизонтально в пределах одного линейного блока, то они распределяются по двум или более вертикально расположенными линейным блоками. Таким образом, абзац представляет собой набор вертикально расположенных линейных блоков. Линейные блоки располагаются без вертикальных разделителей и никогда не перекрываются.

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

Когда суммарная ширина строковых блоков в строке, меньше ширины содержащего их линейного блока, то горизонтальное распределение этих блоков в пределах линейного блока определяется свойством 'text-align'. Если это свойство имеет значение 'justify', то агент пользователя может так же растягивать пробелы и слова в строковых блоках (за исключением блоков inline-table и inline-block).

Когда ширина строкового блока превышает ширину линейного блока, он разбиваются на несколько блоков и эти блоки распределяются по нескольким линейным блокам. Если строковый блок не может быть разбит (например, если строковый блок содержит единственный символ, или свойственные языку правила переноса слов не позволяют разбить в пределах строкового блока, или если строковый блок находится под влиянием значения пустого пространства в элементах nowrap или pre), тогда строковый блок выходит за пределы линейного блока.

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

Сроковые блоки могут также разбиваться на несколько блоков внутри одного линейного блока за счет использования обработки двунаправленного текста.

Здесь представлен пример построения строкового блока. Следующий абзац (созданный HTML-элементом уровня блока P) включает безымянный текст, в который вставлены элементы EM и STRONG:


<P>Несколько <EM>акцентированных слов</EM> присутствует
<STRONG>в этом</STRONG> предложении, дорогая.</P>

Элемент P поражает структурный блок, содержащий пять строковых блоков, три из которых являются безымянными:

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

Несколько акцентированных слов присутствует в этом предложении, дорогая.

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

Несколько акцентированных слов присутствует
в этом предложении, дорогая.
или как здесь:
Несколько акцентированных  
слов представлено в этом 
предложении, дорогая.

В предыдущем примере блок EM, был разбит на два блока EM (назовем их "split1" и "split2"). Поля, границы, отступы или элементы текстового оформления не имеют видимого эффекта после split1 или перед split2.

Рассмотрим следующий пример:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Пример разбиения строкового блока на несколько линейных</TITLE>
    <STYLE type="text/css">
      EM {
        padding: 2px; 
        margin: 1em;
        border-width: medium;
        border-style: dashed;
        line-height: 2.4em;
      }
    </STYLE>
  </HEAD>
  <BODY>
    <P>Several <EM>emphasized words</EM> appear here.</P>
  </BODY>
</HTML>

В зависимости от ширины элемента P блоки могут распределяться следующим образом:

Рисунок, иллюстрирующий влияние разрыва строи на отображение полей, границ и отступов   [D]

9.4.3 Относительное позиционирование

После того как блок был размещен в соответствии с моделью нормального потока или перемещен, он может быть смещен относительно исходного положения. Данная процедура называется относительным позиционированием. Подобное смещение блока (B1) не влияет на следующий за ним блок (B2): блоку B2 назначается положение так, как если бы смещение блока B1 не производилось, и это положение не изменяется, даже если блок B1 после этого будет перемещен. Отсюда следует, что при относительном позиционировании может происходить наложение блоков. Однако, если относительное позиционирование ведет к тому, что блок 'overflow:auto' или 'overflow:scroll' выходит за пределы, агент пользователя должен позволить пользователю принять это содержимое (в его смещенном положении), которое, через создание полосы прокрутки, может влиять на отображение.

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

Для относительно позиционированных элементов, 'left' и 'right' перемещает блок(и) по горизонтали, без изменения их размера. 'left' перемещает блок вправо, а 'right' – перемещает его влево. Т.к. блоки не разбиваются и не масштабируются в результате применения 'left' или 'right', то вычисляемое значение всегда равно: left = -right.

Если и 'left' и 'right' установлены в 'auto' (их начальные значения), то вычисляемое значение равно '0' (т.е., блоки остаются на своих нормальных местах).

Если 'left' – 'auto', то его вычисляемое значение равно минус значение 'right' (т.е., блок перемещается влево на значение, заданное 'right').

Если 'right' определено как 'auto', его вычисляемое значение равно минус значение 'left'.

Если ни 'left' ни 'right' не равны 'auto', то положение является перегруженным, и одно из них будет игнорироваться. Если свойство 'direction' контейнера имеет значение 'ltr', то значение 'left' побеждает и 'right' становится -'left'. Если свойство 'direction' контейнера имеет значение 'rtl', то побеждает 'right' и 'left' игнорируется.

Пример(ы):

Пример.Следующие три правила эквивалентны:


div.a8 { position: relative; direction: ltr; left: -1em; right: auto }
div.a8 { position: relative; direction: ltr; left: auto; right: 1em }
div.a8 { position: relative; direction: ltr; left: -1em; right: 5em }

Свойства 'top' и 'bottom' перемещают относительно позиционированный элемент(ы) вверх или вниз без изменения их размеров. 'top' перемещает блоки вниз, а 'bottom' – перемещает их вверх. Т.к. блоки не разбиваются и не масштабируются в результате применения 'top' или 'bottom', то вычисляемое значение всегда равно: top = -bottom. Если оба имеют значение 'auto', то их вычисляемое значение у обоих равно '0'. Если у одного из них значение равно 'auto', то он принимает значение, противоположное другому. Если ни одно из них не имеет значение 'auto', то 'bottom' – игнорируется (т.е., вычисляемое значение свойства 'bottom' равно минус значение свойства 'top').

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

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

9.5 Перемещаемые объекты

Перемещаемый объект – это блок, который смещается в текущей строке в левую или правую сторону. Самым интересным свойством перемещаемого объекта (или "перемещенного" или "перемещаемого" блока) является то, что содержимое может передвигаться вдоль одной из его сторон (либо не делать этого, если существует запрет, устанавливаемый свойством 'clear'). Содержимое может передвигаться вдоль правой стороны перемещенного влево блока и вдоль левой стороны перемещенного вправо блока. Далее следует введение в позиционирование перемещаемых объектов и передвижение содержимого; точные правила, обуславливающие поведение перемещаемого объекта, описаны в разделе, посвященном свойству 'float'.

Перемещенный блок сдвигается влево или вправо до тех пор, пока его внешний край не соприкоснется с краем контейнера или с внешним краем другого перемещаемого блока. Если есть линейный блок, то верхний край перемещенного блока выравнивается по верхнему краю текущего линейного блока.

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

Т.к. перемещаемый объект не принадлежит потоку, то вертикальное передвижение непозиционированных блоков, созданных до и после него, будет осуществляться так, как если бы он отсутствовал. Однако, линейные блоки, созданные непосредственно после перемещаемого объекта, сокращаются для того, чтобы освободить место для блока поля перемещаемого объекта. Если сокращенный линейный блок мал для того, чтобы вместить любое будущее содержимое, то он смещается вниз до тех пор, пока он или не будет подогнан (под имеющееся место) или не будет больше представлено перемещаемых объектов. Любое содержимое, находящейся в текущей строке перед перемещаемым объектом, выводится заново с другой стороны от него в первой доступной строке. Другими словами, если строковые блоки помещены в строку до соприкосновения с перемещаемым влево объектом, который подогнан под оставшееся пустое пространство линейного блока, то перемещаемый влево объект помещается в эту строку, выровненную по верхнему краю строкового блока, а затем строковые блоки уже на строке перемещаются в соответствии с правой стороной перемещаемого объекта (правая сторона становится другой стороной перемещаемого влево объекта) и наоборот для rtl и перемещаемых вправо объектов.

Блок поля таблицы, перемещенный элемент уровня блока, или элемент в нормальном потоке, который создает новый контекст форматирования блока (например, со свойством 'overflow', значение которого отлично от 'visible') не должен перекрывать любой перемещаемый объект в том же, что и сам элемент, контексте форматирования блока. Если возможно, реализации должны очистить упомянутый элемент, помещая его ниже любых предыдущих перемещаемых объектов, но если достаточно пустого места, то могут поместить его так, чтобы он прилегал к таким перемещаемым объектам.

Пример(ы):

Пример.В приведенном ниже фрагменте документа, контейнер слишком узок для того, чтобы вместить содержимого, следующего за перемещаемым объектом, поэтому содержимое будет переставлено перед перемещаемыми объектами, где оно будет выровнено в линейном блоке в соответствии со свойством выравнивания текста (text-align).


p { width: 10em; border: solid aqua; }
span { float: left; width: 5em; height: 5em; border: solid blue; }


...


<p>
  <span> </span>
  Supercalifragilisticexpialidocious
</p>

Этот фрагмент мог бы выглядеть так:

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

Некоторые перемещаемые объекты могут быть сестринскими, и эта модель применима к сестринским перемещаемым объектам в одной и той же строке.

Пример(ы):

Следующее правило перемещает все блоки, порожденные элементом IMG с class="icon" , влево (и устанавливает значение ширины поля равным '0'):


img.icon { 
  float: left;
  margin-left: 0;
}

Рассмотрим следующий исходный текст HTML и таблицу стилей:

  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Перемещаемый элемент</TITLE>
    <STYLE type="text/css">
      IMG { float: left }
      BODY, P, IMG { margin: 2em }
    </STYLE>
  </HEAD>
  <BODY>
    <P><IMG src=img.png alt="Этот рисунок иллюстрирует перемещаемые объекты">
       Некоторый простой текст, который не имеет остальных...
  </BODY>
</HTML>

Блок, порожденный элементом IMG, перемещается влево. Следующее за ним содержимое форматируется справа от перемещаемого объекта, начиная с той же строки, на которой находится он сам. Присутствие перемещаемого объекта влияет на то, что, пока линейные блоки находятся справа от него, они укорачиваются, но как только они достигают его конца, так сразу восстанавливают свою исходную ширину (равную ширине контейнера, назначенного элементом P). Приведенный документ может быть отформатирован следующим образом:

Рисунок, иллюстрирующий взаимодействие перемещаемого блока и полей   [D]

Форматирование было бы точно таким же, если бы документ выглядел так:


<BODY>
  <P>Некоторый простой текст,
  <IMG src=img.png alt="Этот рисунок иллюстрирует перемещаемые объекты">
           который не имеет остальных...
</BODY>

объясняется это тем, что содержимое, находящееся слева от перемещаемого объекта, заменяется им, а само отображается справа от него.

Как заявлено в разделе 8.3.1, поля перемещаемых блоков никогда не перекрываются с полями смежных блоков. Таким образом, в предыдущем примере вертикальные поля между блоком элемента P и перемещаемым блоком IMG не перекрываются.

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

Пример(ы):

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

Рисунок, иллюстрирующий наложение перемещаемого объекта и границ двух абзацев: графический объект разрывает границы   [D]

Перемещаемое изображение затеняет границы перекрываемых им структурных блоков.

В следующем примере проиллюстрировано использование свойства 'clear', позволяющего запрещать перемещение содержимого вдоль относительно объекта.

Пример(ы):

Предполагая правило, такое как это:


p { clear: left }

форматирование могло бы выглядеть так:

Рисунок, иллюстрирующий перемещаемый объект и влияние правила 'clear: left' на расположение двух абзацев   [D]

В обоих абзацах установлено свойство 'clear: left', при действии которого второй абзац "принудительным образом" располагается ниже перемещаемого объекта - для этого увеличивается ширина его верхнего поля (см. свойство 'clear').

9.5.1 Позиционирование перемещаемого объекта: свойство 'float'

'float'
Значение:  left | right | none | inherit
Начальное значение:  none
Область применения:  все, но см. раздел 9.7
Наследование:  нет
Процентное задание значений:  Н/Д
Устройства:  визуальные
Вычисляемое значение:  как определено

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

left
Элемент порождает структурный блок, перемещаемый влево. Содержимое выводится вдоль правой стороны блока, начиная с самого верха (за счет свойств 'clear').
right
Аналогично 'left', за исключением того, что блок перемещается вправо, а содержимое выводится вдоль левой стороны блока, начиная с самого верхнего.
none
Блок не перемещается.

Агент пользователя может обрабатывать перемещение как 'none' в корневом элементе.

Ниже приведены четкие правила, определяющие поведение перемещаемых объектов:

  1. Левый внешний край перемещаемого влево блока не может находиться слева от левого края контейнера. Аналогичное правило имеет место и для перемещаемого вправо блока.
  2. Если текущий блок является перемещаемым влево и существует хотя бы один перемещаемый влево блок, который был сгенерирован в исходном документе раньше него, то левый внешний край текущего блока должен находиться справа от правого внешнего края предыдущего блока, или верхний его край должен быть ниже, чем нижний край предыдущего блока. Подобное правило имеет место и для перемещаемого вправо блока.
  3. Правый внешний край перемещаемого влево блока не может находиться справа от левого внешнего края любого перемещаемого вправо блока. Подобное правило имеет место и для перемещаемого вправо блока.
  4. Верхний сегмент внешнего края перемещаемого блока не может быть выше верхней границы контейнера. Когда перемещаемый объект находится между двумя перекрывающимися полями, он позиционируется так, как если бы он имел вместо этого пустого безымянного родителя блока, принимающего участие в потоке. Позиция такого родителя определяется правилами, изложенными в разделе о перекрытии полей.
  5. Верхний сегмент внешнего края перемещаемого блока не может быть выше аналогичной границы любого структурного или перемещаемого блока, который был сгенерирован в исходном документе раньше рассматриваемого перемещаемого блока.
  6. Верхний сегмент внешнего края перемещаемого блока не может быть выше аналогичной границы любого линейного блока, содержащего блок, который был сгенерирован в исходном документе раньше рассматриваемого перемещаемого блока.
  7. Перемещаемый влево блок, слева от которого расположен другой перемещаемый влево блок, не может иметь правого внешнего края, расположенного справа от правого края его контейнера. (Неточно: перемещаемый влево объект не может прикрепиться к правому краю, если он уже передвинут влево настолько, насколько это возможно.) Аналогичное правило имеет место и для перемещаемого вправо блока.
  8. Перемещаемый блок должен быть помещен насколько возможно выше.
  9. Перемещаемый влево блок должен быть помещен как можно левее, а перемещаемый вправо блок – как можно правее. Самое верхнее положение должен занимать блок, который занимает более крайнее левое/правое положение.

Ссылки на остальные элементы в данном правиле относятся только к остальным элементам в том же контексте форматирования блока, что и перемещаемый объект.

Пример(ы):

Данный фрагмент HTML приведет к тому, что b перемещается вправо.

<P>a<SPAN style="float: right">b</SPAN></P>

Если ширина элемента P достаточна, то a и b будут находиться рядом. Это могло бы выглядеть так:

a находится с левой стороны блока a, и b находится с правой стороны

9.5.2 Управление потоком после перемещаемых объектов:свойство 'clear'

'clear'
Значение:  none | left | right | both | inherit
Начальное значение:  none
Область применения:  элементы структурного уровня
Наследование:  нет
Процентное задание значений:  Н/Д
Устройства:  визуальные
Вычисляемое значение:  как определено

Это свойство определяет, какие стороны блока, порожденного элементом, не могут соседствовать с предшествующим перемещаемым блоком. Свойство 'clear' не рассматривает перемещаемые объекты внутри самого элементе или в других контекстах форматирования блока.

Для встраиваемых блоков это свойство применяется к структурному блоку, которой в итоге будет их содержать.

Зазор представляет собой пространство выше верхнего поля элемента. Он используется для помещения элемента вертикально (обычно вниз), за перемещаемым объектом.

Перечисленные ниже значения при их использовании для незамещаемых структурных блоков приобретают следующий смысл:

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

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

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

Когда это свойство применяется к перемещаемым объектам, оно приводит к изменениям в правилах позиционирования перемещаемых объектов. При этом добавляется дополнительное ограничение (#10):

Примечание. Это свойство применялось ко всем элементам в CSS1. Реализации могут поэтому поддерживать это свойство во всех элементах. В CSS2 и CSS 2.1 свойство 'clear' применяется только к элементам уровня блока. Поэтому авторам следует использовать это свойство только в элементах уровня блока. Если реализации не поддерживают clear в строковых элементах, вместо того, чтобы устанавливать зазор как объяснено выше, реализации следует инициировать разрыв и эффективно вставить один или более пустых строковых блоков (или сместить новый линейный блок вниз как описано в разделе 9.5), чтобы переместить верх очищаемого строкового блока ниже соответствующего перемещаемого блока(ов).

9.6 Абсолютное позиционирование

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

Ссылка в данной спецификации на абсолютно позиционируемый элемент (или его блоки) означает, что для свойства 'position' данного элемента установлено значение 'absolute' или 'fixed'.

9.6.1 Фиксированное позиционирование

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

Авторы могут использовать фиксированное позиционирование для создания фреймоподобных презентаций. Рассмотрим один из примеров такой презентации:

Рисунок, иллюстрирующей фреймоподобное размещение со свойством position='fixed'.   [D]

Подобный эффект можно достичь с помощью следующего HTML-документа и правил стиля:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Документ с фреймом с CSS 2.1</TITLE>
    <STYLE type="text/css" media="screen">
      BODY { height: 8.5in } /* Требуется для процентного задания высоты далее */
      #header {
        position: fixed;
        width: 100%;
        height: 15%;
        top: 0;
        right: 0;
        bottom: auto;
        left: 0;
      }
      #sidebar {
        position: fixed;
        width: 10em;
        height: auto;
        top: 15%;
        right: auto;
        bottom: 100px;
        left: 0;
      }
      #main {
        position: fixed;
        width: auto;
        height: auto;
        top: 15%;
        right: 0;
        bottom: 100px;
        left: 10em;
      }
      #footer {
        position: fixed;
        width: 100%;
        height: 100px;
        top: auto;
        right: 0;
        bottom: 0;
        left: 0;
      }
    </STYLE>
  </HEAD>
  <BODY>
    <DIV id="header"> ...  </DIV>
    <DIV id="sidebar"> ...  </DIV>
    <DIV id="main"> ...  </DIV>
    <DIV id="footer"> ...  </DIV>
  </BODY>
</HTML>

9.7 Взаимодействие свойств 'display', 'position' и 'float'

Три свойства, влияющие на создание и размещение блока – 'display', 'position' и 'float' – взаимодействуют следующим образом:

  1. Если 'display' имеет значение 'none', то 'position' и 'float' не применяются. В данном случае элемент не генерирует ни одного блока.
  2. В противном случае, если 'position' имеет значение 'absolute' или 'fixed', то блок абсолютно позиционируется, вычисляемое значение свойства 'float' – 'none', и значение 'display' устанавливается в соответствии с таблицей, приведенной ниже. Положение блока будет определяться свойствами 'top', 'right', 'bottom', и 'left' и контейнером блока.
  3. В противном случае, если 'float'принимает значение, отличное от 'none', то блок становится перемещаемым и значение свойства 'display' устанавливается в соответствии с таблицей, приведенной ниже.
  4. В противном случае, если элемент является корневым, то значение свойства 'display' устанавливается в соответствии с таблицей, приведенной ниже.
  5. В противном случае, остальные значения свойства 'display' применяются как определено.
Заданное значение Вычисляемое значение  
inline-table table
inline, run-in, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block block
остальные как определено

9.8 Сравнение моделей, описывающих нормальный поток, перемещаемые объекты и абсолютное позиционирование

Чтобы продемонстрировать различия между нормальным потоком, относительным позиционированием, перемещаемым объектом и абсолютным позиционированием, предлагается несколько примеров на основе следующего фрагмента кода HTML:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Сравнение схем позиционирования</TITLE>
  </HEAD>
  <BODY>
    <P>Beginning of body contents.
      <SPAN id="outer"> Start of outer contents.
      <SPAN id="inner"> Inner contents.</SPAN>
      End of outer contents.</SPAN>
      End of body contents.
    </P>
  </BODY>
</HTML>

В данном документе мы предполагаем использование следующих правил:


body { display: block; font-size:12px; line-height: 200%; 
       width: 400px; height: 400px }
p    { display: block }
span { display: inline }

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

Примечание. Рисунки, приведенные в данном разделе являются информативными и выполнены без соблюдения масштаба. Они предназначены для того, чтобы показать разницу между различными схемами позиционирования в CSS 2.1, а не предназначены быть эталонными представлениями данных примеров.

9.8.1 Нормальный поток

Рассмотрим следующие объявления CSS для outer и inner, которые не вносят изменений в нормальный поток блоков:


#outer { color: red }
#inner { color: blue }

Элемент P заключает в себе все содержимое строки: безымянный текст строки и два элемента SPAN. Поэтому все содержимое будет отображаться в контексте форматирования строки внутри контейнера, порожденного элементом P. В результате примерно следующее:

Рисунок, иллюстрирующий нормальный поток текста между родительскими и сестринскими блоками   [D]

9.8.2 Относительное позиционирование

Чтобы пронаблюдать результаты использования относительного позиционирования, мы определим:


#outer { position: relative; top: -12px; color: red }
#inner { position: relative; top: 12px; color: blue }

Текст обычным образом достигает outer элемента. Текст элемента outer затем помещается в конце строки 1 на его позицию и с размерами в нормальном потоке. Затем строковые блоки, содержащие текст (распределенный на три строки) смещаются как объект на '-12px' (вниз).

Содержимое элемента inner, выступающего в роли дочернего элемента outer, будет отображено обычным образом после слов "of outer contents" (в строке 1.5). Однако сам inner текст смещается относительно outer на '12px' (вниз) на свое нормальное положение в строке 2.

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

Рисунок, иллюстрирующий влияние относительного позиционирования на содержимое блока   [D]

Заметьте так же, что если бы элемент outer был смещен на '-24px', то произошло бы наложение содержимого outer и основного элементов.

9.8.3 Перемещение блоков

Рассмотрим результат перемещения текста элемента inner к правому краю с использованием следующих правил:


#outer { color: red }
#inner { float: right; width: 130px; color: blue }

Текст обычным образом выводится до блока inner, который изымается из нормального потока и перемещается к правому полю (его значение 'width' было указано явно). Линейные блоки, находящиеся слева от перемещаемого объекта, укорачиваются, и оставшаяся часть текста документа отображается в них.

Рисунок, иллюстрирующий результаты перемещения блока   [D]

Чтобы продемонстрировать эффективность работы свойства 'clear', добавим в пример сестринский (sibling) элемент:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Сравнение схем позиционирования II</TITLE>
  </HEAD>
  <BODY>
    <P>Beginning of body contents.
      <SPAN id=outer> Start of outer contents.
      <SPAN id=inner> Inner contents.</SPAN>
      <SPAN id=sibling> Sibling contents.</SPAN>
      End of outer contents.</SPAN>
      End of body contents.
    </P>
  </BODY>
</HTML>

Следующие правила:


#inner { float: right; width: 130px; color: blue }
#sibling { color: red }

как и ранее приводят к перемещению блока inner к правому краю, а оставшаяся часть текста документа перемещается на освободившееся место:

Рисунок, иллюстрирующий результат перемещения блока с использованием свойства   [D]

Однако если для свойства 'clear' элемента sibling установлено значение 'right' (т.е. генерируемый блок sibling не располагается следом за перемещаемым блоком справа), то текст sibling будет выводиться ниже перемещаемого объекта:


#inner { float: right; width: 130px; color: blue }
#sibling { clear: right; color: red }

Рисунок, иллюстрирующий результат перемещения блока с использованием свойства    [D]

9.8.4 Абсолютное позиционирование

И наконец, рассмотрим результат применения модели абсолютного позиционирования. Рассмотрим следующие объявление outer и inner:


#outer { 
    position: absolute; 
    top: 200px; left: 200px; 
    width: 200px; 
    color: red;
}
#inner { color: blue }

результате действия которых верхняя часть блока outer размещается относительно его контейнера. Контейнер для размещаемого блока назначается ближайшим размещенным предком (или, в случае отсутствия такового, начальным контейнером, как в данном примере). Верхняя сторона блока outer находится на '200px' ниже верхней стороны контейнера, а левая сторона на '200px' правее его левой стороны. Дочерний блок блока outer перемещается обычным образом относительно его родительского блока.

Рисунок, иллюстрирующий результаты абсолютного позиционирования блока   [D]

В следующем примере показан абсолютно позиционируемый блок, дочерний по отношению к относительно позиционируемому блоку. Хотя родительский блок outer не смещен, присвоение его свойству 'position' значения 'relative' означает, что он может служить контейнером для позиционируемых потомков. Т.к.блок outer является строковым блоком, разбиваемым на сегменты, распределяемые по нескольким строкам, то в качестве нулевой точки отсчета для смещения 'top' и 'left' выступают верхний и левый края первого сегмента (изображенные на рисунке толстыми пунктирными линиями).


#outer { 
  position: relative; 
  color: red 
}
#inner { 
  position: absolute; 
  top: 200px; left: -100px; 
  height: 130px; width: 130px; 
  color: blue;
}

Это приведет к следующему представлению:

Рисунок, иллюстрирующий эффект абсолютного позиционирования блока относительно контейнера.   [D]

Если мы не позиционируем блок outer:


#outer { color: red }
#inner {
  position: absolute; 
  top: 200px; left: -100px; 
  height: 130px; width: 130px; 
  color: blue;
}

то контейнером для блока inner становится начальный контейнер (в данном примере). На следующем рисунке показано окончательное расположение блока inner .

Абсолютное позиционирование блока относительно нормально размещенного назначенного родительским элементом контейнера   [D]

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


<P style="position: relative; margin-right: 10px; left: 10px;">
I used two red hyphens to serve as a change bar. They
will "float" to the left of the line containing THIS
<SPAN style="position: absolute; top: auto; left: -1em; color: red;">--</SPAN>
word.</P>

приведет к следующему представлению:

Рисунок, иллюстрирующий использование перемещаемых объектов для создания маркеров исправлений   [D]

Сначала позиционирование абзаца (стороны контейнера которого показаны на рисунке) осуществляется согласно модели нормального потока. Затем он смещается на '10px' относительно левого края контейнера (таким образом, правое поле размером в '10px' было предусмотрено для компенсации этого смещения). Два тире, выполняющие роль маркеров исправлений, изымаются из потока и помещаются на текущей строке (с помощью свойства 'top: auto') на расстоянии '-1em' от левого края контейнера (назначенного элементом P в момент его окончательного позиционирования). В результате создается эффект перемещения маркеров исправлений влево по текущей строке.

9.9 Многослойный вывод

9.9.1 Определение позиционного уровня: свойство 'z-index'

'z-index'
Значение:  auto | <integer> | inherit
Начальное значение:  auto
Область применения:  позиционируемые элементы
Наследование:  нет
Процентное задание значений:  Н/Д
Устройства:  визуальные
Вычисляемое значение:  как определено

Для размещенного блока свойство 'z-index' указывает:

  1. Позиционный уровень блока в текущем позиционном контексте.
  2. Назначает ли блок локальный позиционный контекст.

Значения имеют следующий смысл:

<наследуемое>
Данное значение является значением позиционного уровня сгенерированного блока в текущем позиционном контексте. Блок также назначает локальный позиционный контекст с позиционным уровнем '0'.
auto
Позиционный уровень сгенерированного блока в текущем позиционном контексте совпадает с позиционным уровнем родительского блока. Блок не назначает нового локального позиционного контекста.

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

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

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

Любой блок обладает единственным позиционным контекстом. У каждого блока в заданном позиционном контексте имеется позиционный уровень, который указывает его положение на оси z относительно других блоков этого же контекста. Блоки с более высоким позиционным уровнем всегда выводятся поверх блоков с меньшим позиционным уровнем. Позиционный уровень блока может иметь отрицательное значение. Блоки, находящиеся в одном и том же позиционном контексте и обладающие одинаковым позиционным уровнем, располагаются снизу вверх, в зависимости от порядка их расположения в дереве документа.

Корневые элементы формируют корневые позиционные контексты. Остальные позиционные контексты генерируются любым позиционируемым элементом (включая относительно позиционируемые элементы) имеющим вычисляемое значение свойства 'z-index' отличное от 'auto'. Позиционные контексты не обязательно связаны с контейнерами. В будущих уровнях CSS, другие свойства могут вводить позиционные контексты, например, 'opacity'.

Каждый позиционный контекст содержит следующие позиционные уровни (с заднего до переднего):

  1. the background and borders of the element forming the stacking context.
  2. the stacking contexts of descendants with negative stack levels.
  3. a stacking level containing in-flow non-inline-level descendants.
  4. a stacking level for floats and their contents.
  5. a stacking level for in-flow inline-level descendants.
  6. a stacking level for positioned descendants with 'z-index: auto', and any descendant stacking contexts with 'z-index: 0'.
  7. the stacking contexts of descendants with positive stack levels.

For a more thorough explanation of the stacking order, please see Appendix E.

The contents of inline blocks and inline tables are stacked as if they generated new stacking contexts, except that any elements that actually create new stacking contexts take part in the parent stacking context. They are then painted atomically in the inline stacking level.

In the following example, the stack levels of the boxes (named with their "id" attributes) are: "text2"=0, "image"=1, "text3"=2, and "text1"=3. The "text2" stack level is inherited from the root box. The others are specified with the 'z-index' property.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Z-order positioning</TITLE>
    <STYLE type="text/css">
      .pile { 
        position: absolute; 
        left: 2in; 
        top: 2in; 
        width: 3in; 
        height: 3in; 
      }
    </STYLE>
  </HEAD>
  <BODY>
    <P>
      <IMG id="image" class="pile" 
           src="butterfly.png" alt="A butterfly image"
           style="z-index: 1">

    <DIV id="text1" class="pile" 
         style="z-index: 3">
      This text will overlay the butterfly image.
    </DIV>

    <DIV id="text2">
      This text will be beneath everything.
    </DIV>

    <DIV id="text3" class="pile" 
         style="z-index: 2">
      This text will underlay text1, but overlay the butterfly image
    </DIV>
  </BODY>
</HTML>

This example demonstrates the notion of transparency. The default behavior of the background is to allow boxes behind it to be visible. In the example, each box transparently overlays the boxes below it. This behavior can be overridden by using one of the existing background properties.

9.10 Text direction: the 'direction' and 'unicode-bidi' properties

Conforming user agents that do not support bidirectional text may ignore the 'direction' and 'unicode-bidi' properties described in this section. This exception includes UAs that render right-to-left characters simply because a font on the system contains them but do not support the concept of right-to-left text direction.

The characters in certain scripts are written from right to left. In some documents, in particular those written with the Arabic or Hebrew script, and in some mixed-language contexts, text in a single (visually displayed) block may appear with mixed directionality. This phenomenon is called bidirectionality, or "bidi" for short.

The Unicode standard ([UNICODE], section 3.11) defines a complex algorithm for determining the proper directionality of text. The algorithm consists of an implicit part based on character properties, as well as explicit controls for embeddings and overrides. CSS 2.1 relies on this algorithm to achieve proper bidirectional rendering. The 'direction' and 'unicode-bidi' properties allow authors to specify how the elements and attributes of a document language map to this algorithm.

User agents that support bidirectional text must apply the Unicode bidirectional algorithm to every sequence of inline boxes uninterrupted by a forced line break or block boundary. This sequence forms the "paragraph" unit in the bidirectional algorithm. The paragraph embedding level is set according to the value of the 'direction' property of the containing block rather than by the heuristic given in steps P2 and P3 of the Unicode algorithm.

Because the directionality of a text depends on the structure and semantics of the document language, these properties should in most cases be used only by designers of document type descriptions (DTDs), or authors of special documents. If a default style sheet specifies these properties, authors and users should not specify rules to override them.

The HTML 4 specification ([HTML4], section 8.2) defines bidirectionality behavior for HTML elements. The style sheet rules that would achieve the bidi behavior specified in [HTML4] are given in the sample style sheet. The HTML 4 specification also contains more information on bidirectionality issues.

'direction'
Value:  ltr | rtl | inherit
Initial:  ltr
Applies to:  all elements, but see prose
Inherited:  yes
Percentages:  N/A
Media:  visual
Computed value:  as specified

This property specifies the base writing direction of blocks and the direction of embeddings and overrides (see 'unicode-bidi') for the Unicode bidirectional algorithm. In addition, it specifies the direction of table column layout, the direction of horizontal overflow, and the position of an incomplete last line in a block in case of 'text-align: justify'.

Values for this property have the following meanings:

ltr
Left-to-right direction.
rtl
Right-to-left direction.

For the 'direction' property to affect reordering in inline-level elements, the 'unicode-bidi' property's value must be 'embed' or 'override'.

Note. The 'direction' property, when specified for table column elements, is not inherited by cells in the column since columns are not the ancestors of the cells in the document tree. Thus, CSS cannot easily capture the "dir" attribute inheritance rules described in [HTML4], section 11.3.2.1.

'unicode-bidi'
Value:  normal | embed | bidi-override | inherit
Initial:  normal
Applies to:  all elements, but see prose
Inherited:  no
Percentages:  N/A
Media:  visual
Computed value:  as specified

Values for this property have the following meanings:

normal
The element does not open an additional level of embedding with respect to the bidirectional algorithm. For inline-level elements, implicit reordering works across element boundaries.
embed
If the element is inline-level, this value opens an additional level of embedding with respect to the bidirectional algorithm. The direction of this embedding level is given by the 'direction' property. Inside the element, reordering is done implicitly. This corresponds to adding a LRE (U+202A; for 'direction: ltr') or RLE (U+202B; for 'direction: rtl') at the start of the element and a PDF (U+202C) at the end of the element.
bidi-override
For inline-level elements this creates an override. For block-level, table-cell, table-caption, or inline-block elements this creates an override for inline-level descendents not within another block-level, table-cell, table-caption, or inline-block element. This means that inside the element, reordering is strictly in sequence according to the 'direction' property; the implicit part of the bidirectional algorithm is ignored. This corresponds to adding a LRO (U+202D; for 'direction: ltr') or RLO (U+202E; for 'direction: rtl') at the start of the element or at the start of each anonymous child block box, if any, and a PDF (U+202C) at the end of the element.

The final order of characters in each block-level element is the same as if the bidi control codes had been added as described above, markup had been stripped, and the resulting character sequence had been passed to an implementation of the Unicode bidirectional algorithm for plain text that produced the same line-breaks as the styled text. In this process, non-textual entities such as images are treated as neutral characters, unless their 'unicode-bidi' property has a value other than 'normal', in which case they are treated as strong characters in the 'direction' specified for the element.

Please note that in order to be able to flow inline boxes in a uniform direction (either entirely left-to-right or entirely right-to-left), more inline boxes (including anonymous inline boxes) may have to be created, and some inline boxes may have to be split up and reordered before flowing.

Because the Unicode algorithm has a limit of 61 levels of embedding, care should be taken not to use 'unicode-bidi' with a value other than 'normal' unless appropriate. In particular, a value of 'inherit' should be used with extreme caution. However, for elements that are, in general, intended to be displayed as blocks, a setting of 'unicode-bidi: embed' is preferred to keep the element together in case display is changed to inline (see example below).

The following example shows an XML document with bidirectional text. It illustrates an important design principle: DTD designers should take bidi into account both in the language proper (elements and attributes) and in any accompanying style sheets. The style sheets should be designed so that bidi rules are separate from other style rules. The bidi rules should not be overridden by other style sheets so that the document language's or DTD's bidi behavior is preserved.

Example(s):

In this example, lowercase letters stand for inherently left-to-right characters and uppercase letters represent inherently right-to-left characters:


<HEBREW>
  <PAR>HEBREW1 HEBREW2 english3 HEBREW4 HEBREW5</PAR>
  <PAR>HEBREW6 <EMPH>HEBREW7</EMPH> HEBREW8</PAR>
</HEBREW>
<ENGLISH>
  <PAR>english9 english10 english11 HEBREW12 HEBREW13</PAR>
  <PAR>english14 english15 english16</PAR>
  <PAR>english17 <HE-QUO>HEBREW18 english19 HEBREW20</HE-QUO></PAR>
</ENGLISH>

Since this is XML, the style sheet is responsible for setting the writing direction. This is the style sheet:

/* Rules for bidi */
HEBREW, HE-QUO  {direction: rtl; unicode-bidi: embed}
ENGLISH         {direction: ltr; unicode-bidi: embed} 

/* Rules for presentation */
HEBREW, ENGLISH, PAR  {display: block}
EMPH                  {font-weight: bold}

The HEBREW element is a block with a right-to-left base direction, the ENGLISH element is a block with a left-to-right base direction. The PARs are blocks that inherit the base direction from their parents. Thus, the first two PARs are read starting at the top right, the final three are read starting at the top left. Please note that HEBREW and ENGLISH are chosen as element names for explicitness only; in general, element names should convey structure without reference to language.

The EMPH element is inline-level, and since its value for 'unicode-bidi' is 'normal' (the initial value), it has no effect on the ordering of the text. The HE-QUO element, on the other hand, creates an embedding.

The formatting of this text might look like this if the line length is long:

               5WERBEH 4WERBEH english3 2WERBEH 1WERBEH

                                8WERBEH 7WERBEH 6WERBEH

english9 english10 english11 13WERBEH 12WERBEH

english14 english15 english16

english17 20WERBEH english19 18WERBEH

Note that the HE-QUO embedding causes HEBREW18 to be to the right of english19.

If lines have to be broken, it might be more like this:

       2WERBEH 1WERBEH
  -EH 4WERBEH english3
                 5WERB

   -EH 7WERBEH 6WERBEH
                 8WERB

english9 english10 en-
glish11 12WERBEH
13WERBEH

english14 english15
english16

english17 18WERBEH
20WERBEH english19

Because HEBREW18 must be read before english19, it is on the line above english19. Just breaking the long line from the earlier formatting would not have worked. Note also that the first syllable from english19 might have fit on the previous line, but hyphenation of left-to-right words in a right-to-left context, and vice versa, is usually suppressed to avoid having to display a hyphen in the middle of a line.