Главная » Полезные статьи » HTML-верстка » Введение в инлайновый контекст форматирования (ИКФ): основные понятия (1-я публикация цикла “Тайны CSS2.1″)
Распечатать статью

Введение в инлайновый контекст форматирования (ИКФ): основные понятия (1-я публикация цикла “Тайны CSS2.1″)

В основе этой статьи лежит перепевка спецификации CSS 2.1 по телефону Рабиновичем SelenIT-ом. Если что-то вышло криво — я не виноват, это всё он. Конструктивная критика и предложения по улучшению материала приветствуются!

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

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

Ну, как говорится – с Богом!

 

Лайн-бокс

Зачем вообще нужен лайн-бокс?

Говоря простым языком, лайн-бокс — это удобный виртуальный контейнер, от которого «пляшут» элементы строки (инлайн-боксы). Дело в том, что при построении строки рендерер должен как-то узнать, какую Y-координату дать следующей порции инлайнового контента (текста, картинок и т.п.). Можно сказать, что лайн-бокс — это способ учёта пространства по вертикали, занимаемого инлайном.

Построение лайн-бокса

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

Так, стоп. Понимаю, что многие из вас уже запутались и потеряли нить. Поэтому теперь предлагаю чуть помедленнее, с кодом и картинками.

Вначале рассмотрим простой пример. Код будет таким:

<p> один <em> два </em> три </p>

Вроде бы всё просто, обычный блочный элемент (<p>), содержащий в себе одну строку, в которой есть текст и инлайн-элемент (<em>). Но на самом деле в подногонтой самой строки произошёл следующий эффект.

 

На картинке мы можем видеть параграф, генерирующий блочный бокс, в котором и должны находится лайн-боксы. Этот блочный элемент содержит в себе один лайн-бокс (1), три инлайн-бокса (2a, 2n, 2a), в одном из которых (2n) находится просто текст.  А теперь разберём более детально.

Под цифрой «1» изображён лайн-бокс, сгенерированный сразу же после генерации блочного бокса (параграфа). Так как у нас одна строка, то лайн-бокс соответственно тоже один (о двух-строчных чуть позже).
Под цифрами 2a, 2n, 2a находятся инлайн-боксы. На рисунке их ровно три. Они очень похожи на друг друга, но, несмотря на это между некоторых из них есть одно важное отличие. Два боковых лайн-бокса (2a) на самом деле являются анонимными, в отличии от среднего (2n), «натурального». Что это значит?

Анонимный инлайн-бокс

Анонимными инлайн-боксами называются те боксы, который находится непосредственно в самом лайн-боксе. Те, которые являются его ближайшим текстовым потомком, не обёрнутыми  ни в один инлайн-элемент. Для чего это нужно? Давате представим себе ситуацию. Есть такой html:

<p> red <em>green <span>blue</span></em></p>

И вот такие вот стили:

p { color: red }
em {color: green }
span { color: blue }

Вопрос: Кто расскажет про цвет текста «red» (первый дочерний текст у параграфа)? Сам блок (p) не может этого сделать, он находится слишком далеко по структуре. А если так, то как же управлять  ::first-line? Сам лайн-бокс не может взять на себя эту работу и наследование, он нужен для других вещей, которые я описывал выше. Лайн-бокс не имеет сущности, а всего лишь является «счётчиком», передавая главному «штабу» информацию о своих координатах. В связи с этим нужен тот, кто сможем взять на себе стили и передать их дальше. И этим «кто-то» является анонимный инлайн-бокс, к которому и применяется CSS.

Да, стоит уточнить, что в строчном контексте форматирования CSS применяется именно к инлайн-боксам, будь то они анонимные или «натуральные». Ну, и конечно же то, что в самих инлайн-боксах не бывает анонимных инлайн-боксов, они существуют только на верхнем уровне, как я и говорил выше. В самих инлайн-боксах текст является просто текстом.

«Натуральный» инлайн-бокс (т.е. не анонимный)

«Натуральным» инлайн-боксом можно назвать тот бокс, который генерируется самим инлайн-элементом, в нашем случае это элемент <em>. Так же существует ещё ряд «натуральных» инлайн-боксов, таких как: картинки, инлайн-блоки и т.д. В общем, все «живые» инлайн-сущности, которые мы можем видеть в структуре, превращаются в инлайн-боксы.

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

  • * Block (p)
    • * line box
      • * anonimus inline box (текст: «один»)
      • * inline box (em)
      • * anonimus inline box (текст: «три»)

Это был самый лёгкий пример, но, пожалуй, рассмотрим более сложную ситуацию, где структура будет такой:

<p> один <em> два <i> три </i> четыре </em> пять
шесть <span> семь <i> восемь </i> девять </span></p>

В 99% случаев текст в документе состоит из двух и более строк. Что же происходит в таком случае с лайн-боксом? Нет, он не разрывается, вместо этого у нас появляется уже два лайн-бокса! Да, именно так. В этой ситуации рендерер заканчивает с первой строкой и начинает ренредить новую. Причём рендерер производит абсолютно такую же операцию над следующей строкой, как и с предыдущей, т.е. начинает выкладывать в ней новые кирпичи один за другим, заново.

