@font-face Browser Support & Tutorial

Up to now, web developers were limited in what typography they could use on a website to what the client had installed in their environments. Now that we have finally convinced designers to not include any fonts outside of georgia, helvetica, arial, times roman, and a handful of others because of the awfulness of text images, @font-face allows us to retrain designers to use unique fonts, only if they have the legal right to post those fonts on the web.

What is @font-face

Generally, we’ve been limited to using the fonts pre-installed on MS Windows, Mac and Linux OSs. Increasing support of the CSS3 @font-face allows us to load a font onto our servers, link to and name that font in our CSS, and then use that font we’ve imported as if it were a native font in the client’s environment. With @font-face, we can worry less about what font our users have installed, and make our sites better match the intentions of our designers. @font-face enables you to provide your own font(s), @font-face eliminates the need to depend on the limited number of fonts users have installed on their computers

Browser Support for @font-face

CSS2 introduced @font-face. CSS2.1 killed it. CSS3 is reintroducing it. Why do you need to know the history? Because, it means there is actually a feature of CSS3 that internet explorer supports, albeit, differently than all other supporting browsers.

Because I am browser support table happy, here is the @font-face browser support table:

CSS Property IE6 IE7 IE8 Safari iPhone Chrome Firefox Opera
@font-face       3.2 3.5 10
format EOT EOT EOT TTF/OTF 3.1 supports SVG TTF/OTF support added 1/25/10
SVG supported by default

* SVG is supported, but it’s a larger file size

Google Chrome and @font-face:

Google Chrome actually does support @font-face, but it was turned off by default until version released on 1/25/20. Chrome has supporte SVG fonts for a while now.

While developers have been able to turn on @font-face support in Chrome in their own environment, only Chrome users who have updated to the January 25, 2010 release have it on by default. Google chrome users tend to be quick at updating, but stats don’t indicate the version number, so as of right now you can’t assume that Chrome has @font-face turned ON as the default settings for most users. Like with all site enhancement features, feel free to include fonts of type TTF/OTF, but make sure to pick a font backup that degrades nicely.

Note: Digging deeper, I found Becoming a font embedding master which both explains a link on where you can convert TTF2EOT so you can display similarly on IE than on good browsers (yeah, I said it) and exporting to SVG for font support on iPhone 3.1, Chrome 2 & 3, and 4 less than, and Opera 9 (your SVG font will work in Opera 10 and future versions of FF, Chrome, iPhone and Safari as well). Also check out FontSquirrel to convert your font files to differing formats (EOT, SVG, WOFF) for greater browser support. WOFF is a new format that Mozilla is hoping will become the browser standard. It is supported in FireFox only, as of FF3.6

Internet Explorer and @font-face:

Internet Explorer has been implementing @font-face support since version 4*. In any event, it is defintely supported in IE6, IE7 and IE8. However, their implementation relies on Embedded Open Type (.eot), a proprietary format, which no other browsers use. To make IE users happy (which some could argue you shouldn’t, as a method to encourage them to upgrade), import EOT fonts in addition to TTF/OTF fonts, and included them as "fall backs" in the font family declaration (discussed in @font-face implementation below) . FontSquirrel is a place where you can convert fonts you can legally distribute to EOT (and SVG) format.

* Note: Most people say original support of @font-face was IE5. I am not sure and I am not going to pull out my 286 to check. However, with a search, I found that IE4 had a few rendering issues, like not rendering anything on the page until the font was downloaded, so I am sticking with 4.

@font-face implementation

The syntax for the @font-face implemenation is:

@font-face {
  font-family: yourNameForTheFont; /* required */
  src: source;						/* required */
  font-weight: weight;				/* optional */
  font-style: style;				/* optional */

The font-family name can be anything you make up. I like to make it one word, for ease of entering it correctly as a value of the font-family property of a CSS selector later.

Declaring font-family source(s):

The source can take several formats. In addition, you can declare more than one source. If the browser doesn’t find the first source, it will go for the next source, and so on, until it either finds a source, or it runs out of sources. Example formats include:

@font-face {
     font-family: curlyQ;
     src: url('../fonts/makeUpSomethingElse.eot');
     src: local('Edwardian Script ITC'),
          url('../fonts/EdwrdScrpItc') format('opentype'),
          url('../fonts/GaelicWimsy') format('svg'),

In the above example, I’ve listed 5 sources. A bit excessive, but I wanted to explain those five components, so I made an excessive example.

The first declaration is for IE. IE ignores local, which is the first declaration in the second listing. In this way, IE only downloads what it needs and doesn’t download stuff it doesn’t understand.

Next I declare a font local to the user’s machine: local('Edwardian Script ITC')**. This looks for the font file locally on the site visitors computer. IE ignores local, which is great, since it will then ignore the other stuff it doesn’t understand. If you don’t have a local font style to declaration, it is OK. IE also doesn’t understand the multiple listings or the format, so as long as you include local, more than one declaration or a declaration with a format suggestions, IE will do o.k. IE will either ignore in the case of local, or misunderstand it, if there is a format or more than one declaration withing a property/value pair.

If your suggested format is incorrect, as long as the file is an understood format, it should work in Safari, Opera and Firefox.

The next example looks for a file in the SVG format. This is what you are feeding to Chrome and Opera 9.

The last example is a data example, cut way short. Actual fonts will have a few thousand characters. Similar to how you can include a data source for images, you can include them for fonts. TypeKit (described below) actually serves their fonts up in data format to Firefox and Safari, and serves EOT for IE.

**Note: Watch this page become the first google results for Edwardian Script. That would be funny. None of these examples are actually meant to work. I made the URLs and file names up.

Applying imported fonts with CSS selectors

Once the font is declared using the @font-face syntax, you can then refer to it as you would helvetica, arial, etc. Using the example above:

h3 {
    font-family: yourNameForTheFont, curlyQ, arial, helvetica, sans-serif;

Note that I have included two imported font family names. That is legal. Note that I have also included common fonts and a default font. That is HIGHLY recommended.


While the TypeKit website indicates support for Firefox 3.5+, Safari 3.4+ and all versions of IE, parsing the TypeKit javascript, they have support for the following browser engine versions:

Browser Type Version
Gecko 1.9.1
Safari 525.13

supported by TypeKit.
Chrome has @font-face support turned off by default

IE 6.0
iPhone specifically excluded in Typekit
Opera not included in Typekit, though Opera Supports @font-face

However, I am reading obfuscated code, so I could be talking out of my tushy. I did test in those browsers (not necessarily those versions, but those browsers), and it works in all except iPhone.

The way TypeKit works is you join TypeKit, enter the domain you want to use TypeKit on (you’re only allowed one domain for the free version), and select the fonts you would like to enable for that domain. TypeKit provides you with a link to a script file and a javascript snippet to add to your document <head>. TypeKit also provides you with a class that you can add to elements that you want to have the font, and provides you with a snippet of CSS code for the font-family property that you can sprinkle your CSS with for selectors where you want to use the TypeKit font.

The TypeKit javascript that you attach to your code basically does a LOT of browser sniffing, and only serves up to Gecko, Safari (not iPhone), Chrome and IE6+. Since it is sniffing, it doesn’t serve up any CSS to browsers not in the sniffing. So, while Opera10 does support @font-face, TypeKit does not.

Microsoft WEFT

The Microsoft WEFT is a free utility to create linked font objects. WEFT font objects are compressed and are privately installed by IE in a way that is inaccessible to other applications on the computer and other websites. WEFT supports OpenType (OTF) and TrueType (TTF) fonts in TrueType (TTF) format.


The main issue with @font-face is the ownership of the fonts. Make sure you are legally allowed to upload and share a font before using @font-face, as when you embed a font, that is what you are doing: sharing a file. Just like music, for most fonts it is illegal to upload and share without proper attribution and/or payment.

Posted in Browsers, CSS (including hacks), Web Development | 25 Comments

Web Development for the iPhone: HTML, CSS & JS Support

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


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


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


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


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

Posted in Accessibility, Best Practices, Browsers, Character Entities, contactApp, CSS (including hacks), DTD, firebug, HTML, IE7, InvoiceApp, iPhone, JavaScript, Web Development | 5 Comments

Moving from Web 1.0 to Web 2.0

Moving from Web 1.0 to Web 2.0: Skills you need to know to stay relevant.

Here is the audio.

Posted in AJAX, Best Practices, Browsers, firebug, Web Development | Leave a comment

Dreamweaver tip for screen shot creation

I write a lot of tutorials. Really, really basic tutorials. While I generally program in BBedit, Eclipse, vi, gEdit, NoteTab, or whatever makes sense at the moment, I write most of my tutorials and blog posts in Dreamweaver. While this blog doesn’t contain many screen shots, my basic tutorials are filled with them. I made a new discovery today that is going to make my tutorial writing so much easier. This may be old news for avid Dreamweaver users, but it’s new to me, so I thought I would share.

The Tip: When you do a screen capture in Firefox (or any other open application) and you go to Dreamweaver, pasting whatever is in memory (your screenshot) into Dreamweaver design view enables you to save and add your screen shot directly into your open page.

I’ve been spending a huge amount of time creating my tutorial images for my Community MX workshops in Fireworks. I’ve successfully reduced the time to create screen shots.

Here are my steps:

  1. While in Firefox, I go into Firebug to alter the text of what i want to take a screen shot of so I can anonymize my email address and provide generic domain names. I don’t really own “[email protected]”. With Firebug, I can change all the email address examples, IP addresses, domain names, etc., to make them generic to hide from possible creeps who enjoy stalking in their spare time. Using firebug to alter text is much faster than trying to create text that fits into the available space and matches the other text in an image editing program.
  2. Then I use “screengrab”, another firefox extension, to take a screen shot of just the section of my Firefox. I could also use “grab” to capture a selection on my Mac.
  3. Then, in Dreamweaver, I hit where I want the picture added to my tutorial. I get the Fireworks style “Export image as” and “Save” screens, enabling me to save the image to my images folder.  If i am in design view, I also get prompted for an alt attribute, and the image is added to the page. If I am in code view, the image is not actually added to the page.

Maybe this is old news, but I just discovered it (I don’t use DW much).

Posted in Web Development | 1 Comment

iPhone Screen Orientation: Portrait and Landscape

When you tilt your iPhone, the screen changes orientation. The website you developed for the default portrait orientation may not look good in landscape mode, especially if you developed your page for the 480 (h) x 320 (w) screen.

In my original iPhone post, I instructed detecting the width of the screen at regular intervals to detect the orientation of the iPhone. That post was written within a week of the launch of v1 of the iPhone. There is now a better method: use the onOrientationChange method to change the class of your body based on the page’s orientation. Include CSS for both normal page layout, and then include a series of overrides for when the screen is displaying your iPhone application in landscape mode.

What you want to include is the unobstrusive javascript equivalent of:

<body onOrientationChange="changeMyClass();">

In this case, we’ll call

   case 0:
       //handle portrait actions
       //document.getElementsByTagName('body')[0].className = 'portrait';
  case -90:
  case 90:
       // handle landscape actions
       //document.getElementsByTagName('body')[0].className = 'landscape';
} //end switch

Posted in Browsers, Character Entities, HTML, iPhone, JavaScript, Web Development | Tagged | 8 Comments

More CSS, XHTML and JavaScript at Community MX

I have been somewhat prolific as a technical writer for Community MX over the past 12 months. If you are interested in any of the articles, they are listed below. I will add new articles to this list as they get published (and as I get around to it). While Community MX is a subscription based website, you can get a one week free trial, and several of the articles (as noted below) are accessible without a subscription, and without logging in.

Most articles are part of a series. These four random ones are standalone:

There is a lot of interest in my IE8 post. It was a basic post, and I couldn’t get my butt in gear to write more. By writing for community MX, I kind of forced myself to research IE8. This seried has just begun… there will be a bunch more.

Based on my blog post on all XHTML elements, their attributes and their semantic meaning that I was wrote for this blog, I wrote an 18 part series going into each element in greater detail. The Object and input element (free) ones are the most intersting. The table of XHTML elements (also free) is the most useful:

While simple, the Three Column layout series teaches the reader how to make a three column layout, with the columns being able to be rearranged into any order without touching the HTML source code. If you don’t know how to make a CSS 3-column layouts, this series is definitely worth the read.

My firebug tutorial has already had over 100,000 views. Obviously there is interest. My Community MX Firebug series is only half way done, but as you can imaging, it’s going deeper into this most excellent tool. Similar to the IE8 series, I am still in the middle of this series. There should be several more.

The EMail Setup series is especially useful for anyone using CPanel or anyone trying to manage several email to and from accounts:

The CSS for Absolute Beginners series is very basic, and likely to simplistic for readers of this blog: as noted, it’s fore beginners. However, if you do want the basics, I am including the list of articles for those of you who are interested:

Don’t worry. Obviously I am still writing here too. Just wanted to share these in case anyone is interested.

Posted in CSS (including hacks), firebug, JavaScript, Web Development | 2 Comments

6 Firefox 3.5 updates of interest

Firefox 3.5 CSS 3 Selector Support

Firefox 3.5 was released today. Like the beta version that I tested a few months ago, FF3.5 supports all CSS3 selectors. See the CSS3 Browser support grid. This is great news, and makes us all tingly and happy, except for one thing: it means the CSS Google Chrome hack I wrote about in September also hits Firefox 3.5.

I did update the CSS3 Browser support grid to reflect Firefox 3.5 general release. All you’ll see is the pretty shade of green for FF3.5 as it does support all the CSS2.1 and CSS3 selectors.

Firefox 3.5 CSS & HTML Features

  1. @font-face

    The @font-face declaration (it’s not really a property, but rather like a download) allows you to define a font face, download that font face, and then use the font family name in other font family property value declarations throughout your site.

    @font-face {
      font-family: <a-remote-font-name>;
      src: <source> [,<source>]*;
      [font-weight: <weight>];
      [font-style: <style>];
  2. media type

    Before you could target on limited criteria, such as screen, all, print. Firefox 3.5 supports more specific media queries, such as serving CSS based on color-index, device-aspect-ratio, device height and/or width, orientation, resolution, among others. We learned about some of these techniques in iphone CSS. In other words, very cool new feature for FF, but already mostly supported in Webkit, so this won’t make a good way to target just FF3.5, but it is a great way to target different devices. In addition, FF3.5 supports logical operators within the media type declaration, which is not supported by older browsers, so a hack may be coming soon.

    @media screen and (min-width: 600px) and (max-width: 800px) // low resolution laptop?
    <link rel="stylesheet" media="print and (min-width: 11in)"... // landscape printing
  3. HTML 5 Features supported in Firefox 3.5

    Firefox 3.5 supports for the HTML 5 audio and video elements, offline resources and a HTML 5 drag and drop API supporting for drag and drop within and between web sites. Firefox 3.5 has improved support for canvas

Firefox 3.5 CSS2.1 and CSS3 New Features and Failure’s

Firefox 3.5 has made some improvements, but still has a way to go in supporting CSS: both CSS3 and CSS2.1. In addition to the support for @font-face and more media specificity, according to the Mozilla site, they have made improvements in the following areas (I’ll update here and on the CSS Properties and Values grid after I do more testing):

  1. :before and :after updated to CSS 2.1 specs

    The :before and :after pseudo-elements did not have full CSS 2.1 support for positioning, float, list-style-*, and some display properties. see CSS Properties and Values grid. I still see some issues with this, but my CSS isn’t totally valid in my test… so need to test further.

  2. opacity, text-shadow, word-wrap

    While these CSS3 (and in the case of text-shadow, 2.0 too) properties enjoyed some support in prior versions of Firefox, you no longer have to include the -moz extension in front of these three properties.

  3. CSS3 properties with the -moz- extension

    -moz-box-shadow, -moz-border-image, -moz-column-rule, -moz-column-rule-width, -moz-column-rule-style, and -moz-column-rule-color are now supported in FF3.5

I still haven’t done much testing, but thought I would throw what is already known out there. I’ll be updating this page and the CSS properties and values grid when life gives me a chance.



Posted in Accessibility, Browsers, CSS (including hacks), Web Development | 1 Comment

90 CSS Properties, Values and Browser Support

CSS Properties Index

Below is every CSS 2.1 Property, all the possible values for that propery, and the support for each property value from grade-A browsers

This is a work still in progress (i.e. unfinished) , but if you find a mistake, please let me know. Scroll on the table to see all the properties. Note, this was done with Opera 9.64, and FF 3.5, so I am currently updating those too. Also, if you hover over some of the yellow delta’s, some have title tags that explain how they work or fail.

Property CSS 2.1 Default Value ie6 ie7 ie7comp ie8 FF3 Saf OP Notes
Property CSS 2.1 Default Value ie6 ie7 ie7comp ie8 FF3 Saf OP  
azimuth Audio center aural  
angle (270deg)    
left-side | far-left | left | center-left | center | center-right | right | far-right | right-side    
leftwards | rightwards    
background CSS2.1 transparent none scroll repeat 0% 0% see individual background properties below
background-attachment CSS2.1 scroll Δ Δ Δ  
scroll     Δ Δ Δ  
fixed     Χ Χ Χ  
local CSS3   Δ Δ Δ Χ Χ Χ Χ  
background-color CSS2.1 transparent  
rgb()     Δ Δ  
colorName     Δ  
transparent     Δ  
rgba() CSS3   Χ Χ Χ Χ Χ  
background-image CSS2.1 none  
inherit     Δ Δ Δ  
url, url CSS3   Χ Χ Χ Χ Χ Χ  
background-position CSS2.1 0% 0%  
left | top | right | bottom | center      
background-position-x CSS3   Χ Χ  
backgroun-position-y CSS3   Χ Χ  
background-repeat CSS2.1 repeat  
repeat-x / repeat-y      


border-bottom | border-left | border-right | border-top

CSS2.1 medium none (current color) Δ Δ Δ border-width || border-style || border-color

border-bottom-color | border-left-color | border-right-color | border-top-color

CSS2.1 (current color)  
rgb()     Δ Δ Δ  
colorName     Δ  
transparent     Χ Δ Δ  
rgba()     Δ Δ  

border-right-style |

CSS2.1 none  
groove     Δ  
hidden     Χ Χ Χ  
inset     Δ  
outset     Δ Δ Δ Δ  
ridge     Δ  




CSS2.1 medium Δ Δ Δ  
length (3px)      
border-collapse CSS2.1 separate Δ Δ Δ 'table' and 'inline-table' elements
collapse     Δ Δ Δ  
border-spacing CSS2.1 0 Χ Χ Χ 'table' and 'inline-table' elements
length     Χ Χ Χ  
length length     Χ Χ Χ  
inherit     Χ Χ Χ  
bottom CSS2.1 auto Δ  
length     Δ  
percent     Δ  
auto     Δ  
caption-side CSS2.1 top Χ Χ Χ  
bottom     Χ Χ Χ  
left / right not in spec   Χ Χ Χ Χ Χ Χ  
clear CSS2.1 none  
clip CSS2.1 auto Χ Χ Χ on absolutely positioned elements
rect(T, R, B, L)     Χ Χ Χ  
inherit     Χ Χ Χ  
color CSS2.1 depends on element and browser  
rgb()     Δ Δ  
transparent     Χ Χ Χ Χ Χ  
rgba()     Χ Χ Δ Δ Δ Δ Χ  
:before & :after
CSS2.1 normal Χ Χ Χ  
none     Χ Χ Χ Χ  
normal     Χ Χ Χ Χ Χ  
url()     Χ Χ Χ  
string     Χ Χ Χ  
open-quote / close-quote     Χ Χ Χ Χ Δ  
no-open-quote / no-close-quote     Χ Χ Χ Χ  
attr(x)     Χ Χ Χ  
counter     Χ Χ Χ  
inherit     Χ Χ Χ  
counter-increment CSS2.1 none Χ Χ Χ  
counterName int     Χ Χ Χ  
none     Χ Χ Χ  
inherit     Χ Χ Χ  
counter-reset CSS2.1 none Χ Χ Χ  
counterName int     Χ Χ Χ  
none     Χ Χ Χ  
inherit     Χ Χ Χ  




CSS2.1 none aural  
cursor CSS2.1 auto  
url(x.cur)     Χ Χ  
move     Δ  
direction CSS2.1 ltr (left-to-right)              
display CSS2.1 inline (depends on element)  
run-in     Δ Δ Δ      
inline-block     Δ Δ Δ  
table     Δ Δ Δ  
table-row     Δ Δ Δ    
table-column-group     Δ Δ Δ    
table-row     Δ Δ Δ    
table-column     Δ Δ Δ    
table-cell     Δ Δ Δ    
table-caption     Δ Δ Δ    
elevation CSS2.1 level aural
angle (270deg)    
below | level | above | higher | lower    
empty-cells CSS2.1 show Χ Χ Χ sets whether or not to show empty cells in a table when "separated
show                   Borders are drawn around empty cells
hide Default                 No borders are drawn around empty cells
float CSS2.1 none  
font CSS2.1 depends on element and browser              
fStyle fVariant fWeight fSize/lineHeight fFamily                    
font-family CSS2.1 depends on element and browser              
font-1, font-2, generic                    
font-size CSS2.1 medium  
xx-small | x-small | small | medium | large | x-large | xx-large      
larger | smaller      
length (12px)      
percent (108%)      
font-style CSS2.1 normal  
italic     Δ Δ Δ Δ Δ Δ Δ  
oblique     Δ Δ Δ Δ Δ Δ Δ  
font-variant CSS2.1 normal  
font-weight CSS2.1 normal  
100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900   couldn’t fully test because i don’t have "light" fonts            
height CSS2.1 auto Δ      
length / percent     Δ      
auto     Δ      
inherit     Δ      
left CSS2.1 auto  
length / percent      
letter-spacing CSS2.1 normal  
length (3px)      
normal     Δ  
line-height CSS2.1 normal  
number (2)      
length (3px)      
list-style CSS2.1 depending on individual properties  
type position image      
list-style-image CSS2.1 none              
list-style-position CSS2.1 outside              
list-style-type CSS2.1 disc  
decimal-leading-zero     Χ Χ Χ  
lower-greek     Χ Χ Χ  
lower-latin     Χ Χ Χ  
upper-latin     Χ Χ Χ  
armenian     Χ Χ Χ Δ Δ Δ Δ  
georgian     Χ Χ Χ Δ Δ Δ Δ  



CSS2.1 depends on element and browser Δ Δ Δ  
length (3px)     Δ Δ Δ  
inherit     Δ Δ Δ  
max-height CSS2.1 none Χ      
length / percent     Χ      
none     Χ      
inherit     Χ      
max-width CSS2.1 none Χ      
length / percent     Χ      
none     Χ      
inherit     Χ      
min-height CSS2.1 0 Χ      
length / percent     Χ      
inherit     Χ      
min-width CSS2.1 0 Χ      
length / percent     Χ      
inherit     Χ      
orphans CSS2.1 2 Χ Χ Χ Χ Χ  
integer     Χ Χ Χ Χ Χ  
inherit     Χ Χ Χ Χ Χ  
outline CSS2.1 depending on individual properties Χ Χ Χ see individual properties below
color style width     Χ Χ Χ  
none     Χ Χ Χ  
inherit     Χ Χ Χ  
outline-color CSS2.1 invert Χ Χ Χ  
rgb / #fff / colorName     Χ Χ Χ          
invert     Χ Χ Χ          
inherit     Χ Χ Χ          
outline-style CSS2.1 none Χ Χ Χ  
dashed     Χ Χ Χ  
dotted     Χ Χ Χ  
double     Χ Χ Χ  
groove     Χ Χ Χ  
hidden     Χ Χ Χ  
inset     Χ Χ Χ  
none     Χ Χ Χ  
outset     Χ Χ Χ  
ridge     Χ Χ Χ  
solid     Χ Χ Χ  
inherit     Χ Χ Χ  
outline-width CSS2.1 medium Χ Χ Χ  
thin     Χ Χ Χ  
medium     Χ Χ Χ  
thick     Χ Χ Χ  
length (3px)     Χ Χ Χ  
inherit     Χ Χ Χ  
overflow CSS2.1 depending on individual properties  
visible     Δ  
overflow-x CSS3                  
overflow-y CSS3                  



CSS2.1 depends on element and browser Δ Δ Δ  
length (3px)     Δ Δ Δ  
page 2.0 auto                
page-break-after CSS2.1 auto not inherited
always     force a page break after the element
auto                   page break where it would normally break
left / right                   force page breaks so that next page is a left page
right                   force page breaks so that next page is a right page
avoid                   Avoid a page break after the element
page-break-before CSS2.1 auto not inherited
always     force a page break after the element
auto                   page break where it would normally break
left                   force page breaks so that next page is a left page
right                   force page breaks so that next page is a right page
avoid                   Avoid a page break after the element
page-break-inside CSS2.1 auto               not inherited
avoid                   Avoid a page break inside the element
auto                   page break where it would normally break
pause CSS2.1 implementation dependent aural Shorthand for pause-before pause after
time (in ms)      
pause-after CSS2.1 implementation dependent  
time (in ms)     time in milliseconds
%     pause the % of time it would take to say a word (>100% ok)
pause-before CSS2.1 implementation dependent  
time (in ms)      
pitch CSS2.1 medium  
Hz / kHz      
x-low | low | medium | high | x-high      
pitch-range CSS2.1 50  
0 or more      
play-during CSS2.1 auto  
url(x.wav) mix      
url(x.wav) repeat      
position CSS2.1 static  
fixed     Χ Δ Δ Δ  
relative     Δ Δ Δ  
quotes CSS2.1 implementation dependent Χ Χ Χ      
string (‘”’ ‘“’ "’" "‘")     Χ Χ Χ          
none     Χ Χ Χ          
inherit     Χ Χ Χ          
richness CSS2.1 50 aural
number (50)    
right CSS2.1 auto Δ  
length / percent     Δ  
auto     Δ  
inherit     Δ  
size 2.0 auto                
length (8.5in 11in)                    
portrait / landscape                    
speak CSS2.1 normal aural
speak-header CSS2.1 once  
speak-numeral CSS2.1 continuous  
speak-punctuation CSS2.1 none  
speech-rate CSS2.1 medium  
x-slow | slow | medium | fast | x-fast | faster | slower      
stress CSS2.1 50  
table-layout CSS2.1 auto  
text-align CSS2.1 start  
text-decoration CSS2.1 none  
text-indent CSS2.1 0  
length / percent      
text-shadow 2.0 none Χ Χ Χ Χ Χ Not in the 2.1 spec
color leftOffset topOffset blurRadius 2.0   Χ Χ Χ Χ Χ √- text-shadow sandbox
multiple shadows CSS3   Χ Χ Χ Χ Χ √- Χ  
text-transform CSS2.1 none text-transform standbox
top CSS2.1 auto  
length / percent      
unicode-bidi CSS2.1 normal              
vertical-align CSS2.1 baseline inline-level and table-cell elements only
baseline     Χ √; Χ Δ  
sub     Δ Δ Δ  
super     Δ Δ Δ  
middle     Δ Δ  
text-bottom     Δ Δ Δ Δ  
percent     Δ Δ Δ  
length (3px)     Δ Δ Δ  
visibility CSS2.1 visible  
hidden     Δ Δ Δ  
collapse     Χ Χ Χ Δ Δ collapse in tables, hidden elsewhere
voice-family CSS2.1 implementation dependent aural
specificVoice, genericVoice    
volume CSS2.1 medium
number / percent    
silent | x-soft | soft | medium | loud | x-loud    
white-space CSS2.1 normal  
normal test   Δ Δ Δ  
pre test    
pre-wrap     Χ Χ Χ  
pre-line     Χ Χ Χ Χ  
widows CSS2.1 2 Χ Χ Χ Χ Χ  
integer     Χ Χ Χ Χ Χ  
inherit     Χ Χ Χ Χ Χ  
width CSS2.1 auto Δ Δ Δ  
length / percent     Δ Δ Δ  
auto     Δ Δ Δ  
inherit     Δ Δ Δ  
word-spacing CSS2.1 normal  
length (3px)     Δ Δ Δ  
z-index CSS2.1 auto Δ Δ Δ applies to positioned elements
integer (3)     Δ Δ Δ  


  • Level of support for property is based on CSS2.1. So, if a browser supports all of CSS2.1 but not CSS3, they will get be listed as supporting the property.
  • Browsers include:
    • IE6
    • IE7
    • IE7 compatibility mode
    • IE8
    • Firefox 3 (some 3.5 beta)
    • Safari 3.2 (some 4 beta)
    • Opera 9.64
  • When you hover over the deltas, in standards compliant browsers, informaiton on how the browsers fails to comply with standards should be displayed.
  • This is still a work in progress, but it’s pretty far along, so I am posting. It will be updated soon and often until done… then I’ll remove this bullet point.


Haven’t run tests yet Fails Some Support Almost Compliant Compliant Aural (will not support) Print
will test soon   may add links to tests may add link to tests   will unlikely be supporting will add support soon

Posted in Browsers, CSS (including hacks), Web Development | 6 Comments

CSS content, counter-increment & counter-reset

I have never used the counter or increment properties since they aren’t supported in IE7 or earlier, nor are the :before pseudo elements, or content property. Since IE8 does support all of these, soon we may be able to include these CSS properties, so I thought I would explain them.

The <ol> start attribute and <li> value element were deprecated in HTML 4.01 and not supported in XHTML strict. The value attribute set the number of a list item, enabling the following list items to increment from that value. While there is no (X)HTML replacement for these elements, CSS 2.1 provides methods for setting and incrementing counters on any element, not just <li>’s. This article focuses on the following CSS pseudo elements and properties:

  • content CSS property
  • :before pseudo-element
  • :after pseudo-element
  • counter-increment CSS property
  • counter-reset CSS property

The content property is used in conjunction with the :before or :after pseudo-elements. The value of the content property is added to the visual layout of your document, but is NOT added to the DOM. If you’re reading this tutorial, you should already know that! We’re discussing :before, :after and content here because without them, the counter is kind of useless: if you’re not going to display the content of a counter before (or perhaps after) an element, why include it?

Overview of content property

To make understanding this tutorial easier, we are going to use the concrete example of adding ” – <hrefValue>” after every link, which is helpful when using print CSS.

<ul id="showlinkafterlink">
  <li><a href="http://www.yahoo.com">Yahoo</a></li>
  <li><a href="http://www.google.com">Google</a></li>
  <li><a href="http://evotech.net/blog">CSS, JavaScript and XHTML explained</a></li>

Listing 1: Without any CSS, this is how the code above looks

#showlinkafterlink a:after {
    content: "  - <" attr(href) ">";

Listing 2: If you are using a standards compliant browser (i.e. NOT IE6 or IE7), the above should have the hrefs following the links.

A few things to note about the content rendered via the content property:

  • Generated content does not alter the document tree. The content is rendered only: it doesn’t appear in the DOM tree, altering the presentation only, not the document
  • To control the appearance of the generated content, you can use other CSS properties. All properties in the :after declaration impact the generated content.
  • In case you were wondering, you can only add one pseudo-element per side of your element. element:before:before does not work.
#showlinkafterlink a:after {
    content: "  - <" attr(href) ">";
    color: #ff0000;	 font-style: italic;

Listing 3: Here we’ve defined the color and font-style for the generated content.

While the generated content is NOT added to the DOM, think of it as an added span that inherits everything from it’s parent. The content cannot contain any HTML, just ASCII, escaped and ISO characters. As mentioned, content is used with the :before and :after pseudo-elements to generate content in a document.

Values of the CSS content property

The CSS content property can take as its value none | normal | <string> | url | open-quote | close-quote | no-open-quote | no-close-quote | attr(attribute) | counter(name[, style]). Values have the following meanings:

  • content: none;

    none: The pseudo-element is not generated.

  • content: normal;

    normal: Computes to ‘none’ for the :before and :after pseudo-elements unless the default browser rendering includes content (i.e. <q>) which is handled differently based on the browser – Safari shows the default content, IE8 and FF do not.

  • content: "Estelle: ";content: "\00a3 "; /* includes '£' */

    string: Adds a string before or after the element (depending on which pseudo-element is used). Strings can either be written with double or single quotes. If your string includes a quotation mark, make sure you escape it with a slash-quote or slash-ISO value. If you are going to include any non-ASCII characters or entities, declare the charset in your CSS and XHTML, and/or use the ISO code for the character. Check out my blog post on including named entities in CSS and Javascript

  • content: url(myBullet.gif);

    url: The value is a URI that designates an external resource (such as an image). If the browser can’t display the resource, FF and IE8 omit it, as if it were not specified, but Safari indicates that the resource cannot be displayed with a missing image icon.

  • content: open-quote;

    open-quote and close-quote: These values are replaced by the appropriate string from the ‘quotes’ property. Opera handles this, but does not nest quotes correctly, Safari ignores this completely. IE8 and Firefox get it right.

  • content: open-quote;

    no-open-quote and no-close-quote: Introduces no content, but increments (decrements) the level of nesting for quotes. Safari ignores this completely. Opera, IE8 and Firefox get it right.

  • content: attr(title);

    attr(x): This function returns as a string the value of attribute X for the subject of the selector. The string is not parsed by the CSS processor. If the subject of the selector doesn’t have an attribute X, an empty string is returned. The case-sensitivity of attribute names depends on the document language.

    For uber coolness, or geekiness as the case may be, you can add text dynamically without using javascript.

    a.tooltip {
      position: relative;
    a.tooltip:hover:after {
      content: attr(title);
      padding: 5px;
      border: 1px solid #f00;
      background-color: #dedede;
  • content: counter(subtitles, decimal);content: counter(headers) "." counter(subtitles) ": ";

    or counter(name, style): The counter takes two parameters: the name, which you can reference to increment or reset, and the style, which, if not declared, defaults to “decimal”. While you can name the counter almost anything except ‘none’, ‘inherit’ or ‘initial’, avoid key terms.

Browser support for the CSS content property and :before and :after pseudo elements

The CSS content property and possible values
IE6 IE7 IE7 in IE8 IE8 FF3 FF 3.5 Beta Saf 3.2 Saf 4 Beta Opera 9.64
content Since :before and :after is not supported in these browsers, testing is not possible, and moot. It is assumed that IE6 and IE7 does not support the content property, therefore supports none of these values works, except for issues below works, except for issues below works, except for issues below
none n
normal displays quotes on <q> Makes sense, but not the spec.
url() nothing nothing nothing missing image icon missing image icon missing image alt
Does not nest quotes correctly, but does include quotes.

counter-increment and counter-reset CSS properties

Counters don’t work on their own! if you just write p:before {content: counter(subtitles, decimal);} every paragraph will have a zero in front of it. To more easily understand this, let’s think of real world examples:

  • footnotes
  • creating numbering for outlines: counting chapters, sections and subsections, restarting the subsection counter for each new section, and resetting the section counter for each new chapter

Using the CSS counter syntax you can define as many counters as you like in your page, increment the counters and reset the counters. While the counter gets physically added to the presentation of the page (not the DOM) using the CSS counter value on the content property as a pseudo element using the :before or :after syntax, the increment happens on an actual element on the page.

<p> With this paragraph, I have included <cite class="footnote">citation to footnote</cite>.</p>

cite.footnote {counter-increment: citations;}

cite.footnote:after {content: counter(citations); vertical-align:text-top;}

In our example above, we would increment the counter on every <cite class="footnote">, then add the footnote numbers using the content property on the :after pseudo element. In order to use a counter, you should give it a name. In the above scenario, the name is “citations”. You can also specify the style. If the style is not declared, the style defaults to decimal. The values include all the list-style-type values, though only <ol> values make sense with a counter. Values include decimal | decimal-leading-zero | lower-alpha | lower-greek | lower-roman | upper-alpha | upper-roman | lower-latin | upper-latin | hebrew | georgian and others.

You can include more than one counter in generated content. For example, in legalese, you often have sections within sections all numbered. This is doable with CSS counters.

<h1>First Header</h1>
<h2>another subsection</h2>
<h2>yet another subsection</h2>
<p>more text....</p>
<h1>Another Header</h1>
<h2>another subsection</h2>
<h2>yet another subsection</h2>
<p>more text....</p>

To add counters in front of every h1, with counters on the h2s that reset after each h1, the CSS would look like:

h1 {
	counter-increment: headers;
	counter-reset: subsections;
h1:before {
	content: counter(headers, upper-roman);
h2 {
h2:before {
	content: counter(headers, upper-roman) "." counter(subsections, lower-roman) ":";

Now all <h2>s are preceded by their header number and subsection number.

A few things to note about the code: note that in the h2:before declaration we’ve included two counters: the header counter and the subsection counter. We declared the style in both calls, as style is NOT inherited. Also, we’ve included strings within our declaration. Note that there are quotes delimiting our strings, but not our counters, and there are no concatenation elements without our content value. To combine multiple counter ID’s in the same style attribute, string them together using space delimited counter ID values.

Incrementing of the counter was done through the counter-increment declaration. While the default value is to increment by 1, we can increment by other values. You can also reset counters. It makes sense to reset subsections after every header. To overwrite the default value of 1, and to reset after each <h1> the CSS could be:

h1 {
  counter-increment: headers 10;
  counter-reset: subsections 5;
h2 {
  counter-increment:subsections 2;
Posted in Web Development | 12 Comments

22 Questions to Ask Before Developing a Website

I developed this “Website Development Questionnaire” in 2002. It is old, but it still serves me well, so I thought I would share. I don’t actually add the bold or italic sections below. Those were added here to help you understand the rationale for the questions:

1) Corporate Identity: Corporate Information (for site development):
Company Name (Legal)
Company Name (Branding)
Company Tag Line:
Company Phone Number
Company Fax Number
Other contact information
Business hours of operation (store hours / when phones will be answered, if relevant)

2) Domain Names and Hosting:
Main Domain Name:
What other domain names do you own?
Do you have web hosting? If so, what type (IIS, Apache?)

3) Briefly describe what your company does:

4) Adjectives: Please list 5 (or more) adjectives that you think describe your company or should describe your company in order of relevance / importance

This information is used to get a sense for design, and to help in SEO

5) Competitors: Are there any websites that you would consider your “competition”? Feel free to provide more information on how they are your “competition”, but, at minimum, provide for each competitor, include the company name, web address, and a list of “keyterms” that describe what they do and/or sell.

In addition to getting a good look at what key terms they may be targeting, I take a look at these sites to get an idea of the features they may need, target audiences we should be considering, and what the competition will be like in terms of SEO

6) Favorite Sites: Please list 5 websites you like. Include the URL, what you like about each site, and what you would improve upon.

These sites don’t have to be in the same business realm. By getting sites they like, i get a good feeling for their design sense. By finding out what they would improve upon, you learn alot more about what they are looking for in their site.

7) Least favorite sites: Please list 5 websites you don’t like, Include the URL. What don’t you like about these sites? What redeeming qualities to they have?

The pitfalls they list tells you what you need to avoid. Though redeeming qualities are rarely included when clients fill out this list, I get a good sense of what they like when they do answer that question. I usually find that the redeeming qualities from this answer helps me understand better their answer to question 6 above.

8) Products / Services: List the top ten products / services you provide

This should be redundant to the answer of question 5. If it’s not, I usually have to do some business development with the client to get them to focus the purpose of their site. I ask this question this way as well because I don’t want to start developing a site for a client if they haven’t finished developing their business strategy.

9) Selling points: Tell us why you, your products or your services are better than your competition (both online competitors from question 3, and offline competition)

10) User goals: Why do you think people will visit your site? When people don’t know you exist, why would they find you or happen upon your site? Why would they come back? If they do know you, why would they take the time to visit your site?

Most clients think users will just come to their site. This question helps them focus on why an average Jane or John Doe may end up on their site. Many brochure sites get most of their visits from people looking for an address or phone number. You can create a one page website for that. This helps the client focus on what the site’s real goals should be.

11) Target Audience: What types of visitors do you want to get? Who is your target audience? (age, education, and other demographics? Job status? Economic status? Role in the community?) Describe your “average” visitor as best you can.

