6 Best Practices for Marking up your HTML5

There are several coding rules required for XHTML that were optional or even unsupported in HTML 4. While HTML5 supports both coding formats, here are some non-required best practices:

  1. Use lowercase for markup: In XHTML the element tags must all be in lowercase as must all the attribute names. While HTML5 supports camel case and everything else, please use all lowercase markup. Nothing in the W3C states that attribute values need to be lowercase, but some, like id, are case sensitive, so stick to lower case.
  2.  Quote all attributes: In XHTML, all attribute values must be encased in single or double quotes. In HTML5, only attribute values with spaces or special characters are required to be in quotes. Make your code legible. Make us happy. Quote all attributes.
  3. Close all elements: In XHTML, every opening tag must have a closing tag. Empty elements such as <img/> and <br/> must be self-closing. In HTML5 some tags can be left unclosed. While omitting the trailing slash or closing element reduces the number of characters on a page, it also allows for sloppy code.Some speakers / blog posts recommend omitting trailing slashes and end tags to reduce the number of characters to make smaller files for mobile. The few bytes saved are not worth the risk, especially in non-empty elements. Reducing the number of DOM elements will have more of an impact than reducing the number of characters in this way. Make us happy. Provide a closing tag for each opening tag.
  4.  Nest all elements: In XHTML, all tags must be properly nested: If you start tag <a> and then start, or nest, a <strong>, you must close tag </strong> before you close the </a>. All tags must be nested correctly, which is easier to trouble shoot if you close all elements (see above).
  5. Be consistent in providing values for all attributes: In XHTML, all attributes must be coded as attribute/value pairs, even Boolean values. The default selected option in XHTML should be written selected=”selected”. In HTML5, the same can simply be coded as selected. Providing values for Boolean attributes is not necessary, since including the attribute property makes a Boolean value true even if the value of the attribute is false in most browsers. Whether you choose to include or not include Boolean values, be consistent with your decision either way. If you include Boolean values, always include them. If you omit them, always omit them. And, if you include a =”” for a Boolean (or even non-Boolean) attribute, always include the value, as the empty quotes can have unintended consequences, especially when it comes to the form attribute.
  6.  Use the most semantically correct element for the job: In XHTML, elements need to be coded in a semantic manner. Tables and forms cannot be included in paragraphs. Form elements, being phrase elements, need to be contained within a semantic block level element, such as a paragraph or table cell. Yes, you can use spans and divs to contain everything on your page, but if a header is a header, use an <h1-6> tag.

HTML5 Web Forms & Browser Support

HTML 5 Forms support in Modern Browsers and IE

Note: This is only valid thru input type. After that, I still need to do more testing and the grid is just a placeholder. Safari 5 is out. THat is not yet included in this. Opera seems to have reverted, and no longer supports placeholder, so I have to redo this. Feel free to use this as a general guideline, but not fact at the moment. EEK!

<elements> / attributes / “values”   IE6 IE7 IE8 FF3.6 Saf4 Saf5 Chrome Opera 10.5
<elements> / attributes / “values”   IE6 IE7 IE8 FF 3.6 Saf4 Saf5 Chrome Opera 10.5
autocomplete   Χ Χ Χ Χ Χ Χ Χ Χ
novalidate                 Χ
disabled   Δ Δ Χ Χ Χ Χ
accept file only Χ
alt image only
autocomplete most Χ Χ Χ Χ Χ Χ Χ Χ
autofocus   Χ Χ Χ Χ
checked radio & checkbox
formenctype / formaction / formmethod / formtarget sumbit buttons              
form in spec (back in) Χ Χ Χ Χ Χ Χ Χ
height image
list texttypes Χ Χ Χ Χ Χ Χ Χ
max date, range, #s Χ Χ Χ Χ Χ
maxlength texttypes
min dates & range Χ Χ Χ Χ Χ
multiple email & file Χ Χ Χ Χ
novalidate in spec???               Χ
pattern texttypes Χ Χ Χ Χ Χ
placeholder texttypes Χ Χ Χ Χ Χ
required   Χ Χ Χ Χ Χ
size texttypes
src image
step date, range, #s Χ Χ Χ Χ Χ  
type required
"button" button
"checkbox" checkbox
"color" color picker Χ Χ Χ Χ Χ Δ Δ Δ
"date" calendar Χ Χ Χ Χ Χ Δ Δ
"datetime" calendar Χ Χ Χ Χ Χ Δ Δ
"datetime-local" calendar Χ Χ Χ Χ Χ Δ Δ
"email"   Χ Χ Χ Χ Χ Δ
"file" input + button
"hidden" invisible
"month" calendar Χ Χ Χ Χ Χ Δ Δ
"number"   Χ Χ Χ Χ Δ Δ Δ
"password" obscured
"radio" radio
"range" slider Χ Χ Χ Χ Δ Δ
"reset" button
"search" search field Χ Χ Χ Χ Χ
"submit" button
"tel"   Χ Χ Χ Χ Χ
"text" (default value)  
"time" calendar Χ Χ Χ Χ Χ Δ Δ
"url"   Χ Χ Χ Χ
"week" calendar Χ Χ Χ Χ Χ Δ Δ
autofocus   Χ Χ Χ Χ      
novalidate                 Χ
form   Χ Χ Χ Χ Χ Χ Χ
<datalist>   Χ Χ Χ Χ Χ Χ Χ
autofocus   Χ Χ Χ Χ
cols (required)  
required   Χ Χ Χ Χ Χ Χ
rows (required)  


The <form> element creates a form for user input to pass user entered data to the server. Note that the accept attribute is no longer included in HTML 5.

<elements> / attributes Values IE6 IE7 IE8 Firefox 3.6 Safari 4 Chrome Opera 10.5
accept-charset charset(s)
action URL
autocomplete on | off              
enctype mime type
method get | post |
put | delete              
name unique name
novalidate novalidate Χ Χ Χ Χ Χ Χ Χ
target _blank | _self | _parent | _top | winname

The reason there appears to be so much HTML5 support for the <form> element is that only two new attributes were added to the form element in HTML 5: autocomplete and novalidate.

autocomplete takes the values off | on. When ‘on’, the browsers stores the form’s input values, to auto-fill the form when the user returns. “off” tells the browser to not store user input.

novalidate, if set (and supported), tells the browser to not validate the form upon submission.



The <fieldset> element is not new to HTML 5, but it does have new attributes – disabled, form, and name. The <fieldset> element is used to group together related elements in a form, drawing a box around the encompassed elements. The options <legend> element, if included as the first child of the <fieldset>, display a caption within the box border.

<fieldset name="car_elements" disabled>
   <input type="checkbox" name="cars"> Use Car Finder
  <p><label>Make: <input name=make  type="text" required></label></p>
  <p><label>Year: <input name=year required pattern="[-0-9]{4}"></label></p>

Browser support of <fieldset> and its HTML 5 attributes

<elements> / attributes   IE6 IE7 IE8 Firefox 3.6 Safari 4 Chrome Opera 10.5
disabled   Δ Δ Χ Χ Χ

Weirdly, IE6 actually supports something Mozilla and Webkit don’t. ‘disabled’ in IE6 and Opera disables all form elements within the fieldset. In IE7 and IE8, the attribute only disables form elements in the <legend>.


The <label> defines a label for a form element, providing enhanced usability. When used in conjunction with radio or check boxes, clicking on the label text toggles the control.

The for attribute of the <label> tag should be equal to the id attribute of the related element to bind them together.

<elements> / attributes   IE6 IE7 IE8 Firefox 3.6 Safari 4 Chrome Opera 10.5
form id of form
for id of form element


HTML5 defines 13 new values for the type attribute of the HTML <input> element (search, tel, url, email, datetime, date, month, week, time, datetime-local, number, range, and color). Currently, Opera has the best support, with some decent support from Webkit, especially for mobile.

<elements> / attributes input type values IE6 IE7 IE8 FF3.6 Saf4 Saf5 Chrome Opera 10.5
accept file only mime types Χ
alt image only  
autocomplete most on | off Χ Χ Χ Χ Χ Χ Χ
autofocus   autofocus Χ Χ Χ Χ
checked radio & checkbox checked
disabled   disabled
formenctype sumbit buttons enctypes              
formaction url
formmethod methods
formtarget targets
form in spec??? form Χ Χ Χ Χ Χ Χ Χ
height image  
list texttypes   Χ Χ Χ Χ Χ Χ Χ
max date, range, #s   Χ Χ Χ Χ Χ
maxlength texttypes  
min dates & range   Χ Χ Χ Χ Χ
multiple email & file   Χ Χ Χ Χ
name in spec???  
novalidate in spec???                 Χ
pattern texttypes   Χ Χ Χ Χ Χ
placeholder texttypes *see js Χ Χ Χ Χ
required     Χ Χ Χ Χ Χ
size texttypes  
src image  
step date, range, #s   Χ Χ Χ Χ Χ  
type required  
Values     IE6 IE7 IE8 FF3.6 Saf4 Saf5 Chrome Opera 10.5
"button" button  
"checkbox" checkbox  
"color" color picker   Χ Χ Χ Χ Χ Δ Δ Χ
"date" calendar   Χ Χ Χ Χ Χ Δ Δ
"datetime" calendar   Χ Χ Χ Χ Χ Δ Δ
"datetime-local" calendar   Χ Χ Χ Χ Χ Δ Δ
"email"   text Χ Χ Χ Χ Χ Δ
"file" input + button  
"hidden" invisible  
"month" calendar   Χ Χ Χ Χ Χ Δ Δ
"number"     Χ Χ Χ Χ Δ Δ Δ
"password" obscured  
"radio" radio  
"range" slider   Χ Χ Χ Χ Δ Δ
"reset" button  
"search" search field   Χ Χ Χ Χ Χ
"submit" button  
"tel"   text Χ Χ Χ Χ Χ
"text" (default value)    
"time" calendar   Χ Χ Χ Χ Χ Δ Δ
"url"   text Χ Χ Χ Χ
"week" calendar   Χ Χ Χ Χ Χ Δ Δ

You’ll note that I changed some of the values from No to Iffy support because while some browsers don’t support the new features that go with email, url, tel, etc., input types, they do actually support the element. When a type is not supported or understood, the browsers interpret it as the default, which is text, which works fine. Un-understood types are treated as ‘text’ and don’t provide any new features. Because browsers old don’t break with these new types, you can go ahead and start using them now.

<input> attributes by type & Browser Support



Text, search, url, tel Email Password Dateandtime
range color Checkbox, radio file
accept WK, O,
autocomplete O O O O O O O
autofocus WK, O WK, O WK,O WK, O WK, O WK, O WK, O WK, O
checked WK, O,
disabled WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
Form O O O O O O O O
list WK, O WK, O WK, O WK, O WK, O WK, O
max O, WK O, WK O, WK
maxlength WK, O,
WK, O,
WK, O,
min O, WK O, WK O, WK
multiple FF, WK, IE FF, WK
Name WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
WK, O, FF, IE WK, O,
WK, O,
pattern WK, O WK, O WK, O
placeholder WK WK WK
readonly WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
required WK, O WK, O WK, O WK, O WK, O WK, O WK, O
size WK, O,
WK, O,
WK, O,
step O, WK O, WK O, WK
checked WK, O,
value WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
WK, O,
WK, O, FF, IE WK, O,
WK, O,
  • WK = Webkit (tested Safari 5)
  • O = Opera (10.5 on Mac)
  • FF = Firefox (3.6.3 on Mac)
  • IE = Internet Explorer (IE8 on XP)

that don’t support the specific type attribute may still support other attributes in the
input as the browser may support attributes on the text input type (such as maxlength or size), and will therefore support those
attributes on a type it doesn’t support, as the input will default to text
type. For example, while IE and FF don’t currently support the email type, they
do support the multiple attribute on that type, since
they will accept a text type including space separated email addresses.


With some input types, even if the browser does support it, you can’t tell. The big difference in support comes to the iPhone: when an input has type email, url or tel, the iPhone provides a more input type suitable keyboard for user data entry.

JavaScript for placeholder attribute functionaility until supported by browsers

      if($(this).val()==$(this).attr("placeholder")) $(this).val("");

Note: this is as far as i’ve gotten at this point on explaining web forms. I do plan on coming back and revisiting this page in June 2010 to update.


The <datalist> is a list of <options>. The <datalist> is used in conjunction with an <input> element, defining which values the input element can take. When used, the <datalist> is not visible to the user, but rather is associated with the <input> element thru the <input>’s ‘list’ attribute that takes as its value the id attribute value of the datalist. The <datalist> defines what values are valid for that <input>.

In the end, this is very similar to a select list, except that the user is not limited to the suggested values.

<label>Enter a car manufacture: <input type="text" name="make" list="makes">
    <datalist id="makes">
    <option value="Toyota" /> <!-- works -->
    <option>Honda</option> <!-- doesn't work in Opera -->
   <option value="Hummer" label="Stupid Ass Gas Guzzler"> <!-- not right -->

   <!-- add more -->


New in HTML 5, the <output> tag defines different types of output, such as output written by a script.

