Friday, April 15, 2011

Front-End Development Best Practice

Front-End Development Best Practice: "

Table of contents



  1. Browsers
  2. HTML
  3. CSS
  4. Javascript
  5. Frameworks
  6. Performance
  7. HTML5 / CSS3
  8. Accessibility


Foreword


This little book is to aid a shared understanding of front-end development best practice at PUP.


It's to help us deliver high quality content that works better, reaches more people - not only in today's browsers & devices, but in tomorrows.


Browsers



Statistics, naturally


Our own user logs are almost all that matters in deciding which browsers we officially support.

However, if we give our clients good reason to upgrade or switch to a newer, more standards compliant browser our jobs will be easier and our work higher quality as we won't need to be spending time fixing bugs in older browsers.


Do web sites need to look the same in every browser?


No. A page needs to serve its purpose in function and not appear broken.

It's not about browsers, it's about serving the users of our software by delivering content that that is valuable to them.


We currently support


The latest versions of all modern browsers, IE6-9 & top-level modern mobile browsers Opera & Safari.



  • IE6-9
  • Firefox
  • Chrome
  • Safari
  • Opera




  • Opera Mobile & Opera Mini
  • Mobile Safari

Install the latest versions of these browsers from U:/


IE6-8 are currently best tested on VM's pageuptest-ie[6,7,8] or run your own VM's.


You can test Opera Mobile from your desktop machine - You can also introspect Opera mobile inside a phone using Opera Dragonfly.


The iPhone SDK comes with Mobile Safari but is mac only, there's plenty of iPhones and iPads around the office. Make sure error reporting is enabled in Safari settings.

If you write front-end code you will need to test in all of these browsers to ensure it looks ok and functions as it should.



  • Scale the window down and see what happens at different screen resolutions and with different amounts of content.
  • Javascript will throw errors if something is wrong, most of the time.

Mobile


Mobile is hugely important today, we will need to review our mobile support regularly and follow the industry and our user-base. It will soon be more important than the desktop.


Writing front-end code without considering mobile doesn't cut the mustard, it cuts the cheese.


Simple things we can do



  • Optimise styles for small screens with @media queries & viewport meta
  • Add touch support - 44px x 44px minimum tap size
  • Don't rely on :hover, or mouseover events to get to content
  • Keep popups stand-alone - they cannot send data to the parent(e.g. binoculars)
  • Avoid scrolling content areas - It can be achieved in Mobile Safari using touch events and CSS transitions but it's not easy
  • Keep bandwidth to a minimum

@ppk writes about mobile at http://www.quirksmode.org/mobile/


Web standards


To 'Write once, deploy everywhere' was the great goal of the web standards movement.
Thanks to the efforts of web designers & browser vendors supporting web standards, browser compatibility is far easier today than it ever has been.


The W3C and WHATWG are groups that debate 'What the web should be', argue over APIs and publish standards for browser vendors and developers to implement.
These are open groups, anyone interested enough in them can contribute.



Follow


Following changes to the specs and listening to developers& designers is important. Follow changes at
@w3c
@whatwg

People to follow
@paul_irish
@brucel
@nimbuin
@keithclarkcouk
@thecssninja
@leaverou


Read from great authors
Dan Cederholm
Andy Clarke
Jeremy Keith


Join a forum
SitePoint


Rendering engines


The rendering engine in a browser reads HTML, CSS, other standards like XSLT, SVG, and paints the pixels on the screen.


The four biggies



Trident

IE

Gecko

Firefox

Webkit

Chrome, Safari, Apple & Android mobile devices.

Presto

Opera, Opera mini


Understanding the differences and quirks in these 4 rendering engines will reduce the amount of time needed to test layout & rendering.


HTML


HTML is the unifying language of the World Wide Web. Using just the simple tags it contains, the human race has created an astoundingly diverse network of hyperlinked documents, from Amazon, eBay, and Wikipedia, to personal blogs and websites dedicated to cats that look like Hitler.

- @adactio

Semantics


HTML gives meaning to content so that browsers and devices can then give that meaning to a user. e.g.


  • Headings h1 to h5 form a document outline and can give a table of contents for easy navigation.
  • A screen reader gets to a <table> and explains to a blind user how to navigate its content by rows/columns.
  • When a user clicks on a <label for="email"> the associated input control gains focus <input id="email">

If it's a heading use a heading.


If it's tabular data use a table.


If it's a list of links then make it so.


Lonely HTML


HTML should work without the presence of CSS or Javascript.
The content should be accessible, form submissions should work, the HTML on it's own should have value.

A good way to test the quality of the HTML is to disable images, CSS and Javascript and see how meaningful it is.


