Monday, September 28, 2015

CSS LAYOUT TUTORIAL - Absolute Positioning - PART 1

In this article, we're going to learn about absolute positioning in CSS.

What is absolute positioning?
Absolute positioning is a CSS layout technique that allows you to move an element to a precise location by supplying values known as offsets.

For example:

Here, I am using absolute positioning to place the paragraph 53 pixels away from the left edge and 107 pixels away from the top edge of the browser's viewport. This was done by adding a left offset of 53 pixels, and a top offset of 107 pixels.

Let's see how this works by creating our own example. Copy the code below and save it as an HTML document.
<!DOCTYPE html>

<html lang="en">

<head>

 <meta charset="utf-8">

 <title>Absolute Positioning</title>

 <style type="text/css">

  h1 {
   margin: 0;
   background-color: blue;
  }

 </style>

</head>

<body>

 <h1>Heading</h1>

 <p>This is a paragraph.</p>

 <h1>Another heading</h1>

</body>

</html>
What we have here is a basic html page that contains a heading, followed by a paragraph, followed by another heading. And if you take a look at the head element, you will see that there is a style sheet that contains a style rule for the h1 element that sets the margins to 0 and the background color to blue.

So if you view the page in the browser, it will look like this:

NOTE: The existing margins that you see are from the default html, body, and paragraph margins. But the h1 elements themselves have 0 margins.

Now let's go ahead and create a style rule for the paragraph so that we can position it absolutely. To do that, we use the CSS position property and give it a value of absolute. Other values are static, fixed, and relative, but we won't talk about those in this lesson.

So go back to the code and add this new style rule:
p {
 position: absolute;
}
We've just specified a position of absolute for the paragraph style rule, but we haven't added any offsets yet. The offsets are what will change the element's position. We'll add that later. For now, save the document and refresh your browser.

Now, even though we haven't added any offsets yet, we should see some changes just by adding the position:absolute property. The browser should display something like this:

You'll notice that the 2 headings no longer have any space in between them. This is why I added the background color and removed the margins for the h1 elements. I wanted you to clearly see the effect once position:absolute was added. It may look strange, but this is exactly what's supposed to happen when you apply a position of absolute to an element - the element will be taken out of the document's normal flow. Before we added an absolute position to the paragraph, the normal flow was:
  1. heading
  2. followed by the paragraph
  3. followed by another heading
But now that the paragraph was taken out of the normal flow, the new normal flow is now:
  1. heading
  2. followed by another heading
Basically, an element that's taken out of the normal flow will still be visible, but will be ignored by the other elements that still flow normally. That's why the headings are now adjacent to each other. We still see the paragraph, but the headings that used to surround it are now ignoring the space that the paragraph is supposed to be taking up, because to them, the paragraph is no longer part of the normal flow.

So remember: absolutely positioned elements are taken out of the normal flow.

Now that we've demonstrated that, let's go ahead and remove the heading elements, as well as the h1 style rule. So now, the style sheet should look like this:
<style type="text/css">

 p {
  position: absolute;
 }

</style>
And the body should look like this:
<body>

 <p>This is a paragraph.</p>

</body>
And now let's move on to offsets.

Setting the position property to absolute is not quite useful on its own. We'll also need to specify offset values so that we can move the element to a new location. But before we do that, let's set some more properties for the paragraph style:
p {
 width: 200px;
 height: 200px;
 margin: 0;
 padding: 0;
 background-color: aqua;
 position: absolute;
}
Here, I've specified a content area of 200px by 200px, a background color of aqua, and 0 margins and padding. I'm adding these because I want the paragraph to visually stand out more in order to better illustrate the paragraph's position.

Now we're ready to add offsets to our absolutely positioned paragraph. We have the option to add a horizontal offset and a vertical offset. To add a horizontal offset, use either the left or the right property. You'll have to choose just one. You cannot use both on the same element. To add a vertical offset, use either the top or bottom property. You can only choose one as well. You can, however, combine a horizontal and vertical offset. So in those cases, the possible combinations are:
  • top and left
  • top and right
  • bottom and left
  • bottom and right
