Matt Snider JavaScript Resource

Understanding JavaScript and Frameworks

Wednesday, March 12, 2008

Building Better Forms

Most of the times when building forms, you will have a label either to the left or above the field that the label is associated with. Designers come up with all kinds of crazy ways to handle the layout, but most are not semantic and require browser hacks. In the past, I have used the following markup:

Example 1: Semantic Forms Version 1 HTML

<form> <ul> <li><label>Label1</label><input type=”text” value”" /><li> <li><label>Label2</label><input type=”text” value”" /><li> … </ul> </form>

The label can then either float left or right, or be displayed as block, depending on your needs. However, I recently saw on the social networking site Facebook.com a nice technique using the definition list tag (dl). I found this particularly appealing, because browsers (by default) and designers apply less styles to DL tags, so your design is more portable. Plus, it is a semantic to use a DL tag anytime you have key/value pairs; in this case, the key is the label and the value is the field.

Here is an example of what your Form could look like:

Example 2: Facebook Message Form

Example of Facebook Message Form

To produce such a nice looking Form, your HTML will be something like:

Exmaple 3: Semantic Form Version 2 HTML

<form action=”someURL” class=”clearfix” id=”someID” method=”post”><dl> <dt><label for=”form-msg-to”>To:</label></dt> <dd><input id=”form-msg-to” name=”to” type=”text” value=”"/></dd> <dt><label for=”form-msg-subject”>Subject:</label></dt> <dd><input id=”form-msg-subject” name=”subject” type=”text” value=”"/></dd> <dt><label for=”form-msg-message”>Message:</label></dt> <dd><textarea cols=”30″ id=”form-msg-message” name=”body” rows=”5″></textarea></dd> </dl></form>

And the associated styles:

Example 3: Semantic Form Version 2 CSS

#message form { /* Optional, just a littl nice padding */ padding: 3em 0pt 1em 9em; } #message dl { /* Replace with desired width */ width: 47em; } #message dl dt { float: left; /* Spacing between label and field */ padding: 0 1em 0 0em; text-align: right; /* Width of largest label */ width: 6.5em; } #message dl dt label { /* Make whatever you like */ color: #666; /* Labels with “for” attribute are clickable, ensure they look that way */ cursor: pointer; display: block; /* Use whatever font-size you prefer */ font-size: larger; /* Adjust padding to align with fields */ padding-top: 0.5em; } #message dl dd { float: left; /* This is the padding between form field rows */ margin: 0 0 1em; /* Remaining width dl - dt - padding */ width: 39em; } #message input.txt, #message textarea { /* Prevents x-browser bug */ overflow: hidden; padding: 0.4em 0 0.4em 0.2em; width: 33em; }

You may also need to add the “clearfix” style to the form if other elements depend on its positioning, as the content of the form floats, so it won’t have any height. Otherwise, I think the comments are pretty self-explanatory.

posted by Matt Snider at 11:31 am  

Tuesday, February 26, 2008

CSS List Boxes Improved

I came across a slick CSS List Box widget the other day and wanted to share it. The original page was done by Mike Cherim, CSS: List Boxes. I liked how relatively simple the HTML and CSS was, plus the design was very visually appealing.

Example 1: Modified HTML

<div class=”clb-shell”> <h3>Web Services (List Boxes Example)</h3> <p>We offer a variety of web services for our customers. Our services include:</p> <ul> <li> <h5><a href=”#”>Web Hosting</a></h5> <p>We have professional web hosting services suited to your needs. Read more about our <a href=”#”>Web Hosting</a> services.</p> </li> <li> <h5><a href=”#”>Web Design</a></h5> <p>Need a web site? We can help you build your place on the web. Read more about our <a href=”#”>Web Design</a> services.</p> </li> <li> <h5><a href=”#”>Web Master</a></h5> <p>Need the works? Our Web master services take care of every need. Read more about our <a href=”#”>Web Master</a> services.</p> </li> </ul> <p>To learn more about these services, check out the links above or <a href=”#”>contact us</a> today!</p> </div>

I have changed very little of the HTML, as it was already well design and minimalist. One notable change is that the sectional heading tag are now H3 tags instead of H2 tags, and the H3 tags are now H5 tags. This follows the conventions I mentioned in last Fridays article, When to Use Heading Tags. Another change is that I removed the ID from the UL tag, because it is simply not necessary due to specificity (you may want to keep it in if you are using JavaScript to interact with the UL tag). The last change, is that I changed the “clb-shell” ID attribute into a CLASS attribute, this way you can use multiple instances of this widget on the same page.

You may be wondering why we use an anchor tag inside of the H5 tags. Ideally, this wouldn’t be necessary, but in IE 6 and lower you can only apply the pseudo class “:hover” to anchor tags. So if you like the hover style on the heading of the box, then this is necessary.

