Tuesday 10 September 2013

Detailed Positioning - Part1

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. <div class="box-set">
  2. <div class="box">Box 1</div>
  3. <div class="box">Box 2</div>
  4. <div class="box">Box 3</div>
  5. </div>
CSS
  1. .box-set {
  2. background: #e8eae9;
  3. }
  4. .box {
  5. background: #8ec63f;
  6. height: 100px;
  7. float: left;
  8. margin: 10px;
  9. width: 200px;
  10. }

Containing Floats Demo

BOX 1
BOX 2
BOX 3
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 theoverflow 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. .box-set {
  2. background: #404853;
  3. overflow: auto;
  4. }

Overflow Technique Demo

BOX 1
BOX 2
BOX 3
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

BOX 1
BOX 2
BOX 3

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 :beforepseudo-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. .box-set:before,
  2. .box-set:after {
  3. content: "";
  4. display: table;
  5. }
  6. .box-set:after {
  7. clear: both;
  8. }
  9. .box-set {
  10. *zoom: 1;
  11. }

Clearfix Technique Demo

BOX 1
BOX 2
BOX 3

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. .group:before,
  2. .group:after {
  3. content: "";
  4. display: table;
  5. }
  6. .group:after {
  7. clear: both;
  8. }
  9. .group {
  10. *zoom: 1;
  11. }

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.