Deck the Form

For the final exercise in this tutorial, the form will undergo a drastic metamorphosis. This is more along the lines of other flashy CSS demos. By adding strategic markup and then styling it with CSS, the form will go from bland to bold.

Adding Markup

While it may be possible to work with the markup already on the page, for maximum flexibility some additional tags will be added. There are two types of tags used for style specific markup. These tags have no real semantic meaning and are the only tags that should be used for styling. Before employing any other HTML tag for layout control, consider carefully the consequences.

In the previous example some tags were inline format and others were block. HTML 4.0 and XHTML 1.0 have two tags dedicated to styling. The "span" tag is by default an inline tag. The "div" tag is a block tag by default. These tags can have their properties changed just as with any other tag, but in most cases it is least complex to use the tag already best suited for the job.

Using div tags, the screen can be divided into columns, rows, and other forms of boxes. These boxes can be nested and one popular technique is to nest boxes to make complex and controlled designs. Applying too many styles to any one tag can cause problems, so most designers prefer to split up the work load.

Nest the "h1" and "p" tag at the top of the body with two div tags. Set the outside tag's id attribute to "topleft" and the inside tag's id attribute to "topright".

  <body>
<div id="topleft"><div id="topright>
<h1>An accessible form made attractive with CSS</h1>
<p>Please fill out all required fields,
any additional information that is applicable,
and press the send button.
</p>
</div></div> ...

Next nest the form tag the same way with div tags with the ids: "formleft" and "formright".

<div id="formleft"><div id="formright>
<form action="script.php" method="post" title="Personal Information">
...
</form>
</div></div>

Wrap four div tags around four sections of the form: the first three text fields, the ice cream question, the pet question, and the rest. id the divs, "one", "two", "three" and "four" respectively.

...
<form action="script.php" method="post" title="Personal Information">
<div id="one"> <label>Your Name
... </div> <div id="two"> <fieldset> <legend>What flavors of ice cream do you like?</legend>
... </div> <div id="three"> <fieldset> <legend>If you could get a pet it would be a:</legend>
... </div> <div id="four"> <label> State of Birth ...
</div>
</form>

Finally apply a span tags around the text portion of the labels with "class=hidden".

  </fieldset>
<label class="hidden"><span>If other please specify</span> <input type="text" name="other icecream"> </label>
<fieldset> ...
</fieldset>
<label class="hidden"><span>If other please specify</span> <input type="text" name="other pet"> </label>
<label> State of Birth ...

Notice how none of these tag affects the appearance of the page. These unstyled tags blend in perfectly to the existing style sheet.

More Styles to Choose From

This time around the style sheet will change more than just margins and display properties. Remove the existing styles and then apply a drastic change by styling the body tag with the following style:

  body{
background: #000 url(stylesheet/stylesheet2.jpg) top left repeat-y;
margin: 0;
padding: 0;
color: #FFF;
font-family: Geneva, Arial, Helvetica, sans-serif;
}

This rule set changes the background-color property to black and runs a background image down the left side. The background property is a shorthand allowing the change of any and all background properties, such as background-color, background-image, and background-position, all in one line. Another shorthand used in this rule is the abbreviated color, #000. In CSS 2 color hex codes can be abbreviated if both digits for all three colors are matched. #000000 can be written as #000, #FFFFFF as #FFF, #CC0000 (NC State Red) as #C00, and so forth. By default the body tag as a margin and padding, which many designers choose to remove.

The color property refers to the color of the text. Font-family can be changed in the body tag, applying the selected font to every other tag, except the "pre" (preformatted text) tag and a few others.

One caveat of to note, the only way to make a background image repeat from top to bottom of a page is to apply it to the body tag. There are currently no other techniques that force a background image, or even an absolutely positioned image, to align with the bottom of the page. To date, only Opera 8 features the ability to position based on the bottom of the document. Other browsers align to the bottom of the window which is the behavior of Mozilla, Safari, and IE.

  #topleft h1, #topleft p{