Assuming then, that you adopt my recommendations, you will need the following CSS:

Example 2: Modified CSS (assumes you are using Reset.css

/* First define a content are width and position, if needed. This centers (in most browsers) and applies a width */ div.clb-shell { margin : auto; width : 62.3em; } /* Default color, border of the heading */ div.clb-shell h3 { color : #669900; } /* P tags should pad and clear floats */ div.clb-shell p { padding : 1em; clear : both; } /* Always use EMs for the height, so that the boxes scale well. List-style-type: none should already be applied, but just in case Should be 4px thinner than the main container */ div.clb-shell ul { width : 61.9em; height : 9em; text-align : center; list-style-type : none; } /* Now I style the individual boxes (li) */ div.clb-shell ul li { margin : 0 0.2em; border : 1px solid #666; width : 20em; height : auto; background : #ffffea url(images/clb_li_back.jpg); /* Main background image */ float : left; display : inline; } /* Style the li links */ div.clb-shell a { color : #669900; } div.clb-shell a:hover, div.clb-shell a:focus, div.clb-shell a:active { color : #000; text-decoration : none; } div.clb-shell a:focus, div.clb-shell a:active { background-color : #fff; } /* Style the h5 links */ div.clb-shell ul h5 a { color : #ffffaa; display : block; width : 19.4em; padding : 0.2em 0.3em; background : #333 url(images/clb_h5_back.jpg) repeat-x; /* header background image */ border-bottom : 1px solid #666; text-decoration : none; } div.clb-shell ul h5 a:hover, div.clb-shell ul h5 a:focus, div.clb-shell ul h5 a:active { background : #957412 url(images/clb_h5_back_over.jpg) repeat-x; /* header hover image */ color : #fff; } /* This styles the text p content within the li separately. The most important thing here is to re-kill the padding and add the margin to create good gutters */ div.clb-shell ul p { font-size : 0.9em; padding : 0; margin : 1em; }

The only major change, beside the previously mentioned updates, is that I made to the styles was to rename the background images to clb_h5… instead of clb_h3. The other change is that since I assume you are using “reset.css”, we can safely use EMs instead of PXs. This allows your widgets to scale.

One other great benefit from using CLASS attributes instead of ID attributes is that you can easily override the styles here for different looks on the same page. For example, lets assume you use the ‘overload’ class to override the second CSS List Box:

Example 3: Override Colors

<ul class=”overload”>
div.clb-shell ul.overload li { background : #ffffea url(images/clb_li_back_2.jpg); /* Main background image */ } div.clb-shell ul.overload h5 a { background : #333 url(images/clb_h5_back_2.jpg) repeat-x; /* header background image */ } div.clb-shell ul.overload h5 a:hover, div.clb-shell ul h5 a:focus, div.clb-shell ul h5 a:active { background : #957412 url(images/clb_h5_back_over_2.jpg) repeat-x; /* header hover image */ }
posted by Matt Snider at 10:54 pm  

Saturday, February 23, 2008

When to Use Heading Tags

Heading tags are probably the most misused tag in all of HTML. Since the advent of CSS, many web-designers no longer care that an H1 tag is the most important tag of the page or that an H2 is the second most important tag. I have seen pages with multiple H1s and only a few H2s, or pages where HN (where N > 1) styles are bolder than H1 tags. You might be asking yourself, why should I care since CSS can masked these flaws? Well, here are few reasons:

  1. Semantic HTML - following this practice your HTML design should have meaning; so an H1 tag should mean the most important Heading on the page and H2 the second, etc
  2. Accessibility - Screen Readers do not understand the class or styles you have applied to your tags, they take meaning from context and assume the importance of a heading is based on the HTML specification (H1 > H2 > H3 …)
  3. No CSS - If a user turns their CSS off, your page won’t make as much sense as the browsers expect heading tags to follow HTML specifications
  4. Cleaner code - Generally, you need less HTML and CSS code when properly using tags

Points 1-3 can really be summed up by saying that your pages should make sense contextually, and with or without CSS. By writing semantic HTML your code is easier to be read by and shared with your colleagues. Typically, semantic HTML is cleaner as well. In this case, you can replace whatever you are using to show your page headings (I was using: “<div class=”header”>) with just <h1>.

When I redesigned some of my older work to be more semantic, I came up with these rules:

  • H1 - page heading/title, each page should have no more than 1 of these (except very rare situations)
  • H2 - page subheading/subtitle, should follow H1 tags; I reserve this tag for subheadings, because in most projects I use an optional subheading below my page headings.
  • H3 - section headings/titles, each content block on the page usually needs a heading and I reserve this tag for that purpose
  • H4 - section subheadings/titles, should follow H3 tags; again, I reserve this for a possible sectional subheading
  • H5 - mini-sections, inside of a section; often I style these only slightly large than the surrounding text and with an underline
  • H6 - minor-sections, often used when multiple ideas are expressed below an H5, but can be used in place of the H5 tag. Same style as H5, but no underline

When styling your tags, I use these general rules:

  • all your heading tags should be bolded and (slightly) larger than surrounding text
  • font-sizes should scale with H1 being the largest and H6 being the smallest
  • sometimes, I use the same font-size for the tags used in conjunction (ie, H1 size = H2, H3 size = H4, H5 size = H6), but that is up for designer interpretation
  • I like to use a color different from the rest of the text for H1 and H2 tags (and possibly a background color as well, depending on design), but use the standard text color for all other headings
  • I generally don’t use the underline text style for tags (except H5), instead if a heading needs to be underlined, then apply a bottom border line
  • and all heading tags should be block level

Following these guidelines, I find it easier to move between projects and make quick design changes. My markup is also simpler and I need less CSS selectors to change my heading styles than I previously needed when each DIV or heading tag had required a class or id selector to overwrite the default style. Lastly, my pages make a lot more sense when viewed by a Screen Reader or without CSS.

posted by Matt Snider at 12:17 pm  

Saturday, December 29, 2007

Faux Columns

This past week has been really crazy: 3 Christmas celebrations, 1 Birthday, and family staying over for the last 3 days. Consequently, I have not succeeded in a finishing my xJson Object article. So instead of discussing xJson, today we will discuss a simpler, but very useful technique, known as Faux Columns.

The Problem:
If you have ever tried to design a two-column layout without using tables, you should know that the two columns (by default) will not be the same height. This is normally not a problem until you want a line of some kind dividing the columns. This line should be the height of the tallest column. Initially, you might think that adding a border-right to the left column or a border-left to the right column, will do the trick. However, because one column may (and probably will) be larger than the other, borders will not work. The simplest fix is to apply a height to both columns and call it a day. However, many layouts have dynamic content, such as this blog, and you will not be able to specify a height.

The Solution:
There are many different solutions to this problem (including JavaScript, CSS hacks, etc.), but the simplest (and x-browser safest) one is Faux Columns; it requires no hacks, only good HTML and CSS design. Faux Columns were first introduce by A List Apart. Since, the column height can be dynamic, instead of applying a background or border to the columns, you wrap the columns inside an element and apply a background style to that element. That background style will have your column background and border styles. For example, lets assume you use the following HTML:

Example 1: Simple HTML

… <body><div id=”doc”> <div id=”header”>This is my header</div> <div id=”main”> <div id=”sidebar”>Put sidebar elements here</div> <div id=”content”>Put content elements here</div> <div class=”clearfix”></div> </div> <div id=”footer”>This is my footer</div> </div></body> …

And you want to use this HTML to produce a two column layout with a column-independent header and footer:

Example 2: Layout

faux layout example

Then apply the following styles (I recommend using reset.css and base.css as well):

Example 3: Styles

/** Center the doc div; excluding IE, see IEHacks for more info on how to do this in IE < 6 */ #doc { margin: 0.5em auto; overflow: hidden; width: 90em; } /** Replace these with whatever styles you prefer */ #header { border-bottom: 1px solid #830A04; height: 3.6em; } /** Creates the faux column */ #main { background: #EFEFEF url(../images/bg/column.gif) 25em 10px repeat-y; /** faux column graphic */ clear: both; } /** Right column */ #content { float: right; width: 64em; } /** Left column */ #sidebar { float: left; width: 24em; } /** Replace these with whatever styles you prefer */ #footer { background-color: #FFF; border-top: solid 1px #000; clear: both; padding-top: 1em; } /* (en) clearfix method for clearing floats */ .clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } /* (en) essential for Safari browser !! */ .clearfix { display: block; }

I prefer my designs to be 100% elastic so that they are accessible and have used ems to specific widths. However, you could just as easily use pixels and a fixed layout. If you use the ‘reset.css’ and ‘base.css’ then 1em = 10pixels. In this example, the background image is a solid color with the column divider graphic on the left side, and the sidebar color is specified by the background style of main. This way, I simply offset the background image to the width of the sidebar, and it scales to all font-sizes. The only constraint on the background image is that it needs to repeat vertically, otherwise, you will not get the column effect (so you need to create a repeating vertical pattern).

If you use a fixed layout and want a less plain sidebar design, then do not offset the image. Instead offset the column divider in your graphic to the width of the sidebar (or wherever you need the gutter).

You might be wondering why the empty div with class ‘clearfix’ is there. This is needed because the ‘main’ div’s height will not reflect the height of the content floating inside it. The ‘clearfix’ div forces an empty div to be placed at the end of the columns that clears both the left and right float. This non-floating element, is positioned after the tallest floating content and causes the ‘main’ div to then expand to the height of the largest column.

Here is a simple example that uses a double vertical line to divide the columns.

posted by Matt Snider at 3:43 pm  

Tuesday, December 18, 2007

Semantic HTML for a Simple 5-Star Rating System

I am going to deviate this week from the Json Object discussion, as I have not had any time to work on it. Instead, I wanted to share a technique you can use to write semantic HTML for a rating system. If you have ever used a site like Amazon.com or Yelp.com, then you are familiar with the star rating system (0 stars = worst rating, 5 stars = best rating). However, most rating systems do not do a good job when browser font-size or zoom changes, making them inaccessible. Also, most tend to use a different graphic for each rating, requiring up to 10 graphics to load. The technique I worked on this week, not only scales well, but only requires 2 graphics, and you can change the color of your ratings with simple CSS.

Step 1: Create 2 Images

First decide which size you want the image to normally be (for me this was 80px wide by 16px high); this is a 1 to 5 ratio, because I am going to use a 5 point rating system, which will play an important role for the size of each rating point symbol. Use a program like Photoshop to create an image with these dimensions and a transparent background. In a separate window create an 16 x 16 (or 1/5 of the default width you chose) transparent image and draw in the symbol you want to use for the rating point (I used black for the color of my symbol, but it is up to you). I used a star, but it doesn’t matter what you choose so long as the center is transparent and the symbol fills the dimensions. All spaces outside the symbol should be the background color of your page (this is white for my example page). Here is an example of my star:

Example 1: Star Graphics

Single star graphic

Single star graphic

The first graphic shows what “star.gif” looks like by default. The second show, the difference when a background color is applied. I choose red, but you can change it to whatever hex you prefer.

Next copy your 16×16 symbol image 5 times into the original image you created. You should have something that looks like the following:

Example 2: Rating Graphics

5 star graphic

5 star graphic

Example 2 is the first image we will need. I made the background yellow to show how easy it is to change. The second image we need is a background masking image used to cover the part of the rating inverse (if the rating is 1.5, then this will cover the other 3.5 of the symbols). The background should be the color of the site background (white for me), and the left-most pixels should all be the color of the symbols (black for me). This image should be taller and wider than the rating image, because it will need to scale as the browser does. I usually do 2x the original dimensions, which supports up to a +4 font-size. Therefore, the dimensions of my “ratingbg.gif” is 160×32px:

Example 3: Rating Background Graphics

5 star graphic

The gray border is only here to show contrast so you can see what the image looks like. The small sliver of black on the left will be the line that marks the rating position inside of the symbols. This completes all the images and HTML you will need to get the rating system to work.

Step 2: Create Styles to Control the Ratings

Next we style the image tag to support our ratings. I suggest using classes, here are the styles I used:

Example 4: Rating Styles

img.rating { background: #FC0 url(/assets/img/bg/ratingbg.gif) 5em 0 no-repeat; /* specify your color; 5 em is the 5:1 ratio; and the url is wherever the ratingbg.gif is located */ font-size: 1.6em; /* this is the height of a single symbol; mine is 16px */ height: 1em; /* this will cause the image to scale as the font-size changes, default is 16px */ width: 5em; /* this the 5 to 1 ratio that I mentioned, but could be different if your symbols aren’t symetric */ } /* higher specificity than img.rating */ html body img.r9 { background-position: 4.5em 0; } html body img.r8 { background-position: 4.0em 0; } html body img.r7 { background-position: 3.5em 0; } html body img.r6 { background-position: 3.0em 0; } html body img.r5 { background-position: 2.5em 0; } html body img.r4 { background-position: 2.0em 0; } html body img.r3 { background-position: 1.5em 0; } html body img.r2 { background-position: 1.0em 0; } html body img.r1 { background-position: 0.5em 0; } html body img.r0 { background-position: 0 0; }

Step 3: Tie it all Together

Here is a rating of 2.5 in yellow, 1 in blue, and 4.5 in green:

Example 5: 3 Star Rating Variations

2.5 in yellow rating example
1 in blue rating example
4.5 in green rating example

The image heights in this article are slightly off by a fraction, due to rounding issues with other styles inherited in this wordpress theme. I have also created a test page so you can play with the uncorrupted styles and view them in different browsers. Try to scale the font-size and see how nicely the images scale and the rating stays in the appropriate place.

posted by Matt Snider at 3:45 pm  

Powered by WordPress