I'm a fixed position element! Quack!

Positioning elements using CSS

Positioning and changing the order in which elements come will be the source of more confusion and headaches while building a web page than any other stylistic problem.

Let's try to approach the subject from the most general settings to the more specific. Firstly, we have to take into account exactly *how* an element is being drawn on the page as opposed to *where*, which will involved the "display" property.

Display

The "Display" property can be thought of as a property to define how an element interacts with those around it that supercedes "position".

There are actually quite a few values that can be used with the display property so let's just look at the most common and important.

  • Block
    Elements set to "block" will display in vertical stacks and allow you to define width and height properties. This is similar to the default display mode.
  • Inline
    This value is similar to a floating element in that it will allow elements to stack horizontally. It differs in that it constricts the size of the element to whatever is contained within. Width and height properties will be ignored (but margin and padding are not). For instance, all of the elements in the example to the right have both their height and width properties defined, but only the large green square which has its display property set to "block" is using them. The "Inline" rectangles take their size and shape from the contents (in this case the word "Inline" itself).
Inline
Inline
Inline
Block
Inline
Inline
Inline
  • Table
    Normally tables are drawn differently than other elements. You can assign those qualities of tables (such as automatic centering) to other elements by changing their display property to Table.
  • None
    If you want to completely remove an element from both display and the flow of the page then "none" will do just that. It's a way of removing an object from consideration while leaving it in memory. This is useful for scripted interfaces that might hide and show images in the same place or removing elements from a list via script.

You may have also seen the visibility property which has values such as "visible" (the default) and "hidden" which hides the element, and be wondering what the difference is between that and the "none" value of the display property.

Difference from "visibilty"

To the right are five elements and below are their cooresponding properties. Notice the difference between the square with a display of "none" and the square with a visibility of "hidden".

  1. display : block ; visibility : visible ;
  2. display : none ; visibility : visible ;
  3. display : block ; visibility : visible ;
  4. display : block ; visibility : hidden ;
  5. display : block ; visibility : visible ;

As you can see the square with a "Display" property of "none" might as well not exist while the square with a "visibility" property of "hidden" continues to take up the space it normally would, just without being seen.

1
3
4
5

Position

While "display" is not a required property for styling elements, any element you want to change the position of will typically require a position property. The position property has 6 different properties.

  • Static
    This is the default value.
  • Relative
    This value allows the directional properties to move the element *from the point* of the natural position but *leaves it within* the flow of the page.
  • Absolute
    "Absolute" will allow you to define the *exact* position of an element under its parent. Absolutely positioned elements DO NOT interact with other elements on their same level (under their parent) and need position properties of some kind such as "left" or "top".
  • Fixed
    Setting a "fixed" values will remove the element from the flow of the document and keep it in a constant position within the window as defined by the top, left, etc. values.

    The bird you were so desperately trying to ignore is a fixed element. It does not matter how far down you scroll, he will always be there, watching you. Waiting.
  • Inherit
    Will take the property of the immediate parent.
  • Initial
    Sets the position value to the browser's default setting.

In reality, the vast majority of elements you define will only make use of two of these values; "relative" and "absolute". Sometimes "fixed" for menus, logos or social link items.

Let's look at the most widely used values first.

Static

Elements will be shown in order. The flow of the document will simply appear as the first element, then the seccond, and third, and so on.

As with any property that has a "default" value. You do not actually have to enter the value. It exists only to override the effects of predefined "catch all" selectors that might have been applied to an element. This means there is no difference between the following two possibilities.


.one {
    position:static;
    width:100px;
    height:100px;
    background-color:red;
}

.two {
    width:100px;
    height:100px;
    background-color:red;
}

Relative

Imagine you had a site where it was acceptable to leave all the elements at their default value of "static". But in actual rendered it appeared that one element was just a pixel or two misaligned from the others. The "relative" value would allow you to offset them to fix that.

If a button is too close to the left side of the screen then changing the position to "relative" and adding a "left" value of "10px" would space the button 10 pixels from the left of its original position.

To the right you see 10 boxes in their natural vertical position and in the order their elements are written in. Only one is misaligned. All boxes share following CSS.


.shared {
	position:relative;
	width:50px;
	height:50px;
	margin:2px;
	border:1px solid black;
	background-color:lightblue;
	text-align:center;
	line-height:50px;
}

The only property to take note of is the position property. Note that none of them have "left" or "top" properties at all. Because of that they are appearing as they naturally would in order from top to bottom.

Box no. 3 however, has additional CSS, which does contain a "left" and "top" property.


	left:20px;
	top:10px;

You can see how this is causing displacement from the natural flow of things. The key thing to realize is that it is not displacing the boxes around it. These two properties are only moving the visible location of the box they have been applied to.

If you want an element to actually move other elements around it then you'll want to use a margin. For instance box no. 7 has the following property/value added...


	margin-top:20px;

Because of this box no. 7 is not only farther down from its natural position but it is also pushing down every element that comes after it.

1
2
3
4
5
6
7
8
9
10

Absolute

In this case the element is allowed to move around, and the position of it will be based on the previous element, but it will not change the flow of the document itself. That means that any non-absolute (or floated) element that comes after it will be allowed to fill the space the "absolute" element should have taken up.

Let's look at a visual comparing both "relative" and "absolute" again.

Here we have two sets of rectangular shapes. First lets look at the natural order of three rectangles within one larger one. All three of them, the blue, the green, and the grey, have a position value of "relative" and have no "left" or "top" values set.

Now lets see what happens when we change the position values of a few properties for the second version. The key points in the second set of squares are as follows...

  • The positions of all of these objects are relative to the red square because they are children of it.
  • The blue square *would* be against the upper left corner of the red square but it has been given "left" and "top" properties with values of "20px" which are pushing it down.
  • The green square is in its natural position under the *natural* position of the blue square, and *not* where the blue square visibly sits. It is only overlapping the blue square because the blue square's "top" property has pushed it down.
  • The grey square is no longer anywhere near where it used to be. The "position" property for it has set to "absolute" it is no longer affecting, or being affected by, the other squares *next* to it. At all. And with a "left" of 100 and "top" of 40 it is now being manually positioned near the top right of the pink square.
Relative
Relative
Relative

Relative
Relative
Absolute

For some students new to web design it is tempting to just set all elements to absolute and position them exactly. This approach actually works fine until you require elements of variable size. If at any time you do not know the total length of the content of an element (pretty much any time you have long passages of text for instance) then you run the risk of not allocating enough space for that content.

Fixed

As noted, when an element is fixed it will adhere to a particular place within the view window (the browser itself), such as the title bar at the top of this very page.

There are a few quirks that are introduced with the use of "fixed" however.

Fixed elements will have their starting position altered by elements around them, but will not alter the starting position of those same elements. In other words they can be pushed, but they will not push in return.

This changes several behaviors. For instance the "auto" margin trick for centering elements will not work on fixed elements. Instead of trying to apply auto margins to the fixed element apply them to a container for the fixed element and then position the fixed element based on that like so...


<style>
    .fixed_container{
        position:relative;
        width:800px;
        margin-left:auto;
        margin-right:auto;
    }
    .fixed {
        position:fixed;
        width:800px;
        height:50px;
        background-color:blue;	
    }
</style>
    
<div class="fixed_container">
    <div class="fixed"></div>
</div>

It does not matter that the fixed element is a child of a non-fixed element, it will still "escape" the parent element when you scroll the page.

Floating elements

The phrase "floating" can be kind of misleading as it might create the image of elements floating over each other like clouds. Or maybe above each other as if on water. Neither are really good examples.

When an element is "floated" it essentially remains within the flow of the document, pushing aside elements around it, but is moved up to fill empty space it may have above it. Basically "floating" allows you to fill horizontal space where normal HTML thinks to only fill vertical space.

This is useful for two main reasons.

  1. When making horizontal navigation menus.
  2. When you think there's a good chance the user might zoom in or out on their page (such as a pag with a lot of fine text) and you don't want the content to go beyond the page border that has been zoomed out.

Let's look at actual examples.