background: url(stylesheet/stylesheet.jpg) top left repeat-y;
padding-left: 20px;
}

Even the backgrounds of tags such as the "h1" and the "p" can be styled. This can be used to help draw divisions between sections, or add subtle shade. The above rule sets only apply to h1 and p tags found inside the div with the id "topleft". Just like assigning styles to classed tags, tags with ids can be targeted with CSS too. While classes are usually selected by the notation, "tagname.class" they can also be selected by "*.class" or ".class". The first notation has the best support among browsers, bugs in some browsers occasionally skip the latter two notations. For tags with an id assigned the selection notation is "tag#id", but because an id can only be assigned to one tag "#id" is more commonly used and is well supported. Later tutorials will cover CSS selectors more in

  #formleft{
background: url(stylesheet/stylesheet2.jpg) top left repeat-y;
padding-left: 130px;
}
#formright{
background: url(stylesheet/stylesheet3.jpg) top right repeat-y;
float: left;
width:100%;
}
#topright{
background: url(stylesheet/stylesheet3.jpg) bottom right no-repeat;
}

The tags that were id'd as "formleft" and "formright" are assigned backgrounds. Since no color is specified the backgrounds from tags that precede these two will "show through" any portions of these tags that are not covered by the background image. Background images can be layered like decals to create complex appearing designs. Until IE7 comes out there are limitations to the creativity that can be used since transparent PNG support has always been lacking in IE. Background images can align to sides of the containing box: top, bottom, left, right, and center. These can be used in combinations, and pixel, em, and percentages (from the top or from the left) can also be used if position is desired somewhere between the key points. Background images can scroll with the content or appear to be "fixed" in place with the content scrolling above it. Background images can also be tiled with repeating in both directions, only horizontally, or only vertically.

The two rule sets above do more than just apply background. The padding-left property pushes content inside the "formleft" tag to the right, preventing it from appearing on top of the background image. This style is applied here because the rest of the tags inside are "floated". Floating is a powerful formatting tool that CSS provides, but it can cause problems when combined with too many other property changes in the same tag.

The tag with the id "formright" is inside "formleft" and floated to the left. This means that it will try to line up horizontally with other elements that appear before it as long as there is room but will go down a line and move to the far left if there isn't room on the current line. Floating makes block elements behave like inline elements in some ways, but allows them to retain the advantages of being block, such as control over height. Floating is extremely useful, but also extremely tricky to work with. It has poor support in older browsers and comes with some extra restrictions. Floated tags must have a set width. This can be in pixels, percents, ems, or any other unit, but it must be set. Floating blocks cannot automatically set their widths the way normal blocks can. Failing to set width in a float will cause it to behave unpredictably.

Another limitation of floats is that they tend to "pop-out" of non-floating tags they appear inside of. This causes the containing tag to appear deflated. To see this effect try removing the background property from the body tag. Notice how even thought the "formleft" tag contains the "formright" tag, the left hand background image doesn't stretch vertically the way the right handed background does. This shows why the background for the body tag is needed, but also shows that the background for the "formleft" tag is now useless.

  #topleft p{ margin-bottom:0;}			
form{float: left; width: 100%;}

Even after being floated, block elements will respect the margins of other tags. To get rid of extra spacing, the bottom margin of paragraph tags only in the "topleft" tag is removed. The "formright" tag above was floated because it need to float to avoid being deflated. The divs inside the form need to float, and so anything that contains them must also be floated or face the deflating effect. The form tag is floated left and so it's width must also be set.

  #one, #two, #three, #four{
float: left;
width: 300px;
height: 300px;
padding: 10px;
}

Now the previous floats become important. With the four form input containers floated, the layout of the page changes drastically. Depending on the width of the browser window the form will now show the form elements as a row of 4, 3 and 1, 2 by 2, or a column of 4.