The ‘for’ attribute takes the ids of the other elements for which it is defining the outputs. The’form’ attribute takes as it’s value the form’s name with which the <output> element is associated. The ‘name’ attribute is a unique name for the element that defines the output element when the form gets submitted.

HTML5: <section> v. <article>

I have been asked several times “when do you use <article> and when do you use <section> in HTML5?” I use an analogy that I figured I would share, as it seems to help developers make sense of the two elements.

Think of a newspaper. The paper comes in sections. You have the sports section, real estate section, maybe home & garden section, etc. Each of those sections, in turn, has articles in it. And, some of those articles are divided into sections themselves.

In other words, you can have parent <section>s with nested <article>s that in turn have one or many <section>s. Not all pages documents need these, but it is perfectly acceptable and correct to nest this way.

I hope that helps explain it.


CSS Background Properties: possible values, default values, browser support and DOM

Everything you could possibly want to know about CSS Background Properties: Interpreting the w3c specifications with browser support and links to examples and test cases.

Last Major Update: May 26, 2011

There are 8 attributes controlling background images. The CSS3 background properties are very well supported in modern browsers, but a few values are not. Also, there are some properties and values that have not yet made it into the specifications, but are already supported in all browsers except Firefox.. This blog post goes over all the existing and future attributes, targeting them with the DOM, and lets you know of bugs you may find when implementing backgrounds.

  • background-attachment
  • background-color
  • background-image
  • background-position
  • background-repeat
  • background-clip
  • background-origin
  • background-size
  • background-inline-policy – (not in the specifications)
  • shorthand: background, which includes the above attributes that are in the specifications.
  • Each property has a list of possible values. Many developers use the “background:” shorthand. I advocate against using the shorthand, as I spend a lot of time correcting other people’s code when they forget to declare all the possible values, and therefore inadvertently set some of the attributes to their default values, when that was not their intention. For example, in th CSS reset script I recommend, the reset sets background-repeat: no-repeat;. When this reset value is included, if a coder writes background: url(myImg.gif); the background-repeat value gets reset to the default value of repeat — repeating along the x and y axis — which is almost never the intended value. Note that none of the background properties are inherited by default, though several do have “inherited” as a value option. See below for more information on the background shorthand.

    default IE6 IE7 IE8 IE9 IE10 FF 3.6 FF 4 FF 5 Safari Chrome Opera
    background-attachement CSS2.1 Χ Χ
    fixed   Χ Χ
    scroll default
    local CSS3 Χ Χ Χ Χ 5
    background-color CSS2.1 Δ Δ Δ
    transparent default Δ
    rgb(r, g, b)  
    rgba(r, g, b, a) CSS3 Χ Χ Χ
    hsla() CSS3 Χ Χ Χ
    140+ named colors
    none default     1 1 1 1
    url, url CSS3 Χ Χ Χ 3.6
    left/top default
    center default when only one declaration
    CSS3 Χ Χ Χ 3.6
    4 Values
    CSS3 Χ Χ Χ Χ Χ Χ Χ Χ Χ Χ
    background-position-x not in the spec Χ Χ Χ Χ
    background-position-y not in the spec Χ Χ Χ Χ
    repeat-x / repeat-y
    multiple images Χ Χ Χ
    space Χ Χ Χ Χ Χ Χ
    round Χ Χ Χ Χ Χ Χ
    x / y values separate Χ Χ Χ Χ Χ Χ
    background-clip CSS3 Χ Χ Χ Δ -webkit-
    border-box Χ Χ Χ Δ
    padding-box Χ Χ Δ
    content-box Χ Χ Χ Δ
    background-origin CSS3 Χ Χ Χ Δ
    border-box Χ Χ Δ
    padding-box default Χ Χ Δ
    content-box Χ Χ Χ Δ
    background-size CSS3 Χ Χ Χ -moz-
    auto default -moz-
    contain Χ Χ Χ -moz-
    cover Χ Χ Χ -moz-
    (length) Χ Χ Χ -moz-


    The background-attachment attributes sets whether the background-image scrolls with the the document or remains fixed at the same location within the viewport. For example, if you include a “fixed” background image in a div, as the div scrolls up the page, the background image will stay in the same spot relative to the viewport, and will exit off the bottom edge of the div, disappearing from view, as the div moves up the screen. The default value is scroll. IE6 is the only browser that fails to support it correctly.

    Property Values for background-attachment

    background-attachment: fixed | scroll  | local;

    Browser support for background-attachment

    Explorer 6
    Explorer 7
    Explorer 8
    Internet Explorer 9 Firefox Opera Chrome Safari
    fixed behaves as “scroll” behaves as “scroll” works, but the placement of the image is off.
    scroll behaves as “local” behaves as “local”
    local Works because it inherits scroll, which erroneously renders as local. Works because it inherits scroll, which erroneously renders as local. 10.5 5


    In elements with background images that are background-attachment:fixed; the position of the fixed image is relative to the viewport (the browser), not the element that it is in. In other words, if you declare a fixed background image, the image is positioned relative to the document window rather than relative to the element. Because of this, as you scroll thru the page, and your element with the background image that is fixed moves thru the viewport, the background image will come into view as it passes over the location of the otherwise hidden background image.

    Note: background-attachment: local is a new value added in CSS3. “Local” is basically how “scroll” has been acting on scrolling elements in IE6 and IE7. An example is a div with "overflow: scroll.” Generally, as you scroll thru to div, the background image stays exactly where it was initially in the scrolling div’s viewport. Using local, the div’s background image scrolls with the element’s content. In the case of ’scroll’, the background does not scroll with the element’s content, except in non-compliant IE6 and IE7. In the case of ‘local’, the background scrolls along with the element’s content.

    Mobile Note: Mobile webkit does support fixed, but it doesn’t behave as you might expect. Smart phones show websites thru a viewport, displaying just a portion of the webpage. As you scroll, you are moving the viewport, not the actual page. So, the fixed background image is doing what it should, but it doesn’t look like you would expect.


    • IE8 does suppord fixed and not local, but get’s the positioning of the background image wrong.
    • IE6 and IE7 mistakingly renders fixed as scroll and scroll as local. Since scroll is the default, scroll renders as local, and the browser ignores the keyterm local, you can actually use local in these browsers as it will render local correctly.




    The background-color property sets the background color of the element. This attribute, like all other background attributes, is NOT inherited. If you set a background image that is a transparent gif, transparent PNG, or gradient with transparency,, the declared background color will show thru the transparent pixels.

    All browsers support background colors.

    The default value is “transparent”. In using RGB instead of Hex values, you can either use integer range 0 – 255 or percent values of 0-100%. If you go over (for example, 300 or 110%), the browsers will reduce the value to the maximum allowable value (either 255 or 100%).

    Note that if you mix RGB between integer and percents, some browsers will fail. If you include the wrong number of characters in a hex value, some browsers will ignore the declaration. If you misspell a named color, the browser will ignore the declaration.

    CSS3 provided us with new colors. Any valid value for color is valid for the value of background-color. For example, you can set the opacity or transparency level of the background color using background-color: rgba(255, 255, 255, 1);, where 255 is an integer between 0 and 255 or a percent value, and the 1 is any value between 0 and 1, with 0 being completely transparent and 1 being completely opaque. test page

    Property Values for background-color

    background-color: transparent | rgb(255, 255, 255) / rgb(r%, g%, b%) | rgba(255, 255, 255, 1) /  rgba(r%, g%, b%, 1)  | #fff | #123456 | magenta;

    Browser support for background-attachment

    IE6 IE 7 IE 8 IE 9 IE10 FireFox Safari Chrome Opera
    rgb(r, g, b) Renders with mixed values Renders with mixed values
    rgba(r, g, b, a) ignores the entire call ignores the entire call ignores the entire call  
    hsl(h, s, l) ignores the entire call ignores the entire call ignores the entire call  
    hsla(h, s, l, a) ignores the entire call ignores the entire call ignores the entire call  
    named colors didn’t test      


    • Do not using mixed values (percents and integers) in RGB. This is against the specifications, and will fail in all modern browsers.
    • IE6 and IE7 get “partially compliant” for RGB, since they erroneously display color if integers and percents are mixed. This may be a good thing, but it’s not in the specifications. test page
    • Do not use RGBA without browser targeting: color will fail in non-supporting browsers.
    • Bug: IE6 sometimes completely chokes on background-color: transparent. For example, if you declare background-color: transparent on pop-out in a suckerfish menu, the links in that menu will not be clickable and it will display as black.
    • Named colors have been expanded to include many new colors. Check out my list of named, hsl, hex and rgb colors.




    The background-image property allows us to define none, one or more background images for an element. This property only declares what image or gradient, if any, should be used. Other properties on this page can be used to define the position, movement, size, etc., or your declared images.

    In CSS3, an element can have multiple background images or layers. Separate each layer/image background image with a comma. When more than one image/layer/gradient is defined, the last image is drawn below all other layers and the first one is drawn on top, with each layer displayed in front to back order in between.

    Note that background images are not limited to jpegs, gifs and pngs. Browsers support data URIS, and (almost) all supporting gradients and some are supporting inline SVG.

    Property Values for background-image

    background-image: inherit | none | url(relative to CSS) | [gradients];
    background-image: url(relative to css), url(second image); // CSS3 allows for multiple background images.

    Browser support for background-image

    IE 6 IE 7 IE 8 IE 9 IE 10 FireFox Safari Chrome


    inherit if url doesn’t work, neither does inherit if the background image on parent doesn’t work, neither does inherit if the background image on parent doesn’t work, neither does inherit      
    url needs to have adequate size to work IE7 zoom function does not increase the size of background images IE7 zoom function does not increase the size of background images      
    url, url 3.6     10.5
    gradient -ms- -moz- -webkit- -webkit


    background-image browser bugs

    IE6 has several bugs with background images that are worth noting.

    1. The area of an element with a background-image must be at least 2500 pixels, or the image may not display. Fix by giving area or hasLayout=true.
    2. The repeated background image position starts and ends at the inside of the border and is therefore not seen thru a dashed or dotted border. Compliant browsers start the image at 0 0, but repeat it thru the border on all sides.
    3. For background images on links, IE6 fetches the image from the server for every “hover”, causing flickering.
    4. IE6 does not handle transparency of PNGs. Use proprietary filter to get around this bug
    5. If the background-image of a link is a transparent PNG, the link will not work in IE6.
    6. Using background images on <li>, <dd> and <dt> the background image may not render, especially if the list is placed within a floated, relatively-positioned parent.

    IE7 and IE8 has bugs too:

    1. The IE7 zoom function does not increase the size of background images.
    2. Same as IE6, in IE7 and IE8 the repeated background image position starts and ends at the inside of the border and is therefore not seen thru a dashed or dotted border. Compliant browsers start the image at 0 0, but repeat it thru the border on all sides.


    Browsers are beginning to support gradients as background image values. See my CSS Gradients Library and Library of World Flags in CSS Gradients as examples. The syntax differs in Safari 5 (and slightly in FF 3.6) from the standard, and all browsers that support gradients support gradients only as a prefixed value.

    I’ll be posting a tutorial on gradients shortly, so am not including details here.

    SVG as Background image

    There are two ways to include SVG as background images. Either point to an svg file as you would to any jpg file: Old Example of SVG as bgimage

    or you can include the SVG directly in the background image call.

       <svg xmlns='http://www.w3.org/2000/svg'>
       <linearGradient id='gradient'>
       <stop offset='1%' stop-color='#F00'/>
       <stop offset='90%' stop-color='#C33'/>
       <rect fill='url(#gradient)' x='0' y='0' 
       		width='100%' height='100%'/>
       </svg>"); }

    Note that spacing was added for legibility. All spacing must be removed for SVG to work. example of svg as background URI




    In CSS2.1 background position takes two: left and top (in that order!) of the background image. If you only declare one attribute, the outcome depends on the type of value used (percent, measurement or keyword). The default value is “top left”, well, actually, “0 0″.

    NOTE: If you are using anything other than the keyterms, make sure the order is LEFT and TOP in that order.

    Property Values for background-position

    background-position: bottom | center | inherit | left | right | top | 10px 10px | 50%  50%;
    background-position: 0 0, 50% 50%, 100% 100%; /* multiple placements */

    In CSS3 we can have up to 4 values for a single image’s background-position!!!

    If only one value is specified, the second value is assumed to be ‘center’. For example, background-position: bottom; will position the image centered at the bottom of the element. When using lengths instead of keyterms, the value refers to the horizontal positioning, so background-position: -20px; will position the background image centered veritally, with 20px of the background image being cut off the left hand side of the element.

    If two values are given and they’re not both keywords, the first value represents the horizontal position and the second represents the vertical position as an offselt from the top left corner of the element (background origin determines is its the top left corner of the outside of the border, inside of the border or inside the padding.

    New to CSS3, we can include three or four values for background-position, enabling us to position a background image relative to the bottom right of the element.

    Let’s start by explaining the four value property value, since the 3-value value is insanely confusing. The default of background-position is to offset your background image from the top left corner. Use four values to set your own offset corner. the syntax with an example:

    background-position: [bottom | center  | left | right ][length][bottom | center  | left | right ][length];
    background-position: bottom 40px right 20px;

    Pick one side, then list the offset from that edge, then include a perpendicular side and the offset from that second edge.In our example, the background image will be positioned 40px from the bottom and 20px from the right toward the bottom right of our element.


    If three values are given, 2 values must be keyterms and the missing offset is assumed to be zero. Currently only Opera supports 3 and 4 value background position. And, if you get any part of the syntax wrong (like try to offset from center which is not allowed), the entire declaration will be ignored. Because the 3-value syntax is confusing and prone to error, I recommend defining the 4 value whenever offsetting from any corner other than the top left corner. JS Fiddle Example

    Browser support for background-position

    IE 6 IE7 IE 8 IE 9 !E 10 Firefox Opera Chrome Safari iPhone
    mulitple     since 3.6 10.5
    4-value offset 11

    Note that background position with percent values can be confusing! A background-position of X% will place the pixel that is X% from the left of the image at the pixel that is X% of the way in from the left of the element in which it is placed.

    • For 0, the 0%, or left/top most pixel, will be placed at 0%, or the left/top.
    • For 100%, the 100%, or right/bottom most pixel of the bg image, will be placed at 100%, or bottom/right of the element.
    • For 50%, the middle of the image will be placed in the center of the element.

    Any other percentage value is a bit more confusing:

    A background-position of 25% will place the pixel that is 25% from the left of the image at the pixel that is 25% of the way in from the left of the element in which it is placed. If your image is 1000px wide, the pixel at 750px will be placed 75% in. In an element that is 1000px wide, it will be placed at 0,0. If your parent is 2000px, the pixel at 75% is 1500, so the 1000px background image will go from px 750 to 1750. Likely, that’s not what you want.

    Because of this, know the width of the image and the width of the element before using percent (other than 0, 50% and 100%) when creating liquid layouts. If you have a content area that is 80% of the viewport, to put a faux column background image for a 25% width column, create a background image with a ratio of 1:3 that is wide enough to cover a wide scree browser., and place the background-position-x: 20%; (80% * 25% = 20%).




    Although not part of the W3C specifications, backgroundPositionX and backgroundPositionY are part of the DOM and supported by some browsers. Colors are different in the following table, since green means the browser follows the W3C specifications and red means it fails, and these values are not in the specifications.. This property was added by MS for IE5.5, made it into the CSS3 specifications for a while, but was removed in 2009. Test case


    Property Values for background-position-x

    background-position-x: center | inherit | left | right | px/em | %;

    Browser support for background-position-x

    Internet Explorer 6 Internet Explorer 7 Internet Explorer 8 Internet Explorer 9 Firefox Chrome Safari Opera
    % Supported Supported Supported Supported Supported Supported
    px (length) Supported Supported Supported Supported Supported Supported
    left / center /right Supported Supported Supported Supported Supported Supported




    Property Values for background-position-y

    background-position: bottom | center | inherit | top | 10px | 2em | 50%;

    Browser support for background-position-y

    Internet Explorer 6 Internet Explorer 7 Internet Explorer 8 Internet Explorer 9 Firefox Chrome Safari Opera
    % Supported Supported Supported Supported Supported Supported
    px (length) Supported Supported Supported Supported Supported Supported
    left / center /right Supported Supported Supported Supported Supported Supported




    The backround-repeat property specifies whether the background image is repeated or tiled. And, if so, how that image is tiled. The default value is repeat, which repeats the image along both the x and y axis. Since this is generally NOT the effect I go for, i include background-repeat: no-repeat in my CSS reset.

    There are two new values for background-repeat: space and round. Space means the image is repeated as many times as can fully fit, separated by white space if repeating does not create an exact fit. Round means the image is repeated as often as will fit. If it doesn’t fit a whole number of times, the background images are rescaled so they do.

    You can also declare different values for the x and y axis. While this new feature is in the specifications, it is not supported yet in Firefox.


    Property Values for background-repeat

    background-repeat: inherit | no-repeat | repeat | repeat-x | repeat-y;
    IE 6 IE 7 IE 8 IE 9 IE 10 Firefox Chrome Safari Opera
    repeat-x / repeat-y
    multiple comma separated values
    separate x/y values




    With possible values of border-box | padding-box, the background-clip property determines whether the background position is relative to the border or the padding, specifying whether an element’s background extends underneath its border. This only has any visual effect when the border has transparent regions (because of border-style) or partially opaque regions; otherwise the border covers up the difference. The default value is “border”, which is the effective default of all current browsers. Firefox 3 supports -moz-background-clip. Safari’s implementation is -webkit-background-clip.
    Supporting browsers also support content-box, which is not in the CSS3 specifications at this time. Border box is the default. Webkit uses both -webkit-border and -webkit-border-box. Firefox uses -moz-background-clip, and does not include the term ‘box’ in the value. The syntax may change.

    Property Values for background-clip

    background-clip: [border-box | padding-box ] [ , [border-box | padding-box ] ]* ;
    -moz-background-clip: border;
    -webkit-background-clip: border-box;

    Browser support for background-clip

    IE 6 IE 7 IE 8 IE9 IE 10 Firefox 3.6 Firefox 4 Chrome Safari 4/5 Opera
    border-box     -moz-: border   -webkit- -webkit-
    padding-box     -moz-: padding   -webkit- -webkit-
    content-box         -webkit- -webkit-


    IE 7 (in yellow) behaves like background-clip:padding if overflow property is set to hidden, auto or scroll.

    FF 3.6 is both prefixed, and supports values of border and padding (not border-box | padding-box)

    Safari 4 is both prefixed, and supports values of border, padding and content (not border-box | padding-box | content-box)




    The background-origin property determines how the ‘background-position’ is calculated. Takes one or two parameters: border-box | padding-box | content-box. With a value of ‘padding-box’, the position is relative to the padding edge (‘0 0′ is the upper left corner of the padding edge, ‘100% 100%’ is the lower right corner). ‘Border-box’ means the position is relative to the border edge, and ‘content-box’ means relative to the content edge.

    Each comma-separated value applies to one image of ‘background-image’. This is useful only in safari at this point… but haven’t tested to see if supported. Safari’s current implementation is -webkit-background-origin. Mozilla is supporting -moz-background-origin. Has no impact when background attachement is set to fixed.

    Unlike clip, the value of content-box is in the proposed specifications.

    Note that the spec has changed. Mozilla and webkit have support, but use the original value terms of border | padding | content instead of the currect proposed specifications border-box | padding-box | content-box.

    Property Values for background-origin

    background-origin: [border-box | padding-box | content-box ] [ , [border-box | padding-box  | content-box] ]* ;
    -moz-background-origin: border; /* does not yet support multiple images, so no support for multiple values */
    -webkit-background-origin: border-box, padding-box, border-box;

    Browser support for background-origin

    IE 6 IE 7 IE 8 IE9 IE 10 Firefox 3.6
    Firefox 4 Safari 3
    Safari 4 Safari 5 Chrome Opera
    border-box     border   border -webkit-      
    padding-box     padding   padding -webkit-      
    content-box     content   content -webkit-      

    Sandbox: Background-clip in action




    Supported by Opera, Safari and Chrome, and Firefox , the background-size property specifies the size of the background images. The ‘contain’ values scales the image, while preserving its aspect ratio (if any), which may leave uncovered space. The ‘cover’ scales the image so that it covers the whole area, completely covering the element, but perhaps not showing part of the image if the element and the image did not have the same aspect ratio.
    see background-size specifications at the W3C

    Note that you still need to use the -moz- prefix if you’re supporting FF3.6 and the -webkit- prefix if for some unexplainable reason you’re still supporting Safari 4.

    Internet Explorer 6 Internet Explorer 7 Internet Explorer 8 Internet Explorer 9 Firefox 3.6 Firefox 4 Chrome Safari Opera
    auto -moz-
    contain -moz-
    cover -moz-
    (length) -moz-



    The background shorthand.

    The background shorthand (or shortcut) attribute enables the declaration of all five background attributes in one statement. Before CSS3, the values could be in any order, but were generally in the color, image, attachment, position and repeat order. If an attribute value is not specified, the value gets reset to the default value, which is why I recommend against using the shorthand.

    If you use the background shorthand and fail to declare any of the individual properties that make up the shorthand, those properties will revert to their default values listed below:


    	background-color: transparent;
    	background-position: 0% 0%;
    	background-size: auto auto;
    	background-repeat: repeat repeat;
    	background-clip: border-box;
    	background-origin: padding-box;
    	background-attachment: scroll;
    	background-image: none

    If you are declaring several background images using the shorthand property, the background color, if declared, should be declared as part of the shorthand of the final image only.

    Since they have the same value syntaz, if one <box> value is declared, then both the ‘background-origin’ and ‘background-clip’ are set to that value. If two values are present, then the first sets ‘background-origin’ and the second defines the ‘background-clip’ property.

    Property Values and order for the background shorthand

    background: background-image | background-position / background-size | background-repeat  | background-attachment | backgroun-origin | background-clip | background-color 
    background: url(myImg.jpg) bottom 20px right 20px / 200px 100px no-repeat fixed red;
    background: url(myImg.gif) 0 0 /  200px 100px no-repeat fixed border-box padding-box blue;  /*in action*/

    Default Values for background when values aren’t explicitly declared

    Property IE 6 IE 7 IE 8 IE 9 Firefox Safari Chrome Opera
    background-color transparent transparent transparent transparent transparent transparent transparent transparent
    background-image none none none none none none none none
    background-attachment “local” “local” scroll scroll scroll scroll scroll scroll
    background-position 0 0 0 0 0 0 0 0
    background-repeat repeat repeat repeat repeat repeat repeat repeat repeat
    background-size       auto auto auto auto auto
    background-clip       border-box border-box border-box border-box border-box
    background-origin       padding-box padding-box padding-box padding-box padding-box




    Mozilla only, pecifies how the coordinate system for the background-position of an inline element is chosen when the content of the inline element wraps onto multiple lines. -moz-background-inline-policy values include bounding-box | continuous | each-box, with a default of continuous. Property has no effect when background-attachment is fixed.

    iPhone: HTML, CSS & JS Support

    See Estelle at the 2nd annual CSS Summit
    Wouldn’t it be cool to be able to use CSS3 and HTML5 unfettered by the lack of support in IE? Mobile developers for smart phones get to do just that! When developing for mobile devices using webkit browsers we can use CSS animations, transforms, multiple background images, rounded corners, text and box shadows, CSS columns, and HTML5 form elements.

    In my CSS Summit session we’ll use some CSS3 features learned in earlier sessions to create a native looking iPhone web app. We’ll also cover some CSS UI and HTML5 form elements that will help you get up to speed on developing for mobile webkit. You don’t have to wait any longer to use CSS3! Join Us!

    Safari and Safari for the iPhone support all HTML elements, including deprecated elements and even some proprietary elements that were never part of any W3C specifications. In addtion, Safari is supporting some HTML5 elements, even though the HTML5 specifications have not been finalized. I’ve also added the attributes that each element supports. I didn’t include id, class, style, dir & title, since all elements basically support those, but I did include element specific attributes as well as some webkit only attributes.

    iPhone Support for CSS3 Selectors

    All CSS Selectors are supported by Safari on the iPhone. See CSS browser support for a chartcomparison of all the selectors. Selectos include:

    • *
    • E
    • .class
    • #id
    • E F
    • E > F
    • E + F
    • E[attribute]
    • E[attribute=value]
    • E[attribute~=value]
    • E[attribute|=value]
    • :first-child
    • :link
    • :visited
    • :lang()
    • :before
    • ::before
    • :after
    • ::after
    • :first-letter
    • ::first-letter
    • :first-line
    • ::first-line
    • E[attribute^=value]
    • E[attribute$=value]
    • E[attribute*=value]
    • E ~ F
    • :root
    • :last-child
    • :only-child
    • :nth-child()
    • :nth-last-child()
    • :first-of-type
    • :last-of-type
    • :only-of-type
    • :nth-of-type()
    • :nth-last-of-type()
    • :empty
    • :not()
    • :target
    • :enabled
    • :disabled
    • :checked
    • see them all

    iPhone Support for CSS3 properties

    Almost all CSS2.1 properties and values are supported by Safari on the iPhone, except for some keyword values for content. Position: absolute is supported, but due to the viewport, does not appear to be supported. See the list of all CSS2.1 properties and values by browser for more details. In addition, the iPhone Safari browser supports some CSS3 type properties and values including:

    Some CSS3 including the following, which will be discussed in future blog posts.

    • hsl(), rgba(), hsla() color support
    • native rounded corners (-webkit-border-radius)
    • IE box model (-webkit-box-sizing)
    • Shadows on text (text-shadow was in CSS2.0)
    • Shadows on elements (-webkit-box-shadow)
    • multiple background images
    • opacity /gradient transparency
    • @font-face web fonts
    • CSS Animation
    • Media Queries
    • namespaces

    iPhone & Safari Support for HTML elements, including HTML5

    includes HTML attributes for the iPhone and Safari

    Below is a grid of all of the elements, including deprecated elements (at the way bottom), and HTML5 elements interspersed with HTML4 elements in alphabetical order.

    <ELEMENT> Element Name Safari
    iPhone Support Attributes (and Notes in italic)
    Elements occuring outside the body element
    <!DOCTYPE> Document Type Declaration 1.0 1.0
    <html> html 1.0 1.0 manifest (Saf. 4, iphone 2.2)
    <head> document head 1.0 1.0 profile
    <base /> url base for links 1.0 1.0 href, target
    <link /> link 1.0 1.0 charset, href, media, rel, rev, target
    <meta /> meta 1.0 1.0 content, name, http-equiv, scheme
    <style> style 1.0 1.0 media, type
    <script> script 1.0 1.0 charset, defer, language, src, type
    <title> document title 1.0 1.0
    Elements Occuring in the <body> in HTML 4.01 and HTML5
    <body> document body 1.0 1.0 bgproperties (value: fixed)
    <a> Anchor 1.0 1.0 different event handlers for iPhone than Safari
    accesskey, charset, href (required), hreflang, rel, rev, shape (rect/cirlce/poly), target (deprecated, but useful), type
    <abbr> Abbreviation 1.0 1.0 title shows on hover in Safari
    <acronym> acronym 1.0 1.0 title shows on hover in Safari
    <address> address 1.0 1.0 italic
    <area> image map area 1.0 1.0 accesskey, alt (required), coords, href (required), hreflang, shape (rect/cirlce/poly), target
    <article> HTML5
    <aside> HTML5
    <audio> audio 3.1 3.0 HTML5: Similar to object, can nest sources and content to cascade until supported found.
    Audio support includes AAC, M4A, MP3, Wave, AIFF , Apple Lossless, Quicktime, but not OGG;

    autoplay, controls, end, loopend, loopstart, playcount, src, start
    <bdo> bi-directional override 1.0 1.0
    <blockquote> long quote 1.0 1.0 cite
    <br> break return or forced line break 1.0 1.0
    <button> push button 1.0 1.0 accesskey, disabled, type, value
    <canvas> canvas drawing region 1.3 1.0 HTML5: Stroke and fill colors, rgba/hsla colors, paths, rectangles, shadows, gradients, patterns, translations, rotation and scale
    <caption> caption 1.0 1.0
    <cite> citation 1.0 1.0
    <code> code 1.0 1.0
    <col /> column 1.0 1.0 char, charoff, span
    <colgroup> column group 1.0 1.0 char, charoff, span
    <dd> definition description 1.0 1.0
    <del> delete 1.0 1.0 datetime
    <dfn> definition 1.0 1.0
    <div> generic block element 1.0 1.0 aria-checked, aria-level, aria-pressed, aria-valuemax, aria-valuemin, aria-valuenow, role (Safari 4.0)
    <dl> definition list 1.0 1.0
    <dt> definition term 1.0 1.0
    <em> emphasized text 1.0 1.0
    <fieldset> field set 1.0 1.0
    <figure> HTML5
    <footer> HTML5
    <form> form 1.0 1.0 accept, accept-charset, action, enctype. method, target
    <frame /> frame 1.0 1.0 frameborder, longdesc, marginheight, marginwidth, noresize, scrolling (yes/no/auto), src
    <frameset> frameset 1.0 1.0 cols, rows
    <h1-6> headers 1.0 1.0
    <header> HTML5
    <hgroup> HTML5
    <hr /> horizontal rule 1.0 1.0
    <iframe> internal frame 1.0 1.0 frameborder, longdesc, marginheight, marginwidth, scrolling (yes/no/auto), src
    <img /> image 1.0 1.0 alt (required), composite, ismap, longdesc, src, usemap
    <input /> input 1.0 1.0 accept, accesskey, alt, autocapitalize (iphone 1.1, values: on/off), autocomplete, autocorrect (iphone 1.1, values: on/off), autosave (safari), checked, disabled, incremental (safari), ismap, max, maxlength, min, placeholder, results, src, type, usemap, value
    <ins> Insert 1.0 1.0 datetime
    <kbd> keyboard 1.0 1.0
    <keygen> key generation 1.0 1.0 challenge, keytype
    <label> label 1.0 1.0 accesskey, for
    <legend> caption for fieldset 1.0 1.0 accesskey
    <li> list item 1.0 1.0 type, value
    <map> image map 1.0 1.0
    <mark> HTML5
    <meter> HTML5
    <object> object 1.0 1.0 archive, classid, codetype, data, declare, loop, type, usemap
    <ol> ordered list 1.0 1.0 type
    <optgroup> option group 1.0 1.0 disabled, label
    <option> option 1.0 1.0 disabled, label, selected, value
    <p> paragraph 1.0 1.0
    <param> parameter 1.0 1.0 type, value, valuetype
    <pre> preformatted text 1.0 1.0
    <progress> HTML5
    <q> inline quotation 1.0 1.0 cite
    <samp> sample computer code 1.0 1.0
    <select> option selector 1.0 1.0 disabled, multiple
    <source> 3.1 HTML5
    <span> span (generic non-semantic container) 1.0 1.0 aria-checked, aria-level, aria-pressed, aria-valuemax, aria-valuemin, aria-valuenow, role (Safari 4)
    <strong> strong emphasized text 1.0 1.0
    <sub> subscript 1.0 1.0
    <sup> superscript 1.0 1.0
    <table> data table 1.0 1.0 frame (values: above, below, hsides, vsides, rhs, lhs, box, border), rules (values: none, groups, rows, cols, and all), summary
    <tbody> table body 1.0 1.0 char, charoff
    <td> table data cell 1.0 1.0 abbr, axis, char, charoff, colspan, headers, rowspan, scope
    <textarea> text area 1.0 1.0 accesskey, cols, disabled, readonly, rows, wrap
    <time> HTML5
    <tfoot> table footer 1.0 1.0 char, charoff
    <th> table header cell 1.0 1.0 abbr, axis, char, charoff, colspan, headers, rowspan, scope
    <thead> table head 1.0 1.0 char, charoff
    <tr> table row 1.0 1.0 char, charoff
    <ul> unordered list 1.0 1.0
    <var> variable 1.0 1.0
    <video> video 3.1 3.0 HTML5
    autoplay, controls, end, loopend, loopstart, playcount, poster, src, start
    Elements you should not be using, that are still valid
    <tt> teletype 1.0 1.0
    <i> italic
    <b> bold
    <big> big font
    <small> small font
    <noframes> no frames 1.0 1.0
    <noscript> no script 1.0 1.0
    Elements that are deprecated or were never in a W3C spec, but you may still see on older websites
    <applet> applet 1.0
    <center> center 1.0 1.0
    <dir> direction 1.0 1.0
    <embed> embed 1.0 1.0 use object instead
    hidden, loop, pluginpage, pluginspage, pluginurl
    <font> font 1.0 1.0
    <layer> layer 1.0 1.0
    <listing> listing 3.0 1.0 use <pre> instead. from HTML 3.2
    <marquee> ,arquee 1.0 1.0 behavior, direction, loop, scrollamount, scrolldelay, truespeed
    <menu> menu 1.0 1.0
    <nobr> no break 1.0 1.0
    <noembed> no embed 1.0 1.0
    <nolayer> no layer 1.0 1.0
    <plaintext> plaintext 1.0 1.0
    <strike> strikethrough 1.0 1.0 use <del>
    <u> underline
    <wbr> with breaks 1.0 1.0
    <xmp> sequence of literal characters 1.o 1.0

    Safari and iPhone Event Handlers:

    Event Safari iPhone Explanation
    onabort 1.0 1.0 When an image element is aborted during load. (for <img /> elements)
    onbeforecopy 1.3 before the element is copied.
    onbeforecut 1.3 before the element is cut.
    onbeforepaste 1.3 before the element has something pasted into it.
    onbeforeunload 1.3 before the element is unloaded from the page.
    onblur 1.0 1.0 when the element loses focus.
    onchange 1.0 1.0 when the element changes its value.
    onclick 1.0 1.0 when the element is clicked.
    oncontextmenu 1.1 when the element is right-clicked or when the mouse button is held down long enough to generate a contextual menu.
    oncopy 1.3 when the element is copied.
    oncut 1.3 when the element is cut.
    ondblclick 1.0 when the element is double-clicked.
    ondrag 1.3 when the element is dragged.
    ondragend 1.3 when the element is done being dragged.
    ondragenter 1.3 when a drag has entered the element.
    ondragleave 1.3 when a drag has left the element.
    ondragover 1.3 when a drag is over the element.
    ondragstart 1.3 when the element has started to be dragged.
    ondrop 1.3 when the element is dropped.
    onerror 1.0 1.0 when the element has an error in loading.
    onfocus 1.0 1.0 when the element gets focus.
    ongesturechange 2.0 When fingers are moved during a gesture.


    ongestureend 2.0 When the gesture ends (when there are 1 or 0 fingers touching the surface).


    ongesturestart 2.0 When two or more fingers touch the surface.


    oninput 1.3 1.0 when text is entered into the element.
    onkeydown 1.0 1.0 when a key is pressed over the element.
    onkeypress 1.0 1.0 when a key is pressed and released over the element.
    onkeyup 1.0 1.0 when a key is released over the element.
    onload 1.0 1.0 when the element finishes loading.
    onmousedown 1.0 1.0 when the mouse button is pressed over the element.
    onmousemove 1.0 1.0 when a key is moved within the element.
    onmouseout 1.0 1.0 when the mouse leaves the element.
    onmouseover 1.0 1.0 when the mouse is over the element.
    onmouseup 1.0 1.0 when the mouse button is released over the element.
    onmousewheel 1.0 1.0 when the mouse wheel button is rotated.
    onorientationchange 1.1 When the orientation of the device changes.
    onpaste 1.3 when the element is pasted.
    onreset 1.0 1.0 when the form element is reset.
    onresize 1.0 1.0 when the element is resized.
    onscroll 1.2 1.0 when the element is scrolled (a text box would use this, for example).
    onsearch 1.3 when a search is performed.


    onselect 1.0 1.0 when text within the element is selected.
    onselectstart 1.3 when the element begins to be selected. You can use this to prevent selections.
    onsubmit 1.0 1.0 when the form element is submitted.
    ontouchcancel 2.0 When the system cancels tracking for the touch.


    ontouchend 2.0 When a given event lifts from the surface.


    ontouchmove 2.0 When a finger for a given event moves on the surface.


    ontouchstart 2.0 When a finger for a given event touches the surface.


    onunload 2.1 when the element is unloaded from the page.

    Other iPhone posts in my blog

    Alternative Text for Images: the ALT attribute

    For a webpage to validate and be accessible, all images must have a value for the alt attribute, even if that value is empty. The XHTML DTD requires only two atttributes for the img element: src and alt. The XHTML DTD tells you it needs to be there. WCAG tells you a bit more about what it needs to look like. Unfortunately, W3C writings are is not always understandable. This entry will explain, in human terms, how to write the values for your alt attributes.

    Section 508/WCAG alt attribute Guidelines:

    The first Section 508 guidelines states, “A text equivalent for every non-text element shall be provided (e.g., via “alt”, “longdesc”, or in element content)”. Checkpoint 1.1, the first priority of priority 1 of the WCAG guidelines states the same thing: Provide a text equivalent for every non-text element (e.g., via “alt”, “longdesc”, or in element content). This includes: images, graphical representations of text (including symbols), image map regions, animations (e.g., animated GIFs), applets… (I shortened it. the W3C tends to be loquacious.)

    Decorative Images

    Decorative images include background images, bullets, <hr /> equivalents, spacer images, etc. These types of images make the page prettier but have no semantic value for a webpage. The alt attribute for decorative images should be empty: <img src=”path/image.gif” alt=”” />.


    • If you’ve read any of my other blog entries, or other articles on web standards, you likely will never have an empty alt attribute, since you are separating the content layer from the presentation layer; and therefore not including decorative images in your XHTML; opting instead for the use of CSS.
    • If you include an empty alt attribute, screen readers will skip over the image. If you fail to put an alt attibute in, the screen reader will read the entire URL of the image. Can you imagine listening to a robot say “spacer gif spacer gif spacer gif” repeatedly, or, worse, going letter bu letter thru the underscores and extensions of a filename generated by ImageReady.


    The alt attribute of an icon should describe the intention of the icon, since an icon can have differing meanings depending on the context, and someone who has never seen the icon wouldn’t understand whatit emant if only visually described.

    icon possible relevant values for alt useless alt
    “correct”, “open”, “start”, “completed”, “asset”, “” circle with check mark
    “stop”, “wrong”, “delete”, “close window”, “”, “remove module”, “delete email” red cross
    “RSS Feed”, “add RSS feed to reader, “” orange square with 3 lines.
    “answer”, “enter password”, “”, “primary key”, “security feature”, “” gold key
    “security feature”, “blocked”, “password protected” closed lock

    The desription of the appearance of the icon is almost alwasys a useless alt attribute value. Unless you are writing a manual on graphic design or on understanging iconography, don’t include a description of the icon as the value of the alt attribute.

    An empty string is a possible relevant value for all icon alt attributes. When an icon appears directly before an equivalent definition of the function of that icon, then the value of the alt attribute should be empty. The two most common examples of this are the print and email icons:

    icon possible relevant values for alt useless alt
    “open email”, “email messages”, “go to inbox”, “send an email, “” letter
    print, “” printer

    When an icon describes the text immediately preceding or following it, it is redundant to include a value for the alt attribute of the icon. The screen reader will read “print print”, or “email email”.

    Sample alt attribute encoding for icons:


    <a href="inbox.html"><img src="icon/email.gif" /> inbox</a> //missing alt attribute

    Will validate, but not really good: Screenreader will say “go to inbox inbox”

    <a href="inbox.html"><img src="icon/email.gif" alt="go to inbox" /> inbox</a> //redundant alt attribute

    Better, and correct:

    <a href="inbox.html"><img src="icon/email.gif" alt="" /> inbox</a>

    Best: seperates content from presentation

    <a href="inbox.html" class="email">inbox</a>

    with the css of

    a.email {
        padding-left: 18px;
        background: tranparent url(icon/email.gif) no-repeat 0 0;


    • Although it is generally best to use CSS background images (including sprites) if you are going to use an icon
    • If you use a sprite, the alt altribute should describe the relevant section of the sprite. Don’t write “sprite of icons”. Instead, follow the recommendations above (all those images are actually one transparent .gif — a sprite.

    Buttons, navigation and other images with text

    If you are still using images for the elements in your navigation bar (shame on you!), the general rule is that the value of the alt attribute must match the text of the image. If your image says only “about”, the value of the alt attribute should also read about. Then include more detail about the destination in the title attribute of the parent anchor tag.

    <a href="about/index.html" title="About the Author"><img src="img/nav_about.jpg" alt="about" /></a>.

    Include the text that appears within your image as the value of the image’s alt attribute.

    If you are using mystery meat navigation, you should describe relevant text in the alt, not the an explanation of the iconography of the tab. This may go against standards guidelines, but since mystery meat navigation goes against web standards, at least make your website accessible to the visually impaired, even if it isn’t accessible to sighted users.

    Instead of using an <img> for navigation, use text, and make your link attractive, including using your image, via CSS using image replacement. I will include a blog entry on image replacement in the near future, since i use it a lot. In the meantime, you can look it up on any search engine.

    Images, without text, that link to somewhere

    Sometimes it makes sense to actually use images, without image replacement, to link to a page. For example, on Facebook, Yahoo, and maybe on your company’s about page, thumbnail images of people or avatars may link to the person’s profile. If the image is within the same link as a text link, the alt attribute should be left empty. If not, however, the link should describe the purpose of the link: <a href="bios/jane.html"><img src="img/thmb_jane.jpg" alt="Jane Smith's profile" /></a>.

    This is similar to the explanation on icons above. Let’s say you do use just the email icon (from the icon example above). The correct presentation would be:

    <a href="inbox.html"><img src="icon/email.gif" alt="go to inbox" /></a>

    Complex, detailed images that “convey 1000 words”

    Sometimes images are worth a thousand words. Maps, Graphs and Charts are examples of images that contain information necessary to understanding the message of a page but too complex to be described in under 255 characters. If the complex image is followed by text explaining or detailing the content of the image, like you might find in a journal article, then a simple alt attribute value suffices.If there is information conveyed in the image that is not explained in the text following the image and is too complex to describe in 2 sentences, like you might find in a powerpoint presentation, then you need an alternative method of explaining the content of the image to those unable to view the image. In other words, if all the data presented in your image is reiterated as text, then an alt attribute value of “graph of blood pressure by age group” suffices. If there is information that is conveyed in the image that is not reiterated as text for all of your visitors to read (and search engines to find), then you should include a longer description of the image in the form of a longdesc attribute linking to content describing in full detail the contents of your image.

    The longdesc attribute

    longdesc is an optional attribute of the <img> and <frame> elements. The longdesc property specifies a url for a longer description of the contents of the current frame. The longdesc attribute is coded like this::

    <img src="graph.gif" alt="graph of blood pressure by age group(long description available)" longdesc="supportfiles/graphdescribed.html" />

    You then need to create a separate page for your longdescription. This page should include the description and a link back the current page. The longdesc attribute’s purpose is to provide a link to a separate page where a long description is available. This link is invisible to the sighted user but available to those using screen readers.

    The longdesc functionality is rarely implemented in websites despite it’s being the recommendation of the WC3 and Section 508 guidelines. For this reason, you should:

    • Include the fact that a long description is available in the alt attribute value of the image: it’s used so infrequently that even those using screen readers may not otherwise notice you included it. alt="graph of blood pressure by age group(long description available)"
    • It’s better to not use the longdesc attribute, opting instead to fully describe the contents of the image in the text for all readers. This method provides more fodder for search engines, and explains the content of your graph that even sighted users may not have otherwise noticed or derived.
    • To test whether it’s necessary, turn off images and see if all the information conveyed in the image is presented in the text in the page. If yes, longdesc is not necessary. If not, either include more descriptive text, or include a longdesc.
    • When I receive data graphs, I usually include a datatable with the data conveyed in the graph. Most charts are created using MS Excel (open MS Excel, select “Insert” > “Chart”). Ask whoever created your chart image for the original Excel file, and present the data from the spreadsheet in a data table. If you don’t have the original spreadsheet, if the chart is detailed enough to require a longdesc, then it’s detailed enough to be able to cull the data.
    • WebAIM provides more information on the longdesc attribute.

    Other images

    This is for all other images! If you included a picture of yourself standing with Britney Spears, your alt attribute value should minimally read “Britney Spears and me”. You can, of course, add a few more details to better describe the image if there is other relevant information presented in the image that the visitor should know.

    Making basic web pages accessible

    Web Accessibility / Section 508 Guidelines

    Making your site accessible

    Web accessibility is the ability of users with various functional requirements to use web sites easily and effectively. This includes keyboard access, screen enlargement, screen reading and voice recognition. If you don’t think this is important, just remember that your two most important visitors are blind, deaf and unable to use a mouse: googlebot and slurp, Google and Yahoo!’s spiders, can only read the text of and tab thru your page. They can’t see your cool mouseover effects, interpret the nuances of your images, or enjoy your nifty sound effects.

    Below are brief rules to make your site accessible. After the table of contents below are methods to ensure that your content is visible to users, but to considered compliant that content must be presented in an accessible manner. The list below should get you 90% of the way there. The rest addresses specifics to ensure complete access.

    Here are the brief rules:

    • Content that is well written will be easier for everyone to access including people with cognitive and learning difficulties. Content should be short, simple and well organized. Paragraphs should be brief with one key idea per paragraph. Make sure there are no spelling or grammatical mistakes.
    • The language of the content should be defined using the "lang" attribute. In addition to defining the language for the document, all changes in the primary language of the page should be indicated. Provide definitions/explanations of technical terms, abbreviations and acronyms.
    • Each page must have a unique title element, which relates to its content. Use meaningful headings and subheadings. Page headings and sub-headings should be defined using <h1> to <h6> heading structure. Correct mark-up should be used for lists. Sub-lists should be nested properly. Content should appear in paragraphs or list items: avoid anonymous (tag-less) text.
    • Users must be able to reach and trigger all links, forms and functionality without the use of a mouse. Additionally, the text of links and the "alt" attributes of image links should make sense when read out of context.
    • Start with accessible content by first coding your page in XHTML first, with no presentation (CSS) or interactivity (Javascript). Then add the presentation (CSS) and behavioral (JavaScript) layers with external stylesheets and scripts. Think "Web Standards": if your site is semantically coded, it will likely be accessible.
    • Do not target assistive technology with display: none, as that will hide the content from all users with CSS enabled, including screen readers. Instead position the hidden content off the page. Do this wisely as form elements and links positioned off the page can still receive “focus” by use of the keyboard.

    Assistive Technology

    Screen readers are a form of assistive technology.  A screen reader is software that sits on top of other applications, reading aloud what other sofware displays to the screen. While web developers often think of screen readers when developing accessible website, we need to remember that screen readers are not the only assistive technologies that may be used with your site: users can magnify your site, use the browser to increase font size, visit your site with refreshable braille display devices or print your pages with braille printer, navigate your site with a keyboard or apply their own style sheet to your site.

    Section 508 guidelines and other tips to making your site accessible

    The WCAG (Web Content Accessibility Guidelines 1.0) recommendations were written in 1999, so are a bit outdated. The following is based on their recommendations and updated to reflect modern web standards and Web 2.0. The WCAG 2 guidelines are still in draft form, but are nearing completion. You should find this page more helpful and easier to understand than the official guidelines.

    Below are guidelines to consider when developing websites. While the W3C calls these "guidelines", they should be considered "rules". Following these guidelines will not only help make your website more accessible to those with disabilities of various sorts, but your site’s search-ability will improve, your site will likely function on alternative media such as cell phones, you’ll be considered a really good person and you’re site will be legal in all the countries that require sites to be accessible.

    Text Equivalent for images and animations:

    A text equivalent for every non-text element should be provided (e.g., via "alt", "longdesc", or in element content).

    alt attribute: alternative text for images

    The "alt" text attribute provides a title or descriptive phrase about the image it accompanies. The "alt" attribute should describe the content of the image. Describe the image, but don’t start with "This is an image of…". The user already knows it’s an image. If you don’t know what alt text to use, imagine reading the document over the phone: how would you describe the image to the person on the other end? Alt attributes are essential for users of reader software who are vision impaired, it is valuable for users of graphical browsers who have "load images" turned off (which many cell phone users do), and it helps you should your image fail to load. It is also useful for users of text-only WWW tools like Lynx and some cell phone browsers. While some images formats, such as PNGs, allow for the inclusion of meta data describing the content, no browser or reader supports this function, so while you may include the data for future comatibiltiy, you can not rely on it for current compatibility. If I haven’t convinced you of the importance yet, it also helps with SEO, since search engines have no way to "read" your images.

    There are 2 circumstances in which null or empty alt attributes (alt=””) may be used: layout images and images that are included within the same anchor tag as a textual link. If you are a web standards oriented web developer then you likely will never have empty alt attributes. Why? Because good web developers use background images, not layout image. And good web developers use background images (and sprites) instead of link foreground images.

    longdesc attribute: long description for images and media

    The "longdesc" attribute can be essential when an image conveys important information such as a pie chart or a scientific discovery. The longdesc is a link to a separate text only page containing a longer, text only, description of the the image. If the contents of the image are described within the text content of the page, a longdesc is not necessary.


    Equivalent alternatives for any multimedia presentation should be synchronized with the presentation. In English, when including multi-media components in your web page, such as a flash movie, an animated gif, a video clip, etc., the alternative text describing the contents of the media should change as the presentation changes. Any dynamic changes occuring in the multimedia content (either in a <frame>, <img>, <object>, or <script>) must also update the "alt" element when it changes.

    Implementation of this web accessibility requirement include captioning and transcriptions of any spoken audio in the media (think "hearing impaired"), and text descriptions of the visual changes (think "visually impaired"). You do not need to include captioning for non-informative sounds, such as background music. But include captioning for all sounds that convey meaning in the audio, including all spoken words and background sounds, such as a window breaking, and even words to a song, if the sound or song lyrics are necessary in conveying the meaning of the multimedia component.


    Don’t convey information with color only

    Web pages should be designed so that all information conveyed with color is also available without color. For example, my chart of browser CSS support uses color to show various levels of browser support. Without color this chart would be completely useless were it not for the semantic markup of checkmarks, deltas and exes providing reduntant data. Visual color cues should not be the only way of conveying information, as had I only used color in this chart, not only would this page be a challenge for color blind users, but users accessing this page via cellphones, Lynx, with CSS turned off, and with Safari (there is a typo in the page that i have yet to fix, so the colors don’t show in Safari) would be completely unable to use this chart.

    Use enough contrast in your web design so your site is readable for users with color blindness.

    In developing your web pages, choose text and background colors to provide maximum contrast. Page design must present a clear contrast between foreground and background colors. Many people think that color blindness means that sufferers see the world like a black and white TV. This form of colorblindness does exist, but is extremely rare. Color blindness, though, is not rare. Thirty percent of all males suffer from some form of color deficiency rendering colors as grays or spreading one color across several others.Contrast is also very important for individuals who can see but have reduced vision. Is your text green and are your links of a similar hue with no text decoration? Take a look at your website as with simulated color blindness.

    In developing the site, do not include any HTML color on the page. All the colors should be controlled via external style sheets. This allows the user to implement their own style sheets and color palette.

    Style Sheets:

    Documents should be coded semantically, included coding the text in an order that makes sense if it is read without a style sheet. Headers should be used for headers, lists for lists, paragraphs for paragraphs. This helps not only for humann accessibility, but enables your pages to be accessible to search engines. Separate your presentation, or "style", from your content. All your style sheets should be external. Do not include inline styles. Do not use !important.

    All text should re-size relative to browser font size settings: use ems instead of pixels in declaring font-size. If you declare font size using pixels, IE6 will not change the font size when the user chooses to change it via their browser. IE6 does respect relative font sizes, which is why ems are recommended instead of pixels. Percentages work as well, but they are a wild beast to tame when it comes to the cascade and cross browser issues; so use ems. (WCAG 3.4: Use relative rather than absolute units in markup language attribute values and style sheet property values. Priority 2)


    Natural Language

    Indicate the language of your content. If the page is in English, French, Spanish or Urdu, you need to let the browser know. The screen reader uses this information. Google uses this information. If you then use a different language within the page, indicate that the language has changed for that section of the page. (WCAG 4.1 – Clearly identify changes in the natural language of a document’s text and any text equivalents (e.g., captions). [Priority 1]) In print, foreign language quotes are usually displayed in italics. Similarly, you should use the lang attribute to indicate language.

    <p>I had another <span lang="fr">deja vu</span> last night.</p>

    Using the lang attribute you are informing the screen reader to use alternative pronunciation, informing braille translators to not contract letters, and allowing the Babel Fish translator how to interpret individual chunks of content.

    Language Level

    Use the clearest and simplest language appropriate for a site’s content. If you are writing a children’s site, use first, second or third grade level language as appropriate. If you are writing for the general public, use the simplest language that isn’t pedantic. Generally, the eigth grade level is appropriate. If you are writing a scientific journal article, or a technical article, use appropriate terminologogy without being needlessly complex.

    Try to remember what you learned in your middle school English classes: describe what you are going to talk about in headings, and state your subject or theses of your paragraph at the beginning of the paragraph or section, and limit your paragraphs to one main idea.

    Abbreviations and Acronyms

    Specify what each abbreviation or acronym in a document means. Although the WCAG recommendations state that you should expand the term only where the first abbreviation or acronym occurs, your visitor may be visiting your page thru an anchored hyperlink, thereby missing the defintion. You don’t have to expand all abbreviations or acronyms: expand ones that could be helpful to the user, and don’t expand ones that are used in everyday language. For example, we all know the definitions is for TV, DVD is it’s own definition and who knows what it really expands to. If you’re going to use THC you need to expand it because you’re likely defining it, and few people remember that it means Tetrahydrocannabinol. You will want to define it the first time you use it for all users, and use <acronym title="Tetrahydrocannabinol">THC</acronym> for all other occurrences within a page. If you are going to use an acronym that is commonly used and not easily misconstrued, such as HTML, expand it the first time it’s used: if a user doesn’t know what it means, they can look for the first occurrence.

    Server-side image maps:

    Likely not an issues for most developers, and server-side image maps have become almost obsolete. Most sites have moved away from server-side image maps. The exception is for such things as geographical information system clickable maps. So, if you insist on a server side image map, redundant text links should be provided for each active region.

    Client-side image maps:

    Include the alt attribute for each map area. Also include the alt attribute (duh!) in the image. Client-side image maps, unlike server side image maps, are generally accessible with just a little code, so the recommendation is to include client side image maps instead of server-side images maps. Modern browsers support client-side image maps, with the addition of "alt" attributes for the image hot spots, assistive technology readers can provide additional clues. However, if the user has "load images" turned off, the only approach is to provide alternative links. So, include an "alt" attribute in each and every hot spot.

    Data tables

    Tables should only be used for tabular data. Don’t use tables for layout. Again. Don’t use tables for layout.

    Row and column headers should be identified for data tables.

    Using row and column headers — <th> instead of <td> — becomes crucial when a table is larger than two columns or two rows. Without the headers, assistive technology such as reader software can only recite the table contents with no reference to what that column or row pertains to.

    Multi-logic row or column headers

    The <thead> and <tbody> tags should be used to differentiate between the data table header and the data table body. Markup should be used to associate data cells and header cells for data tables that have two or more logical levels of row or column headers. Additional information such as "summary" and "scope" can be applied to data tables to render their contents and intent meaningful to users of assistive technology. The "summary" attribute should summarize the data that the table contains. "Scope" can be very useful for column headers. For simple data tables, the “scope” attribute should be used to differentiate between row headers and column headers. For complex data tables, each data table cell should be explicitly associated with its relevant table header. To do this, add an “id” attribute to the <th> tags and reference this id by using the “headers” attribute within each <td> tag.


    Don’t use frames, especially complex frame sets. But, if you are going to use frames, title frames with text that facilitates frame identification and navigation. If you do use frames (please don’t) include a “title” attribute that accurately identifying its role or purpose. With the "title", "name" and "longdesc" attributes, frames can be made more navigable for reader software, but they still shouldn’t be used. Iframes are o.k.  Use the title attribute for iframes.

    Flicker Frequency

    Unless you are aiming to be on http://www.websitesthatsuck.com, you shouldn’t have flickering on your website.  But, if that is indeed your goal, design pages to avoid causing the screen to flicker with a frequency greater than 2 Hz and lower than 55 Hz. Flicker and continuous motion (as from applets or scripts or from refreshes) can cause seizures in individuals with photosensitive epilepsy. Try not to use time-sequenced elements. If used, choose your timing carefully.

    Text only equivalent

    Provide a text-only page, with equivalent information or functionality to make web pages accessible when compliance cannot be accomplished in any other way. The content of the text-only page should be updated whenever the primary page changes. Only resort to alternative pages when there aren’t any other ways of making your pages accessible. An out-of-date page is as frustrating as one that is inaccessible since, in both cases, the information presented on the original page is unavailable. Before resorting to an alternative page, reconsider the design of the original page.

    Making Scripting languages accessible

    When pages use scripting languages to display content, or to create interface elements, the information provided by the script should be identified with functional text that can be read by assistive technology. The easiest method to provide this accessible alternative is to write HTML code which includes the <noscript> tag. Other options include ensuring that dynamic content and refreshes can be made or are accessible.  Some will argue that the <noscript> should not be used; and I definitely understand their rationale, since the <script> should be external making <noscript> moot.  However, there are certain cases where it does make sense, so I won’t say "don’t use it."

    If you are using javascript and have a "return false" as an event for the onClick event handler, the link’s href should redirect to a page where the required effect. Do not use <a href="#" ....> or <a href="javascript:.....>. Instead use <a href="validURL....>. If you have an X as a link to hide a div on a page, clicking on the link to with javascript turned off should redirect the user to a page with that div hidden.

    According the the W3C, you should use event handlers in pairs for mouse users and keyboards users: using "onmousedown" with "onkeydown", "onmouseup" with "onkeyup" and "onclick" with "onkeypress", but since most sites aren’t accessible, many users who are unable to use mice actually set up a key to act like a mouseclick, and using onkeypress can override their settings. So, it’s important to make sure that any event that is required via javascript is also available to those without javascript.

    Accessible AJAX

    Screen readers are not informed when an AJAX or DHTML implementation dynamically changes the content of the page. AJAX is considered accessible if it doesn’t change the content of the page to any extent other than enhancement, or, if it does change the content of the page, that the user is informed of a change by a means other than a visual cue. When content is dynamically changed, the new content should receive focus to inform the user that the content is new. However, only form elements and links can receive focus.

    There are two suggestions for making AJAX more accessible

    The suggestion first is to make the screen reader know there new content by giving a tabindex value of -1 to the new elements unable to receive focus. Although -1 is not a valid tabindex value, it is able to receive focus with JavaScript, but will not be placed in the tab order, which makes it findable to screen readers but will not cause problems for keyboard navigators. To make dynamic content available, give focus to added content via the tabindex using javascript.

    The second suggestion is to use the role attribute. Not just in with AJAX, but with everything in Web 2.0 applications, anything can be a button or a control interface (like a slider or container). The accessibility problem is that there’s no way for a screen reader to know about the functionality of those elements. The XHTML role attribute enables the addition of semantic information to the containing element.

    Applets, Objects, Plug-ins

    When a web page requires that an applet, plug-in or other application be present on the client system to interpret page content, the page should provide a link to a plug-in or applet that complies. Objects and data which require plug-in applications can be presented in HTML code in a nested manner such that, if the user’s browser can’t display the topmost data type, it will attempt to display equivalent data type in the object specification. This is more complicated HTML code to create and requires several data types to be resident on the server, but it is a more complete method of inclusion which favors neither advanced nor dated browser technology.


    When electronic forms are designed to be completed on-line, the form should allow people using assistive technology to access the information, field elements, and functionality required for completion and submission of the form, including all directions and cues. If you are going to dynamically submit the form based on user action other than clicking on a submit, ensure that the form is still submittable with javascript disabled.

    Also, every form field should have a label element that is uniquely associated with it using the “for” and “id” attributes. Where a textual label does not fit into the visual design of the page, the field should still have the label hidden through CSS. Remember that you should not use display: none, as that will hide it from screen readers as well.

    Content tracking

    A method should be provided that permits users to skip repetitive navigation tasks. There are a number of methods of facilitating navigation for users of assistive technology. Be consistent in page-to-page design, designers can provide a jump-link to bypass a series of links on a page similar to the "back to top" used in long pages, when using multiple links close together, separate the links so the reader software can parse it correctly. For example, use list items or separate text links with a pipe (|). Links should be referenced with text which make sense if a user if link-jumping. Also, consider adding a site map, which is useful to nearly everyone.

    Links need to be contextual and real

    Contextual Links
    Links need to mean something. Can you images tabbing thru a list of "MORE", "MORE", "MORE" with a screen reader. While your designers and marketing team might insist that your links look meaningless, you can still make meaningful links with XHTML and CSS.

    The XHTML content will look like this:

    <a href="link.html">MORE <span class="accessibilty"> on Contextual Links</span></a>

    and the CSS looks like this:

    a span.accessibility {
       position: absolute;
       left: -2000px;

    In this manner, visually it looks like just the word "MORE", but to the screen reader the purpose of the link is visible. Do not use visibility: hidden; display; none; as hiding from the screen also hides it from the screen reader

    Real Links with Real Destinations

    All <a href=" ... should link to a real URL or a real anchor.
    If you have a link with an event handler that retrieves content via AJAX, the href of that link should redirect the user to a page that contains the content that would have been retrieved. If you don’t have a destination for the link, don’t use a link.  You can add event handlers to any object in the DOM, not just links.  The best way to understand this concept is to turn off javascript and make sure that all of your links are indeed links. If you are including an element simply to create a dynamic effect, consider employing a span with an event handler attached instead of a meaningless javascript:void().

    Timed Response

    When a timed response is required, the user should be alerted and given sufficient time to indicate more time is required.


    The site should validate. You can validate your web page here.

    The "Role" Attribute

    In Web 2.0 applications, when an HTML element such as a form element is converted into a button or a control interface, there is no way for the screen reader to understand the conversion and the functionality of the converted element. The XHTML role attribute enables the addition of semantic information to converted elements.

    <p class="note" role="note">
    <ul role="navigation">

    See the w3 guidelines and ARIA Roles for more information.

    16 Common JavaScript Gotchas

    We all know that JavaScript can trip you up. Here are a 16 common traps that can trip you up when coding javascript. You likely know most of the code on the page, but if you keep these 16 gotchas in your mind, coding and debugging will be less of a headache:

    1. Case sensitivity: Variable names, properties and methods are all case sensitive
    2. Mismatching quotes, parenthesis or curly braces will throw an error
    3. Conditional Statments:3 common gotchas
    4. Line breaks: Always end statements in semi-colons to avoid common line break issues
    5. Punctuation:Trailing commas in object declarations will trip you up
    6. HTML id conflicts
    7. Variable Scope: global versus local scope
    8. string replace function isn’t global
    9. parseInt should include two arguments
    10. ‘this’ and binding issues
    11. Function overloading: Overwriting functions, as overloading doesn’t exist
    12. Setting default values for parameters in case you omit them
    13. For each loops are for objects, not arrays
    14. switch statements are a little tricky
    15. Always check for Undefined before checking for null
    16. Function location may matter
    Case Sensitivity
    Variables and function names are case sensitive. Like mismatched quotes, you already know this. But, since the error may be silent, here is the reminder. Pick a naming convention for yourself, and stick with it. And, remember that native javascript function and CSS properties in javascript are camelCase.

    getElementById('myId') != getElementByID('myId'); // it should be "Id" not "ID"
    getElementById('myId') != getElementById('myID'); // "Id" again does not equal"ID"
    document.getElementById('myId').style.Color; // returns "undefined"
    Mismatching quotes, parenthesis and curly brace
    The best way to avoid falling into the trap of mismatched quotes, parentheses and curly brackets is to always code your opening and closing element at the same time, then step into the element to add your code. Start with:

    var myString = ""; //code the quotes before entering your string value
    function myFunction(){
         if(){   //close out every bracket when you open one.
    //count all the left parens and right parens and make sure they're equal
    alert(parseInt(var1)*(parseInt(var2)+parseInt(var3))); //close every parenthesis when a parenthesis is open

    Every time you open an element, close it. Put the arguments for a function into the parenthesis after you’ve added the closing parenthesis. If you have a bunch of parenthesis, count the opening parenthesis and then the closing parenthesis, and make sure those two numbers are equal.

    Conditional statements (3 gotchas)
    1. All conditional comments must be within parentheses (duh!)
      if(var1 == var2){}
    2. Don’t get tripped up by accidentally using the assignment operator: assigning your second argument’s value to your first argument. Since it’s a logic issue, it will always return true and won’t throw an error.
      if(var1 = var2){} // returns true. Assigns var2 to var1
    3. Javascript is loosely typed, except in switch statements. JavaScript is NOT loosely typed when it comes to case comparisons.
      var myVar = 5;
      if(myVar == '5'){ // returns true since Javascript is loosely typed
        alert("hi");  //this alert will show since JS doesn't usually care about data type.
        case '5':
        alert("hi"); // this alert will not show since the data types don't match
    Line Breaks
    • Beware of hard line breaks in JavaScript. Line breaks are interpreted as line-ending semicolons. Even in a string,if you include a hard line break in between quotes you’ll get a parse error (unterminated string).
          var bad  = '<ul id="myId">
                         <li>some text</li>
                         <li>more text</li>
                      </ul>'; // unterminated string error
          var good = '<ul id="myId">' +
                         '<li>some text</li>' +
                         '<li>more text</li>' +
                     '</ul>'; //correct
    • The line break being interpreted as a semi-colon rule, discussed above, does not hold true in the case of control structures: line breaks after the closing parenthesis of a conditional statement is NOT given a semi-colon.

    Always use semi-colons and parenthesis so you don’t get tripped up by breaking lines, so your code is easier to read, and, less thought of but a source of quirks for those who don’t use semicolons: so when you move code around and end up with two statements on one line, you don’t have to worry that your first statement is correctly closed.

    Extra commas
    The last property in any JavaScript object definition must never end with a comma. Firefox won’t barf on the trailing, unnecessary commas, but IE will.

    HTML id conflicts
    The JavaScript DOM bindings allow indexing by HTML id. Functions and properties share the same namespace in JavaScript. So, when an id in your HTML has the same name as one of your functions or properties, you can get logic errors that are hard to track down. While this is more of a CSS best practice issue, it’s important to remember when you can’t solve your javascript issue.

    var listitems = document.getElementsByTagName('li');
    var liCount = listitems.length; // if you have <li id="length">, returns that <li> instead of a count.

    If you’re marking up (X)HTML, never use a javascript method or property name as the value for an ID. And, when you’re coding the javascript, avoid giving variables names that are ID values in the (X)HTML.

    variable scope
    Many problems in javascript come from variable scope: either thinking that a local variable is global, or overwriting a global variable unwittingly with what should be a local variable in a function. To avoid issues, it’s best to basically not have any global variables. But, if you have a bunch, you should know the “gotchas”.

    Variables that are not declared with the var keyword are global. Remember to declare variables with the var keyterm to keep variables from having global scope. In this example, a variable that is declared within a function has global scope because the var ke

    anonymousFuntion1 = function(){
    	globalvar = 'global scope'; // globally declared because "var" is missing.
    	return localvar;
    alert(globalvar); // alerts 'global scope' because variable within the function is declared globally
    anonymousFuntion2 = function(){
    	var localvar = 'local scope'; //locally declared with "var"
    	return localvar;
    alert(localvar); // error "localvar is not defined". there is no globally defined localvar

    Variable names that are introduced as parameter names are local to the function. There is no conflict if your parameter name is also the name of a global variable as the parameter variable has local scope. If you want to change the global variable from within a function that has a parameter duplicating the global variable’s name, remember that global variables are properties of the window object.

    var myscope = "global";
    function showScope(myscope){
      return myscope; // local scope even though there is a global var with same name
    function globalScope(myscope){
      myscope = window.myscope; // global scope
      return myscope;

    You should even declare variables within loops

    for(var i = 0; i < myarray.length; i++){}
    string replace
    A common mistake is assuming the behavior of the string replace method will impact all possible matches. Infact, the javascript string replace method only changes the first occurrence. To replace all occurrences, you need to set the global modifier.

      var myString = "this is my string";
      myString = myString.replace(/ /,"%20"); // "this%20is my string"
      myString = myString.replace(/ /g,"%20"); // "this%20is%20my%20string"
    The most common error with parding integers in javascript is the assumption that parseInt returns the integer to base 10. Don’t forget the second argument, the radix or base, which can be anything from 2 to 36. To ensure you don’t screw up, always include the second parameter.

    parseInt('09/10/08'); //0parseInt('09/10/08',10); //9, which is most likely what you want from a date.
    Another common mistake is forgetting to use ‘this‘. Functions defined on a JavaScript object accessing properties on that JavaScript object and failing to use the ‘this’ reference identifier. For example, the following is incorrect:

    function myFunction() {
      var myObject = {
         objProperty: "some text",
         objMethod: function() {
    function myFunction() {
      var myObject = {
         objProperty: "some text",
         objMethod: function() {

    There’s an A List Apart article that puts this binding issue into plain English

    Overwriting functions / overloading functions
    When you declare a function more than once, the last declaration of that function will overwrite all previous version of that function throwing no errors or warnings. This is different from other programming languages, like java, where you can have multiple functions with the same name as long as they take different arguments: called function overloading. There is no overloading in javascript. This makes it vitally important to not use the names of core javascript functions in your code. Also, beware of including multiple javascript files, as an included script may overwrite a function in another script. Use anonymous functions and namespaces.

    	// creation of my namespace
        // if namespace doesn't exist, create it.	if(!window.MYNAMESPACE) {		window['MYNAMESPACE'] = {}; 		}
        // this function only accessible within the anonymous function
        function myFunction(var1, var2){
    		//local function code goes here
        /* attaches the local function to the namespace
           making it accessible outside of the anoymous function with use of namespace */
        window['MYNAMESPACE']['myFunction'] = myFunction; 
     })();// the parenthesis = immediate execution	  // parenthesis encompassing all the code make the function anonymous
    Missing Parameters
    A common error is forgetting to update all the function calls when you add a parameter to a function. If you need to add a parameter to handle a special case call in your function that you’ve already been calling, set a default value for that parameter in your function, just in case you missed updating one of the calls in one of your scripts.

    function addressFunction(address, city, state, country){
          country = country || "US"; // if country is not passed, assume USA
          //rest of code

    You can also get the length of the argument array. But we’re focusing on “gotchas” in this post.

    For each
    The “for” loop in javascript will iterate it over all object attributes, both methods and properties, looping thru all of the property names in an object. The enumeration will include all of the properties—including functions and prototype properties that you might not be interested in—so filter out the values you don’t want using hasOwnProperty method and typeof to exclude functions. Never use for each to iterate thru an array: only use for each when needing to iterated thru object properties and methods.

    • for each (var myVar in myObject) iterates a specified variable over all values of object’s properties.
    • for (var myVar in myObject) iterates a specified variable over all the properties of an object, in arbitrary order. The for...in loop does not iterate over built-in properties. For each distinct property the code is executed
    • for (var 1=0; i < myArray.length; i++) iterates thru all the elements of an array.

    To fix the problem, generally you’ll want to opt for for ... in for objects and use the for loop for arrays:

    listItems = document.getElementsByTagName('li');
    for each (var listitem in listItems){
        // this goes thru all the properties and methods of the object,
        // including native methods and properties, but doesn't go thru the array: throws error!
    //since you have an array of objects that you are looping thru, use the for loop
    for ( var i = 0; i < listItems.length; i++) {
        // this is what you really wanted
    Switch statements
    I wrote a whole blog post on switch statement quirks, but the gist is:

    • there is no data type conversion
    • once there is a match, all expressions will be executed until the next break or return statement is executed, and
    • you can include multiple cases for a single block of code
    Undefined ≠ null
    Null is for an object, undefined is for a property, method or variable. To be null, your object has to be defined. If your object is not defined, and you test to see whether it’s null, since it’s not defined, it can’t test, and will throw an error.

    if(myObject !== null  && typeof(myObject) !== 'undefined') {
    	//if myObject is undefined, it can't test for null, and will throw an error
    if(typeof(myObject) !== 'undefined' && myObject !== null) {
    	//code handling myObject

    Harish Mallipeddi has an explanation of undefined versus null

    Function location can matter
    There are two ways to declare function: When declaring a function in the form of a variable assignment, location does matter:

    var myFunction = function(arg1, arg2){
      // do something here

    A function declared with

    function myFunction (arg1, arg2){}

    can by used by any code in the file no matter its location (before or after the function declaration). A function declared with the variable assignment syntax can only be used by code that executes after the assignment statement that declares the function.

    WAI-ARIA: Accessible Rich Internet Applications basics

    What is ARIA?

    ARIA stands for Accessible Rich Internet Applications. With the proliferation of internet applications, there has been an increase in the number of sites requiring javascript that update without page refreshes. This imposes accessiblity issues that weren’t addressed by WCAG 1, as those specifications were written when “sites must work without javascript” was a reasonable accessibility specification. With the increase of web based “applications” (versus “sites”) requiring JavaScript, and improved support of javascript in assistive technologies, new accessibility issues have emerged. ARIA attempts to handle some of those issues. Through the inclusion of roles, states and properties your dynamically generated content can be made accessible to assistive technologies. Additionally, static content can be made more accessible thru these additional, enhanced semantic cues.

    Why use ARIA?

    By including ARIA accessibility features on your website you are enhancing the accessibility of your site or application. By including roles, states and properties, ARIA enables the developer to make the code semantically richer for the assistive technology user. ARIA enables semantic description of element or widget behavior and enables information about groups and the elements within them. ARIA states and properties are accessible via the DOM.

    Similar to including the title attribute, ARIA is purely an enhancement and will not harm your site in any way. In other words, there is no valid reason to not include these features! DojoTools currently supports ARIA. Now that IE8 and Firefox 3 (both in beta at the time of this writing) support ARIA, the other JavaScript libraries should soon follow suit.

    The easiest to include and most important properties of ARIA are the inclusions for the role attribute, and inclusion of states and properties.

    How to incorporate ARIA

    1. Use XHTML the way it was meant to be used wherever possible. Limit ARIA usage to augment XHTML: only use it when XHTML does not support all the semantics required .
    2. Apply ARIA the role attribute in cases where the XHTML needs to be semantically enhanced and in cases where elements are being employed outside of their semantic intent. This includes setting up relationships between related elements (grouping)
    3. Set ARIA states and properties. Set the properties and initial state on dynamically and user changing elements. States, such as “checked”, are properties that may change often. Assistive technology that supports ARIA will react to state and property changes. role changes, on the other hand, may confuse the assistive technology
    4. Support full, usable keyboard navigation. Elements should all be able to have keyboard focus. I am not covering this here, but you can read up on this at For a more in-depth understanding of keyboard navigation see ARIA Best Practices
    5. Make the visual user interface visually match the defined states and properties in browsers that support the ARIA CSS pseudo-classes.

    The ARIA role attribute

    The role attribute enables the developer to create semantic structure on repurposed elements. While to a sited user, the above example of a span repurposed as a checkbox is not noticeable, the role attribute makes this seemingly non-semantic mark up accessible, usable and interoperable with assistive technologies. Two notes about roles: 1) once set, a role should not be dynamically changed, since this will confuse the assistive technology, and 2) roles take precendence over element default semantic meaning.

    Example: Your designer insists that they want the checkboxes on your page to look a certain way. “Impossible” you say. You know that you can use CSS to make a span look like a checkbox. The sited user would never know that your weren’t using <input type="checkbox"...., but for accessibility concerns, you know a screen reader user will not know it’s a checkbox. With the ARIA role attribute included in your code, a both a browser and screen reader that support ARIA, you can make your repurposed span accessible with:

    <span role="checkbox" aria-checked="true" tabindex="0" />

    Of course, this case makes me cringe, since it doesn’t work without javascript and it is not inherintly semantic. However, if you are creating a web application requiring javascript, and you are coding this when browsers actually support ARIA, then you gotta do what you gotta do. If you include spans transformed into checkboxes, you will need to include equivalent unobtrusive onkeydown and onclick events.

    Implementation of the ARIA role attribute

    <ul role="navigation">
      <li><a href="mypage.html">My Page</li>

    Values for the ARIA role attribute (For descriptions, roll over the items below)

    A message with an alert or error information

    A separate window with an alert or error information
    A software unit executing a set of tasks for its users
    A banner is usually defined as the advertisement at the top of a web page. The banner content typically contains the site or company logo and other key advertisements for the site
    Allows for user-triggered actions
    A control that has three possible values, (true, false, mixed)
    A table cell containing header information for a column
    Combobox is a presentation of a select, where users can type to locate a selected item
    This is information about the content on the page. For example, footnotes, copyrights, links to privacy statements, etc. would belong here
    The contents of the associated element represent a definition (e.g., of a term or concept). If there is a dfn element within the contents, then that represents the term being defined.
    Descriptive content for a page element which references this element via describedby.
    A dialog is a small application window that sits above the application and is designed to interrupt the current processing of an application in order to prompt the user to enter information or require a response
    A list of references to members of a single group.
    Content that contains related information, such as a book.
    A grid contains cells of tabular data arranged in rows and columns (e.g., a table).
    A gridcell is a table cell in a grid. Gridcells may be active, editable, and selectable. Cells may have relationships such as controls to address the application of functional relationships.
    A group is a section of user interface objects which would not be included in a page summary or table of contents by an assistive technology. See region for sections of user interface objects that should be included in a page summary or table of contents.
    A heading for a section of the page.
    An img is a container for a collection elements that form an image.
    Interactive reference to a resource (note, that in XHTML 2.0 any element can have an href attribute and thus be a link)
    Group of non-interactive list items. Lists contain children whose role is listitem.
    A list box is a widget that allows the user to select one or more items from a list. Items within the list are static and may contain images. List boxes contain children whose role is option.
    A single item in a list. Should be within an element with the role of list
    A region where new information is added and old information may disappear such as chat logs, messaging, game log or an error log. In contrast to other regions, in this role there is a relationship between the arrival of new items in the log and the reading order. The log contains a meaningful sequence and new information is added only to the end of the log, not at arbitrary points.
    This defines the main content of a document.
    A marquee is used to scroll text across the page.
    Offers a list of choices to the user.
    A menubar is a container of menu items. Each menu item may activate a new sub-menu. Navigation behavior should be similar to the typical menu bar graphical user interface.
    A link in a menu. This is an option in a group of choices contained in a menu.
    Defines a menuitem which is checkable (tri-state).
    Indicates a menu item which is part of a group of menuitemradio roles.
    This is a collection of links suitable for use when navigating the document or related documents.
    The content is parenthetic or ancillary to the main content of the resource.
    A selectable item in a list represented by a select.
    An element whose role is presentational does not need to be mapped to the accessibility API.
    Used by applications for tasks that take a long time to execute, to show the execution progress.
    A radio is an option in single-select list. Only one radio control in a radiogroup can be selected at the same time.
    A group of radio controls.
    Region is a large perceivable section on the web page.
    A row of table cells.
    A table cell containing header information for a row.
    This is the search section of a web document. This is typically a form used to submit search requests about the site or a more general Internet wide search service.
    This is any unique section of the document. In the case of a portal, this may include but not be limited to: show times; current weather; or stocks to watch.
    Indicates that the element contains content that is related to the main content of the page.
    A line or bar that separates and distinguishes sections of content.
    A user input where the user selects an input in a given range. This form of range expects an analog keyboard interface.
    A form of Range that expects a user selecting from discrete choices.
    This is a container for process advisory information to give feedback to the user.
    A header for a tabpanel.
    A list of tabs, which are references to tabpanels.
    Tabpanel is a container for the resources associated with a tab.
    Inputs that allow free-form text as their value.
    A numerical counter which indicates an amount of elapsed time from a start point, or the time remaining until an end point.
    A toolbar is a collection of commonly used functions represented in compact visual form.
    A popup that displays a description for an element when a user passes over or rests on that element. Supplement to the normal tooltip processing of the user agent.
    A form of a list having groups inside groups, where sub trees can be collapsed and expanded.
    A grid whose rows can be expanded and collapsed in the same manner as for a tree.
    An option item of a tree. This is an element within a tree that may be expanded or collapsed

    Note: when i have time to populate a dB, i will add a little ajaxian explanation as to the possible parents and children of each role. In the meantime, please visit WAI-ARIA Roles.

    ARIA states and properties

    Whereas roles are a static attribute of elements, states are properties that can change with user and server interactions. Properties include both dynamic states that need to be updated, and static properties, such as “required”.

    Values for the ARIA States

    Indicates whether a live region is finished updating.
    The checked state indicates something has been rendered as being chosen by the user in the sense that it is a binary or tertiary operation. An example is a checkbox.
    Indicates that the widget is present, but the value cannot be set and it cannot be internally navigated.
    Indicates whether an expandable/collapsible group of elements is currently expanded or collapsed.
    This property is set to show an object’s state in drag and drop.
    Defines whether or not the object is visible to the user.
    Indicates that the element’s value is currently invalid, which discourages the form from being submitted.
    Used for buttons that are toggleable to indicate their current pressed state.
    Sets whether the user has selected an item or not.

    Values for the ARIA Properties

    An element which has focus may specify its current active child. This is used when a element is responsible for managing its current active child to reduce the overhead of having all children be focusable.
    Atomic is an optional property of live regions. When the region is updated, the atomic property is used to indicate if the assistive technology should present all or part of the changed region to the user.
    Indicates whether user input completion suggestions are provided.
    This property specifies which channel should be used to present the updates for its associated live region.
    Defines the elements that are controlled by the current element.
    Datatype defines the format type of an element.
    Points to an element which describes the object.
    This property is set for the target of a drag and drop operation to show the effect when the dragged object is released.
    Establishes the recommended reading order of content, overriding the general default to read in document order.
    Indicates that element may launch a pop-up window such as a context menu or submenu.
    Points to the element which labels the current element.
    Level is the hierarchical level of an element within a structure.
    Describes the types of updates the user agent, assistive technology, and user can expect from an alert or live region of Web content.
    Indicates whether a text box accepts only a single line, or if it can accept multiline input.
    Indicates that the user may select more than one item from the current list.
    Defines an object as a parent of another document element, when the child does not appear directly in the subtree of the owner.
    Indicates an item’s number or position within the current level of a tree or list.
    Indicates that the widget is not editable.
    Indicates the relevant areas of change within a live region.
    Indicates that user input is required on the control before a form may be submitted.
    Provides the user with the ability to supply information to the system in a manner that makes it difficult for someone else (who may be watching) to discern the value that is being supplied.
    The setsize property refers to the number of items in the current level of a list or tree.
    The sort property is used to indicate if items in a table or grid are sorted in ascending or descending order.
    Indicates tab order of elements. Elements with negative values are able to receive focus but are not included in the basic tabbing navigation list or cycle.
    The templateid is a unique identifier, represented as a URI, for which an assistive technology may customize its user interface.
    Maximum allowed value for a range type of widget.
    Minimum allowed value for a range type of widget.
    The current value of a widget

    Certain properties belong with certain roles. For example, autocomplete makes sense with the roles combobox and textbox. The value of the property or state is also limited to certain value types. In our autocomplete example, the value would need to be selected from a list of predetermined values, whereas a checkbox could have a state of invalid, disabled, required or checked, to name a few, with a bolean as the value.

    Working with ARIA in Rich Internet Applications

    ARIA and Live Regions

    Live regions are sections of a web page or application that change dynamically either thru automatic updates or user interaction.
    There are 5 properties specific for Live Regions:

    indicate if the assistive technology should present all or part of the changed region to the user.
    has the live region is finished updating

    Politeness levels: Should ARIA intrude on the user on updates?

    The value of the “live” state are expressed in terms of “politeness” levels. “Polite” regions notify of updates but do not interrupt users, and updates take low priority. A level of “rude” would indicate that the assistive technology should interupt the users current action to provide update information. A good example of using a polite level would be the ticker on a financial page — the user does not need to be interupted every 10 seconds to be informed as to whether a stock value has change. An example of a time to use a “rude” level is when the user has completed a step in a checkout process and the next step is visible. Values: Off, Polite, Assertive, Rude.

    Validating your XHTML when including un-speced attributes

    There is a tweak that you need to make in your XHTML page if you include ARIA: you need to use XHTML 1.1 and include the ARIA module in your header area. XHTML 1.0 does not support modularization. The ARIA States and Properties attributes will be understood by user agents in XHTML 1.0 by declaring and using the appropriate namespace the same as for XHTML 1.1, but such documents will not validate to the XHTML 1.0 DTD. None of the DTD snippets below enable validation, but I will update when the modules and/or specifications are updated. The first doctype listed is the HTML5 doctype, which will fully support ARIA when the spec is approved.

    <!DOCTYPE html>
    <DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1
        For Accessible Adaptable Applications//EN" "http://www.w3.org/2005/07/aaa/xhtml11-aaa.dtd">
    <!DOCTYPE html PUBLIC "Accessible Adaptive Applications//EN"
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 Strict//EN" "
    <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:aaa="http://www.w3.org/2005/07/aaa" lang="en">


    • ARIA and HTML4: HTML 4.01 is non-extensible, so you can’t use namespaces for the property and state names. Please view the specs as they become available to see the HTML 4.01 support for ARIA.
    • ARIA and HTML5: Note that this post was originally written in 2008.  It is expected that ARIA will be fully supported as a module of the HTML5 specifications. HTML5 WHATWG ARIA spec

    IE8: What you need to know

    IE8 CSS Support and Rendering Mode, IE8 debugging, etc.

    IE8 and CSS

    IE8 came out today. I appended the CSS selector browser support blog post to include IE8 CSS Selector support and IE7 compliance mode CSS Selector support. Most notable is that IE8 Supports all of CSS2.1 and passes the Acid 2 test.

    IE8 compliance mode / preventing IE7 rendering in the IE8 browser

    Important to know is that IE8 has a button that allows users to render your page in IE7. If that button is clicked enough, your page will always render in IE7 for everyone (not just those who clicked the button). So, do you have to test your pages in IE8 in IE7 mode? No, you don’t. To ensure that your page is not rendered in IE7 mode inside the IE8 browser add the following meta tag to your pages:

    <meta http-equiv="X-UA-Compatible" content="IE=8" />

    Alternatively, if you want your pages to render in IE7 mode you can write: <meta http-equiv="X-UA-Compatible" content="IE=7" />. The issue with this is that IE7 rendering in IE8 is not identical to plain IE7. So, I recommend against using this meta tag.

    So, to ensure that you DON’T have to test in IE7, IE8 and IE8 in IE7 mode, add the code above.

    To learn more about what IE8 supports, check out IE8 CSS Selector support.

    IE8 bugs

    IE8 JavaScript Bug: Apparently IE8 doesn’t much care for prototype and prototip. I think it’s an issue with className that causes IE8 to choke. In the meantime, if you are using Ruby on Rails, then you’re probably using prototype.js. And, if you’re using prototype.js, then IE8 chokes, so you have to use the meta tag. And, if you use the
    <meta http-equiv="X-UA-Compatible" content="IE=7" /> tag, make sure it’s the FIRST thing on your page, because IE8 suck ass, just like IE7 and IE6.

    If you’re more of an ASP.net fan (which I am NOT!), there is another issue with menus not showing. Mark Hidreth explains it in his blog., but in short, the solution is to add a z-index of greater than zero to <asp:Menu>. Thanks to Attiq Jafar for alerting me to this bug and solution.

    IE8 Disappearing Page Bug: If you put two adjacent nodes, both positioned absolutely, and set only one of x- or y- positioning, you may get a blank page.

    Differences between IE7 compatibility mode and IE8

    These are just a few differences that I have found so far. Please do NOT consider this an exhaustive list

    1. default padding on <p> is not equal
    2. table { border-collapse: collapse;} is NOT rendered the same. If dashed, IE8 is properly dotted or dashed, whereas IE7 overlays the lines and it looks ugly, and otherwise does not collapse
    3. border bottoms on an inline element will not display in IE7 if the border is the lowest part of the page. The page will not grow to include the border, unless the bordered element is block. IE8 will grow.
    4. border: hidden; IE7 does NOT understand the value of hidden for the border property.
    5. border-style: outset The coloring is different for IE7 than IE8. IE7 is darker on the bottom/right. IE8 has the darker color on the top/left. Groove and
    6. RGB – IE7 displays RGB mixed number types: The spec states that values for RGB should be three integers or three percentages, but not a combo of the two. (IE7 and IE6 display mixed types. IE8 and standards compliant browsers dow not render colors with mixed value types.
    7. IE8 has support for content:, counter-increment: and counter-reset: IE7 doesn’t!
    8. Empty declarations overide in IE7, but not 8: IE7 will not show a property if there is a malformed declaration after the element. p { color:green; color: } – IE8 will show green. IE7 wont.
    9. Identifiers starting with a digit or non-letter character followed by a digit: Identifiers starting with dash-number choke IE7: If there is a series of classes or ids listed, including ones that start with a dash followed my an integer, IE7 will choke, and ignore all the selectors in the series. For example,
      .-3myClass, .blue {color: blue;}
      #-3myClass, .blue {color: blue;}
      .3myClass, .blue {color: blue;}
      #3myClass, .blue {color: blue;}

      The element with a class of blue will NOT inherit the blue from either of these declarations

    10. @import is not correctly supported in IE7: @import “support/import-coloroveride.css”; (see the one before it for comparison)
    11. border-width: thin appears to be 1px wide in IE8 and 2px wide in IE7
    12. clearing: if you clear an element in IE7 after a floated element, and the element has a margin top, that will be the space between it and the floated element. In IE8, the margin top will be the space between it and the last non-floated element.
    13. box model: Some people believe that IE got the box model right, and the w3c got the box model wrong. IE8 gets the box model right according to the w3c.

    IE8 CSS Hack

    This IE8 CSS hack uses the star hack to target IE7 and lower, but you can use any other of the many IE hacks to target older IE browseres.

     p.myclass {    
         color: green;    
         *color: red; 
    body:last-child p.myclass {
         color: blue; 

    IE8 Developer Toolbar (or Firebug for IE8)

    IE8 comes with a developer toolbar. The developer toolbar is definitely more robust than what came with IE7. Similar to Firebug, you highlight an element, and can edit CSS on the fly, but the mechanism is less robust. The CSS module informs you of inherited CSS and current values (in reverse order from Firebug). The CSS panel has check boxes next to each css property so you can turn on and off that property, and you can indeed edit the value or property by clicking on the value or property. You can’t use the up/down arrows like in Firebug, and unlike Firebug, the change isn’t instant: you have to click out of the property to see the change. However, it is definitely an improvement on the previous dev toolbar.

    I should probably write a tutorial on this developer toolbar, but I really don’t care enough about this browser to put the effort in to it…. but maybe.