CSS static and relative positioning
Contents [hide]
1 Introduction
2 The wonderful world of rectangles
3 Static positioning
3.1 Block box layout
3.2 Inline box layout
4 Relative positioning
4.1 Multi-column layout with source order requirements
4.1.1 Making columns
4.1.2 Working around quirks in Internet Explorer
4.2 Other uses for relative positioning
5 Summary
6 Exercise questions
Introduction
In this Web Standards Curriculum article I’ll start looking in depth at how you can use CSS to position HTML elements wherever you want on the page, using the position CSS property and some related properties.
The position property in CSS has four legal values (in addition to the ubiquitous inherit): static, relative, absolute and fixed. These values have a significant impact on how an element is rendered. The two values static and relative are closely related, and we’ll look into those in great detail in this article. The values absolute and fixed are also closely related, and I’ll save those for the next article in the series.
The wonderful world of rectangles
Now for a bit of a recap on CSS and HTML boxes, as discussed in my [floats and clearing article]. An HTML document consists of a number of elements interspersed with character data (text). When such a document is rendered on a computer screen or printed on paper, those elements generate rectangular boxes. Just as the set of HTML elements is divided into block-level elements and inline elements, boxes in CSS are essentially either block boxes or inline boxes.
By default, the built-in user agent style sheet in a browser makes block-level HTML elements such as p and div generate block boxes, while inline elements such as strong and span generate inline boxes. We can control the type of box that is generated using the display property.
The boxes generated by the elements in a document are laid out according to a clearly defined set of rules in the CSS2.1 specification. Those rules are written for the relatively few people who write browser software to learn how CSS works though, not for those of us who design web pages for a living—or a hobby. This is why this entire course exists! As a result, the specification can be a bit difficult to understand. In this article I’ll try to explain the basics in a way that is better suited for web designers and developers.
Static positioning
This is really a misnomer. Boxes with position:static are not really “positioned” at all in the CSS sense. They are simply laid out in the order they occur in the markup and take up as much room as they need—this is the default behavior you get when you don’t apply any CSS at all to your HTML.
There are fundamental differences in how block boxes are laid out compared to how inline boxes are laid out, so let’s examine the two types one at a time. I’ll start with block boxes, because they are simpler.
Block box layout
Unless we apply any specific CSS declarations, block boxes are laid out vertically from top to bottom in the order they occur in the markup. Each box is normally as wide as the document (the body element), but even if we make them narrower they will not be laid out side by side even if there’s room; they’ll still be laid out one below the other. You can think of it as if each block box had an implicit line break before and after it, to make sure it ends up on a “line” of its own.
The vertical distance between two block boxes is controlled by the margin-bottom property of the first box and the margin-top property of the second box (you’ve seen how to manipulate these earlier in the course). For boxes in the normal flow, ie boxes that aren’t floated or absolutely positioned, the vertical margins between two adjacent block boxes will collapse—overlap—so that the net result is not the sum of the two margins, but the greater of the two, as seen in Figure 1 below.
Consider the following HTML fragment:
This paragraph has a 40px bottom margin.
This paragraph has a 20px top margin.
When viewed in a browser, the margins collapse, as shown in Figure 1.
Figure 1: The margins collapse—the distance between the two is 40px, not 60px.
A block box will either contain only other block boxes or only inline boxes. If a block-level element contains a mix of block-level and inline children—which is permissible, although semantically questionable’so-called anonymous block boxes will be generated to encompass the inline child boxes, so that the parent only contains block boxes.
You can specify the dimensions of a block box using the width and height properties. You can also set both vertical and horizontal margins on them. The initial (default) value for width and height is auto, and the initial value for margin properties is . These factors in combination mean that a block box will by default be as wide as its parent, as illustrated in Figure 2.
Figure 2: Block boxes are laid out vertically.
Inline box layout
This section may be difficult to understand if you’re new to CSS, but don’t despair if you don’t get it the first time you read it. Experimenting a little on your own is probably the best way to get a solid understanding of these issues—just make sure that you’re using a good, standards-compliant browser when testing, such as Opera or Firefox.
Inline boxes are generated by default by inline HTML elements, but there are also anonymous inline boxes generated to encompass the text content of elements. The inline boxes are laid out horizontally, one after the other, in the order in which they occur in the markup. Depending on the direction property, the inline boxes will either be laid out from left to right (direction:ltr ) or from right to left (direction:rtl ).
Left-to-right direction is used with, for instance, European languages, while right-to-left direction is used with languages such as Arabic and Hebrew. The set of inline boxes that make up one line on the screen (or paper) are enclosed in yet another rectangle, known as a line box. Line boxes are laid out vertically within their block-level parent, with no space between them. We can affect the height of line boxes through the line-height property.
For inline boxes we cannot specify any dimensions. We can specify horizontal margins, but not vertical margins. If necessary, an inline box will be split into several inline boxes, distributed over two or more line boxes. When such a split occurs, any horizontal margins and padding, and any vertical borders, will only apply before the first box and after the last box. Consider a document with the following rule for em elements:
em {
margin: 0 2em;
padding: 0 1em;
border: 1px dotted blue;
}
This will give you a layout somewhat like that seen in Figure 3, when the styled elements are broken over multiple lines.
Figure 3: Margins, padding and border do not apply where breaks occur.
The vertical alignment of inline boxes within the encompassing line box is determined by the vertical-align property. The default value is baseline, which means that the inline boxes are aligned so that their text baselines line up. The baseline is the imaginary line on which letters without descenders stand. It is placed some distance above the bottom of the line box to leave room for the descenders of lowercase letters, as shown in Figure 4.
Figure 4: Letters stand on the imaginary baseline.
Note that the vertical-align property applies to inline boxes and table cells only, and it isn’t inherited. Figure 5 shows some small images with different vertical alignment.
Figure 5: Images placed using settings of the vertical-align CSS property.
When the total width of the inline boxes within a line box is less than the width of the line box itself, the horizontal alignment is controlled by the text-align property. With text-align:justify, extra space is inserted between the inline boxes, if necessary, to make the content both left- and right-justified. This property applies to block boxes, table cells and inline blocks, and it is inherited—Figure 6 shows the result of applying different values of the text-align property to text inside table cells.
Figure 6: Controlling the alignment of text using the text-align property.
Relative positioning
Relative positioning is a positioning scheme in CSS, but it is more closely related to static “positioning” than with its cousins—absolute and fixed positioning. An element with position:relative is first laid out just like any static element; block-level or inline. But then something interesting happens: the generated box is shifted according to the top, bottom, left and right properties.
The thing to remember about relative positioning is that it’s only the generated box that is shifted. The element still remains where it was in the static document flow. That’s where it “takes up space” as far as other elements are concerned. This means that the shifted box may end up overlapping other elements’ boxes, because they still act like the relatively positioned element has remained where it should be, before the positioning was applied. As far as the document flow is concerned, the element has not moved—it is just the end visual result that shows the box being moved. Let’s look at it in practice.
Copy the HTML code below into a new document in your favourite text editor and save it as relative.html.
Relative Positioning
Lorem ipsum dolor sit amet consectetuer adipiscing elit.
Curabitur feugiat feugiat purus.
Aenean eu metus. Nulla facilisi.
Pellentesque quis justo vel massa suscipit sagittis.
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos.
Quisque mollis, justo vel rhoncus aliquam