Pull to refresh

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

Reading time 5 min
Views 51K

Задача


Заданы два блочных элемента – один с текстом статьи (ширина 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;                                                            
  display: block;
  width: 75%;                                                                    
  left: 25%;                                                                     
  background-color: #8888FF;                                                     
}                                                                                
                                                                                 
aside {                                                                          
  position: absolute;                                                            
  display: block;
  width: 33%;                                                                    
  left: -33%;                                                                    
  height: 100%;                                                                  
  background-color: #F88888;                                                     
}     


Процентное значения для аболютных элементов также как и 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 элемента, отобразить зависимость одной колонки от другой в коде и не прибегать к методу табличного позиционирования для нетабличных данных.
Tags:
Hubs:
+5
Comments 16
Comments Comments 16

Articles