The blue blox to the left of this text has a "float" property with a value of "left". The red box to the right has a "float" property with a value of "right". Other elements, like this text, can now fill in the space around them. This is obviously useful for inserting pictures or text within a text block that is related, but not directly so, to the information you are conveying.

Keep in mind a few principles.

  • Any element can be floated.
  • If there is no room for an element to wrap against your floated object then it will automatically position itself under the floated element.
  • When floating an element inside text, make sure to watch the height dimensions of the element, or you might get too much of a margin on the lower side.
  • Remember that floated objects are *REMOVED* from the flow of the page. Meaning that if they are the only child in a containing div or the last children within a div, they will not actually take up space, and will seem to extend beyond the bottom of the parent div.

Floating is also one way of getting objects to sit next to each other horizontally as oppposed to the default vertical placement. Here are 10 blocks which ALL have a float property with a value of "left". On top of that, however, two of them have been given a property of "clear" with a value of "left".

clear
clear

The "clear" property is a way of resetting the float position. It has 3 main values in itself.

  • "Left", where the element to the left of this one will not float elements after it.
  • "right", where the element to the right of this one will not float elements after it.
  • "both", where the elements on either side of this one will not float elements around it.

Margin & Padding

The main thing to remember about Margins and Padding is of course that, while they both add space around the element, the "margin" property will make that space clear while the "padding" property will use the background color or image of the element itself. Otherwise they are very similar.

Take for example the boxes below. These boxes is a visual representation of the difference between padding and margins.

Below are three boxes as they would normally appear where all properties are similar except the padding / margin values. Take note of two things for each box; the proximity of the box to the red line above it, and of the distance of the content (the text) from the edge of the box itself.

width:200px;
height:100px;
width:200px;
height:100px;
20px padding
width:200px;
height:100px;
20px margin

In this case since we used the generic "margin" and "padding" so the value of "20px" was added to all sides of that box.

So keep in mind that like many elements they are directional. Just "margin" by itself will apply the given value to all sides. We can apply a margin to just one side by using the "margin-left", "margin-right", "margin-top", "margin-bottom" or any combination of these.

The "padding" property follows the same structure.

The Z-index Property

The z-index property doesn't really define position as other properties like "position" or "float" might. It does not change the horizontal or vertical position of an element. Instead it defines the "depth" of an element. This means that it dictates whether or not that element is drawn over or under elements that it overlaps on the screen.

The basics of z-index are as follows.

  • If not defined, the default z-index value of all elements is "auto", which will be the same value of its parent.
  • Z-index values do NOT have to come in order. You can define any integer you want for them. One element can have a value of "10" and the next a value of "1000". Whats important is that you not lose track of your values or else you'll have an increasingly complex logic puzzle on your hands.
  • The key thing to remember about z-index is that if an element has a z-index defined then all of its children will be subject to that level.

To the right are three copies of the same HTML objects. Remember that the light blue box is a child of the dark blue box. Like so.


<div id="blue">
    <div id="lightblue"></div>
</div>
<div id="red"></div>
<div id="green"></div>

Notice that when there is no z-index defined for any of the boxes that they are drawn on the screen in their natural order.

  1. blue box
  2. light blue box
  3. red box
  4. green box

But when we start to add z-index properties for each we can change this natural order. The z-index value is noted in each of the boxes to the right.

In the second version nothing has happened. Even though the light blue box has a higher z-index value than any of the other three boxes it still remains below the pink and green boxes. This is because its parent is on the same level as the pink and green boxes.

The third examples is more interesting. Here we have the light blue box above the red but not above the green. This is because the parent dark blue box has been given an index of "1", placing both it and all of its children above the red box but below the green box.

The fourth set of boxes shows that when a parent is left undefined, and when a child is given a negative value for the index, then you can actually get a child to appear *behind* he parent. Since the green box has a value of "-2" it is rendered behind the light blue child.

The labels below represent that elements z-index value.
Undefined
Undefined
Undefined
Undefined
"0"
"20"
"0"
"0"
"1"
"3"
"0"
"2"
"Undefined"
"-1"
"0"
"-2"