Содержание
В этой и следующей главах описывается модель визуального форматирования: как агенты пользователей обрабатывают дерево документа для визуальных устройств.
Согласно модели визуального форматирования каждый элемент дерева документа порождает произвольное количество (возможно, равное нулю) блоков в соответствии с блочной моделью. Размещение этих блоков обуславливается:
Свойства, которые рассматриваются в этой и следующей главах, используются как с устройствами, не осуществляющими разбивку на страницы, так и с устройствами, осуществляющими постраничную разбивку. Однако, при применении к устройствам, осуществляющим постраничную разбивку, происходит преобразование значений свойств полей (подобную информацию см. в разделе о модели постраничного отображения документа).
Модель визуального форматирования не является исчерпывающим описанием формата вывода документа (например, она не определяет алгоритм задания межсимвольного интервала). Поэтому поведение соответствующих агентов пользователей, использующих элементы форматирования, которые не рассматриваются в данной спецификации, может быть различным.
Агенты пользователей, управляющие выводом на устройства без постраничной разбивки, предоставляют пользователям область просмотра (окно или другую область экрана), с помощью которой пользователи взаимодействуют с документом. Агенты пользователей могут менять положение документа в случае изменения размера области просмотра (см. начальный контейнер).
Если область просмотра меньше, чем область вывода, в которой документ представляется, агентам следует использовать механизм прокрутки. На каждую область вывода приходится не больше одной области просмотра, но агенты могут использовать несколько областей вывода (т.е. предоставлять несколько альтернативных вариантов отображения одного и того же документа).
В CSS 2.1 положение и размеры блоков вычисляются относительно краев определенной области прямоугольной формы, называемой контейнером. Генерируемые блоки, как правило, являются контейнерами блоков, выступающих в качестве их потомков. В этом случае говорят, что блок "назначает" контейнер своему потомку. Выражение "контейнер блока" обозначает контейнер, в котором находятся рассматриваемый блок, но не контейнер, порожденный этим блоком.
Положение каждого блока задается относительно содержащего его контейнера, но его размеры никак не ограничиваются размерами последнего, так что блок может выходить за пределы контейнера.
Подробная информация о том, как вычисляются размеры контейнера, находится в следующей главе.
В следующих разделах описаны различные типы блоков, которые можно создавать в CSS 2.1. Тип блока частично влияет на его поведение в рамках модели визуального форматирования. Тип блока определяется с помощью свойства 'display', описанного ниже.
К элементам уровня блока относятся элементы исходного документа, которые визуально форматируются в виде неких структурных единиц текста (например, абзацев). Принадлежность уровню блока определяется значениями свойства 'display': 'block', 'list-item' и 'run-in' (часть из них; см. раздел, посвященный вставляемым блокам), а также 'table'.
Элементы уровня блока (кроме элемента 'table', который описан в следующем разделе) генерируют главный структурный блок, который содержит или только структурные блоки или только строковые блоки. Главный блок может участвовать в рамках любой схемы позиционирования и вместе с этим назначать контейнер для блоков, выступающих в качестве его потомков, и для генерируемого содержимого. Главные структурные блоки используются в контексте форматирования блоков.
Некоторые элементы уровня блока порождают дополнительные блоки за пределами главного: элементы 'list-item'. Дополнительные блоки размещаются относительно главного блока.
В документе типа такого:
<DIV>
Некий текст
<P>Больше текста
</DIV>
(и считая, что для элементов DIV и P установлено значение 'display:block') элемент DIV имеет два типа содержимого: и принадлежащего строке и принадлежащего блоку. Чтобы упростить процесс форматирования, предполагается, что надпись "Некий текст" заключена в безымянный структурный блок.
На рисунке, иллюстрирующем пример выше, изображены три типа блоков, из которых один – безымянный.
Другими словами: если структурный блок (например, сгенерированный для элемента 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. Это не применимо к агентам пользователей, разработанным после выхода данной спецификации.
Элементы строкового уровня – это те элементы исходного документа, которые не формируют новых структурных единиц содержимого; содержимое выводится в строках (например, выделенные отрывки текста в абзаце, вложенные в строку рисунки и т.д.) Определенные значения свойства 'display' делают элемент принадлежащим строке: 'inline', 'inline-table', и 'run-in' (часть из них; см. раздел, посвященный вставляемым блокам). Элементы строкового уровня порождают строковые блоки.
В документе с разметкой HTML, таком как этот:
<p>Некоторый <em>выделенный</em> текст</p>
<p> порождает структурный блок, содержащий внутри несколько строковых блоков. Блок, содержащий слово "выделенный", является строковым блоком, порожденным строковым элементом (<em>), но остальные блоки, ("Некоторый" и "текст") являются строковыми блоками, порожденными элементом структурного уровня (<p>). Последние называются безымянными строковыми блоками, т.к. не существует элемента строкового уровня, который был бы связан с ними.
Такие безымянные строковые блоки принимают значения наследуемых свойств их родительского структурного блока. Ненаследуемые свойства принимают их начальные значения. В этом примере цвет безымянных строковых блоков наследуется от элемента P, но фон остается прозрачным.
Содержимое с пустым пространством, которое было впоследствии сокращено в соответствии со свойством 'white-space', не генерирует никаких строковых блоков.
Если из контекста видно, какой тип анонимного поля имеется в виду, и безымянные строковые блоки и безымянные структурные блоки в этой спецификации просто называют безымянными блоками.
Больше типов безымянных блоков возникают при форматировании таблиц.
Вставляемый блок ведет себя следующим образом:
Блок '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>
Данный пример можно отформатировать следующим образом:
Вставляемый заголовок. И абзац текста, который следует за ним.
Несмотря на представление визуальной части следующего структурного блока, вставляемый элемент все еще наследует свойства от своего родителя в дереве исходного кода.
Информацию о взаимодействии вставляемых блоков с генерируемым содержимым можно найти в разделе о генерируемом содержимом.
| Значение: | 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 |
| Область применения: | все элементы |
| Наследование: | нет |
| Процентное задание значений: | Н/Д |
| Устройства: | все |
| Вычисляемое значение: | см. описание |
Значения данного свойства имеют следующий смысл:
Примите во внимание, что в результате использования значения 'none' не создается невидимых блоков; оно вообще не создает блоков. В CSS имеются такие механизмы, которые позволяют элементам порождать в структуре форматирования определенные блоки, влияющие на форматирование, но при этом явно не отображаемые. Подробную информацию можно найти в разделе о видимости.
Вычисляемое значение то же, что и заданное значение, за исключением позиционируемых и перемещаемых элементов (см. Взаимодействия между 'display', 'position' и 'float') и корневых элементов. Для корневого элемента, вычисляемое значение выбирается как описано в разделе о взаимодействиях между 'display', 'position' и 'float'.
Примите во внимание, что хотя в качестве начального значения свойства 'display' используется значение 'inline', правила, содержащиеся в таблице стилей, принятой по-умолчанию в агенте пользователя, могут перезаписать это значение. См. информацию о простой таблицы стилей для HTML 4, приведенную в приложении.
Далее представлено несколько примеров использования свойства 'display':
p { display: block }
em { display: inline }
li { display: list-item }
img { display: none } /* Не отображать рисунки */
В CSS 2.1 блок может размещаться согласно трем схемам позиционирования:
Свойства 'position' и 'float' определяют алгоритм позиционирования CSS 2.1, используемый для определения положения блока.
| Значение: | static | relative | absolute | fixed | inherit |
| Начальное значение: | static |
| Область применения: | все элементы |
| Наследование: | нет |
| Процентное задание значений: | Н/Д |
| Устройства: | визуальные |
| Вычисляемое значение: | как определено |
Значения данного свойства имеют следующий смысл:
@media screen {
h1#first { position: fixed }
}
@media print {
h1#first { position: static }
}
Агенты пользователей не должны разбивать на страницы содержимое фиксируемых блоков. Примите во внимание, что агенты пользователей могут распечатывать невидимое содержимое другими способами. См. "Содержимое за пределами блока страницы" в главе 13.
Агент пользователя может обрабатывать положение как 'static' в корневом элементе.
Говорят, что элемент был позиционирован, если для свойства 'position' устанавливается значение, отличное от 'static'. Позиционированные элементы порождают позиционированные блоки, положение которых регулируется с помощью следующих четырех свойств:
| Значение: | <длина> | <проценты> | auto | inherit |
| Начальное значение: | auto |
| Область применения: | позиционируемые элементы |
| Наследование: | нет |
| Процентное задание значений: | относительно высоты контейнера |
| Устройства: | визуальные |
| Вычисляемое значение: | для 'position:relative' – см. раздел Относительное позиционирование. Для 'position:static' – 'auto'. Иначе: если определено как длина – соответствующая абсолютная длина; если определено как процентное значение – заданное значение; иначе – 'auto'. |
Это свойство задает насколько абсолютно позиционированный верхний край поля блока смещен ниже верхнего края контейнера блока. Для относительно позиционируемых блоков, смещение осуществляется относительно верхнего края самого блока (сначала блоку присваивается положение в нормальном потоке, а затем с использованием названных свойств указывается смещение относительно этого положения). Примечание: Для абсолютно позиционированных элементов, чей контейнер основывается на элементе уровня блока, это свойство является смещением относительно краевой линии отступа такого элемента.
| Значение: | <длина> | <проценты> | auto | inherit |
| Начальное значение: | auto |
| Область применения: | позиционируемые элементы |
| Наследование: | нет |
| Процентное задание значений: | относительно ширины контейнера |
| Устройства: | визуальные |
| Вычисляемое значение: | для 'position:relative' – см. раздел Относительное позиционирование. Для 'position:static' – 'auto'. Иначе: если определено как длина – соответствующая абсолютная длина; если определено как процентное значение – заданное значение; иначе – 'auto'. |
Как и 'top', но задает на сколько правый край поля блока смещен влево от правого края контейнера блока. Для относительно позиционируемых блоков, смещение осуществляется относительно правого края самого блока. Примечание: Для абсолютно позиционированных элементов, чей контейнер основывается на элементе уровня блока, это свойство является смещением относительно краевой линии отступа такого элемента.
| Значение: | <длина> | <проценты> | auto | inherit |
| Начальное значение: | auto |
| Область применения: | позиционируемые элементы |
| Наследование: | нет |
| Процентное задание значений: | относительно высоты контейнера |
| Устройства: | визуальные |
| Вычисляемое значение: | для 'position:relative' – см. раздел Относительное позиционирование. Для 'position:static' – 'auto'. Иначе: если определено как длина – соответствующая абсолютная длина; если определено как процентное значение – заданное значение; иначе – 'auto'. |
Как и 'top', но задает на сколько нижний край поля блока смещен выше нижнего края контейнера блока. Для относительно позиционируемых блоков, смещение осуществляется относительно нижнего края самого блока. Примечание: Для абсолютно позиционированных элементов, чей контейнер основывается на элементе уровня блока, это свойство является смещением относительно краевой линии отступа такого элемента.
| Значение: | <длина> | <проценты> | auto | inherit |
| Начальное значение: | auto |
| Область применения: | позиционируемые элементы |
| Наследование: | нет |
| Процентное задание значений: | относительно ширины контейнера |
| Устройства: | визуальные |
| Вычисляемое значение: | для 'position:relative' – см. раздел Относительное позиционирование. Для 'position:static' – 'auto'. Иначе: если определено как длина – соответствующая абсолютная длина; если определено как процентное значение – заданное значение; иначе – 'auto'. |
Как и 'top', но задает на сколько левый край поля блока смещен вправо от левого края контейнера блока. Для относительно позиционируемых блоков, смещение осуществляется относительно левого края самого блока. Примечание: Для абсолютно позиционированных элементов, чей контейнер основывается на элементе уровня блока, это свойство является смещением относительно краевой линии отступа такого элемента.
Значения этих четырех свойств имеют следующий смысл:
Блоки, содержащиеся в нормальном потоке, принадлежат контексту форматирования, который может быть либо блоковым, либо строковым, но не тем и ни другим одновременно. Структурные блоки участвуют в контексте форматирования блоков. Строковые блоки участвуют в контексте форматирования строк.
Перемещаемые объекты, абсолютно позиционируемые объекты, строковые блоки, ячейки таблиц, оглавления таблиц и элементы со свойством 'overflow' другие, чем 'visible' (кроме случаев, когда значение распространяется на область просмотра) устанавливают новые контексты форматирования блока.
В контексте форматирования блоков блоки располагаются друг за другом вертикально, начиная с верхнего края контейнера. Вертикальное расстояние между двумя сестринскими блоками определяется с помощью свойства 'margin'. В контексте форматирования блоков вертикальные поля между соседними структурными блоками перекрываются.
В контексте форматирования блоков каждый левый сегмент внешнего края блока соприкасается с левым сегментом краевой линии контейнера (при форматировании справа налево соприкасаются правые края). Это справедливо и при наличии перемещаемых объектов (хотя при этом строковые блоки структурного блока могут уменьшиться за счет перемещаемых), кроме блок назначает новый контекст форматирования блока (в этом случае блок сам может стать узким за счет перемещаемых блоков).
Информацию о разделителях страниц, используемых в устройствах с постраничной разбивкой, можно найти в разделе о допустимых разделителях страниц.
В контексте форматирования строк блоки располагаются горизонтально, один за другим, начиная с верхнего края контейнера. Горизонтальные поля, границы и отступы внутри этих блоков сохраняются. Существуют различные способы вертикального выравнивания блоков: их нижние или верхние края могут быть выровненными, или базовые линии текста в них могут быть выровнены. Прямоугольная область, которая содержит блоки, формирующие строку, называется линейным блоком.
Ширина линейного блока определяется шириной контейнера и наличием перемещаемых объектов. Высота линейного блока регулируется правилами, описанными в разделе "Вычисления высоты строк".
Линейный блок всегда имеет высоту, достаточную для все содержащиеся в нем блоков. Однако он может быть выше, чем самый высокий блок, содержащийся в нем (если, например, блоки выровнены таким образом, что базовые линии текста находятся на одной оси). Если высота блока 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 блоки могут распределяться следующим образом:
После того как блок был размещен в соответствии с моделью нормального потока или перемещен, он может быть смещен относительно исходного положения. Данная процедура называется относительным позиционированием. Подобное смещение блока (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'). Несмотря на то, что относительное позиционирование может быть использовано как средство для создания верхних и нижних индексов, высота строки не регулируется автоматически, препятствуя осуществлению позиционирования. Дополнительную информацию можно найти в разделе о вычислении высоты строк.
Примеры относительного позиционирования представлены в разделе о сравнении нормального потока, перемещаемых объектов и абсолютного позиционирования.
Перемещаемый объект – это блок, который смещается в текущей строке в левую или правую сторону. Самым интересным свойством перемещаемого объекта (или "перемещенного" или "перемещаемого" блока) является то, что содержимое может передвигаться вдоль одной из его сторон (либо не делать этого, если существует запрет, устанавливаемый свойством '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). Приведенный документ может быть отформатирован следующим образом:
Форматирование было бы точно таким же, если бы документ выглядел так:
<BODY>
<P>Некоторый простой текст,
<IMG src=img.png alt="Этот рисунок иллюстрирует перемещаемые объекты">
который не имеет остальных...
</BODY>
объясняется это тем, что содержимое, находящееся слева от перемещаемого объекта, заменяется им, а само отображается справа от него.
Как заявлено в разделе 8.3.1, поля перемещаемых блоков никогда не перекрываются с полями смежных блоков. Таким образом, в предыдущем примере вертикальные поля между блоком элемента P и перемещаемым блоком IMG не перекрываются.
Содержимое перемещаемых объектов расположено в стеке, как будто перемещаемые объекты генерировали новые контексты накопления, за исключением того, что любые элементы, которые фактически создают новые контексты накопления, принимают участие в контексте накопления родителя перемещаемого объекта. Перемещаемый объект может перекрывать другие блоки в нормальном потоке (например, когда блок нормального потока следует за перемещаемым объектом, чьи поля имеют отрицательное значение). Когда это происходит, перемещаемые объекты представлены перед непозиционированными in-flow блоками, но позади in-flow строковых блоков.
Ниже показано, что происходит при наложении перемещаемого объекта на границы элементов нормального потока.
Перемещаемое изображение затеняет границы перекрываемых им структурных блоков.
В следующем примере проиллюстрировано использование свойства 'clear', позволяющего запрещать перемещение содержимого вдоль относительно объекта.
Предполагая правило, такое как это:
p { clear: left }
форматирование могло бы выглядеть так:
| Значение: | left | right | none | inherit |
| Начальное значение: | none |
| Область применения: | все, но см. раздел 9.7 |
| Наследование: | нет |
| Процентное задание значений: | Н/Д |
| Устройства: | визуальные |
| Вычисляемое значение: | как определено |
Данное свойство определяет, будет ли блок перемещен влево, вправо или вообще не будет перемещен. Оно может устанавливаться для любых элементов, но применяется только к элементам, порождающим блоки, не являющиеся абсолютно позиционируемыми. Значения данного свойства имеют следующий смысл:
Агент пользователя может обрабатывать перемещение как 'none' в корневом элементе.
Ниже приведены четкие правила, определяющие поведение перемещаемых объектов:
Ссылки на остальные элементы в данном правиле относятся только к остальным элементам в том же контексте форматирования блока, что и перемещаемый объект.
Данный фрагмент HTML приведет к тому, что b перемещается вправо.
<P>a<SPAN style="float: right">b</SPAN></P>
Если ширина элемента P достаточна, то a и b будут находиться рядом. Это могло бы выглядеть так:
| Значение: | none | left | right | both | inherit |
| Начальное значение: | none |
| Область применения: | элементы структурного уровня |
| Наследование: | нет |
| Процентное задание значений: | Н/Д |
| Устройства: | визуальные |
| Вычисляемое значение: | как определено |
Это свойство определяет, какие стороны блока, порожденного элементом, не могут соседствовать с предшествующим перемещаемым блоком. Свойство 'clear' не рассматривает перемещаемые объекты внутри самого элементе или в других контекстах форматирования блока.
Для встраиваемых блоков это свойство применяется к структурному блоку, которой в итоге будет их содержать.
Зазор представляет собой пространство выше верхнего поля элемента. Он используется для помещения элемента вертикально (обычно вниз), за перемещаемым объектом.
Перечисленные ниже значения при их использовании для незамещаемых структурных блоков приобретают следующий смысл:
Вычисление зазора элемента, у которого установлено свойство 'clear', выполняется первым путем определения гипотетической позиции верхнего края границы элемента в пределах его родительского блока. Эта позиция определяется после того, как верхнее поля элемента было перекрыто с предыдущими смежными полями (включая верхнее поле родительского блока).
Если верхний край границы элемента не проходит через соответствующие перемещаемые объекты, то его зазор устанавливается такого размера, который необходим для размещения края границы блока даже с нижним внешним краем самого нижнего перемещаемого объекта, который должен быть очищен.
Когда это свойство применяется к перемещаемым объектам, оно приводит к изменениям в правилах позиционирования перемещаемых объектов. При этом добавляется дополнительное ограничение (#10):
Примечание. Это свойство применялось ко всем элементам в CSS1. Реализации могут поэтому поддерживать это свойство во всех элементах. В CSS2 и CSS 2.1 свойство 'clear' применяется только к элементам уровня блока. Поэтому авторам следует использовать это свойство только в элементах уровня блока. Если реализации не поддерживают clear в строковых элементах, вместо того, чтобы устанавливать зазор как объяснено выше, реализации следует инициировать разрыв и эффективно вставить один или более пустых строковых блоков (или сместить новый линейный блок вниз как описано в разделе 9.5), чтобы переместить верх очищаемого строкового блока ниже соответствующего перемещаемого блока(ов).
В модели абсолютного позиционирования величина смещения блока относительно его контейнера задается явно. Он полностью удаляется из нормального потока (так что не влияет на последующие сестринские элементы). Абсолютно позиционированный блок назначает новый контейнер для дочерних элементов из нормального потока и абсолютно (но не фиксируя) позиционирует потомков. Однако, содержимое абсолютно позиционируемого элемента не перемещается вокруг любых других блоков. Оно может затенять содержимое другого блока (или сам быть затененным) в зависимости от уровней расположения накладывающихся блоков.
Ссылка в данной спецификации на абсолютно позиционируемый элемент (или его блоки) означает, что для свойства 'position' данного элемента установлено значение 'absolute' или 'fixed'.
Фиксированное позиционирование является разновидностью абсолютного позиционирования. Единственным его отличием является то, что при фиксированном позиционировании контейнер определяется областью просмотра. Для устройств без разбивки фиксированные блоки не перемещаются при прокрутке документа. В этом отношении они схожи с фиксированными фоновыми изображениями. Для устройств с постраничной разбивкой блоки с фиксированным положением повторяются на каждой странице. Это оказывается удобным, например, при размещении подписей в нижней части каждой страницы.
Авторы могут использовать фиксированное позиционирование для создания фреймоподобных презентаций. Рассмотрим один из примеров такой презентации:
Подобный эффект можно достичь с помощью следующего 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>
Три свойства, влияющие на создание и размещение блока – 'display', 'position' и 'float' – взаимодействуют следующим образом:
| Заданное значение | Вычисляемое значение |
|---|---|
| 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 |
| остальные | как определено |
Чтобы продемонстрировать различия между нормальным потоком, относительным позиционированием, перемещаемым объектом и абсолютным позиционированием, предлагается несколько примеров на основе следующего фрагмента кода 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, а не предназначены быть эталонными представлениями данных примеров.
Рассмотрим следующие объявления CSS для outer и inner, которые не вносят изменений в нормальный поток блоков:
#outer { color: red }
#inner { color: blue }
Элемент P заключает в себе все содержимое строки: безымянный текст строки и два элемента SPAN. Поэтому все содержимое будет отображаться в контексте форматирования строки внутри контейнера, порожденного элементом P. В результате примерно следующее:
Чтобы пронаблюдать результаты использования относительного позиционирования, мы определим:
#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.
Заметьте так же, что если бы элемент outer был смещен на '-24px', то произошло бы наложение содержимого outer и основного элементов.
Рассмотрим результат перемещения текста элемента inner к правому краю с использованием следующих правил:
#outer { color: red }
#inner { float: right; width: 130px; color: blue }
Текст обычным образом выводится до блока inner, который изымается из нормального потока и перемещается к правому полю (его значение 'width' было указано явно). Линейные блоки, находящиеся слева от перемещаемого объекта, укорачиваются, и оставшаяся часть текста документа отображается в них.
Чтобы продемонстрировать эффективность работы свойства '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 к правому краю, а оставшаяся часть текста документа перемещается на освободившееся место:
Однако если для свойства 'clear' элемента sibling установлено значение 'right' (т.е. генерируемый блок sibling не располагается следом за перемещаемым блоком справа), то текст sibling будет выводиться ниже перемещаемого объекта:
#inner { float: right; width: 130px; color: blue }
#sibling { clear: right; color: red }
И наконец, рассмотрим результат применения модели абсолютного позиционирования. Рассмотрим следующие объявление outer и inner:
#outer {
position: absolute;
top: 200px; left: 200px;
width: 200px;
color: red;
}
#inner { color: blue }
результате действия которых верхняя часть блока outer размещается относительно его контейнера. Контейнер для размещаемого блока назначается ближайшим размещенным предком (или, в случае отсутствия такового, начальным контейнером, как в данном примере). Верхняя сторона блока outer находится на '200px' ниже верхней стороны контейнера, а левая сторона на '200px' правее его левой стороны. Дочерний блок блока outer перемещается обычным образом относительно его родительского блока.
В следующем примере показан абсолютно позиционируемый блок, дочерний по отношению к относительно позиционируемому блоку. Хотя родительский блок outer не смещен, присвоение его свойству 'position' значения 'relative' означает, что он может служить контейнером для позиционируемых потомков. Т.к.блок outer является строковым блоком, разбиваемым на сегменты, распределяемые по нескольким строкам, то в качестве нулевой точки отсчета для смещения 'top' и 'left' выступают верхний и левый края первого сегмента (изображенные на рисунке толстыми пунктирными линиями).
#outer {
position: relative;
color: red
}
#inner {
position: absolute;
top: 200px; left: -100px;
height: 130px; width: 130px;
color: blue;
}
Это приведет к следующему представлению:
Если мы не позиционируем блок outer:
#outer { color: red }
#inner {
position: absolute;
top: 200px; left: -100px;
height: 130px; width: 130px;
color: blue;
}
то контейнером для блока inner становится начальный контейнер (в данном примере). На следующем рисунке показано окончательное расположение блока inner .
Относительное и абсолютное позиционирование может использоваться для вставки маркеров исправлений, как показано в следующем примере. Следующий фрагмент:
<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>
приведет к следующему представлению:
Сначала позиционирование абзаца (стороны контейнера которого показаны на рисунке) осуществляется согласно модели нормального потока. Затем он смещается на '10px' относительно левого края контейнера (таким образом, правое поле размером в '10px' было предусмотрено для компенсации этого смещения). Два тире, выполняющие роль маркеров исправлений, изымаются из потока и помещаются на текущей строке (с помощью свойства 'top: auto') на расстоянии '-1em' от левого края контейнера (назначенного элементом P в момент его окончательного позиционирования). В результате создается эффект перемещения маркеров исправлений влево по текущей строке.
| Значение: | auto | <integer> | inherit |
| Начальное значение: | auto |
| Область применения: | позиционируемые элементы |
| Наследование: | нет |
| Процентное задание значений: | Н/Д |
| Устройства: | визуальные |
| Вычисляемое значение: | как определено |
Для размещенного блока свойство 'z-index' указывает:
Значения имеют следующий смысл:
В данном разделе выражение "поверх" или "спереди" означают, что объект расположен ближе к пользователю, обращенному лицом к экрану.
В CSS 2.1 каждый блок размещается в трехмерном пространстве. Помимо горизонтальных и вертикальных координат блоки имеют координаты вдоль "оси z", располагаясь один поверх другого. Позиционирование объектов вдоль оси z оказывается удобным, когда визуально происходит их наложение. В этом разделе обсуждаются способы позиционирования блоков вдоль оси z.
Порядок, в котором дерево представления рисуется в области вывода определяется в терминах позиционных контекстов. Позиционные контексты могут содержать будущие позиционные контексты. Позиционный контекст является атомарным с точки зрения его родительского позиционного контекста; блоки в других позиционных контекстах не могут следовать между любыми их блоками.
Любой блок обладает единственным позиционным контекстом. У каждого блока в заданном позиционном контексте имеется позиционный уровень, который указывает его положение на оси z относительно других блоков этого же контекста. Блоки с более высоким позиционным уровнем всегда выводятся поверх блоков с меньшим позиционным уровнем. Позиционный уровень блока может иметь отрицательное значение. Блоки, находящиеся в одном и том же позиционном контексте и обладающие одинаковым позиционным уровнем, располагаются снизу вверх, в зависимости от порядка их расположения в дереве документа.
Корневые элементы формируют корневые позиционные контексты. Остальные позиционные контексты генерируются любым позиционируемым элементом (включая относительно позиционируемые элементы) имеющим вычисляемое значение свойства 'z-index' отличное от 'auto'. Позиционные контексты не обязательно связаны с контейнерами. В будущих уровнях CSS, другие свойства могут вводить позиционные контексты, например, 'opacity'.
Каждый позиционный контекст содержит следующие позиционные уровни (с заднего до переднего):
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.
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.
| 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:
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.
| 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:
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.
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.