Lesson 2
Detailed Positioning
When it comes to building layouts and positioning content on a page there are a handful of different techniques to use. Which technique to use largely depends on the content and the goals of the page, as some techniques may be better than others.
For example, the ability to float elements side by side provides a nice, clean layout that is receptive to the different elements on a page. However, when more strict control is needed, elements may be positioned using other techniques, including relative
or absolute
positioning.
In this lesson, we’ll start by taking a look at how to contain floats. Following that, we’ll cover more detailed positioning techniques, including how to precisely position elements on both the x
and y
axis as well as the z
axis.
Containing Floats
Floating elements is a natural process when building a website’s layout, and is the instinctive method for positioning elements on a page. Floats allow elements to appear next to, or apart from, one another. They provide the ability to build a natural flow within a layout and allow elements to interact with one another based on their size and the size of their containing parent.
When floated, an element’s position is dependent on the other elements positioned around it. Will that element run into the one next to it? Will it appear on a new line? This all depends on the DOM (Document Object Model) and what surrounds an element.
What is the DOM?
The DOM, or Document Object Model, is an API for HTML and XML documents which provides their structural representation. In our case, we are speaking specifically to HTML documents, thus the DOM represents all of the different elements and their relationship to each other.
The representation can be considered a tree of sorts, with each element having a different relationship with those around it. Elements nested inside others have a parent and child relationship while elements that share the same parent have a sibling relationship.
While floats do provide quite a bit of fire power, they do come with a few of their own problems. The most popular problem involves a parent element that contains numerous floated elements. Content on the page will respect the size and placement of the floated children element, but these floated elements no longer impact the outer edges of the parent container. In this event the parent element loses context of exactly what it contains and collapses, thus giving the parent element a height
of 0
and ignoring various other properties. A lot of times this may go unnoticed, specifically when the parent element doesn’t have any styles tied to it and the nested elements look to have aligned correctly.
Should the nested elements not line up correctly, styling errors may appear. Taking a look at the demo below, the .box-set
division should have a light gray background, however the background is not seen as all of the elements nested within it are floated. Upon inspecting the .box-set
division you will see it has a height
of 0
.
HTML
1
2
3
4
5
6
<div class="box-set">
<figure class="box">Box 1</figure>
<figure class="box">Box 2</figure>
<figure class="box">Box 3</figure>
</div>
CSS
1
2
3
4
5
6
7
8
9
10
.box-set {
background: #eaeaed;
}
.box {
background: #2db34a;
float: left;
margin: 1.858736059%;
width: 29.615861214%;
}
Containing Floats Demo
See the Pen Containing Floats by Shay Howe (@shayhowe) on CodePen.
One way to force containing these floats would be to place an empty element just before the parent elements closing tag, of which would need to include the style declaration clear: both;
. Clearing the floats this way works and is valid in most cases, but it isn’t exactly semantic. Depending on how many different floats need to be cleared on a page the number of empty elements can begin to stack up quickly, while not providing any real contextual value to the page.
Fortunately there are a couple of different techniques we can use to contain these floats, the most popular of which include the overflow technique and the clearfix technique.
The Overflow Technique
One technique for containing floats within a parent element is to use the CSS overflow
property. Setting the overflow
property value to auto
within the parent element will contain the floats, resulting in an actual height
for the parent element, thus including a gray background in our example.
For this to work within Internet Explorer 6 a height
or width
is required on the parent element. Since the height
may likely be variable a width
of 100%
will do the trick. Using overflow: auto;
in Internet Explorer on an Apple computer will also add scrollbars to the parent element, in which it is better to use the overflow: hidden;
declaration.
1
2
3
4
.box-set {
overflow: auto;
}
Overflow Technique Demo
See the Pen Overflow Technique by Shay Howe (@shayhowe) on CodePen.
Using the overflow technique does come with a few drawbacks. For example, when adding styles or moving nested elements that span outside of the parent, like when trying to implement box shadows and dropdown menus. In the demonstration below, you can see how the box shadow is being cut off wherever it lies outside the parent element. Additionally, the second box is cropped outside of the parent element.
Different browsers treat the overflow
property differently, and thus could also implement scrollbars in different fashions here too. Look at the example below in different browsers, noticing how the columns display differently in each browser.
Overflow Pitfall Demo
See the Pen Overflow Pitfall by Shay Howe (@shayhowe) on CodePen.
The Clearfix Technique
Depending on the context of the floated elements a better technique to contain floats may be the clearfix technique. The clearfix technique is a bit more complex but does have better support as compared to the overflow technique.
The clearfix technique is based off using the :before
and :after
pseudo-elements on the parent element. Using these pseudo-elements we can create hidden elements above and below the parent containing the floats. The :before
pseudo-element is used to prevent the top margin of child elements from collapsing by creating an anonymous table-cell element using the display: table;
declaration. This also helps ensure consistency within Internet Explorer 6 and 7. The :after
pseudo-element is used to prevent the bottom margin of child elements from collapsing, as well as to clear the nested floats.
Adding the *zoom
property to the parent element triggers the hasLayout
mechanism specifically within Internet Explorer 6 and 7, which determines how elements should draw and bound their content, as well as how elements should interact with and relate to other elements.
Taking the same example from above you can see how the floats are contained and the elements are able to live outside of the parent element.
1
2
3
4
5
6
7
8
9
10
11
12
.box-set:before,
.box-set:after {
content: "";
display: table;
}
.box-set:after {
clear: both;
}
.box-set {
*zoom: 1;
}
Clearfix Technique Demo
See the Pen Clearfix Technique by Shay Howe (@shayhowe) on CodePen.
Effectively Containing Floats
Which techniques to use boils down to the content at hand and your personal preference. Some people prefer to stick strictly with the clearfix technique as it is consistent across the board. Others feel the clearfix technique is a bit too much code in some cases and prefer a mix of techniques based on the content. What you decide to use is up to you, just make sure it is well documented and easily identifiable either way.
One common practice is to assign a class to the parent element which includes the floats needing to be contained. Using the clearfix technique for example, Dan Cederholm helped coin the class name group
. The group
class name can then be applied to any parent element needing to contain floats.
1
2
3
4
5
6
7
8
9
10
11
12
.group:before,
.group:after {
content: "";
display: table;
}
.group:after {
clear: both;
}
.group {
*zoom: 1;
}
Single Pseudo-Elements
It is worth noting only one :before
and one :after
pseudo-element are allowed per element, for the time being. When trying to use the clearfix technique with other :before
and :after
pseudo-element content you may not achieve the desired outcome.
In the examples above, the clearfix styles would not live under the box-set
class. Instead, the class of group
would need to be added to the parent element containing the floats.
Position Property
Occasionally you need more control over the position of an element, more than a float can provide, in which case the position
property comes into play. The position
property accepts five different values, each of which provide different ways to uniquely position an element.
Position Static
Elements by default have the position
value of static
, meaning they don’t have, nor will they accept, any specific box offset properties. Furthermore, elements will be positioned as intended, with their default behaviors.
In the demonstration below, all the boxes are stacked one on top of the other as they are block level elements and are not floated in any specific direction.
HTML
1
2
3
4
5
6
7
<div class="box-set">
<figure class="box box-1">Box 1</figure>
<figure class="box box-2">Box 2</figure>
<figure class="box box-3">Box 3</figure>
<figure class="box box-4">Box 4</figure>
</div>
CSS
1
2
3
4
5
6
7
8
9
.box-set {
background: #eaeaed;
}
.box {
background: #2db34a;
height: 80px;
width: 80px;
}
Position Static Demo
See the Pen Position Static by Shay Howe (@shayhowe) on CodePen.
Position Relative
The relative
value for the position
property is very similar to that of the static
value. The primary difference is that the relative
value accepts the box offset properties top
, right
, bottom
, and left
. These box offset properties allow the element to be precisely positioned, shifting the element from its default position in any direction.
How Box Offset Properties Work
The box offset properties, top
, right
, bottom
, and left
, specify how elements may be positioned, and in which direction. These offset properties only work on elements with a relative
, absolute
, or fixed
positioning value.
For relatively positioned elements, these properties specify how an element should be moved from its default position. For example, using a top
value of 20px
on a relatively positioned element will push the element 20 pixels down from where it was originally placed. Switching the top
value to -20px
will instead pull the element 20 pixels up from where it was originally placed.
For elements using absolute
or fixed
positioning these properties specify the distance between the element and the edges of its parent element. For example, using a top
value of 20px
on an absolutely positioned element will push the element 20 pixels down from the top of its relatively positioned parent. Switching the top
value to -20px
will then pull the element 20 pixels up from the top of its relatively positioned parent.
While the relative
position does accept box offset properties the element still remains in the normal, or static, flow of the page. In this case other elements will not impede on where the relatively positioned element was originally placed. Additionally, the relatively positioned element may overlap, or underlap, other elements without moving them from their default position.
In the demonstration below you will notice that the elements are still stacked on top of one another, however they are shifted from their default positions according to their individual box offset property values. These values cause the boxes to overlap one another, yet do not push each other in different directions. When an element is positioned relatively the surrounding elements will observe the relatively positioned elements default position.
HTML
1
2
3
4
5
6
7
<div class="box-set">
<figure class="box box-1">Box 1</figure>
<figure class="box box-2">Box 2</figure>
<figure class="box box-3">Box 3</figure>
<figure class="box box-4">Box 4</figure>
</div>
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.box-set {
background: #eaeaed;
}
.box {
background: #2db34a;
height: 80px;
position: relative;
width: 80px;
}
.box-1 {
top: 20px;
}
.box-2 {
left: 40px;
}
.box-3 {
bottom: -10px;
right: 20px;
}
Position Relative Demo
See the Pen Position Relative by Shay Howe (@shayhowe) on CodePen.
In the event that the top
and bottom
box offset properties are both declared on a relatively positioned element, the top
properties will take priority. Additionally, if both the left
and right
box offset properties are declared on a relatively positioned element, priority is given in the direction in which the language of the page is written. For example, in English pages the left
offset property is given priority, and for Arabic pages the right
offset property is given priority.
Position Absolute
Absolutely positioned elements accept box offset properties, however they are removed from the normal flow of the document. Upon removing the element from the normal flow, elements are positioned directly in relation to their containing parent whom is relatively or absolutely positioned. Should a relatively or absolutely positioned parent not be present, the absolutely positioned element will be positioned in relation to the body
of the page.
Using absolutely positioned elements and specifying both vertical and horizontal offset properties will move the element with those property values in relation to its relatively positioned parent. For example, an element with a top
value of 50px
and a right
value of 100px
will position the element 50 pixels down from the top of its relatively positioned parent and 100 pixels in from the right of its relatively positioned parent.
Furthermore, using an absolutely positioned element and not specifying any box offset property will position the element in the top left of its closest relatively positioned parent. Setting one box offset property, such as top
, will absolutely position the element vertically but will leave the horizontal positioning to the default value of flush left.
In the demonstration below you can see how each box is absolutely positioned in relation to the parent division, of which is relatively positioned. Each individual box is moved in from a specific side with a positive value, or pulled out from a specific side with a negative value.
HTML
1
2
3
4
5
6
7
<div class="box-set">
<figure class="box box-1">Box 1</figure>
<figure class="box box-2">Box 2</figure>
<figure class="box box-3">Box 3</figure>
<figure class="box box-4">Box 4</figure>
</div>
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.box-set {
background: #eaeaed;
height: 200px;
position: relative;
}
.box {
background: #2db34a;
height: 80px;
position: absolute;
width: 80px;
}
.box-1 {
top: 6%;
left: 2%;
}
.box-2 {
top: 0;
right: -40px;
}
.box-3 {
bottom: -10px;
right: 20px;
}
.box-4 {
bottom: 0;
}
Position Absolute Demo
See the Pen Position Absolute by Shay Howe (@shayhowe) on CodePen.
When an element has a fixed height
and width
and is absolutely positioned, the top
property takes priority should both the top
and bottom
offset properties be declared. As with the relatively positioned elements, should an element with a fixed width
have both the left
and right
box offset properties, priority is given to the direction of which the language of the page is written.
If an element doesn’t have a specific height
or width
and is absolutely positioned, using a combination of the top
and bottom
box offset properties displays an element with a height spanning the entire specified size. Same goes for using both the left
and right
box offset properties, resulting in an element with a full width
based on both of the left
and right
box offset properties. Using all four box offset properties will display an element with a full specified height and width.
Position Fixed
Using the positioning value of fixed
works just like that of absolute
, however the positioning is relative to the browser viewport, and it does not scroll with the page. That said, elements will always be present no matter where a user stands on a page. The only caveat with fixed
positioning is that it doesn’t work with Internet Explorer 6. Should you want to force fixed
positioning within Internet Explorer 6 there are suitable hacks.
Using multiple box offset properties with fixed
positioning will produce the same behaviors as an absolutely positioned element.
Keeping the same box offset properties from the previous demonstration, watch how the boxes are positioned in relation to the browser’s viewport and not the containing, relatively positioned parent.
HTML
1
2
3
4
5
6
7
<div class="box-set">
<figure class="box box-1">Box 1</figure>
<figure class="box box-2">Box 2</figure>
<figure class="box box-3">Box 3</figure>
<figure class="box box-4">Box 4</figure>
</div>
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.box {
background: #2db34a;
height: 80px;
position: fixed;
width: 80px;
}
.box-1 {
top: 6%;
left: 2%;
}
.box-2 {
top: 0;
right: -40px;
}
.box-3 {
bottom: -10px;
right: 20px;
}
.box-4 {
bottom: 0;
}
Fixed Header or Footer
One of the most common uses of fixed
positioning is to build a fixed header, or footer, anchored to one side of a page. As a user scrolls the element stays prevalent, always within the viewport for users to interact with.
The code and demonstration below outline how this may be achieved. Notice how both left
and right
box offset properties are declared. This allows the footer
to span the entire width of the bottom of the page, and it does so without disrupting the box model, allowing margins, borders, and padding to be applied freely.
HTML
1
2
<footer>Fixed Footer</footer>
CSS
1
2
3
4
5
6
7
8
9
10
11
body {
background: #eaeaed;
}
footer {
background: #2db34a;
bottom: 0;
left: 0;
position: fixed;
right: 0;
}
Fixed Footer Demo
See the Pen Fixed Footer by Shay Howe (@shayhowe) on CodePen.
Z-Index Property
By nature web pages are often considered to be two dimensional, displaying elements upon a x
and y
axis. However when you begin to position elements they are occasionally placed on top of one another. To change the order of how these elements are stacked, also known as the z-axis, the z-index
property is to be used.
Generally, elements are positioned upon the z-axis as they appear within the DOM. Elements coming at the top of the DOM are positioned behind elements coming after them. Changing this stacking using the z-index
property is pretty straight forward. The element with the highest z-index
value will appear on the top regardless of its placement in the DOM.
In order to apply the z-index
property to an element, you must first apply a position
value of relative
, absolute
, or fixed
. The same as if you were to apply any box offset properties.
In the example below, without the z-index
property each box will be positioned precisely, starting with box two sitting on top of box one, then box three sitting on top of box two, and so forth. Reordering the stacking with the z-index
property now positions box two on top of every other box, followed by box three underneath it, and box four underneath box three.
HTML
1
2
3
4
5
6
7
<div class="box-set">
<figure class="box box-1">Box 1</figure>
<figure class="box box-2">Box 2</figure>
<figure class="box box-3">Box 3</figure>
<figure class="box box-4">Box 4</figure>
</div>
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.box-set {
background: #eaeaed;
height: 160px;
position: relative;
}
.box {
background: #2db34a;
border: 2px solid #ff7b29;
position: absolute;
}
.box-1 {
left: 10px;
top: 10px;
}
.box-2 {
bottom: 10px;
left: 70px;
z-index: 3;
}
.box-3 {
left: 130px;
top: 10px;
z-index: 2;
}
.box-4 {
bottom: 10px;
left: 190px;
z-index: 1;
}
Resources & Links
- All About Floats via CSS-Tricks
- A New Micro Clearfix Hack via Nicolas Gallagher
- CSS Positioning 101 via A List Apart
- A Detailed Look at the z-index CSS Property via Impressive Webs