1 |
[HTML5 Boilerplate homepage](http://html5boilerplate.com) | [Documentation |
2 |
table of contents](README.md) |
3 |
|
4 |
# Extend and customise HTML5 Boilerplate |
5 |
|
6 |
Here is some useful advice for how you can make your project with HTML5 |
7 |
Boilerplate even better. We don't want to include it all by default, as not |
8 |
everything fits with everyone's needs. |
9 |
|
10 |
|
11 |
## DNS prefetching |
12 |
|
13 |
In short, DNS Prefetching is a method of informing the browser of domain names |
14 |
referenced on a site so that the client can resolve the DNS for those hosts, |
15 |
cache them, and when it comes time to use them, have a faster turn around on |
16 |
the request. |
17 |
|
18 |
### Implicit prefetches |
19 |
|
20 |
There is a lot of prefetching done for you automatically by the browser. When |
21 |
the browser encounters an anchor in your html that does not share the same |
22 |
domain name as the current location the browser requests, from the client OS, |
23 |
the IP address for this new domain. The client first checks its cache and |
24 |
then, lacking a cached copy, makes a request from a DNS server. These requests |
25 |
happen in the background and are not meant to block the rendering of the |
26 |
page. |
27 |
|
28 |
The goal of this is that when the foreign IP address is finally needed it will |
29 |
already be in the client cache and will not block the loading of the foreign |
30 |
content. Less requests result in faster page load times. The perception of this |
31 |
is increased on a mobile platform where DNS latency can be greater. |
32 |
|
33 |
#### Disable implicit prefetching |
34 |
|
35 |
```html |
36 |
<meta http-equiv="x-dns-prefetch-control" content="off"> |
37 |
``` |
38 |
|
39 |
Even with X-DNS-Prefetch-Control meta tag (or http header) browsers will still |
40 |
prefetch any explicit dns-prefetch links. |
41 |
|
42 |
**_WARNING:_** THIS MAY MAKE YOUR SITE SLOWER IF YOU RELY ON RESOURCES FROM |
43 |
FOREIGN DOMAINS. |
44 |
|
45 |
### Explicit prefetches |
46 |
|
47 |
Typically the browser only scans the HTML for foreign domains. If you have |
48 |
resources that are outside of your HTML (a javascript request to a remote |
49 |
server or a CDN that hosts content that may not be present on every page of |
50 |
your site, for example) then you can queue up a domain name to be prefetched. |
51 |
|
52 |
```html |
53 |
<link rel="dns-prefetch" href="//example.com"> |
54 |
<link rel="dns-prefetch" href="//ajax.googleapis.com"> |
55 |
``` |
56 |
|
57 |
You can use as many of these as you need, but it's best if they are all |
58 |
immediately after the [Meta |
59 |
Charset](https://developer.mozilla.org/en/HTML/Element/meta#attr-charset) |
60 |
element (which should go right at the top of the `head`), so the browser can |
61 |
act on them ASAP. |
62 |
|
63 |
#### Common Prefetch Links |
64 |
|
65 |
Amazon S3: |
66 |
|
67 |
```html |
68 |
<link rel="dns-prefetch" href="//s3.amazonaws.com"> |
69 |
``` |
70 |
|
71 |
Google APIs: |
72 |
|
73 |
```html |
74 |
<link rel="dns-prefetch" href="//ajax.googleapis.com"> |
75 |
``` |
76 |
|
77 |
Microsoft Ajax Content Delivery Network: |
78 |
|
79 |
```html |
80 |
<link rel="dns-prefetch" href="//ajax.microsoft.com"> |
81 |
<link rel="dns-prefetch" href="//ajax.aspnetcdn.com"> |
82 |
``` |
83 |
|
84 |
### Browser support for DNS prefetching |
85 |
|
86 |
Chrome, Firefox 3.5+, Safari 5+, Opera (Unknown), IE 9 (called "Pre-resolution" |
87 |
on blogs.msdn.com) |
88 |
|
89 |
### Further reading about DNS prefetching |
90 |
|
91 |
* https://developer.mozilla.org/En/Controlling_DNS_prefetching |
92 |
* http://dev.chromium.org/developers/design-documents/dns-prefetching |
93 |
* http://www.apple.com/safari/whats-new.html |
94 |
* http://blogs.msdn.com/b/ie/archive/2011/03/17/internet-explorer-9-network-performance-improvements.aspx |
95 |
* http://dayofjs.com/videos/22158462/web-browsers_alex-russel |
96 |
|
97 |
|
98 |
## Search |
99 |
|
100 |
### Direct search spiders to your sitemap |
101 |
|
102 |
[Learn how to make a sitemap](http://www.sitemaps.org/protocol.php) |
103 |
|
104 |
```html |
105 |
<link rel="sitemap" type="application/xml" title="Sitemap" href="/sitemap.xml"> |
106 |
``` |
107 |
|
108 |
### Hide pages from search engines |
109 |
|
110 |
According to Heather Champ, former community manager at Flickr, you should not |
111 |
allow search engines to index your "Contact Us" or "Complaints" page if you |
112 |
value your sanity. This is an HTML-centric way of achieving that. |
113 |
|
114 |
```html |
115 |
<meta name="robots" content="noindex"> |
116 |
``` |
117 |
|
118 |
**_WARNING:_** DO NOT INCLUDE ON PAGES THAT SHOULD APPEAR IN SEARCH ENGINES. |
119 |
|
120 |
### Firefox and IE Search Plugins |
121 |
|
122 |
Sites with in-site search functionality should be strongly considered for a |
123 |
browser search plugin. A "search plugin" is an XML file which defines how your |
124 |
plugin behaves in the browser. [How to make a browser search |
125 |
plugin](http://www.google.com/search?ie=UTF-8&q=how+to+make+browser+search+plugin). |
126 |
|
127 |
```html |
128 |
<link rel="search" title="" type="application/opensearchdescription+xml" href=""> |
129 |
``` |
130 |
|
131 |
|
132 |
## Internet Explorer |
133 |
|
134 |
### Prompt users to switch to "Desktop Mode" in IE10 Metro |
135 |
|
136 |
IE10 does not support plugins, such as Flash, in Metro mode. If your site |
137 |
requires plugins, you can let users know that via the X-UA-Compatible meta |
138 |
element, which will prompt them to switch to Desktop Mode. |
139 |
|
140 |
```html |
141 |
<meta http-equiv="X-UA-Compatible" content="requiresActiveX=true"> |
142 |
``` |
143 |
|
144 |
Here's what it looks like alongside H5BP's default X-UA-Compatible values: |
145 |
|
146 |
```html |
147 |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1,requiresActiveX=true"> |
148 |
``` |
149 |
|
150 |
You can find more information in [Microsoft's IEBlog post about prompting for |
151 |
plugin use in IE10 Metro |
152 |
Mode](http://blogs.msdn.com/b/ie/archive/2012/01/31/web-sites-and-a-plug-in-free-web.aspx). |
153 |
|
154 |
### IE Pinned Sites (IE9+) |
155 |
|
156 |
Enabling your application for pinning will allow IE9 users to add it to their |
157 |
Windows Taskbar and Start Menu. This comes with a range of new tools that you |
158 |
can easily configure with the elements below. See more [documentation on IE9 |
159 |
Pinned Sites](http://msdn.microsoft.com/en-us/library/gg131029.aspx). |
160 |
|
161 |
### Name the Pinned Site for Windows |
162 |
|
163 |
Without this rule, Windows will use the page title as the name for your |
164 |
application. |
165 |
|
166 |
```html |
167 |
<meta name="application-name" content="Sample Title"> |
168 |
``` |
169 |
|
170 |
### Give your Pinned Site a tooltip |
171 |
|
172 |
You know — a tooltip. A little textbox that appears when the user holds their |
173 |
mouse over your Pinned Site's icon. |
174 |
|
175 |
```html |
176 |
<meta name="msapplication-tooltip" content="A description of what this site does."> |
177 |
``` |
178 |
|
179 |
### Set a default page for your Pinned Site |
180 |
|
181 |
If the site should go to a specific URL when it is pinned (such as the |
182 |
homepage), enter it here. One idea is to send it to a special URL so you can |
183 |
track the number of pinned users, like so: |
184 |
`http://www.example.com/index.html?pinned=true` |
185 |
|
186 |
```html |
187 |
<meta name="msapplication-starturl" content="http://www.example.com/index.html?pinned=true"> |
188 |
``` |
189 |
|
190 |
### Recolor IE's controls manually for a Pinned Site |
191 |
|
192 |
IE9+ will automatically use the overall color of your Pinned Site's favicon to |
193 |
shade its browser buttons. UNLESS you give it another color here. Only use |
194 |
named colors (`red`) or hex colors (`#ff0000`). |
195 |
|
196 |
```html |
197 |
<meta name="msapplication-navbutton-color" content="#ff0000"> |
198 |
``` |
199 |
|
200 |
### Manually set the window size of a Pinned Site |
201 |
|
202 |
If the site should open at a certain window size once pinned, you can specify |
203 |
the dimensions here. It only supports static pixel dimensions. 800x600 |
204 |
minimum. |
205 |
|
206 |
```html |
207 |
<meta name="msapplication-window" content="width=800;height=600"> |
208 |
``` |
209 |
|
210 |
### Jump List "Tasks" for Pinned Sites |
211 |
|
212 |
Add Jump List Tasks that will appear when the Pinned Site's icon gets a |
213 |
right-click. Each Task goes to the specified URL, and gets its own mini icon |
214 |
(essentially a favicon, a 16x16 .ICO). You can add as many of these as you |
215 |
need. |
216 |
|
217 |
```html |
218 |
<meta name="msapplication-task" content="name=Task 1;action-uri=http://host/Page1.html;icon-uri=http://host/icon1.ico"> |
219 |
<meta name="msapplication-task" content="name=Task 2;action-uri=http://microsoft.com/Page2.html;icon-uri=http://host/icon2.ico"> |
220 |
``` |
221 |
|
222 |
### (Windows 8) High quality visuals for Pinned Sites |
223 |
|
224 |
Windows 8 adds the ability for you to provide a PNG tile image and specify the |
225 |
tile's background color. [Full details on the IE |
226 |
blog](http://blogs.msdn.com/b/ie/archive/2012/06/08/high-quality-visuals-for-pinned-sites-in-windows-8.aspx). |
227 |
|
228 |
* Create a 144x144 image of your site icon, filling all of the canvas, and |
229 |
using a transparent background. |
230 |
* Save this image as a 32-bit PNG and optimize it without reducing |
231 |
colour-depth. It can be named whatever you want (e.g. `metro-tile.png`). |
232 |
* To reference the tile and its color, add the HTML `meta` elements described |
233 |
in the IE Blog post. |
234 |
|
235 |
### (Windows 8) Badges for Pinned Sites |
236 |
|
237 |
IE10 will poll an XML document for badge information to display on your app's |
238 |
tile in the Start screen. The user will be able to receive these badge updates |
239 |
even when your app isn't actively running. The badge's value can be a number, |
240 |
or one of a predefined list of glyphs. |
241 |
|
242 |
* [Tutorial on IEBlog with link to badge XML schema](http://blogs.msdn.com/b/ie/archive/2012/04/03/pinned-sites-in-windows-8.aspx) |
243 |
* [Available badge values](http://msdn.microsoft.com/en-us/library/ie/br212849.aspx) |
244 |
|
245 |
```html |
246 |
<meta name="msapplication-badge" value="frequency=NUMBER_IN_MINUTES;polling-uri=http://www.example.com/path/to/file.xml"> |
247 |
``` |
248 |
|
249 |
### Suppress IE6 image toolbar |
250 |
|
251 |
Kill IE6's pop-up-on-mouseover toolbar for images that can interfere with |
252 |
certain designs and be pretty distracting in general. |
253 |
|
254 |
```html |
255 |
<meta http-equiv="imagetoolbar" content="false"> |
256 |
``` |
257 |
|
258 |
|
259 |
## Social Networks |
260 |
|
261 |
### Facebook Open Graph data |
262 |
|
263 |
You can control the information that Facebook and others display when users |
264 |
share your site. Below are just the most basic data points you might need. For |
265 |
specific content types (including "website"), see [Facebook's built-in Open |
266 |
Graph content |
267 |
templates](https://developers.facebook.com/docs/opengraph/objects/builtin/). |
268 |
Take full advantage of Facebook's support for complex data and activity by |
269 |
following the [Open Graph |
270 |
tutorial](https://developers.facebook.com/docs/opengraph/tutorial/). |
271 |
|
272 |
```html |
273 |
<meta property="og:title" content=""> |
274 |
<meta property="og:description" content=""> |
275 |
<meta property="og:image" content=""> |
276 |
``` |
277 |
|
278 |
### Twitter Cards |
279 |
|
280 |
Twitter provides a snippet specification that serves a similar purpose to Open |
281 |
Graph. In fact, Twitter will use Open Graph when Cards is not available. Note |
282 |
that, as of this writing, Twitter requires that app developers activate Cards |
283 |
on a per-domain basis. You can read more about the various snippet formats |
284 |
and application process in the [official Twitter Cards |
285 |
documentation](https://dev.twitter.com/docs/cards). |
286 |
|
287 |
```html |
288 |
<meta name="twitter:card" content="summary"> |
289 |
<meta name="twitter:site" content="@site_account"> |
290 |
<meta name="twitter:creator" content="@individual_account"> |
291 |
<meta name="twitter:url" content="http://www.example.com/path/to/page.html"> |
292 |
<meta name="twitter:title" content=""> |
293 |
<meta name="twitter:description" content=""> |
294 |
<meta name="twitter:image" content="http://www.example.com/path/to/image.jpg"> |
295 |
``` |
296 |
|
297 |
|
298 |
## URLs |
299 |
|
300 |
### Canonical URL |
301 |
|
302 |
Signal to search engines and others "Use this URL for this page!" Useful when |
303 |
parameters after a `#` or `?` is used to control the display state of a page. |
304 |
`http://www.example.com/cart.html?shopping-cart-open=true` can be indexed as |
305 |
the cleaner, more accurate `http://www.example.com/cart.html`. |
306 |
|
307 |
```html |
308 |
<link rel="canonical" href=""> |
309 |
``` |
310 |
|
311 |
### Official shortlink |
312 |
|
313 |
Signal to the world "This is the shortened URL to use this page!" Poorly |
314 |
supported at this time. Learn more by reading the [article about shortlinks on |
315 |
the Microformats wiki](http://microformats.org/wiki/rel-shortlink). |
316 |
|
317 |
```html |
318 |
<link rel="shortlink" href="h5bp.com"> |
319 |
``` |
320 |
|
321 |
|
322 |
## News Feeds |
323 |
|
324 |
### RSS |
325 |
|
326 |
Have an RSS feed? Link to it here. Want to [learn how to write an RSS feed from |
327 |
scratch](http://www.rssboard.org/rss-specification)? |
328 |
|
329 |
```html |
330 |
<link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"> |
331 |
``` |
332 |
|
333 |
### Atom |
334 |
|
335 |
Atom is similar to RSS, and you might prefer to use it instead of or in |
336 |
addition to it. [See what Atom's all |
337 |
about](http://www.atomenabled.org/developers/syndication/). |
338 |
|
339 |
```html |
340 |
<link rel="alternate" type="application/atom+xml" title="Atom" href="/atom.xml"> |
341 |
``` |
342 |
|
343 |
### Pingbacks |
344 |
|
345 |
Your server may be notified when another site links to yours. The href |
346 |
attribute should contain the location of your pingback service. |
347 |
|
348 |
```html |
349 |
<link rel="pingback" href=""> |
350 |
``` |
351 |
|
352 |
* High-level explanation: http://codex.wordpress.org/Introduction_to_Blogging#Pingbacks |
353 |
* Step-by-step example case: http://www.hixie.ch/specs/pingback/pingback-1.0#TOC5 |
354 |
* PHP pingback service: http://blog.perplexedlabs.com/2009/07/15/xmlrpc-pingbacks-using-php/ |
355 |
|
356 |
|
357 |
## App Stores |
358 |
|
359 |
### Install a Chrome Web Store app |
360 |
|
361 |
Users can install a Chrome app directly from your website, as long as the app |
362 |
and site have been associated via Google's Webmaster Tools. Read more on |
363 |
[Chrome Web Store's Inline Installation |
364 |
docs](https://developers.google.com/chrome/web-store/docs/inline_installation). |
365 |
|
366 |
```html |
367 |
<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/APP_ID"> |
368 |
``` |
369 |
|
370 |
### Smart App Banners in iOS 6 Safari |
371 |
|
372 |
Stop bothering everyone with gross modals advertising your entry in the App Store. |
373 |
This bit of code will unintrusively allow the user the option to download your iOS |
374 |
app, or open it with some data about the user's current state on the website. |
375 |
|
376 |
```html |
377 |
<meta name="apple-itunes-app" content="app-id=APP_ID,app-argument=SOME_TEXT"> |
378 |
``` |
379 |
|
380 |
## Google Analytics augments |
381 |
|
382 |
### More tracking settings |
383 |
|
384 |
The [optimized Google Analytics |
385 |
snippet](http://mathiasbynens.be/notes/async-analytics-snippet) included with |
386 |
HTML5 Boilerplate includes something like this: |
387 |
|
388 |
```js |
389 |
var _gaq = [['_setAccount', 'UA-XXXXX-X'], ['_trackPageview']]; |
390 |
``` |
391 |
|
392 |
In case you need more settings, just extend the array literal instead of |
393 |
[`.push()`ing to the |
394 |
array](http://mathiasbynens.be/notes/async-analytics-snippet#dont-push-it) |
395 |
afterwards: |
396 |
|
397 |
```js |
398 |
var _gaq = [['_setAccount', 'UA-XXXXX-X'], ['_trackPageview'], ['_setAllowAnchor', true]]; |
399 |
``` |
400 |
|
401 |
### Anonymize IP addresses |
402 |
|
403 |
In some countries, no personal data may be transferred outside jurisdictions |
404 |
that do not have similarly strict laws (i.e. from Germany to outside the EU). |
405 |
Thus a webmaster using the Google Analytics script may have to ensure that no |
406 |
personal (trackable) data is transferred to the US. You can do that with [the |
407 |
`_gat.anonymizeIp` |
408 |
option](http://code.google.com/apis/analytics/docs/gaJS/gaJSApi_gat.html#_gat._anonymizeIp). |
409 |
In use it looks like this: |
410 |
|
411 |
```js |
412 |
var _gaq = [['_setAccount', 'UA-XXXXX-X'], ['_gat._anonymizeIp'], ['_trackPageview']]; |
413 |
``` |
414 |
|
415 |
### Track jQuery AJAX requests in Google Analytics |
416 |
|
417 |
An article by @JangoSteve explains how to [track jQuery AJAX requests in Google |
418 |
Analytics](http://www.alfajango.com/blog/track-jquery-ajax-requests-in-google-analytics/). |
419 |
|
420 |
Add this to `plugins.js`: |
421 |
|
422 |
```js |
423 |
/* |
424 |
* Log all jQuery AJAX requests to Google Analytics |
425 |
* See: http://www.alfajango.com/blog/track-jquery-ajax-requests-in-google-analytics/ |
426 |
*/ |
427 |
if (typeof _gaq !== "undefined" && _gaq !== null) { |
428 |
$(document).ajaxSend(function(event, xhr, settings){ |
429 |
_gaq.push(['_trackPageview', settings.url]); |
430 |
}); |
431 |
} |
432 |
``` |
433 |
|
434 |
### Track JavaScript errors in Google Analytics |
435 |
|
436 |
Add this function after `_gaq` is defined: |
437 |
|
438 |
```js |
439 |
(function(window){ |
440 |
var undefined, |
441 |
link = function (href) { |
442 |
var a = window.document.createElement('a'); |
443 |
a.href = href; |
444 |
return a; |
445 |
}; |
446 |
window.onerror = function (message, file, row) { |
447 |
var host = link(file).hostname; |
448 |
_gaq.push([ |
449 |
'_trackEvent', |
450 |
(host == window.location.hostname || host == undefined || host == '' ? '' : 'external ') + 'error', |
451 |
message, file + ' LINE: ' + row, undefined, undefined, true |
452 |
]); |
453 |
}; |
454 |
}(window)); |
455 |
``` |
456 |
|
457 |
### Track page scroll |
458 |
|
459 |
Add this function after `_gaq` is defined: |
460 |
|
461 |
```js |
462 |
$(function(){ |
463 |
var isDuplicateScrollEvent, |
464 |
scrollTimeStart = new Date, |
465 |
$window = $(window), |
466 |
$document = $(document), |
467 |
scrollPercent; |
468 |
|
469 |
$window.scroll(function() { |
470 |
scrollPercent = Math.round(100 * ($window.height() + $window.scrollTop())/$document.height()); |
471 |
if (scrollPercent > 90 && !isDuplicateScrollEvent) { //page scrolled to 90% |
472 |
isDuplicateScrollEvent = 1; |
473 |
_gaq.push(['_trackEvent', 'scroll', |
474 |
'Window: ' + $window.height() + 'px; Document: ' + $document.height() + 'px; Time: ' + Math.round((new Date - scrollTimeStart )/1000,1) + 's', |
475 |
undefined, undefined, true |
476 |
]); |
477 |
} |
478 |
}); |
479 |
}); |
480 |
``` |
481 |
|
482 |
|
483 |
## Miscellaneous |
484 |
|
485 |
* Use [HTML5 |
486 |
polyfills](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills). |
487 |
|
488 |
* Use [Microformats](http://microformats.org/wiki/Main_Page) (via |
489 |
[microdata](http://microformats.org/wiki/microdata)) for optimum search |
490 |
results |
491 |
[visibility](http://googlewebmastercentral.blogspot.com/2009/05/introducing-rich-snippets.html). |
492 |
|
493 |
* If you're building a web app you may want [native style momentum scrolling in |
494 |
iOS5](http://johanbrook.com/browsers/native-momentum-scrolling-ios-5/) using |
495 |
`-webkit-overflow-scrolling: touch`. |
496 |
|
497 |
* Avoid development/stage websites "leaking" into SERPs (search engine results |
498 |
page) by [implementing X-Robots-tag |
499 |
headers](https://github.com/h5bp/html5-boilerplate/issues/804). |
500 |
|
501 |
* Screen readers currently have less-than-stellar support for HTML5 but the JS |
502 |
script [accessifyhtml5.js](https://github.com/yatil/accessifyhtml5.js) can |
503 |
help increase accessibility by adding ARIA roles to HTML5 elements. |
504 |
|
505 |
|
506 |
*Many thanks to [Brian Blakely](https://github.com/brianblakely) for |
507 |
contributing much of this information.* |