Page Layout Using CSS


CSS works best when it is used to specify the visual properties of html content. It does not do a particularly great job with page layout and seems to be a bunch of hacks, rather than resting on any elegant principles. Further, different browsers seem to interpret CSS differently and IE in particular often requires work arounds. As a result I actually prefer doing layouts using tables because it works off one principle, which is nesting of tables.

Nevertheless, CSS is increasingly being used to do page layout. It is primarily meant to do horizontal layout. If you need to do vertical alignment of block content, such as centering one element with respect to another, you probably need to use tables. At some point you will encounter the vertical-align attribute and think that it is just what you need. However, it works only with images in in-line text, not with arbitrary elements. Similarly you will see hacks for horizontally centering block elements using margin-left and margin-right. These hacks will not work in the vertical direction.


Use div instead of table for doing horizontal layout

  1. CSS does not have the concept of a table.
  2. You can think of the div element as a cell within a table and you can then use CSS style instructions to specify the postion of the div block.
  3. You can nest div blocks, much as you might nest tables


Types of CSS Layouts

  1. Fixed width: Designer specifies the width of the page and it will always be that width, regardless of the resolution of the display. The outermost block, such as body, will have a width set equal to some number of pixels. Within the layout you can still use % to apportion screen space among elements.

    1. Small displays may not be able to fully display the page and the user may have to scroll left and right to view it
    2. Large displays may have white space. The page may either be centered or left-justified.
    3. Format will probably get messed up if user increases the browser's base font size.

  2. Liquid: Adjusts to the browser's size.

    1. Content will get re-sized as the browser window increases or decreases in size.
    2. Designer can specify that some elements are fixed width. Remaining varible-sized elements will re-size.
    3. Lengths are usually specified with % rather than px
    4. Liquid displays can be quickly converted to a fixed display by wrapping a fixed with div element around the whole content of the page.

  3. Elastic: Fixed-width design with font size flexibility.
    1. Define page's size with em values
    2. If user re-defines browser's base font size then all elements of the page will decrease or increase proportionately
    3. Ensures that all elements retain their relative size and position
    4. If browser window is resized to be bigger than the fixed width of the design, the content will not expand to fill the extra space (it will be left-justified or centered depending on the browser and there will be some type of background color that fills the empty space). However, if the user changes the base font size and there is additional room into which the content can expand, then it will. For example, if the fixed width is 750 pixels and the browser window is 1000 pixels, then the content can expand by up to 250 pixels to accommodate bigger font sizes.

Floating Versus Absolute Positioning

Orthogonal to the issue of whether you used a fixed or liquid display is whether you specify the position of an element or give the browser a general direction about where you wish it to appear:

  1. floating layout: the float property gives the browser general directives about where to place elements (e.g, left or right but not top/bottom because CSS is only set-up to do horizontal layout) but leaves it up to the browser to assign absolute positions

  2. absolute positioning layout: the position property tells the browser exactly where to position an element. The position property defines the following values:
    1. fixed: The position of the element is absolutely fixed in the browser window and will stay there, even if you scroll down. Good for content that should always appear in a window, such as a navigation bar or faux frames.
    2. absolute: Sets an absolute location relative to your parent element. You will be ignored in the page layout calculations and you will not leave a big gaping hole in the layout.
    3. relative: Like absolute except that you will be included in the page layout calculations and you will leave a "hole" where you should have been positioned if relative were not used. relative is typically used to re-set a location in preparation for the use of absolute.


Float Layout Basics

  1. Use the float property to float an element
    1. Moves the element to one side of the page. Any html that appears below the floated element moves up on the page and wraps around the float.
    2. Values are left, right, and none
    3. floated elements should typically have a width property.
    4. Example:
      #sidebar {
        float: left;
        width: 170px;
      }
      

  2. Pg. 283 of CSS: The Missing Manual, Fig 11-4 shows a nice example of html source order and CSS page layout

  3. Wrap columns in div's in order to float them
  4. Add margins for main content: if two columns are not the same height, then content from one may flow under the other.
    1. Add a left margin or right margin to the main column to ensure that any excess content does not flow under the sidebar.
    2. The margin should be a few pixels wider than the width of the sidebar, in order to create a whitespace "gutter" of a few pixels
    3. Example:
      .main {
        margin-left: 180px;
      }
        
  5. Do not use a width for the main column. It should use any space that the remaining columns do not consume.
  6. Since column heights are often unequal, you may need to use a hack to get the background color for a column to extend all the way to the bottom of the page. You can do this by creating an image with the desired color, then load it using the background-image property and set the background-repeat property to repeat-y.
  7. Sometimes you will wrap columns within columns to achieve desired effects, such as temporarily splitting a column into two columns.
  8. Float drops: If the width of a page becomes too small to accommodate all the floating columns, then the rightmost column will get dropped. Float drops can be partially avoided by not trying to use every last pixel on the page. There are enough rounding errors using %'s and differences among the browsers that you will often get a float drop if you try to use 100% of the page. You may not be able to prevent float drops if you specify that some columns have fixed pixel widths and use a liquid design, because those columns will always want to have those widths, even if the page width becomes smaller than the column width.
  9. Clearing floats: Sometimes you do not want the content that follows a floated element in an html file to be wrapped around it. In that case you can specify the clear property in the succeeding element. The values for clear are left, right, and both. Specifying left will cause an element's contents to drop below a left floated element, specifying right will cause an element's contents to drop below a right floated element, and specifying both will ensure that the element drops below all floated elements that precede it.

Absolute Positioning

  1. When you specify absolute positioning via the position attribute, you should also specify the position of the element using the left, right, top, and bottom elements.

    1. If you specify both left/right or top/bottom, then you are implicitly also specifying the width/height of the element. You can also control its location and size by specifying just one of left or right and a width, or one of top or bottom and a height. IE 6.0 and earlier has issues to bottom and right so you're often better off just using top and left.
    2. It is okay to specify negative values for the location properties, in which case you will "pop" outside its enclosing box.
  2. Overlapped objects and the z-index property: When you float elements, the browser will ensure that they never overlap. When you specify the position of an element, it is possible that that element will overlap another element.
    1. Normally the stacking order of elements is determined by their position in the source html file, with later occurring elements stacked on top of earlier occurring elements.
    2. You can change the stacking order of elements using the z-index property. Elements with larger z-index values will appear on top of elements with lower z-index values.
    3. The z-index property only works with absolutely positioned elements (i.e., elements that use the position property).
    4. Floating elements have an implicit z-index value of 0, so negative z-index values place absolutely positioned elements beneath floating elements and 0 or greater values place them above floating elements, irrespective of their position in the file.
    5. Example: Consider the following specification and content: <html> <head> <style type="text/css"> img { position:absolute; left:0px; top:0px; z-index:-1; } </style> </head> <body> <h1>This is a heading</h1> <img src="/images/w3css.png" width="100" height="140" /> <p>Because the image has a z-index of -1, it will be placed behind the text.</p> </body> </html> Note how the image is placed between two floating elements and that it overlaps both floating elements. Setting its z-index to a negative value causes the image to appear under the floating elements and setting the z-index to a positive value causes the image to appear above the floating elements. Specifically setting the z-index of the image to 0 still causes it to cover both floating elements, despite the fact that it appears before one and after the other in the html source.


Setting the Size of Elements

  1. You can use the width and height properties to control the width and height of an element's content. These properties do not control the width and height of the padding, margin, and border, only the element's content, so remember to take the values of the other properties into account when calculating the total width/height of your element.

  2. If you do not specify the width/height properties, the browser will display the content at its "natural" width and height. For text this means that it will typically stretch to fit the size of the parent element and for an image it means that the element will display at its natural width and height.

  3. You can use the overflow property to control what happens when an element's content exceeds the dimensions of the element. The values are:

    1. visible: The overflow is not clipped. It renders outside the element's box and will possibly overlap other content. This is the default value.
    2. hidden: The overflow is clipped, and the rest of the content will be invisible.
    3. scroll: The overflow is clipped, but a scroll-bar is added to see the rest of the content. In Safari, both a horizontal and vertical scroll-bar are added, even if one is not needed. You will see less content because the scroll-bars are displayed inside the content area.
    4. auto: If overflow is clipped, the browser should add a scroll-bar to see the rest of the content. Scroll-bars are added only when necessary, and only in the dimension in which they are necessary.


Aligning Content

CSS provides support for aligning in-line content via the text-align and vertical-align attributes. However, it does not provide easy support for aligning block-level elements. Things are made more complicated by the fact that some early versions of IE treat block-level elements as in-line elements for the purposes of page layout. This means that you have to do both in-line and block-level page formatting to align block-level elements and have the alignment be supported by all the major browsers. As a reminder, if you want to do vertical layout, you will need to use the html table element. CSS has a display property with values for table, table-row, and table-cell that is supported by Firefox 2+, Safari 3+, and IE8. However, the lack of support in IE means that you should still use the old html table element for vertical formatting.


Horizontal Centering

For horizontal formatting you can set the margin property to auto (or margin-left and margin-right to auto if you need to do something else with the top and bottom margins) and on Firefox and Safari the margins will be equally spaced, and hence the block-level element will be centered:
.center
{
margin-left:auto;
margin-right:auto;
width:70%;
}
Note that you have to set the width to less than 100% or else the content will fill the entire allotted space, so there will be nothing to center.

This trick does not always work on IE since it may treat an element as in-line content. You can also get centering on IE by wrapping a block in an additional wrapper that uses "text-align: center" in order to center an in-line element. You have to be careful to reset the text-align element in the inner block so that the content within the block is properly aligned (i.e., just because you center the block does not mean you also want the content within the block centered). Here's a way to do centering that works in all major browsers:

.container
{
  text-align:center;
}
.center
{
  margin-left:auto;
  margin-right:auto;
  width:70%;
  text-align:left;
}

<div class="constainer">
  <div class="center">
    content
  


Horizontal Centering in Columns

The above trick works for horizontal centering across an entire page. If you want to horizontally center an element within a column, then you need to wrap the above "container" div in yet another div. The reason is that the auto value will cause the margins to suck up all the remaining space allotted to the parent element, and will not allow another item to float next to this element. Hence you have to define a parent block that will take up only an allotted portion of the display (e.g., 50%), and then specify that the "center" div take up some allotted portion of the parent's block (e.g., 70%). For example:

.left-column {
  width: 50%;
  float: left;
}

<div class="left_column">
<div class="container">
<div class="center">
  content
</div>
</div>
</div>

Comprehensive Example

Here is a comprehensive example that shows how you sometimes have to use nested divs to get the formatting outcome that you desire. Suppose I want to create the two column web page shown below:

The content in the left column is centered within the left column with 10% margins on each side. I have made the background of the left column red to illustrate that the left column is wider than its centered content. The gif in the right column has been floated to the right. Here are some issues I faced when trying to create this web-page:

  1. If I used the left-alignment idiom discussed earlier in these notes, then the left column wants to take up the entire page. Hence I have to embed the text in a .left-col div that is floated left and whose width is set to 45%.

  2. I want the right column to be floated to the right so I create a div named .right-col to float its content to the right. Unfortunately, within this column, the image naturally appears on the left unless I create a style rule for images within .right-col that float them to the right. Hence I created the ".right-col img" selector to do just that.
Here is the style-sheet and html content I created to get my desired formatting: <html> <head> <style type="text/css"> <!-- Create the outer column wrappers --> .col-left { background-color: red; width:45%; float :left; } .col-right { width: 45%; float: right; } <!-- float images within the right column to the right --> .col-right img { float: right; } <!-- container div to handle inline objects in IE --> .container { text-align:center; } <!-- centering div to handle centering in the left column --> .center { margin-left:auto; margin-right:auto; width:80%; background-color:#b0e0e6; text-align:left; } </style> </head> <body> <div class="col-left"> <div class="container"> <div class="center"> <p>In my younger and more vulnerable years my father gave me some advice that I've been turning over in my mind ever since.</p> <p>'Whenever you feel like criticizing anyone,' he told me, just remember that all the people in this world haven't had the advantages that you've had.'</p> </div> </div> </div> <div class="col-right"> <img src="/images/w3css.png" width="100" height="140" /> Here is a w3 schools image that is floated to the right side of the page by nesting it within a div to create a right hand column. </div> </body> </html>