Table of contents
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:
Post a Comment