4.5 Subtemplates
The website is of course not finished once the basic layout is done: the content itself has yet to be arranged. Many pages require several short content sections next to each other - though we are not speaking of tabular data. And of course a traditional column layout does not always meet the demands of today's design: the YAML homepage itself (www.yaml.de) exemplifies a much freer use of content blocks.
For these purposes, YAML offers subtemplates. These are XHTML code snippets (based on nested floating DIV boxes) which allow a horizontal division of content within various containers or as an extremly flexible alternative/enhancement to the column-based layout concept.
Note: all the required CSS definitions for the subtemplates are found in the file base.css. The adjustments for the correct automatic clearing in Internet Explorer are in the file iehacks.css. Subtemplates are integrated in the basic components of the framework and are available to all YAML layout variations.
Subtemplates can also be nested within each other. This allows you to vary the column divisions in countless various ways.
Structural Composition
The structure of such a code snippet is easy to understand with an example. Below is the required XHTML code for a 50/50 split - a division into left and right blocks of equal size.
...
<!-- Subtemplate: 2 columns with 50/50 division -->
<div class="subcolumns">
<div class="c50l">
<div class="subcl">
<!-- left content block -->
...
</div>
</div>
<div class="c50r">
<div class="subcr">
<!-- right content block -->
...
</div>
</div>
</div>
...
You get the general idea: let's now take a look at the details.
The Container
A subtemplate always begins with a DIV container of the .subcolumns class, which encompasses the smaller individual containers that actually divide the space.
<!-- Subtemplate: 2 columns with 50/50 division -->
<div class="subcolumns">
...
</div>
The file base.css assigns the class .subcolumns the following CSS properties, which should not be changed.
/**
* @section subtemplates
* @see ...
*/
.subcolumns { width: 100%; overflow:hidden; }
.subcolumns_oldgecko { width: 100%; float:left; }
The container width is set as 100 percent by default, so that it completely fills the available horizontal space. Simultaneously, this definition activates the property hasLayout in Internet Explorer, forcing it to encompass the content within. All other browsers need the CSS property overflow:hidden (see Section 2.3: Markup-Free Clearing).
Note: Netscape browsers up to and including Version 7.1 as well as old Gecko browsers (up to about July 2004) have problems with the display of the subtemplates due to a bug in connection with overflow:hidden. Netscape's version 7.2 and up display subtemplates correctly.
If support of these older Gecko-based browsers is required, you can use the class .subtemplates_oldgecko instead. Please note the information in Section 5.3 on the Netscape overflow-Bug.
Dividing Space with DIV Blocks
DIV blocks with the CSS classes c50l and c50r divide the horizontal space. The "c" stands for column, the number "50" for 50 percent of the available width and the letters "l" and "r" for left- and right-floating blocks.
<!-- Subtemplate: 2 columns with 50/50 division -->
<div class="subcolumns">
<div class="c50l">
...
</div>
<div class="c50r">
...
</div>
</div>
In general, two blocks (a left and a right) form a pair. The sum of the widths of all blocks within a subtemplate should always equal 100%. The following division ratios are provided for as part of YAML's predefined CSS classes, e.g.:
- 50% / 50% Division (classes c50l and c50r)
- 33% / 66% Division (classes c33l and c66r as well as c66l and c33r)
- 25% / 75% Division (classes c25l and c75r as well as c75l and c25r)
- Golden Ratio (classes c38l and c62r as well as c62l and c38r)
All available classes are defined in the file base.css.
.c20l, .c25l, .c33l, .c40l, .c38l, .c50l,
.c60l, .c62l, .c66l, .c75l, .c80l {float: left; }
.c20r, .c25r, .c33r, .c40r, .c38r, .c50r,
.c60r, .c66r, .c62r, .c75r, .c80r {float: right; margin-left: -5px; }
.c20l, .c20r { width: 20%; }
.c40l, .c40r { width: 40%; }
.c60l, .c60r { width: 60%; }
.c80l, .c80r { width: 80%; }
.c25l, .c25r { width: 25%; }
.c33l, .c33r { width: 33.333%; }
.c50l, .c50r { width: 50%; }
.c66l, .c66r { width: 66.666%; }
.c75l, .c75r { width: 75%; }
.c38l, .c38r { width: 38.2%; }
.c62l, .c62r { width: 61.8%; }
The real width of a floating container is calculated by the browser just before it is rendered. The percentage values' conversion into pixels requires rounding. and Internet Explorer is sometimes less accurate than other browsers relating to the total width of all DIV blocks within a subtemplate.
The result is that the sum of the individual containers is greater than the width of the parent container .subcolumns, and the floating DIV boxes are displaced. To avoid this effect, all right-floating DIV blocks are assigned a margin-left: -5px. This allows any right-floating container to overlap an element to its left by a maximum of five pixels: an elegant compensation for the rounding errors.
Important: the compensation for these rounding errors demands exactly one right-floating container within each subtemplate.
These predefined CSS classes allow the following arrangements, even without nesting the subtemplates:
These blocks can be nested deep within each other simply by inserting further subtemplates. This allows nearly absolute freedom in the division of your columns.
The Content Containers
As in the layout columns of the YAML framework, the outer containers (here the DIV blocks c50l and c50r) set up the division of space, while the inner containers subc, subcl and subcr maintain the padding, margin, and border around the content.
<div class="subcolumns">
<div class="c50l">
<div class="subcl">
<!-- left content block -->
...
</div>
</div>
<div class="c50r">
<div class="subcr">
<!-- right content block -->
...
</div>
</div>
</div>
.subc { padding: 0 0.5em 0 0.5em; overflow: hidden; }
.subcl { padding: 0 1em 0 0; overflow: hidden; }
.subcr { padding: 0 0 0 1em; overflow: hidden; }
The final letters "l" and "r" stand for content blocks on the left or right side of the subtemplate. This influences the padding). For content blocks which are not on the side, such as the middle block of a 33/33/33 division, we have the container subc, which has padding on both sides.
The sum of the assigned paddings must always be identical for each block to guarantee that each column has exactly the same width.
The containers subcl and subcr on the sides are each assigned a padding of 1 em on the inner side. The container subc needs padding on both sides, which must total 1 em: it is assigned left and right paddings of 0.5 em each.
Adjusting the Subtemplates for Internet Explorer
The subtemplates use the CSS property float rather extensively. This means that we must deal with the corresponding IE bugs such as the Escaping Floats Bug and the Doubled-Float-Margin Bug -- and of course the Expanding Box Problem turns up when we work with flexible container widths.
Analogous to the bugfixes for the YAML basic layout, the bugfixes are also applied to the subcolumns.
.c20l, .c25l, .c33l, .c38l, .c40l, .c50l, .c60l,
.c62l, .c66l, .c75l, .c80l, .c20r, .c25r, .c33r,
.c38r, .c40r, .c50r, .c60r, .c66r, .c62r, .c75r, .c80r {
display:inline;
}
/* avoid growing widths */
* html .subc,
* html .subcl,
* html .subcr { word-wrap:break-word; o\verflow:hidden; }
The Escaping Floats Bug is taken care of when the container .subcolumns is provided with hasLayout via width:100%. The property display:inline defuses the Doubled-Float-Margin Bug, and word-wrap:break-word and overflow:hidden ensure that even the older IE generations (IE 5.x and IE 6) cut off oversized content elements and do not let them destroy the layout.
Note: the file iehacks.css sets the property word-wrap back to the standard value of word-wrap:normal for printing.
Examples for Subtemplates Use
The following examples show subtemplates used directly as well as nested. Read the source code carefully to understand exactly what's happening.
Note: You'll find further examples of subtemplate usage for content formatting and page layout in the layout examples, provided in the download package.
50 / 50 Split
Block 1: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. Aliquam ut sem ut leo mattis ultricies. Aliquam aliquam ligula ut purus. ...
Block 2: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. Aliquam ut sem ut leo mattis ultricies. Aliquam aliquam ligula ut purus. ...
33 / 33 / 33 Split
Divisions According to the Golden Ratio
Block 1: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. Aliquam ut sem ut leo mattis ultricies. Aliquam aliquam ligula ut purus. ...
Endless Variety with Nesting
Subtemplates can be endlessly nested within each other, allowing you countless various column divisions. The only requirement is that within each nesting level, the sum of the blocks' width must always be 100%.
The following example shows such a nesting. Within the left 50 percent block are two further 50 percent blocks. The right 50 percent block is further divided according to the Golden Ratio.
Special Case: Equal Height Boxes
Starting with version 3.1, YAML natively supports the creation of content containers of equal height - independent of their content - with pure CSS. The concept behind this bases on the markup of the subtemplates, but combined with several CSS layout concepts in order to ensure correct crossbrowser display.
Technical Background
In modern browsers with complete CSS2 support, the subtemplates are transformed into CSS tables. In Internet Explorer 5.x - 7.0 we must still use floating containers, extended with a CSS hack to simulate equally tall columns with the help of large paddings. This technique is explained at length by Alex Robinson in his "One True Layout" article.
The corresponding CSS rules for the combination of the various techniques are completely integrated in base.css and iehacks.css for easy access. Rules are tied to the CSS class equalize, which overwrites some of the properties of the normal subtemplates via the CSS cascade. Again, the technique is too complex to relate here.
In Practice
The creation of equal height boxes within YAML is very easy. You activate this property of the subtemplates merely by assigning the surrounding container the additional CSS class equalize. The characteristics are then handed down, so all nested subtemplates inherit the equal height.
<!-- Subtemplate: 2 columns with 50/50 division -->
<div class="subcolumns equalize">
...
</div>
(Kopie 1)
By assigning the CSS class .equalize, the column containers .cxxl and .cxxr are forced to the same height. The content containers .subcl, .subcr, and .subc do not change.
The following sample demonstrates the possibilities of this technique with three flexible boxes, lined up next to each other, with a decorated frame.
/examples/06_layouts_advanced/equal_height_boxes.html
Important: as a result of the techniques used for Internet Explorer 5.x - 7.0, neither elements nor background images can be absolutely positioned at the bottom of the equal height boxes.
Should this positioning be necessary for layout reasons, use the CSS class .no-ie-padding to deactivate the expansion of the containers in Internet Explorer. In this case, you as layout designer must ensure the equal height of your boxes -- either with content or by explicitly assigning a specific height.
The layout sample "equal height boxes" demonstrates how this complicated-sounding workaround functions in practice, by positioning the "more" links. For more information, read the source code of the sample layout.