Структура в таком случае выглядит так:

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

Как и на предыдущем рисунке, под цифрами «1» находятся лайн-боксы, на изображении они отмечены ещё и жёлтым цветом. Самое интересное, что, несмотря на то, что контейнер у нас один (<p>), лайн-боксы в нём обсолютно независимы друг от друга. Когда закончилось построение первого, то на «поле»  сразу же появился второй лайн-бокс, с новыми координатами по оси Y. Первый закончил своё построение по той причине, что боксы внутри него попросту заняли всё доступное в нём пространство, а последнему не хватило в лайн-боксе места и он вынужден был переместиться на новую строку.  А раз новая строка – значит новый лайн-бокс. Это железное правило и о нём нужно помнить!

Далее идут уже знакомые вам цифры: «2a» и «2n» обозначают анонимные инлайн-боксы () и соответственно «натуральные»  (2n). Их отличие я уже объяснял в первом примере, поэтому единственное, что хочу тут отметить, это то, что теперь у нас в структуре появились составные инлайн-боксы.

Составной инлайн-бокс

Если в инлайн-боксе находится от двух и более инлайн-боксов или, например, текст и инлайн-боксы, то такой инлайн-бокс считается составным, потому что состоит из нескольких частей. В нашем случае мы имеем два составных инлайн-бокса, один из них элемент <em> в первом лайн-боксе, а другой <span> во втором. Например, <em> состоит из трёх частей: текст («два«), инлайн-бокс (<i>) и за ним снова текст («четыре«).

Ну, и последнее, на чём стоит заострить наше внимание, это цифры «3«, которые указывают на обычный текст в инлайн-боксах. Стоит заметить, что инлайн-боксом для такого текста является их контейнер, а сами они ничего не генерируют, в отличие, например, от текста в самих лайн-боксах (). Дело в том, что внутри инлайн-боксов текст является просто текстом, ему нет смысла генерировать лишние инлайн-боксы, так как CSS стили ему может передать его собственный контейнер.

Дерево такой структуры будет выглядеть так:

  • * Block (p)
    • * line box
      • * anonimus inline box (текст: «один»)
      • * inline box (em)
        • * текст: «два»
        • * inline box (i)
        • * текст: «четыре»
      • * anonimus inline box (текст: «пять»)
    • * line box
      • * anonimus inline box (текст: «шесть»)
      • * inline box (span)
        • * текст: «семь»
        • * inline box (i)
        • * текст: «девять»

Кстати, обратите внимание на один интересный момент. Анонимные инлайн-боксы в конце первого лайн-бокса и в начале второго. Оба они являются анонимными, потому что их родителями, по факту, являются лайн-боксы. А если бы, например структура выглядела бы так:

<p> один <em> два <i> три </i> четыре </em><i> пять
шесть </i><span> семь <i> восемь </i> девять </span></p>

То дерево было бы уже таковым:

  • * Block (p)
    • * line box
      • * anonimus inline box (текст: «один»)
      • * inline box (em)
        • * текст: «два»
        • * inline box (i)
        • * текст: «четыре»
      • * inline box (i)
    • * line box
      • * inline box (i)
      • * inline box (span)
        • * текст: «семь»
        • * inline box (i)
        • * текст: «девять»

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

Пробел – как анонимный инлайн-бокс или текст

Ещё один важный момент в этой части рассказа, который стоило бы разобрать, это пробелы между инлайн-боксами, которые могут превратиться в анонимные инлайн-боксы или в обычный текст. Чтобы было понятно о чём идёт речь, сразу же приведу наглядный пример.

<p> один <em> два <i> три </i> <i> четыре </i> пять </em> <span> шесть </span></p>

Ну и конечно же изображение:

Я не стал расписывать эту структуру по всем частям, здесь суть не в этом. Я лишь прошу вас обратить внимание на два выделенных места, которые помечены цифрами «1» и «2«. Дело в том, что это один из важных моментов при строчном форматировании, о котором следует знать. Суть в самих пробелах. Пробелах между инлайн-элементами или попросту, «натуральными» инлайн-боксами. Выяснилось, что эти, как мне до этого казалось, обычные «сдвиги координат», могут генерировать анонимные инлайн-боксы, точнее не все из них, а только пробелы верхнего уровня, находящиеся непосредственно в самом лайн-боксе. В нашем случае такой (сгенерированый анонимный инлайн-бокс) пробел находится между элементами <em></em> и <span></span> и обозначается цифрой «2» .

А вот пробелы, которые находятся между инлайн-элементами в самих инлайн-боксах, тоже не пропадают зря, а становятся обычным текстом, как и любой другой текст в инлайн-боксах. Такой пробел вы можете наблюдать под цифрой «1» в нашем примере.

Я полагаю, что это логично, так как пробел всё же тоже является символом, а значит так же, как и другие символы, имеет право на собственный контейнер, не так ли?

Источник:  css-live.ru

Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

Оставить комментарий

Похожие статьи