The layout targeting a Japanese middle school students will be very different from a site targeting rural agricultural workers or British graduate school applicants. Knowing your target audience, their culture, their technical savvy, and their internet expectations can help you design your page in terms of look and feel and help you determine site functionality and user experience design

12) Secondary Audience: What other visitors is your site going to get? Job seekers? Board members?

This helps me determine what additional pages to include in a site. Your client may be a sole proprietor, but they may want to hire, incorporate and/or get venture capital funding. Making sure your site can grow to accommodate future features is important. Thinking about those potential features before beginning the design process give you an added edge.

13) Technical: How technically savvy is your average visitor?

14) Accessibility & Usability: Will web visitors have any special needs? (eyesight, language, mobility, reading level?)

15) Site Purpose: What do you want the visitor in question 11 (and 12) to do when they get to your site? What are your goals for the web site in terms of visitor actions? What do you think your site visitor should accomplish on your site?

16) Site Goals: What are your goals for the web site in terms of you company goals? How is your site supposed to help your business? What is the purpose of your site?

17) Site Analytics: What are your goals for the web site in terms of popularity and virality? What type of exposure do you anticipate your website, when “successful” should achieve?

This question has dual purposes: The first is to help set numeric goals for the site that can be tested with common analytics. The second is to guage the sense of reality of the client: if they expect to reach 1,000,000 page views their first month, they’ll let you know their expectations via this question. This is the time to take some sense into them so they aren’t disappointed and don’t set their expectations too high

18) Site Features: What features do you think your website should include? (calendar, forum, login, price comparison chart, contact form, anything?)
For each feature, please state the goal of said feature.

Some clients want the moon. By stating the goal of each feature, they may realize they don’t need the moon. Other clients have no clue what is available to them. They never ask for a contact form at the initial contact, but i have yet to have a sole proprietor client who doesn’t want a contact form after reading this questionnaire they just never thought of it. This question helps define which features are necessary even if they weren’t originally thought of, and which ones sounded good originally, but really won’t help.

19) Site No Nos: Do you have any definite remarks on what you DON’T want to have on your website? (Flash, splash page, the color pink?) Sharing why you don’t want a feature will help me get an understanding of your user experience tastes, so feel free to elaborate.

This question is really helpful as is. Adding the examples has helped me explain against the dreaded splash page.

20) Other: Anything else I should know?

21) Product Manager: Company Contact(s) Information for web decisions:
Primary Contact Name:
Contact Email Address:
Contact Phone:

Secondary Contact Name:
Contact Email Address:
Contact Phone:

Other contact information

22) Billing Contact: Company contact information for Contracts & Billing:
Other contact information

Always know who is going to pay you before you start working

Posted in Best Practices, SEO, UED, Web Development | 42 Comments