Successfully reported this slideshow.
Your SlideShare is downloading. ×

Practical progressive enhancement

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Html5 public
Html5 public
Loading in …3
×

Check these out next

1 of 76 Ad

Practical progressive enhancement

Presented at Cardiff's monthly dev meetup, Unified.diff, on 5 June 2013. Learn what progressive enhancement is and how it can help your content authors do amazing things automagically.

Presented at Cardiff's monthly dev meetup, Unified.diff, on 5 June 2013. Learn what progressive enhancement is and how it can help your content authors do amazing things automagically.

Advertisement
Advertisement

More Related Content

Slideshows for you (18)

Advertisement

Similar to Practical progressive enhancement (20)

Recently uploaded (20)

Advertisement

Practical progressive enhancement

  1. 1. Practical progressive enhancement
  2. 2. Graham Bird Senior Web Producer, Cardiff University @mrgrahambird Hello
  3. 3. Just what is progressive enhancement? STRAW POLL
  4. 4. Here’s the deal * more on this later
  5. 5. 1. Start with accessible, semantic and clean* HTML Here’s the deal * more on this later
  6. 6. 1. Start with accessible, semantic and clean* HTML 2. Add external CSS Here’s the deal * more on this later
  7. 7. 1. Start with accessible, semantic and clean* HTML 2. Add external CSS 3. (Lazy-load) external JavaScript Here’s the deal * more on this later
  8. 8. 1. Start with accessible, semantic and clean* HTML 2. Add external CSS 3. (Lazy-load) external JavaScript 4. End with accessible, semantic and clean HTML Here’s the deal * more on this later
  9. 9. It’s old HOW OLD?
  10. 10. 10 years old
  11. 11. 10 years old 1993 2013 Half as old as the web!One web page 4.1 billion web pages
  12. 12. June 2003
  13. 13. November 2004
  14. 14. December 2008
  15. 15. Content Styling Behaviour 2003 Inclusive Web Design for the Future, Steve Champeon & Nick Finck, SXSW
  16. 16. index.html style.css script.js 2003
  17. 17. How quaint
  18. 18. Bootstrap jQuery Mobile Require.js 2013 jQuery jQuery plugins Retina! Responsive! Polyfills@font-face Content? TodoMVCAPIs Tomorrow HTML5 CSS3
  19. 19. Bootstrap jQuery Mobile Require.js 2013 jQuery jQuery plugins Retina! Responsive! Polyfills@font-face Content? TodoMVCAPIs Tomorrow HTML5 CSS3
  20. 20. <html> <body> <div class=”container”> <div class=”row”> <div class=”span8”> <h1>Latest sales figures</h1> <p>It’s difficult to draw any conclusions from our latest results.</p> <div id=”chart”></div> <h2>Leave a comment, if you can</h2> <div id=”comments”></div> </div> <div class=”span4”> <h4>How to not find us</h4> <div id=”map”></div> <h4>Don’t follow us on Twitter</h4> <div id=”tweets”></div> </div> </div> </div> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  21. 21. <html> <body> <div class=”container”> <div class=”row”> <div class=”span8”> <h1>Latest sales figures</h1> <p>It’s difficult to draw any conclusions from our latest results.</p> <div id=”chart”></div> <h2>Leave a comment, if you can</h2> <div id=”comments”></div> </div> <div class=”span4”> <h4>How to not find us</h4> <div id=”map”></div> <h4>Don’t follow us on Twitter</h4> <div id=”tweets”></div> </div> </div> </div> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  22. 22. ... ... #map#tweets ... #comments ... #chart
  23. 23. “Dude, where’s my content?” Googlebot
  24. 24. Progressive enhancement to the rescue!
  25. 25. <ul class=”nav nav-tabs”> <li class=”active”><a href=”#description”>Description</a></li> <li><a href=”#key-features”>Key features</a></li> <li><a href=”#guarantee”>Guarantee</a></li> </ul> <div class=”tab-content”> <div id=”description” class=”tab-pane active”> <p>This watch is a design classic.</p> </div> <div id=”key-features”> <p>Every watch has a strap and a face with numbers on it.</p> </div> <div id=”guarantee”> <p>All watches come with a 5 year guarantee.</p> </div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
  26. 26. 1. The content
  27. 27. 1. The content 2. Unordered list of anchor links
  28. 28. 1. The content 2. Unordered list of anchor links 3. Nothing else (but classes)
  29. 29. 1. The content 2. Unordered list of anchor links 3. Nothing else (but classes) 4. One div tag
  30. 30. <ul class=”nav nav-tabs”> <li class=”active”><a href=”#description”>Description</a></li> <li><a href=”#key-features”>Key features</a></li> <li><a href=”#guarantee”>Guarantee</a></li> </ul> <div class=”tab-content”> <div id=”description” class=”tab-pane active”> <p>This watch is a design classic.</p> </div> <div id=”key-features”> <p>Every watch has a strap and a face with numbers on it.</p> </div> <div id=”guarantee”> <p>All watches come with a 5 year guarantee.</p> </div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
  31. 31. Clean HTML
  32. 32. 1. The simplest & least HTML possible
  33. 33. 1. The simplest & least HTML possible 2. No inline CSS
  34. 34. 1. The simplest & least HTML possible 2. No inline CSS 3. Unobtrusive JavaScript
  35. 35. 1. The simplest & least HTML possible 2. No inline CSS 3. Unobtrusive JavaScript 4. Nothing in the source for JS purposes
  36. 36. Unclean HTML?
  37. 37. <div id=”myCarousel” class=”carousel slide”> <ol class=”carousel-indicators”> <li data-target=”#myCarousel” data-slide-to=”0” class=”active”></li> <li data-target=”#myCarousel” data-slide-to=”1”></li> <li data-target=”#myCarousel” data-slide-to=”2”></li> </ol> <div class=”carousel-inner”> <div class=”active item”>...</div> <div class=”item”>...</div> <div class=”item”>...</div> </div> <a class=”carousel-control left” href=”#myCarousel” data- slide=”prev”>&lsaquo;</a> <a class=”carousel-control right” href=”#myCarousel” data- slide=”next”>&rsaquo;</a> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  38. 38. <div id=”myCarousel” class=”carousel slide”> <ol class=”carousel-indicators”> <li data-target=”#myCarousel” data-slide-to=”0” class=”active”></li> <li data-target=”#myCarousel” data-slide-to=”1”></li> <li data-target=”#myCarousel” data-slide-to=”2”></li> </ol> <div class=”carousel-inner”> <div class=”active item”>...</div> <div class=”item”>...</div> <div class=”item”>...</div> </div> <a class=”carousel-control left” href=”#myCarousel” data- slide=”prev”>&lsaquo;</a> <a class=”carousel-control right” href=”#myCarousel” data- slide=”next”>&rsaquo;</a> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Oh, the humanity!
  39. 39. <div id=”myCarousel” class=”carousel slide”> <ol class=”carousel-indicators”> <li data-target=”#myCarousel” data-slide-to=”0” class=”active”></li> <li data-target=”#myCarousel” data-slide-to=”1”></li> <li data-target=”#myCarousel” data-slide-to=”2”></li> </ol> <div class=”carousel-inner”> <div class=”active item”>...</div> <div class=”item”>...</div> <div class=”item”>...</div> </div> <a class=”carousel-control left” href=”#myCarousel” data- slide=”prev”>&lsaquo;</a> <a class=”carousel-control right” href=”#myCarousel” data- slide=”next”>&rsaquo;</a> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  40. 40. <div id=”myCarousel” class=”carousel slide”> <div class=”carousel-inner”> <div class=”active item”>...</div> <div class=”item”>...</div> <div class=”item”>...</div> </div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  41. 41. <a href=”#” onClick=”_gaq.push([‘_trackEvent’, ‘Videos’, ‘Play’, ‘Baby’s First Birthday’]);”>Play</a> 1 2
  42. 42. <a href=”#” onClick=”_gaq.push([‘_trackEvent’, ‘Videos’, ‘Play’, ‘Baby’s First Birthday’]);”>Play</a> 1 2
  43. 43. <a href=”#” onClick=”_gaq.push([‘_trackEvent’, ‘Videos’, ‘Play’, ‘Baby’s First Birthday’]);”>Play</a> 1 2
  44. 44. <a href=”#” onClick=”_gaq.push([‘_trackEvent’, ‘Videos’, ‘Play’, ‘Baby’s First Birthday’]);”>Play</a> 1 2
  45. 45. <a class=”ga-event” href=”http://youtu.be/123456” data-category=”Videos” data- action=”Play” data-label=”Baby’s First Birthday”>Play</a> <script type=”text/javascript”> $(function(){ if($(‘.ga-event’).length > 0) { $(‘.ga-event’).each(function() { $(this).click(function() { var linkCategory = $(this).data(‘category’); var linkAction = $(this).data(‘action’); var linkLabel = $(this).data(‘label’); _gaq.push([‘_trackEvent’, linkCategory, linkAction, linkLabel]); }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  46. 46. Progressively enhanced jtwt
  47. 47. <div id=”tweets”></div> <script type=”text/javascript”> $(function(){ $(‘#tweets’).jtwt({ “username”: “unifieddiff” }); }); </script> 1 2 3 4 5 6 7 8 9 10 11
  48. 48. <div id=”tweets”></div> <script type=”text/javascript”> $(function(){ $(‘#tweets’).jtwt({ “username”: “unifieddiff” }); }); </script> 1 2 3 4 5 6 7 8 9 10 11
  49. 49. <div id=”tweets”></div> <script type=”text/javascript”> $(function(){ $(‘#tweets’).jtwt({ “username”: “unifieddiff” }); }); </script> 1 2 3 4 5 6 7 8 9 10 11
  50. 50. <a class=”twitter-feed” href=”http://twitter.com/unifieddiff”>Follow us on Twitter</a> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  51. 51. <a class=”twitter-feed” href=”http://twitter.com/unifieddiff”>Follow us on Twitter</a> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  52. 52. <a class=”twitter-feed” href=”http://twitter.com/unifieddiff”>Follow us on Twitter</a> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  53. 53. <a class=”twitter-feed” href=”http://twitter.com/unifieddiff”>Follow us on Twitter</a> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  54. 54. <a class=”twitter-feed” href=”http://twitter.com/unifieddiff”>Follow us on Twitter</a> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  55. 55. <div id=”tweets-unifieddiff”></div> <a class=”twitter-feed” href=”http://twitter.com/unifieddiff”>Follow us on Twitter</a> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  56. 56. <div id=”tweets-unifieddiff”></div> <a class=”twitter-feed” href=”http://twitter.com/unifieddiff”>Follow us on Twitter</a> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  57. 57. <div id=”tweets-unifieddiff”></div> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  58. 58. <div id=”tweets-unifieddiff”></div> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  59. 59. <a class=”twitter-feed” href=”http://twitter.com/unifieddiff” data- results=”3”>Follow us on Twitter</a> <script type=”text/javascript”> $(function(){ if($(‘.twitter-feed’).length > 0) { $(‘.twitter-feed’).each(function() { var userName = $(this).attr(‘href’).replace(‘http://www.twitter.com/’, ‘’); var numResults = $(this).data(“results”); $(this).prepend(‘<div id=”tweets-’ + userName + ‘”></div>’); $(this).remove(); $(‘#tweets-’ + userName).jtwt({ “username”: userName, “count”: numResults }); }); } }); </script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  60. 60. An automagical demonstration http://dev.pressanything.co.uk/unified/progressive-enhancement
  61. 61. ✓ Make your site usable with CSS and JavaScript disabled
  62. 62. ✓ Make your site usable with CSS and JavaScript disabled ✓ Don’t hide the content
  63. 63. ✓ Make your site usable with CSS and JavaScript disabled ✓ Don’t hide the content ✓ Think features, not browsers (Modernizr)
  64. 64. ✓ Make your site usable with CSS and JavaScript disabled ✓ Don’t hide the content ✓ Think features, not browsers (Modernizr) ✓ Don’t include anything in your HTML that requires JavaScript to work
  65. 65. ✓ Make your site usable with CSS and JavaScript disabled ✓ Don’t hide the content ✓ Think features, not browsers (Modernizr) ✓ Don’t include anything in your HTML that requires JavaScript to work ✓ Get clever with classes and data attributes
  66. 66. ✓ Make your site usable with CSS and JavaScript disabled ✓ Don’t hide the content ✓ Think features, not browsers (Modernizr) ✓ Don’t include anything in your HTML that requires JavaScript to work ✓ Get clever with classes and data attributes ✓ Give your content editors automagical powers
  67. 67. The end @mrgrahambird

×