Holy Grail (web design)
||This article's introduction section may not adequately summarize its contents. (July 2014)|
|Cascading Style Sheets|
The Holy Grail is a multi-column web page layout. It is commonly desired and implemented, although the ways in which it can be implemented with current technologies all have drawbacks. Because of this, finding an optimal implementation has been likened to searching for the elusive Holy Grail.
Many web pages require a layout with multiple (often three) columns, with the main page content in one column (often the center), and supplementary content such as menus and advertisements in the other columns (sidebars). These columns commonly require separate backgrounds, with borders between them, and should appear to be the same height no matter which column has the tallest content. There are many obstacles to accomplishing this:
- CSS, although quite useful for styling, currently has limited capabilities for page layout.
- The height of block elements (such as div elements) is normally determined by their content. So two divisions, side by side, with different amounts of content, will have different heights unless their height is somehow set to an appropriate value.
- HTML is meant to be used semantically; the purpose of HTML tags is to describe the type of content inside them. The appearance of a web page as rendered by a user agent should be determined independently by style rules. Many implementations misuse HTML by using tables for non-tabular data, or nesting multiple div tags without semantic purpose. Non-semantic use of HTML confuses users or user agents who are trying to discern the structure of the page content, and is an accessibility issue.
- As search engines consider content in the beginning of a web page's source code to be more relevant, web designers desire the ability to place the content in the page source in an arbitrary order, without affecting the appearance of the page.
- Because of incorrect rendering of content by different browsers, a method that works in a standards-compliant browser may not work in one that does not implement CSS correctly.
Before the widespread implementation of CSS, tables were commonly used to lay out pages. Sometimes the layout required several tables to be nested inside each other. Although placing the columns inside table cells easily achieves the desired appearance, using a table is semantically incorrect (although the "role" HTML attribute can be set to "presentation" to regain semantic context). There is also no way to control the order of the columns in the page source.
Divisions with display:table
It is possible to make columns equal height using the CSS display property. This requires nested container divisions that are set to "display: table" and "display: table-row", and columns that are set to "display: table-cell". This is semantically correct, as only the display is affected. However, this will not work with older browsers such as Internet Explorer 7, and the method also lacks the ability to control the order of the source code.
This method uses a background image which provides the background colors and vertical borders of all three columns. The content of each column is enclosed in a division, and positioned over its background using floats, negative margins, and relative positioning. The background is normally only a few pixels high, and is made to cover the page using the "repeat-y" attribute. This works fine for fixed-width layouts, and can be adapted for percentage-based variable-width pages, but cannot be used for fluid center pages.
Fixed or absolute positioning
In this method, the corners of the column divisions are locked in a specific place on the page. This may be acceptable or even desired, but does not solve the holy grail problem as it is a significantly different layout. The consequences of this method may include having content appearing below the columns (such as a footer) fixed at the screen bottom, blank space under the column content, and requiring scrollbars for each column to view all the content.
Since a division will grow in height to contain its content, if this containing division is assigned a background, the background will be as tall as the content. This behavior is used to solve the problem by creating three divisions nested inside each other which provide the three backgrounds. These divisions are placed in their proper position using floats and relative positioning, and the three content divisions are placed inside the innermost background division, and positioned. The background divisions become as tall as the tallest content division. The drawbacks of this method include the three non-semantic divisions, and the difficulty of positioning the elements of this complex layout.
A simpler version of the nested division method entails using a single container division. The background properties of this division provides the background of the center column, and the left and right borders, which are given widths equal to the side column widths, provide the background colors of the sidebars.The content of each column is positioned over its background using floats and relative positioning. This method still uses one non-semantic division, and makes it difficult to apply background images and borders to the sidebars.
By placing a large amount of padding at the bottom of the column container, the background will extend far below the column content. A corresponding negative margin will bring content below the columns back into its proper position. Positioning is simple in this method, as the container of a column's content also contains its background. A padding value of 32767px is the largest that will be recognized by all modern browsers. If the difference in column heights is greater than this, the background of the shorter column will not fully fill the column.
The World Wide Web Consortium (W3C) has approached the layout issue through various proposals. As of September 2012, the flexible box module has reached candidate recommendation status, and has support in all current desktop and many mobile browsers (Webkit-based browsers and some other mobile browsers require prefix filters).
- .appendTo: Solving the Holy Grail Layout
- W3C: HTML5/Elements/Semantics
- Build Internet: Four Methods to Create Equal Height Columns
- A List Apart: Faux Columns
- W3C: Tableless Layout HOWTO
- Matthew James Taylor: Equal Height Columns with Cross-Browser CSS
- A List Apart: Articles: Multi-Column Layouts Climb Out of the Box
- Position is Everything: Equal Height Columns - revisited - In search of the One True Layout
- W3C: CSS Flexible Box Layout Module
- Can I use: Flexible Box Layout Module?
- W3C: CSS Grid Layout
- W3C: CSS current work & how to participate
- Can I use: CSS Grid Layout
- Google Code: css-template-layout
- W3C: CSS Regions Module
- .appendTo: Solving the Holy Grail Layout
- Holy Grail Layout — Solved By Flexbox — Cleaner, hack-free CSS
- BlueRobot: Three Column Flanking Layout
- Glish.com Layout Techniques - 3 columns, The Holy Grail