Главная » CSS, Статьи и переводы

Новая техника CSS: имитация абсолютного позиционирования

25 Июнь 2008 просмотров 10 674 комментариев 26


Как известно, существует 2 популярных способа верстки на основе блоков div: плавающая модель (float) и абсолютное позиционирование (absolute). Каждый из них имеет свои плюсы и минусы. Eric Sol вместе со своей командой разработали новый способ позиционирования в CSS под названием "faux absolute positioning" – имитация абсолютного позиционирования.

Большинство дизайнов имеют колоночную структуру, т.е. шапку, 2-3 колонки и подвал. Используя только абсолютное позиционирование невозможно задать правила для подвала, т.к. его положение напрямую зависит от контента. С плавающей моделью тоже возникают сложности: блоки просто разваливаются, если их суммарная ширина будет больше 100%.

Задача команды Эрика была намного сложнее:

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

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

Спонсор статьи: Срочное продвижение web ( веб ) сайта в сети интернет.
Хотите стать спонсором?

Тогда ребята стали экспериментировать и сделали, можно сказать, открытие:

В итоге, мы решили попробовать способ, основанный на вычислении левого отрицательного отступа относительно элемента с фиксированной позицией, в отличие от расчета величины его правого края относительно предыдущего элемента. Сделать это получилось с помощью комбинации свойств: position: relative, left: 100% и отрицательного значения margin-left.

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

<div id="canvas">
<div class="line">
<div class="item" id="item1">
<div class="sap-content">content here</div>
</div>
</div>
</div>

… и так далее. Каждый блок-ячейка имеет дополнительный внутренний блок с классом sap-content. Это сделано для того, чтобы:
- избежать баг отрисовки в IE6,
- управлять отступами внутри ячейки
- использовать свойства overflow (ячейки не будут разваливаться)

CSS код для наших элементов таков:

.line {
float: left;
width: 100%;
display: block;
position: relative;
}
.item {
position: relative;
float: left;
left: 100%;
}

Для позиционирования первого блока-ячейки нам нужно прописать отрицательное значение margin-left и установить ширину блока. Например:

#item1 { margin-left: -100%; width: 30%;}

Наглядно это можно изобразить так:

имитация абсолютного позиционирования

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

Примеры

Первый пример – 3х колоночный макет с фиксированным размером левой и правой колонок. Следует обратить внимание на следующие моменты:

  1. Левая и правая колонки имеют ширину в пикселях. Поэтому, мы не можем высчитать левый отступ для центрального блока, т.к. не знаем ширину рабочей области в процентах, так же как и ширину колонок в процентах от рабочей области. Решение будет простым: установим для главного блока свойства: margin-left: -100% и width: 100% и добавим padding чтобы получить отступы от колонок.
  2. Все 3 колонки отрисованы на одном уровне по оси Z, поэтому необходимо для левой и правой колонок прописать свойство z-index, например 100.
  3. Отступы для левой и правой колонок добавлены к дополнительному внутреннему блоку sap-content, и как говорилось выше, это обеспечивает гибкость работы с ним.

Пример 2 включает 5 колонок, в котором рабочая область, все строки и ячейки имеют ширину в процентах. Добавление изображений, границ и отступов не влияет на отрисовку и позиционирование блоков.

Преимущества метода

Новый способ позиционирования позволяет нам располагать элементы на заранее отведенное для них место, так же как и при абсолютном позиционировании, но все элементы будут следовать в одном потоке, друг за другом. Имитация абсолютного позиционирования имеет множество преимуществ наравне с версткой обычными методами. Каждая строка в сетке всегда будет _той же высоты_ что и центральная часть или той, что определена стилями, и всегда будет иметь 100% ширины, независимо от того сколько ячеек задано в колонке. Кроме того, способ позволяет избежать образования промежутков между элементами – и это большой плюс, т.к. в IE приходилось применять для этого css-фильтры (хаки) в блочной модели.

Еще одним преимуществом является то, что эта техника «смягчает» недостатки плавающей модели. Когда содержимое блока шире чем сам блок, то он толкает следующий блок вправо, а не сбрасывает его вниз. Содержимое блока может быть даже намного больше своего родителя – это никак не скажется на структуру нашего макета. (в этом помогает правило overflow: hidden).
И самое главное – новая техника абсолютно валидна HTML 4.01 и CSS 2.1 и отрицательное значение margin-left одинаково воспринимается всеми браузерами! Больше никаких хаков! К тому же, модель подойдет как для дизайнов с фиксированной, так и 100% шириной, и позволяет работать с одинаковыми высотами колонок, при этом имеющих фиксированную либо % ширину. Имитация абсолютного позиционирования может даже использоваться рекурсивно, т.е. позволяет использовать ячейки как строки с новыми ячейками – как при верстке с использованием table.

Подводные камни

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

Кроме того, есть ситуации, в которых техника не будет работать. Если вы хотите расположить элементы друг за другом, вы не можете использовать единицы измерения, отличные от той, в которых указана ширина рабочей области, иначе вы просто не сможете рассчитать необходимый отрицательный отступ. Например, у вас есть рабочая область шириной 800px и вы хотите сделать левый отступ в 2em для вашей ячейки, но вы не рассчитаете значение отступа, т.к. не знаете сколько em в 800 пикселях.

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

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

Блогун

Комментариев 26 »

  • ]]>Sanya пишет: ]]>

    Как раз начинаю учить каскадные стили. Попробую применить материал на практике :)

      Цитировать

  • ]]>Jeezy пишет: ]]>

    Если в плавающей модели (float) использовать свойство overflow, то блоки не будут разваливать если их суммарная ширина будет больше 100%.

      Цитировать

  • ]]>Jeezy пишет: ]]>

    Точнее, их суммарная ширина никогда не будет больше 100%, если использовать overflow.

      Цитировать

  • ]]>gordi пишет: ]]>

    Если посмотреть пример № 1 в IE7 то картинка расположенная в области контента обрезана слева, чего нет в FF 3, OPERA 9.5.
    z-index:100; не обязательное значение :)
    Нечто подобное реализовано мной здесь: http://trifler.ru/blog/layouts3.html

      Цитировать

  • ]]>Автор пишет: ]]>

    смотря при каком разрешении смотреть ;) Картинка будет обрезаться за счет оverflow:hidden. Основная суть в том, чтобы блоки не разваливались, пусть даже за счет “обрезания” части контента. Можно прописать еще min-width, чтобы оставалась какая-то фиксированная ширина всегда.

      Цитировать

  • ]]>gordi пишет: ]]>

    Говорим конкретно про пример № 1, не так ли?
    Причем здесь разрешение?
    Данный макет имеет фиксированную ширину, но для IE7 допущена небрежность :)
    Что легко правится на раз-два :)

      Цитировать

  • ]]>Автор пишет: ]]>

    в примере №1 фиксированную ширину имеют только правая и левая колонки. Центральный контент в %. Картинка начинает обрезаться с 1004px и менее даже в FF.

      Цитировать

  • ]]>Автор пишет: ]]>

    это и есть подводные камни ;) Однако проблема решается через min-width (кроме IE6 ессетственно). С другой стороны, кто смотрит сайты в таком маленьком окне? ;)

      Цитировать

  • ]]>gordi пишет: ]]>

    Согласен, что в %

    #canvas {
    width: 90%;
    margin: 20px auto;

    Но пример, чтобы в IE6(7) было идеально :)
    надо бы откорректировать.

    Этот прием знаю года два-три и с успехом использую на практике :)
    Хорошая вещь :)

      Цитировать

  • ]]>zxccc11 пишет: ]]>

    test22222

      Цитировать

  • ]]>Dune пишет: ]]>

    Экспериментировал.
    При добавлениее background-image со свойствами к блоку, допустим #item1, то в ie6 этот блок банально “пропадает”. В нормальных браузерах всё остаётся на месте.
    Исправляется добавлением фоновой картинки к подблоку sap-content, а не к #item1 (и иже с ним).

      Цитировать

  • ]]>gordi пишет: ]]>

    Dune: >Исправляется добавлением фоновой картинки к подблоку sap-content…<

    Этот контейнер вообще надо исключить из макета.
    А padding присвоить внутренним блокам: параграфу, спискам, любым другим блочным элементам.

      Цитировать

  • ]]>Автор пишет: ]]>

    sap-content как раз для того и есть чтобы отступы прописывать в одном этом блоке, а не у каждого внутреннего.

      Цитировать

  • ]]>gordi пишет: ]]>

    На любителя :)
    Но моя личная практика, говорит о том, что от этого контейнера лучше избавиться.
    К примеру будет у параграфа горизонтальный margin/padding отступы от колонок навигации станут больше.
    Кстати пример № 1, как раз это наглядно показывает.
    К тому же, чем меньше блоков в глобальной разметке тем лучше.

      Цитировать

  • ]]>tenshi пишет: ]]>

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

      Цитировать

  • ]]>tenshi пишет: ]]>

    а смотрю я, например, с кпк..

      Цитировать

  • ]]>Автор пишет: ]]>

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

      Цитировать

  • ]]>tenshi пишет: ]]>

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

    сделать вёрстку, опрятно выглядящую при низком разрешении – это одно. а убедить менеджера в необходимости уделять дополнительное время на “лайт версию” – это совершенно другое…

      Цитировать

  • ]]>Автор пишет: ]]>

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

      Цитировать

  • ]]>Ayavryk пишет: ]]>

    Если в блоке не будет всплывающих тултипов и пр. Иначе они попадут под overflow

      Цитировать

  • ]]>ko$tik пишет: ]]>

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

      Цитировать

  • ]]>Виктор пишет: ]]>

    блок-ячейка имеет дополнительный в

    лучше всего использовать псевдокласс :after {}

    вместо .class {overflow:hidden}
    можно сделать .class:after {clear:both; content:”"; display:bloc}
    прекрасно заменяет оверфлов)
    конечно иногда без оверфлов никак нельзя, но в большинстве случаев помогает

      Цитировать

Комментарии

Добавьте ваш комментарий, или трекбэк с сайта. Вы также можете подписаться на комментарии к этой статье через RSS.

Вы можете использовать теги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Чтобы получить аватарку, зарегистрируйтесь на Gravatar.