Задача
Заданы два блочных элемента – один с текстом статьи (ширина 75% от ширины документа), другой с перечнем ссылок для навигации по первому элементу (ширина 25%). Высота элемента содержащего статью задается динамически, в зависимости от наполнения блока текстом. Необходимо сделать так, что бы второй блок с навигацией обладал таким же значением параметра высоты как и первый содержащий основной текст статьи.
Техническое уточнение
Ранее подобные задачи решались с помощью TABLE-TR-TD семейства табличных тэгов, но такой подход нарушал принцип отделения структуры данных в разметке (markup — HTML) от способа их стилизации (styling — CSS), поскольки сами данные по характеру представленной информации вовсе не были табличными, а только использовали сходный табличному метод отображения на странице:
<table> <tr> <td id=”navigation”> ...перечень a-href ссылок... </td> <td id=”content”> ..содержимое статьи... </td> </tr> </table>
Позже стандарт СSS был расширен дополнительными значениями table, table-cell для параметра display, что позволило использовать привычные DIV, SPAN элементы в html-структуре разметки страницы и задавать для них соответствующие css-правила для отображения в виде таблицы с колонками сообщающимися в процентном соотношении как по ширине так и по высоте:
<div id=”wrapper”> <div id=”navigation”> ...перечень a-href ссылок... </div> <div id=”content”> ...содержимое статьи... </div> </div>
#wrapper { display: table; } #navigation, #content { display: table-cell }
Казалось бы задача была решена, но к сожалению, такой подход не работал в старших версиях браузеров (IE 6, IE 7) заставляя верстальщиков искать другие подходы. Довольно распространенным стало решение с помощью вложенных элементов-оберток смещение которых относительно друг-друга позволяет добиться визуального эффекта равных по высоте колонок:
<div id="bg-one"> <div id="bg-two"> <div id="navigation"> ...перечень a-href ссылок... </div> <div id="content"> ...содержание... </div> </div> </div>
#navigation, #content { position: relative; float: left; left: -50%; } #navigation { width: 50%; } #bg-one, #bg-two { position:relative; float: left; width: 100%; background-color: #9988ff; } #bg-one { overflow: hidden; } #bg-two { left: 50%; background-color: #99ff99; }
Роль колонок здесь выполняют обертывающие тэги (#bg-one, #bg-two) количество которых дублирует вложенные в них тэги с контентом (#content, #navigation). Такая техника работает даже в IE 6, но ее ощутимым недостатком является необходимость добавления большого количества дополнительных элементов (#bg-one, #bg-two) обертывающих тэги с текстом колонок (#content, #navigation). Количество таких элементов оберток (#bg-N) равно количеству фактических блочных-тэгов с колоноками текста. В приведенном выше примере для добавления еще одной колонки (скажем #advertisement) на одном уровне с #navigation и #content придется добавить еще один общий обертывающий элемент bg-three:
<div id="bg-one"> <div id="bg-two"> <div id="bg-three"> <div id="navigation"> ..перечень ссылок a href... </div> <div id="content"> ..содержание статьи.... </div> <div id="advertisement"> ...рекламные объявления... </div> </div> </div> </div>
#navigation, #content, #advertisement { position: relative; float: left; left: -64%; } #navigation,#content { width: 32%; } #bg-one, #bg-two, #bg-three { position: relative; float: left; width: 100%; background-color: #9988ff; } #bg-one { overflow: hidden; } #bg-two { left: 32%; background-color: #99ff99; } #bg-three { left: 32%; background-color: #a0a0a0; }
В таком случае html-разметка заметно усложняется – причина наличия обертывающих тэгов неочевидна. Таким образом отказываясь от html-таблиц из-за плохой читабельности разметки мы приходим к еще менее читабельному коду. Ситуацию можно улучшить если перенести обертывающие тэги на один уровень с колонками:
<div id="wrapper"> <div id="navigation-bg"></div> <div id="navigation"> ..перечень ссылок с a href.. </div> <div id="content-bg"></div> <div id="content"> ...содержание статьи... </div> </div>
#wrapper{ position: relative; float: left; width: 100%; } #navigation, #content { position: relative; float: left; width: 50%; } #navigation-bg { position: absolute; left: 0; width: 50%; height: 100%; background-color: #ffaaaa; } #content-bg { position: absolute; left: 50%; width: 50%; height: 100%; background-color: #aaffaa; }
В таком случае элементы c фоном (#navigation-bg, #content-bg) расположены перед тэгами содержащими текст колонок, что заметно улучшает понимание разметки. Но к сожалению IE 6 не понимает процентных значений заданных в параметре высоты для блочных элементов с абсолютным позиционированием, а для более свежие версии браузеров поддерживают display: table правило, которое позволяет избежать добавочных div-элементов содержащих фон колонок (в примере выше #content-bg, #navigation-bg).
Решение
Читая задание становится заметным что разметка текста с прицелом на последующие применение css-правила display: table, также содержит один лишний тэг:
<div id=”wrapper”> <nav class=”shakespeare”> ...перечень ссылок... </nav> <article class=”shakespeare”> ...содержание статьи... </article> </div>
#wrapper { display: table; } .shakespeare { display: table-cell; background-color: #f0f0f0; }
Ведь в таком варианте зависимость высоты колонок двунаправлена, то есть высота блока заданного тэгом nav зависит от высоты блока заданного тэгом article и наоборот — блок article зависит от высоты блока nav. Хотя в данном только высота блока nav должна подстраиваться под высоту более длинного тэга article обратная зависимость является лишней:
<article> <aside> ...перечень ссылок... </aside> ..содержание статьи </article>
article { position: relative; width: 75%; left: 25%; background-color: #fafafa; } aside { position: absolute; width: 33%; left: -33%; height: 100%; background-color: #f0f0f0; }
Процентное значения для аболютных элементов также как и display: table работают в браузере IE начиная только с восьмой версии. Значения ширины и длины блока aside берутся из пересчета относительно размеров блока article, так как в CSS координаты и размеры элемента с абсолютным отсчитывается начиная с первого родительского элемента с нестатичным (relative, absolute, fixed) значеним параметра position. То есть ширина блока article (которая составляет 75% от ширины документа) для aside контейнера равна 100%, составляя пропорцию:
75% - 100% 25% - ?
получаем
25% * 100% / 75% = 33.33%
То есть 25% свободного экрана в процентном соотношении блока article.
Таким образом мы можем избавиться от лишнего wrapper элемента, отобразить зависимость одной колонки от другой в коде и не прибегать к методу табличного позиционирования для нетабличных даных.
ссылка на оригинал статьи http://habrahabr.ru/post/183542/
Добавить комментарий