If we write our HTML like this when we get around to redesigning the UI, the HTML doesn't have to be rewritten.


Which version?


HTML5 is the version we use, but HTML versions don't really matter.
Browsers understand the tags they support, regardless of the doctype / version we validate against.


A doctype is necessary to force browsers to render in standards mode and prevent quirks mode head aches in ie.


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<title>
I ♥ HTML</title>
<link rel='stylesheet' href='style.css'>
</head>
<body>

<h1>
HTML5 <abbr title='For The Win'>FTW</abbr>!</h1>

<script src='script.js'></script>
</body>
</html>

* Lower case tags, double quote attributes.


Best practices:



  • Use as few 'nothing elements'(span / div) and styling hooks(class / id attributes) as possible. The leaner the HTML is, the easier it is to work with.
  • Feel free to use HTML5 tags / attributes but keep backwards compatibility in mind.
  • Use uft8 character encoding.
  • Avoid inline styles or event handlers

CSS


Be stylish



  • Keep CSS completely separate from the HTML
  • Re-use specific modules e.g. reset, grid, forms, type, print
  • use shorthand syntax wherever possible
  • use lower-case-hyphenated .class-names and #ids
  • code to a standards compliant browser first, then fix issues in IE

Internet Explorer WTF?


We really should be thankful that non-ie browsers have such great consistency, I have never needed a CSS hack for a non-ie browser.


Without IE, web development would just be too easy.


Prevent IE from switching to unhelpful modes:


<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>

When testing your work in IE start with the latest version and work your way back.


IE conditional comments


<!--[if lt IE 7 ]> <html class="ie6"> <![endif]-->
<!--[if IE 7 ]> <html class="ie7"> <![endif]-->
<!--[if IE 8 ]> <html class="ie8"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <html> <!--<![endif]-->

If we replace our html tag with the above we can use classes to deliver styles to specific versions.

e.g. 'float to fix' a bug with #myElement in ie6


.ie6 #myElement { float: left; width: 100% }

What is hasLayout?


The single most important thing you need to know about fixing bugs in IE!
Giving an element 'Layout' will fix 99% of ie rendering bugs, as if by magic. The other 1% will most likely be related to position: relative; or floats. Use 'zoom: 1' as a trigger for whatever ie versions need it.


.ie6 #myElement, .ie7 #myElement { zoom: 1 }

http://www.sitepoint.com/forums/2041209-post24.html


Media queries


Deliver specific styles to different devices, they can test for things like:



  • screen or print
  • width and height
  • orientation – is mobile device in landscape or portrait mode?
  • resolution

You can optimise styes for different devices


@media only screen and (max-device-width: 480px) {
/* hide header and footer on small screen devices */
#header, #footer { display: none }
}
@media only screen and (max-width:800px) {
/* linearize navigation under 800px */
nav, nav li, nav a { float: none; width: 100% }
}

See http://colly.com/ for a great example


The viewport meta tag is also needed to instruct a mobile device to keep the viewport to the amount of pixels it has on the screen i.e. prevent it from zooming out like a desktop version.


<meta name='viewport' content='width=device-width'>

Great article on viewport and media queries http://dev.opera.com/articles/view/an-introduction-to-meta-viewport-and-viewport/


Best practices:



  • Use meaningful class names and IDs - e.g. 'loading' as opposed to 'bigYellowSpinnyThing'
  • Control the margin and padding on all the elements you use.
  • Avoid absolute positioning
  • Avoid !important
  • Don't suffer from divitus and classitus
  • Don't use breaks <br> just to make space in your layout
  • Avoid hacks unless there is no other way to achieve what you want

Javascript


Hold on there Bald Eagle. Why are we always in such a hurry?

- @malarkey

Moving parts


Javascript sits on top of the HTML and CSS foundation and enhances the user experience & behaviour of the page, that's it.


What is javascript good for?



  • User interaction
  • User experience - e.g. Responsiveness
  • Dynamic behaviour
  • Animation
  • Make pages easier to use
  • Aid accessibility - e.g. add keyboard support.
  • Shims - Adding support to browsers for features they don't natively support

Progressive enhancement


Is an important concept, it means making a page work without a feature that may / may not be supported first.
If a feature is supported the user gets the benefit, if not - it still works.


If we treat javascript like this it makes our code higher quality and prevents atrocities like:


<a href='javascript:myKillerFunction('sucks', true);'>Click here</a>

It means that if something breaks the page can continue to work without the enhancement.
Progressive enhancement also aids maintainability, keeping the javascript separate means there's no need to search all documents for function calls.


Clean API's