Go back to the style sheet, and give the paragraph a top offset of 10px and a left offset of 10px:
p {
 width: 200px;
 height: 200px;
 margin: 0;
 padding: 0;
 background-color: aqua;
 position: absolute;
 top: 10px;
 left: 10px;
}
The effect here is that the left edge of the paragraph will be 10 pixels away from the left edge of the browser's viewport, and the top edge of the paragraph will be 10 pixels away from the top edge of the browser's viewport.

NOTE: The offset takes into account the BOX edge of the absolutely positioned INNER element. In this case, the inner element is the paragraph. But since the paragraph has no margins, padding, and borders, then the CONTENT edge is the same as the box edge (see CSS Box Model for a review on this).

Now what happens if we change the offset properties to bottom and right.
p {
 width: 200px;
 height: 200px;
 margin: 0;
 padding: 0;
 background-color: aqua;
 position: absolute;
 bottom: 10px;
 right: 10px;
}
If we do this, then the BOTTOM edge of the paragraph will be 10 pixels away from the BOTTOM edge of the browser's viewport, while the RIGHT edge of the paragraph will be 10 pixels away from the RIGHT edge of the browser's viewport:

You can also specify an offset of 0.
p {
 width: 200px;
 height: 200px;
 margin: 0;
 padding: 0;
 background-color: aqua;
 position: absolute;
 bottom: 0;
 right: 0;
}
In this case, the bottom and right edges of the paragraph will hug the bottom and right edges of the browser's viewport:

Now let's set the offsets back to 10 pixels for both the top and the left:
p {
 width: 200px;
 height: 200px;
 margin: 0;
 padding: 0;
 background-color: aqua;
 position: absolute;
 top: 10px;
 left: 10px;
}
And then let's add a margin of 10 pixels:
p {
 width: 200px;
 height: 200px;
 margin: 10px;
 padding: 0;
 background-color: aqua;
 position: absolute;
 top: 10px;
 left: 10px;
}
This will result in a 20 pixel space in between the top edge of the viewport and the top edge of the paragraph. Same thing goes for the space in between the left edges:


Now keep in mind that the offset for each side is still 10 pixels each, and that the increase in space is simply a result of the added margins.

It's also important to note that in this example, the paragraph is completely ignoring the html and body elements in terms of how it's positioned. What I mean is that if we changed properties such as the width, height, margins, padding, and borders of the html and body elements, they will NOT affect the position of the paragraph whatsoever. Try adding margins and padding to the html and body elements, and you'll see that the paragraph's position will not change:
html {
 margin: 20px;
 padding: 30px;
} 

body {
 margin: 5px;
 padding: 40px;
}
Preview your webpage after adding these new style rules, and you'll see that the paragraph stays in the same place. Also try adding width, height, and borders. You'll see that the paragraph's position will remain unchanged.

So right now, we see that the paragraph is positioning itself based only on the viewport's edges. None of its other ancestor elements (html and body) are influencing its position whatsoever. The reason for this is because none of the paragraph's ancestors are positioned. In other words, none of them have a position property in their style rules that says absolute, relative or fixed (note that I am intentionally omitting the value of static). And if it is the case that a positioned element has no other positioned ancestors, then the positioned element positions itself based on the viewport.

NOTE: A static position is the default. It is the normal way in which elements are positioned. Saying that an element's position is static is the same as saying that an element is NOT positioned.

So what happens if a positioned element has ancestors that are also positioned? In those cases, the position of the inner element will NOT be based on the viewport. Instead, its position will be based on the positioned ancestor that is NEAREST to it (nearest in the HTML code, not nearest in terms of layout position). And we'll take a look at some examples of that in a future post.

No comments:

Post a Comment