Learning To Love Forms (Web Directions South '07)
-
Upload
aaron-gustafson -
Category
Technology
-
view
65.131 -
download
0
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
- Name
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
- Name
- 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
- Name
...
Send us a message
- 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
- ...
Go
Send us a message
- ...
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
- Name
- 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
- Name
- 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
- Name
- 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
- Name
- 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
- Name
- 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
- Name
- 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
- Name
- 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
- ...
- 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
- ...
- 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
- ...
- 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
- ...
- 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
- ...
- 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
- ...
- 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
- ...
- 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
- 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
- Date ...
- Month January ... December
Now the month
SIMPLE FORM:
DATE SELECT
And so forth
Post Date
- Date ...
- Month ...
- Year 2007 2008
And finally the year
SIMPLE FORM:
DATE SELECT
Post Date
- Date ...
- Month ...
- 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
- Date ...
- Month ...
- 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
- Date ...
- Month ...
- Year ...
.date li { float: left;}
Then bring it all in line
SIMPLE FORM:
DATE SELECT
Post Date
- Date ...
- Month ...
- 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
- Date ...
- Month ...
- Year ...
.date label { position: absolute; left: -999em;}
We can cleverly hide those labels using positioning
SIMPLE FORM:
DATE SELECT
Post Date
- Date ...
- Month ...
- 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
- Date ...
- Month ...
- 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
...
from the start of January
2006 ... December
2006- ...
...
COMPLEX FORM:
RELATED FIELDS
And again
...
- from the start of ...
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
- from the start of January 2006 ...
- 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
*.
-
Name*
...MESSAGING:
REQUIREDIf you want to go all-out, you canbut that seems like overkill
Send us a message Required fields are marked
*.-
Name*
...MESSAGING:
REQUIREDSend us a message Required fields are marked
*.-
Name*
...MESSAGING:
REQUIREDSend us a message Required fields are marked
*.-
Name*
...abbr { cursor: help; font-style: normal; border: 0;}
MESSAGING:
FORMATTINGMESSAGING:
FORMATTINGHow should we emphasize important formatting info?
...
Email*- Phone format: 123-456-7890
-
Subject*
I noticed a website error
...MESSAGING:
FORMATTING...
-
Phone format: 123-456-7890
...MESSAGING:
FORMATTING...
-
Phone format: 123-456-7890
...label em.msg { font-size: .8em; font-style: normal; line-height: 2.5;}
MESSAGING:
FORMATTING...
-
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...
-
Phone format: 123-456-7890
...MESSAGING:
ERRORSMESSAGING:
ERRORSHow should we strongly emphasize even more important error advisories?
How should we highlight the field?
...
-
Email*
You forgot to fill
in your email ...MESSAGING:
ERRORS...
-
Email* You forgot
to fill in your email...
MESSAGING:
ERRORS...
-
Email* You forgot
to fill in your email...
strong.err { color: #ffdfdf; display: block; padding-left: 5px; text-align: left;}
MESSAGING:
ERRORS...
-
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: "
-
-
-