Because we are not cluttering the global scope we can have short awesome names for our methods& variables.


var Toggler = {
open: function() {},
close: function() {},
toggle: function() {}
}

Optional arguments


Add only the absolutely necessary parameters as arguments, put all optional parameters into an options hash.


function circle(x,y,radius,options) {
options = options || {};
}

Controls framework


Controls are initialised via a container element with class=”init” e.g. If you're initialising stuff onload use this.


<input class='init control-awesome-toggler'>

On load this would pick up the above element and try to create a new instance of the AwesomeToggler Control below:


Controls.AwesomeToggler = Class.create(Controls.Base, {
initialize: function ($super, container) {
$super(container);
container.observe('click', eventFn.bind(this));
},
eventFn: function(e) {}
});

Best practices:



  • Favour the framework & DRY
  • Avoid inline & embedded js
  • Keep global scope clean, put code into namespaces Page, Util, Controls
  • Be defensive, feature detect
  • Test performance in all browsers mentioned above - use console.time to track down bottlenecks.
  • Minimise number of event listeners on a page, use event delegation
  • Keep components as independent as possible
  • var every variable

Frameworks



If you want to use a library you must have read it, understood it, agree with it, and not be able to write a better one on your best day of coding.

- @sentience

Frameworks are not evil, they save time, fix cross browser compatibility issues and make us think in new ways.
But, they do add overhead so before we jump in bed with them, see above.


Javascript


We should only have one 'Core' javascript framework, additional libraries for specific tasks not handled by the Core framework can be added if they meet the above requirements.

e.g. Effects & animation, SVG, Charting, Shims(Add support for features that aren't natively supported by some browsers)


Read, Collaborate & Contribute to open source


Open source frameworks are the product of really interested people. Interested people create great stuff.


Schools out, but keep learning
jquery
mootools
prototype
scriptaculous
raphaƫl


Gain heroes
Paul Irish,
Thomas Fuchs,
John Resig,
Dmitry Baranovskiy


Roll your own


Create something great and share it with me.


Performance


YUI best practice


The YUI team has done as much research into front-end performance as anyone.


Here's a cut down version of the YUI best practices for performance, reading the full article is highly recommended though. http://developer.yahoo.com/performance/rules.html


Follow @souders if you're interested in web performance.


Minimize HTTP Requests


Combine all scripts and stylesheets & use image sprites to reduce the number of round trips to the server.


Use a Content Delivery Network


We should move all referenced files css, js, images etc. to dispersed servers like Akamai.


Put Stylesheets at the Top


Putting stylesheets in the <head> allows the page to render progressively.


Put Scripts at the Bottom


<script> tags block parallel downloads, put them last so other resources can be downloaded first.


Avoid Expressions


Expressions are a way of running javascript as part of a CSS rule in ie6-7. They can be used to fix support for non-supported features - like fixed positioning. The problem is they are constantly evaluated which can really slow down the page.


.ie6 .fixed {
top: expression(0+((e=document.documentElement.scrollTop)?e:document.body.scrollTop)+'px');
}

Make JavaScript and CSS External


The Cache is our friend. The only exception would be pages with one view per session which may benefit from inline script.


Minify JavaScript and CSS


We should use a minifier like JSMin, YUI Compressor or Closure Compiler to reduce the file size our CSS & js.

Removing variables from the global scope can get better results from compression as the names can be shortened as they can't be accessed outside of their enclosing functions.


var canIBeShortened = 'no';
(function() {
var willMyReallyLongVariableBeShortnedByTheMinifier = 'yes';
alert(willMyReallyLongVariableBeShortnedByTheMinifier);
})();

// Minified
var canIBeShortened='no'function(){alert('yes')})()

Avoid Redirects


Slows down the user experience.


Reduce the Number of DOM Elements


Smaller pages with fewer elements are faster to traverse and modify.


Minimize the Number of iframes


Costly even if blank because they are new windows, they also block the page's onload event.


No 404s


Look through monitoring and remove these unnecessary trips to the server.


Reduce Cookie Size


Transferred in the page headers, remove unnecessary cookies, keep small, set an Expires date.


Minimize DOM Access


Save references to elements in variables to prevent lookups, innerHTML is generally faster than DOM, avoid fixing layout with js.


Develop Smart Event Handlers


Minimise the amount of event listeners in a page with Event Delegation.

Prototype's 'on' function registers an event listener on the body element once to handle all the occurrences of that event in the page. e.g.


<body>
<p>
<a href='#'>
<span>
linky</span>
</a>
<a href='#'>
<span>
linky 2</span>
</a>


When a <span> element is clicked the event moves up through the tree, all the way to the body where the event handler can find which <span> element fired it.


If you have 100 elements in the page you want respond to click events, Event delegation will save you.


Learn http://icant.co.uk/sandbox/eventdelegation/


Avoid IE Filters in CSS


Filters are 'special features' in CSS for IE, they can slow down the page though, so use sparingly.


Optimize Images


Batch operations like the YUI image compressor, ImageOptim or sprite generators should be used to make the images as small as possible whilst keeping their quality.


Keep Components under 25K


The iPhone won't cache anything bigger than 25K uncompressed.


HTML5 / CSS3


Shiny new toys


Go to town, but keep backwards compatibility and progressive enhancement in mind. Making pages look identical is not the aim, just don't rely on an HTML5 / CSS3 feature for an important feature of a page.


CSS3 can be used, however with the majority of our users on ie6 still we should treat CSS3 features as visual rewards for capable browsers and things which save us lots of time, like gradients and border-radius. Use all vendor prefixes in alphabetical order with the prefixless version last.


#slides img:hover {
-moz-transform: scale(1.6);
-ms-transform: scale(1.6);
-o-transform: scale(1.6);
-webkit-transform: scale(1.6);
transform: scale(1.6);
}

HTML5 can be used, consider using shims to add support for more of our users and test the performance impact.


Learn http://diveintohtml5.org/ http://html5doctor.com/


Maintain a support chart


Maintaining your own pages with test cases of standards being developed is the best way to keep up to date. It helps you to really learn how to use them, if you don't practice you quickly forget what you learnt.


Best practices:



  • Feature detect
  • Treat CSS3 as visual rewards for capable browsers
  • Use shims for HTML5 features if they perform well enough

Accessibility


People



Accessibility matters, it matters to those trying to use our software with a disability, it's in our contracts, it also directly relates to discrimination laws we need to know about, as well as simply being the right thing to do.


Writing semantic HTML, CSS that's flexible with layout & font-size as well as using Javascript to add keyboard support go a long way in making a web app as accessible as possible.


It's not always difficult to make something accessible. Always ask what you can do to improve a pages accessibility.


Visual impairments


Supporting blind users of screen reading software like JAWS / NVDA is the obvious case but there are others. Use a sensibly sized default font and provide alt stylesheets for different font sizes. Use enough contrast between colours and foreground / background to enhance readability.


Use a screen reader, it's the only way to gain a good insight into what using our software is really like for blind users.


Accessible tables & forms


Keep tables simple and avoid nested headings. Using th elements for heading cells with appropriate scope is the first step for accessible tables.


<table>
<tr>
<th scope='col'>
Name</th>
<th scope='col'>
Age</th>
<th scope='col'>
Birthday</th>
</tr>
<tr>
<th scope='row'>
Jackie</th>
<td>
5</td>
<td>
April 5</td>
</tr>
<tr>
<th scope='row'>
Beth</th>
<td>
8</td>
<td>
January 14</td>
</tr>
</table>


Linking labels to inputs with the for attribute is the first step for accessible forms.


<label for='email'>Email</label>
<input id='email'>

Learn
http://www.456bereastreet.com/archive/200410/bring_on_the_tables/

http://www.webstandards.org/learn/tutorials/accessible-forms/


Motor impairments


Most of us can appreciate using keyboard short cuts for navigating forms, people with low mobility will appreciate being able to use our software without a mouse far more than this.


UI consistency


This one is not as obvious as the other points, but is as valid. A consistent UI will help all our users be able to access what they need to. It's rare to find a web application of our size and complexity that doesn't have a style guide, let's make one.


WCAG & WAI ARIA


We have focused on WCAG 1 Level A compliance in the past, WAI ARIA is a fairly recent addition and focuses on the moving parts of a web app. The ARIA attributes can help explain dynamic changes to the page with javascript to users of assistive technologies.


http://dev.opera.com/articles/view/introduction-to-wai-aria/


Best practices:



  • Test in JAWS or NVDA (on U:) - Add alt attributes, accessible forms & tables
  • Consider Ajax & screen readers - How do you alert users to changed content?
  • Add keyboard alternatives to all mouse events - mouseover -> focus, mouseout -> blur - Test without a mouse
  • Assistive features - High contrast stylesheet, font-size stylesheets, access keys, skip links
  • Avoid colour alone for critical information - e.g. Red = bad, Green = good
  • Help everyone - Usable in different screen sizes, consistent navigation and user experience, friendly URLs, favicon etc.

People to follow
@jkiss
@stevefaulkner
@vick08

Go forth and multiply


Let's build something awesome and be home for dinner.





Comments"

No comments: