Как известно, существует 2 популярных способа верстки на основе блоков div: плавающая модель (float) и абсолютное позиционирование (absolute).
Каждый из них имеет свои плюсы и минусы. Eric Sol вместе со своей командой разработали новый способ позиционирования в CSS под названием «faux absolute positioning» – имитация абсолютного позиционирования.
Большинство дизайнов имеют колоночную структуру, т.е. шапку, 2-3 колонки и подвал. Используя только абсолютное позиционирование невозможно задать правила для подвала, т.к. его положение напрямую зависит от контента. С плавающей моделью тоже возникают сложности: блоки просто разваливаются, если их суммарная ширина будет больше 100%.
Задача команды Эрика была намного сложнее:
Мы должны были сделать конструктор форм, основанный на WYSIWYG, который позволял бы пользователю перетаскивать элементы в любую точку рабочей области. Необходимо было реализовать возможность создавать красивые формы, не использующие какие-то уже заданные статичные шаблоны, а чтобы пользователь мог располагать элементы формы как угодно относительно друг друга.
Ни один из стандартных способов позиционирования не помог реализовать эту задачу.
Тогда ребята стали экспериментировать и сделали, можно сказать, открытие:
В итоге, мы решили попробовать способ, основанный на вычислении левого отрицательного отступа относительно элемента с фиксированной позицией, в отличие от расчета величины его правого края относительно предыдущего элемента. Сделать это получилось с помощью комбинации свойств: 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х колоночный макет с фиксированным размером левой и правой колонок. Следует обратить внимание на следующие моменты:
- Левая и правая колонки имеют ширину в пикселях. Поэтому, мы не можем высчитать левый отступ для центрального блока, т.к. не знаем ширину рабочей области в процентах, так же как и ширину колонок в процентах от рабочей области. Решение будет простым: установим для главного блока свойства: margin-left: -100% и width: 100% и добавим padding чтобы получить отступы от колонок.
- Все 3 колонки отрисованы на одном уровне по оси Z, поэтому необходимо для левой и правой колонок прописать свойство z-index, например 100.
- Отступы для левой и правой колонок добавлены к дополнительному внутреннему блоку sap-content, и как говорилось выше, это обеспечивает гибкость работы с ним.
Пример 2 включает 5 колонок, в котором рабочая область, все строки и ячейки имеют ширину в процентах. Добавление изображений, границ и отступов не влияет на отрисовку и позиционирование блоков.
Преимущества метода
Новый способ позиционирования позволяет нам располагать элементы на заранее отведенное для них место, так же как и при абсолютном позиционировании, но все элементы будут следовать в одном потоке, друг за другом. Имитация абсолютного позиционирования имеет множество преимуществ наравне с версткой обычными методами. Каждая строка в сетке всегда будет _той же высоты_ что и центральная часть или той, что определена стилями, и всегда будет иметь 100% ширины, независимо от того сколько ячеек задано в колонке. Кроме того, способ позволяет избежать образования промежутков между элементами – и это большой плюс, т.к. в IE приходилось применять для этого css-фильтры (хаки) в блочной модели.
Еще одним преимуществом является то, что эта техника «смягчает» недостатки плавающей модели. Когда содержимое блока шире чем сам блок, то он толкает следующий блок вправо, а не сбрасывает его вниз. Содержимое блока может быть даже намного больше своего родителя – это никак не скажется на структуру нашего макета. (в этом помогает правило overflow: hidden).
И самое главное – новая техника абсолютно валидна HTML 4.01 и CSS 2.1 и отрицательное значение margin-left одинаково воспринимается всеми браузерами! Больше никаких хаков! К тому же, модель подойдет как для дизайнов с фиксированной, так и 100% шириной, и позволяет работать с одинаковыми высотами колонок, при этом имеющих фиксированную либо % ширину. Имитация абсолютного позиционирования может даже использоваться рекурсивно, т.е. позволяет использовать ячейки как строки с новыми ячейками – как при верстке с использованием table.
Подводные камни
Техника имитации абсолютного позиционирования представляет собой шаблонную сетку, таблицу, и скорее пригодна для сложных макетов. Поэтому если ваш дизайн состоит из двух колонок, то эта техника, скорее всего, вам не понадобиться.
Кроме того, есть ситуации, в которых техника не будет работать. Если вы хотите расположить элементы друг за другом, вы не можете использовать единицы измерения, отличные от той, в которых указана ширина рабочей области, иначе вы просто не сможете рассчитать необходимый отрицательный отступ. Например, у вас есть рабочая область шириной 800px и вы хотите сделать левый отступ в 2em для вашей ячейки, но вы не рассчитаете значение отступа, т.к. не знаете сколько em в 800 пикселях.
Еще одно замечание: когда элемент становиться больше предшествующего элемента согласно html коду, то этот прицепной элемент будет сдвинут вправо на величину равную разнице в ширине между первым элементом и рабочей областью.
Т.к. техника эта новая и еще неопробованная пользователями, то, наверняка, отроются еще и другие ее секреты, как положительные, так и отрицательные. Но приведенные примеры уже доказывают, что новая техника практически замещает нелюбимые нами таблицы и прекрасно подходит для шаблонов на сетке.