Верстка: два блока одинаковой высоты

от автора

Задача

Заданы два блочных элемента – один с текстом статьи (ширина 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *