
Layout: two blocks of the same height
- From the sandbox
- Tutorial
Task
Two block elements are specified - one with the text of the article (75% of the width of the document), the other with a list of links for navigating the first element (25%, located to the left of the first block). The height of the element containing the article is set dynamically, depending on the content of the block with text. It is necessary to make sure that the second block with navigation has the same value of the height parameter as the first containing the main text of the article.
Technical Specification
Previously, similar tasks were solved using the TABLE-TR-TD family of table tags, but this approach violated the principle of separating the data structure in the markup (HTML) from the way they were stylized (CSS), since the data itself by the nature of the information presented was not at all tabular, but only used a similar tabular display method on the page:
...перечень a-href ссылок...
..содержимое статьи...
Later, the CSS standard was expanded with additional table, table-cell values for the display parameter, which allowed us to use the usual DIV, SPAN elements in the html-structure of the page layout and set appropriate css rules for them to display in the form of a table with columns reporting in percentage terms as in width and in height:
...содержимое статьи...
#wrapper {
display: table;
}
#navigation, #content {
display: table-cell
}
It would seem that the problem was solved, but unfortunately, this approach did not work in older versions of browsers (IE 6, IE 7) forcing coders to look for other approaches. The solution with the help of nested wrapper elements that offset relative to each other allows achieving a visual effect of equal height columns:
...содержание...
#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;
}

The role of the columns here is performed by wrapping tags (# bg-one, # bg-two) the number of which duplicates the tags with content embedded in them (#content, #navigation). This technique works even in IE 6, but its significant drawback is the need to add a large number of additional elements (# bg-one, # bg-two) wrapping tags with column text (#content, #navigation). The number of such wrapper elements (# bg-N) is equal to the number of actual block tags with columns of text. In the above example, to add another column (say #advertisement) at the same level as #navigation and #content, you have to add another common wrapping element bg-three:
..содержание статьи....
...рекламные объявления...
#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;
}

In this case, the html markup is noticeably complicated - the reason for the presence of wrapping tags is not obvious. Thus, abandoning html-tables due to poor readability of the markup, we come to even less readable code. The situation can be improved by moving the wrapping tags one level with the columns:
...содержание статьи...
#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;
}

In this case, the elements with the background (# navigation-bg, # content-bg) are located in front of the tags containing the column text, which significantly improves the understanding of the markup. But unfortunately IE 6 does not understand the percentage values specified in the height parameter for block elements with absolute positioning, and for more recent versions of browsers support the display: table rule, which avoids additional div elements containing the background of the columns (in the example above # content-bg , # navigation-bg).
Decision
Reading the task, it becomes noticeable that the markup of the text with an eye to the subsequent application of the display: table css rule also contains one extra tag:
...содержание статьи...
#wrapper {
display: table;
}
.shakespeare {
display: table-cell;
background-color: #f0f0f0;
}
Indeed, in this case, the dependence of the column height is bidirectional, that is, the height of the block specified by the nav tag depends on the height of the block specified by the article tag and vice versa - the article block depends on the height of the nav block. Although in this case only the height of the nav block should be adjusted to the height of the longer article tag, the inverse relationship is superfluous:
..содержание статьи
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;
}

Percentage values for absolute elements as well as display: table work in the IE browser starting with only the eighth version. The values of the width and length of the aside block are taken from the calculation relative to the size of the article block, since in CSS the coordinates and dimensions of the element with absolute are counted starting from the first parent element with a non-static (relative, absolute, fixed) value of the position parameter. That is, the width of the article block (which is 75% of the width of the document) for the aside container is 100%, making up the proportion:
75% - 100%
25% - ?
we get
25% * 100% / 75% = 33.33%
That is 25% of the free screen in the percentage of the article block.
Thus, we can get rid of the extra wrapper element, display the dependence of one column on another in the code and not resort to the table positioning method for non-table data.