Try removing the width and height and see what happens. Some browsers will handle this more gracefully than others, but floats with no width can cause major problems. Try removing the widths on the "formright" and form tags.

With the widths restored, the final bits of style give each dividers a distinctive look:

  #one{
background:#190000 url(stylesheet/div1.gif) bottom right no-repeat;
border: 3px solid #300;
border-top: 0;
border-left: 0;
}
#two{
background:#101010 url(stylesheet/div2.gif) bottom right no-repeat;
border: 3px solid #222;
border-top: 0;
border-left: 0;
}
#three{
background:#000019 url(stylesheet/div3.gif) bottom right no-repeat;
border: 3px solid #003;
border-top: 0;
border-left: 0;
}
#four{
background:#001900 url(stylesheet/div4.gif) bottom right no-repeat;
border: 3px solid #030;
border-top: 0;
border-left: 0;
}

In addition to the above style sheet, the styles from the previous tutorial can be layered to make the page look even better. Above the style tag add a link tag to the first style sheet:

  <title>An accessible form made attractive with CSS</title>
<link rel="stylesheet" href="stylesheet.css"/>
<style type="text/css"> ...

If a copy of Netscape 4 is available, try the page in that. It looks horrible. It's often a good idea to hide more complex style sheets from older browsers, especially the ones with partial CSS support.

Create a new stylesheet file and cut/paste the new style sheet (just the contents of the style tag) into it. Use the @import rule to include this style sheet.

  <style type="text/css">	 
  @import "stylesheet2.css";
  ...

This is one way to gracefully degrade your style sheet. The link tag was a feature of CSS 1, but the @import rule was not added until version 2. This means that browsers with no CSS2 support won't see styles hidden by an import.

Accessibility Options

In the previous, more plain, form a tag was hidden to make the accessible form look just like the original. Hiding this text was not necessary. The text was useful and probably contributed just as much to usability as to accessibly. Suppose that hiding this tag by changing the display property confused a screen reader. How else can this text be styled so that it won't appear?

Another trick is to move a tag "way off screen". Unless the tag contains a lot of content, this trick will allow a screen reader to see the text (because it doesn't care about screen positions) but the text would never appear on screen. On top of the two shared style sheets, add another layer of CSS to the document:

  <style type="text/css">	 
  @import "stylesheet2.css";

  label.hidden span{
position: absolute;
top: -999px;
left: -999px;
}
label.hidden{
display: block;
visibility:visible;
}
label.hidden input{ visibility:visible; margin-left: 7em;}

These three rules override the rules for "label.hidden" and "label.hidden input" in the linked css file and add a new rule. All together they unhide the label tag, move the span around the text off-screen, 999 pixels above the top of the window and 999 pixels to the left. The input box is moved to the right with a normal margin rather than to the left with a negative one since it no longer has to follow the text portion of the label. The text is taken out of the display of the page all together, but still exists off screen.

Absolute positioning is another format model that allows complete control of where a tag appears. It is often used to create columns or move navigation to the top of a page when it appears after content in the HTML. Absolute positioning has a trade off just as all formatting models do. By moving a tag somewhere else on the screen, it's ability to wrap around other tags is taken away. Absolutely positioned tags can cover up other tags if the formatting isn't carefully applied. Absolutely positioned tags can expand their size based on their contents, but they cannot push other tags down out of the way.

Conclusion

CSS can have a sharp learning curve. Even after working with it extensively there are always new applications of the properties to discover. CSS is about control. It allows the designer to provide a consistent look on multiple pages. Style sheets can be modular so that every page has some styles and various sub-sets have their own customizations. In this way change is easier to deploy because than appearance of a document is controlled by an external factor, one that can be single sourced.

The resources page has many links to CSS resources. Floatorial is an excellent way to learn about positioning. Trial and error, and learning by example are just two great ways to develop CSS skills. The benefits out weigh the investments, style sheets are here to stay and with the proliferation of XML and mobile devices the old ways of designing pages will not sustain dynamic sites for much longer.