Learning To Love Forms (Web Directions South '07)

download Learning To Love Forms (Web Directions South '07)

If you can't read please download the document

Transcript of Learning To Love Forms (Web Directions South '07)

AARON GUSTAFSONEASY! DESIGNS, LLC

Now you know who I am and now I want to know a little about you...

FORMS AREA NECESSARYEVIL

So this is the way most of us normally feel about forms

Maybe it is because they require a lot of code, but I think most people don't like forms because they are simply a pain to bend to your will

But they don't have to be

We will be walking through some example form types and components and building them from the ground up, looking at both semantics and style

Hopefully by the end of this session you won't find them quite so evil

SIMPLE FORM:
CONTACT US

We'll begin with a simple contact form

This section will hopefully be a review for most of you, but I want to make sure everyone has a fundamental understanding of how forms work

SIMPLE FORM:
CONTACT US

FORM Elementestablishes a form

ACTION is the only required attribute and should always be a URI

METHOD defaults to get

NAME is depreciated; use ID instead

Obviously FORM is the initial container of any form

Or for those of you who work in .Net, the entire page ;-)

GET by default

ACTION is all that's required

MIME type (using ENCTYPE) for file uploads

SIMPLE FORM:
CONTACT US


Send us a message

FIEDSET Elementused to group related fields

LEGEND Elementused to provide a caption for a FIELDSET

FORM requires some sort of block containing element... usually a FIELDSET

FIELDSET* grouping* can be nested

LEGEND

SIMPLE FORM:
CONTACT US


Send us a message

Containing FORM Controls

P or DIVsensible choices, but not very accurate (except in certain instances)

OL or ULmost forms are lists of questions or form controls, so these are better


Send us a message

Once inside the fieldset we can organize our form controls

Some people use P or DIV, but I prefer lists

In the case of a sequential form, I usually opt for a OL

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email

INPUT Text Controltype="name" is a basic text input field

(also type="password" for content you want hidden)

NAME vs. IDNAME is for the back endID is for the front end

Each form control is contained in a list item

The first two are the most common form control: the text INPUT

Note: NAME != ID different functions

NAME is required for the back end to obtain the values from the form fields.

ID is used on the front end by JavaScript, CSS, and other XHTML elements as we'll see in a moment

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email
  3. Message

TEXTAREAa multiline text form control

requires ROWS and COLS attributes!!!

The other input form control in this example is a TEXTAREA, which allows for multiple lines of input

NOTE: ROWS and COLS are REQUIRED on this element for the page to validate

SIMPLE FORM:
CONTACT US

Working with LABEL this element provides to means of associating its content with a form control:

implicit associationLABEL wraps the form control and the text

explicit association
LABEL's FOR attribute is an ID reference to the form control


Send us a message

  1. Name
    ...


Send us a message

  1. Name
    ...

Now for the bit of text that says what sort of content the form control is expecting...

How many people here are using LABEL elements in their forms? How many have never heard of one?

Well, they come in two forms -- implicit and explicit which has to do with how they are associated with the field they are the label for

SIMPLE FORM:
CONTACT US

Buttonstrigger events in a form; use either INPUT or BUTTON element

Common TYPEssubmit submits the form; default button type

reset resets all form control values back to their defaults when the page loaded

Send us a message

  1. ...

Go

Send us a message

  1. ...

The final element in our form is the button our users will use to submit the form

Most of you are probably used to using the SUBMIT type of the INPUT element

But we can also use the often overlooked BUTTON element to submit a form

As I will get to in a bit, BUTTON element is much more flexible when you want to heavily style a form and have those styles work cross-browser (especially on the Mac)

RESET back to the original values

SIDEBAR:
BUTTONS

Mozilla

WINDOWS XP

OS X

BUTTON

INPUT

IE 6/7
(XP)

IE 6/7
(classic)

Opera

Opera

IE 5

Firefox

Camino

Safari

Alright, so I had mentioned how BUTTONS were quite cool and massively underutilized...

Here you can see a cross-section of how the BUTTON element is rendered

Stylable to a large extent in all browsers

Image replacement

Article on DW extolling the virtues of this element Push My BUTTON

IE mangles multiple BUTTONs but hopefully not for long

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email
  3. Message

Go

So now that we have the markup, let's slap some style on this form

Without any styles whatsoever, this is what we'd see in Firefox and it's pretty ugly

Before we do anything else, let's set some basic typographic rules

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email
  3. Message

Go

body { font: 62.5%
"Lucida Sans Unicode", "Lucida Grande",
sans-serif;}ol, ul, p { font-size: 1.2em; line-height: 1.5;}

Now we need to take care of those numbers on the fields and the formatting of the FIELDSET/LEGEND combo

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email
  3. Message

Go

form, fieldset, legend { border: 0; padding: 0; margin: 0;}legend { font-size: 2em;}form ol, form ul { list-style: none; margin: 0; padding: 0;}

That's a pretty good start

Next we'll make a simple change and see how we can make this into a vertical or stacked form

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email
  3. Message

Go

form li { margin: 0 0 .75em;}label { display: block;}input, textarea { width: 250px;}

That actually doesn't look too bad, but we want to create that elusive side-by-side form

It's actually not difficult to do that, we just have to apply some of the same techniques we use in our page layouts to our form: floats

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email
  3. Message

Go

form li { clear: both; margin: 0 0 .75em; padding: 0;}label { display: block; float: left; line-height: 1.6; margin-right: 10px; text-align: right; width: 120px;}

We've still got a bit of nip-tuck work left to do, namely adding some space below the legend and adjusting the position of the button

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email
  3. Message

Go

legend { font-size: 2em; line-height: 1.8; padding-bottom: .5em;}button { margin-left: 130px; cursor: pointer;}

The LEGEND is a bit tricky as each browser treats it a little differently

To get consistent results in spacing it to other elements, it is best to use padding (some browsers ignore margins on LEGEND elements altogether)

We can also add a margin-left to the BUTTON to move it over to line up with the fields, creating a nice vertical alignment which makes it really easy for people to scan and complete the form

Now, if we wanted to spruce it up a bit more, we can...

SIMPLE FORM:
CONTACT US

Send us a message

  1. Name
  2. Email
  3. Message

Go

label:after { content: ':';}input, textarea { background: #ddd; width: 250px;}input:focus,textarea:focus { background: #fff;}/* Some styles to get
the baselines to
match & to unify the
type used */

We can use things like generated content, background colors and typographic styles to more fully style the form

SIMPLE FORM:
CONTACT US

body { font: 62.5% "Lucida Sans
Unicode", "Lucida Grande",
sans-serif;}ol, ul, p { font-size: 1.2em; line-height: 1.5;}form, fieldset, legend { border: 0; margin: 0; padding: 0;}legend { font-size: 2em; line-height: 1.8; padding-bottom: .5em;}form ol, form ul { list-style: none; margin: 0; padding: 0;}form li { clear: both; margin: 0 0 .75em; padding: 0;}label { display: block; float: left; line-height: 1.6; margin-right: 10px; text-align: right; width: 120px;}

label:after { content: ':';}input, textarea { background: #ddd; font: 1em Arial, Helvetica,
sans-serif; padding: 1px 3px; width: 250px;}textarea { line-height: 1.3em; padding: 0 3px;}input:focus, textarea:focus { background: #fff;}button { background: #ffd100; border: 2px outset #333; color: #333;
cursor: pointer; font-size: .9em; font-weight: bold; letter-spacing: .3em; margin-left: 130px; padding: .2em .5em; text-transform: uppercase;}

A quick look at our stylesheet for this form

pretty simple.

SIMPLE FORM:
CONTACT US

Now let's add a SELECT to the mix

SIMPLE FORM:
CONTACT US

SELECTion Listsallows selection of one or more OPTIONs

On OPTION elements, the VALUE attribute is optional (contents are submitted by default)

Send us a message

  1. ...
  2. Subject I noticed a
    website error I have a
    question Other ...

Go

SELECTion lists allow a user to select one (or more) options from those provided

VALUE on OPTION is optional

You can even get organized within your SELECT, creating groups using OPTGROUP

SIDEBAR:
OPTGROUPS

Golden Delicious Granny Smith Macintosh Red Delicious Blackberries Blueberries Raspberries Strawberries

Here's an example

SIMPLE FORM:
CONTACT US

Send us a message

  1. ...
  2. Subject I noticed a website error I have a question Other ...

Go

By default, most SELECT elements have their width set by the longest OPTION length, but we can adjust it as well

In the case of this form, we want to make sure the SELECT is equal in width with the INPUTs (or pretty close)

SIMPLE FORM:
CONTACT US

Send us a message

  1. ...
  2. Subject I noticed a website error I have a question Other ...

Go

select { background: #ddd; width: 260px; /* width is *usually*
the input width +
input padding +
4px */}input:focus, textarea:focus, select:focus { background: #fff;}

Usually require a size a few pixels longer than an input (4px seems to work pretty reliably)

You can also apply the same background color switching as other form elements

SIDEBAR:
SELECTS

WINDOWS XP

OS X

Mozilla

IE 7
(classic)

IE 6/7
(XP)

IE 6(classic)

Opera

Opera

IE 5

Firefox

Camino

Safari

SELECTs are an odd beast

Most browsers don't let you style anything apart from background and foreground colors

Some, like Firefox, will let you change the border type

Best advice: don't even try to really style the SELECT, but if you really need to, there are some JavaScripts available including a new one I will be releasing shortly which allows complete restyling of a SELECT and is completely accessible.

SIMPLE FORM:
CONTACT US

We're doing pretty well with this form, so let's add some additional fields, starting with a simple selection list

This is great because we can look at sub-organizing our form controls

SIMPLE FORM:
CONTACT US

Nested FIELDSETsa great way to organize radio or checkbox groups

The LEGEND is the question or statement

Lists organize the possible responses (OL or UL)

implicit LABELs provide an easy way to style in IE6

... I would prefer to be
contacted by


  • email

  • phone

...

You can nest a FIELDSET to create a nice little subgroup, using its LEGEND as the question or statement you are asking for feedback on

Radio options become a new list

I usually classify the FIELDSET for added style control, but it isn't completely necessary (depending on how complex you want your style rules to get I like to keep things component-ized, so CLASSification works for me)

SIMPLE FORM:
CONTACT US

... I would prefer to be contacted by


  • email

  • phone

...

Default layout within our current style paradigm ain't pretty

SIMPLE FORM:
CONTACT US

... I would prefer to be contacted by


  • email

  • phone

...

.radio legend { font-size: 1em; line-height: 1.5; padding: 0 0 0 6px; margin: 0;}.radio label { display: inline; width: auto; margin: 0;}

But tapping into our CLASSified FIELDSET makes taking care of the font-sizing of the LEGEND and the display of the LABELS pretty simple

Next up, we have to deal with the nested list enlargement issue and the positioning of the LEGEND

SIMPLE FORM:
CONTACT US

... I would prefer to be contacted by


  • email

  • phone

...

.radio { margin-left: 125px;}.radio ul { font-size: 1em; margin: .3em 0 0;}.radio label:after { content: '';}label input { background:
transparent; width: auto;}

Push the whole thing over

scale down the nested list

Resize the input, which brings it back in line

Now we just need to get the radio options side-by-side

SIMPLE FORM:
CONTACT US

... I would prefer to be contacted by


  • email

  • phone

...

.radio li { float: left; margin: 0; width: 48%; clear: none;}label input { width: auto; position: relative; top: 2px;}

Which we can use floats for

And as each LI in the main OL is already set to clear: both, we don't have to worry about adding a clearing element to keep the layout from breaking

SIMPLE FORM:
CONTACT US

.radio legend { font-size: 1em; line-height: 1.5; padding: 0 0 0 6px; margin: 0; max-width: 270px; width: 270px;}

... This is an exceedingly long LEGEND to demonstrate the odd behavior of LEGENDs


  • email

  • phone

...

Let's take a side track for a moment to talk about some other odd LEGEND behavior

SIMPLE FORM:
CONTACT US

.radio legend span { display: block; width: 270px;}

... This is an exceedingly long
LEGEND to demonstrate the odd behavior of
LEGENDs


  • email

  • phone

...

SIMPLE FORM:
CONTACT US

Finally, let's add another common form component: the confirmation

SIMPLE FORM:
CONTACT US

Send us a message

  1. ...
  2. Please add me to your mailing
    list ...

Go

Confirmationsa little CLASSification goes a long way

This is also broken down quite easily

SIMPLE FORM:
CONTACT US

Send us a message

  1. ...
  2. Please add me to your mailing list ...

Go

With our other styles, it's way the hell over on the left (because the abel width and float properties are working)

We can easily fix that

SIMPLE FORM:
CONTACT US

.confirm label { display: block; float: none; margin-left: 125px; text-align: left; width: 270px;}

Send us a message

  1. ...
  2. Please add me to your mailing list ...

Go

Now we just need a little space

SIMPLE FORM:
CONTACT US

.confirm { margin-bottom: 1.4em;}.radio label:after,.confirm label:after { content: '';}

Send us a message

  1. ...
  2. Please add me to your mailing list ...

Go

And we're done

MORE

FORMS

FORMS OF

Now we're going to examine some other common (and not so common) form interfaces and discuss the coding and design challenges they pose

SIMPLE FORM:
SEARCH BOX

First a simple search form

SIMPLE FORM:
SEARCH BOX

POST vs. GETSearch forms are traditionally GET requests to allow the action page (i.e. the results) to be bookmarkable.

In search forms we usually want to use GET which we don't technically need to specify, but we will in this case

ID: search-form

SIMPLE FORM:
SEARCH BOX

You need somethingSometimes a FIELDSET is unnecessary, but in XHTML, you need something to wrap the contents of a form

You just need a container, so P can work here easily

SIMPLE FORM:
SEARCH BOX

Easy-peasy

Search this
site for

Then we've got the other simple bits

SIMPLE FORM:
SEARCH BOX

Its a BUTTON
big shock, I know

Search this site for Go

Same here

And now we can style it

SIMPLE FORM:
SEARCH BOX

Search this site for Go

body { background: #54af44; font: 62.5% "Lucida
Sans Unicode", "Lucida
Grande", sans-serif;}ol, ul, p { font-size: 1.2em; line-height: 1.5;}

Basic body styles first

SIMPLE FORM:
SEARCH BOX

Search this site for Go

label { line-height: 2em;}input { border: 1px solid #c00; background: #ebebeb; margin: 0 .5em; padding: 2px 4px;}input:focus { background: #fff;}

Then a little border styling and background styles

SIMPLE FORM:
SEARCH BOX

Search this site for Go

button { background: #c00; border: 0; color: #fff; cursor: pointer; font-size: .9em; font-weight: bold; letter-spacing: .1em; padding: 2px 8px; text-transform:
uppercase;}

And we wrap with a treatment of the BUTTON

SIMPLE FORM:
DATE SELECT

Next up: a date picker... no JS required

SIMPLE FORM:
DATE SELECT

Getting organized

Since you all know forms, we'll jump right into the component itself, starting with the FIELDSET

In keeping with the component idea, we'll classify it

SIMPLE FORM:
DATE SELECT

Not really a LABEL

Post Date

The label in this case isn't really a LABEL as it describes the whole group of form controls

Better off with a LEGEND

SIMPLE FORM:
DATE SELECT

Not just a SELECT
we need some LABELing

Post Date

  1. Date 01 ... 31

The LABEL should really be for each field, which we'll add in an unordered list

We will hide these LABELs in a nice, accessible way shortly

So that's the day

SIMPLE FORM:
DATE SELECT

And so on

Post Date

  1. Date ...
  2. Month January ... December

Now the month

SIMPLE FORM:
DATE SELECT

And so forth

Post Date

  1. Date ...
  2. Month ...
  3. Year 2007 2008

And finally the year

SIMPLE FORM:
DATE SELECT

Post Date

  1. Date ...
  2. Month ...
  3. Year ...

body { background: #54af44; font: 62.5% "Lucida
Sans Unicode", "Lucida
Grande", sans-serif;}ol, ul, p, legend { font-size: 1.2em; line-height: 1.5;}legend { color: #000;}

And when we jump in to style it, here's what we get, assuming some simple starting styles

SIMPLE FORM:
DATE SELECT

Post Date

  1. Date ...
  2. Month ...
  3. Year ...

.date { border: 0; padding: 0;}.date ol { list-style: none; margin: 0 0 0 130px; padding: 0;}

We can quickly strip away the unnecessary bits and get it all lined up

SIMPLE FORM:
DATE SELECT

Post Date

  1. Date ...
  2. Month ...
  3. Year ...

.date li { float: left;}

Then bring it all in line

SIMPLE FORM:
DATE SELECT

Post Date

  1. Date ...
  2. Month ...
  3. Year ...

.date select { background: #e2efe0; margin: 0 .25em 0 0;}.date select:focus { background: #fff;}

And once we add a little spacing

SIMPLE FORM:
DATE SELECT

Post Date

  1. Date ...
  2. Month ...
  3. Year ...

.date label { position: absolute; left: -999em;}

We can cleverly hide those labels using positioning

SIMPLE FORM:
DATE SELECT

Post Date

  1. Date ...
  2. Month ...
  3. Year ...

.date { border: 0; padding: 0; position: relative;}.date legend span { display: block; line-height: 1.6; text-align: right; width: 120px; position: absolute; top: 0; left: 0;}

Then it is just takes a little extra markup and a little more positioning to bring the LEGEND over on the left

SIMPLE FORM:
DATE SELECT

Post Date

  1. Date ...
  2. Month ...
  3. Year ...

.date legend
span:after { content: ":";}

And then we can add in the colon

Breaking it all down logically makes it super simple

COMPLEX FORM:
RELATED FIELDS

COMPLEX FORM:
RELATED FIELDS

Organization and coordinationas with other elements, form components can have multiple CLASSifications


Confine results to

COMPLEX FORM:
RELATED FIELDS

Basic implicit LABELnothing shocking here

Confine results to

  • within the last year
    ...

COMPLEX FORM:
RELATED FIELDS

In a slight bending of the rules, implicit LABELs can contain more than one form controlin our case, a radio INPUT as well as a SELECTion box

Confine results to


  • within the last year

  • the month of January ... December ...

COMPLEX FORM:
RELATED FIELDS

How do I code that?!?think about it... what are the relationships of the fields?

Confine results to

  • ...

COMPLEX FORM:
RELATED FIELDS

We know the first bit

Confine results to

  • ...

  • a monthly range

COMPLEX FORM:
RELATED FIELDS

We need to organize this now

Confine results to

  • ...

COMPLEX FORM:
RELATED FIELDS

Simple explicit LABEL

...


  1. from the start of January
    2006 ... December
    2006
  2. ...

...

COMPLEX FORM:
RELATED FIELDS

And again

...

  1. from the start of ...

  2. until the end of January
    2006 ... December
    2006

...

COMPLEX FORM:
RELATED FIELDS

Confine results to

  • within the last year
  • the month of January ...
  • a monthly range
    1. from the start of January 2006 ...
    2. until the end of January 2006 ...

Its a lot of code...

COMPLEX FORM:
RELATED FIELDS

...but the benefits are worth it

Confine results to
List of three items
bullet
Radio button (not checked) within the last year
bullet
Radio button (not checked) the month of
Combo box January
bullet
Definition list of one item
Radio button (not checked) a monthly range
equals
List of two items
one: from the start of
Combo box January 2006
two: until the end of
Combo box January 2006
List end
List end
List end

transcribed by Fangs

COMPLEX FORM:
RELATED FIELDS

Confine results to

/* We'll save some space
and inherit styles
from .radio */

form ol, form ul,
form dl { list-style: none; margin: 0; padding: 0;}
li ul, li ol { font-size: 1em;}

COMPLEX FORM:
RELATED FIELDS

Confine results to

.related li { clear: both; float: none; margin: 0 0 .5em; width: auto;}

/* For IE to recover from
a strange margin */.related li { zoom: 1;}

COMPLEX FORM:
RELATED FIELDS

Confine results to

.related select { margin-left: .25em;}.related dd { margin: .5em 0 0; padding: 0 0 0 3em;}.related dd label { float: left; line-height: 1.9; width: 100px;}

COMPLEX FORM:
RELATED FIELDS

Confine results to

.related legend span { display: block; line-height: 1.8; text-align: right; width: 120px; position: absolute; top: 0; left: -130px;}

MAKING

MESSAGES

THE MOST OF

MESSAGING:
REQUIRED

MESSAGING:
REQUIRED

What is the * anyway?Well, it stands for something else and in HTML, the closest to that we have to convey that is the ABBR element.

Send us a message Required fields are marked
*.



  1. Name*

    ...

    MESSAGING:
    REQUIRED

    If you want to go all-out, you canbut that seems like overkill

    Send us a message Required fields are marked
    *.



    1. Name*


      ...

      MESSAGING:
      REQUIRED

      Send us a message Required fields are marked
      *.



      1. Name*

        ...

        MESSAGING:
        REQUIRED

        Send us a message Required fields are marked
        *.



        1. Name*

          ...

          abbr { cursor: help; font-style: normal; border: 0;}

          MESSAGING:
          FORMATTING

          MESSAGING:
          FORMATTING

          How should we emphasize important formatting info?

          ...


        2. Email*
        3. Phone format: 123-456-7890



        4. Subject*
          I noticed a website error
          ...

          MESSAGING:
          FORMATTING

          ...

        5. Phone format: 123-456-7890
          ...

          MESSAGING:
          FORMATTING

          ...

        6. Phone format: 123-456-7890
          ...

          label em.msg { font-size: .8em; font-style: normal; line-height: 2.5;}

          MESSAGING:
          FORMATTING

          ...

        7. Phone format: 123-456-7890
          ...

          label{ ... position: relative;}label em.msg { color: #aaa; font-size: .8em; font-style: normal; line-height: 2.5; position: absolute; right: -266px; top: 0;}

          MESSAGING:
          FORMATTING

          ...

        8. Phone format: 123-456-7890
          ...

          MESSAGING:
          ERRORS

          MESSAGING:
          ERRORS

          How should we strongly emphasize even more important error advisories?

          How should we highlight the field?

          ...

        9. Email*
          You forgot to fill
          in your email ...

          MESSAGING:
          ERRORS

          ...

        10. Email* You forgot
          to fill in your email

          ...

          MESSAGING:
          ERRORS

          ...

        11. Email* You forgot
          to fill in your email

          ...

          strong.err { color: #ffdfdf; display: block; padding-left: 5px; text-align: left;}

          MESSAGING:
          ERRORS

          ...

        12. Email* You forgot
          to fill in your email

          ...

          strong.err { color: #ffdfdf; display: block; line-height: 1.8; padding-left: 5px; text-align: left; white-space: nowrap; position: absolute; top: 0; left: 390px;}strong.err:before { content: "