<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:series="http://organizeseries.com/"
> <channel><title>SitePoint &#187; HTML</title> <atom:link href="http://www.sitepoint.com/category/html-2/feed/" rel="self" type="application/rss+xml" /><link>http://www.sitepoint.com</link> <description>Learn CSS &#124; HTML5 &#124; JavaScript &#124; Wordpress &#124; Tutorials-Web Development &#124; Reference &#124; Books and More</description> <lastBuildDate>Mon, 13 May 2013 13:12:07 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.5.1</generator> <item><title>Happy 10th Birthday CSS Zen Garden</title><link>http://www.sitepoint.com/zen-garden-tenth-birthday/</link> <comments>http://www.sitepoint.com/zen-garden-tenth-birthday/#comments</comments> <pubDate>Fri, 10 May 2013 12:23:28 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Browsers]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[News]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=66124</guid> <description><![CDATA[CSS Zen Garden is ten years old. Craig discusses why the site became a defining moment in web history and the new HTML5 version announced by Dave Shea.]]></description> <content:encoded><![CDATA[<p></p><p><a
href="http://www.csszengarden.com/">CSS Zen Garden</a> is ten years old. If you started coding recently you may not have heard about the site, but Zen Garden was a defining moment in web history.</p><p>Zen&#8217;s developer, Dave Shea, had a simple objective: <a
href="http://www.csszengarden.com/zengarden-sample-old.html">to illustrate why CSS should be taken seriously and inspire designers</a>. The concept provided a static HTML page and allowed developers to apply and submit their own styles. The only restrictions were that the CSS should validate and the resulting page worked in IE5+ and Mozilla (Firefox&#8217;s predecessor).</p><p>The number of submissions increased exponentially and there was a sudden realization that CSS could do more than just apply color to H1 titles. To put it into historical context, by 2003 CSS techniques had been viable for several years but tables and spacer GIFs remained the predominant page layout methods. Tables worked in all browsers and were well understood.</p><p>Zen Garden did for CSS what Jesse James Garrett&#8217;s <a
href="http://www.adaptivepath.com/ideas/ajax-new-approach-web-applications">A New Approach to Web Applications</a> did for Ajax a couple of years later. The technologies already existed, but it required a spark to ignite developer passion and revolutionize its application.</p><h2>Zen Garden 2013</h2><p>Zen Garden achieved its goal &#8212; <em>who isn&#8217;t using CSS layouts now?</em> To celebrate an amazing ten years, Dave Shea has re-released <a
href="http://www.csszengarden.com/">Zen Garden</a>, put the <a
href="https://github.com/mezzoblue/csszengarden.com">code on GitHub</a> and started work on a new HTML5 version. A lot has happened in the past decade, so the modern requirements permit:</p><ul><li>CSS3 transitions, transformations, animations, shadows, gradients and effects. Remember to prefix properties where necessary but Webkit-only designs will be <em>&#8220;discarded with prejudice&#8221;!</em></li><li>Responsive Web Designs</li><li>Web fonts</li><li>Support for IE9+, recent versions of Chrome, Firefox and Safari, and iOS/Android</li></ul><p>New designs can be <a
href="http://www.mezzoblue.com/zengarden/submit/">submitted now</a>. Please send us the URLs of your groundbreaking examples or designs you like.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/zen-garden-tenth-birthday/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>How to Create a Toggle Switch in CSS3</title><link>http://www.sitepoint.com/css3-toggle-switch/</link> <comments>http://www.sitepoint.com/css3-toggle-switch/#comments</comments> <pubDate>Wed, 08 May 2013 14:59:50 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[Responsive Web Design]]></category> <category><![CDATA[UX]]></category> <category><![CDATA[form]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65585</guid> <description><![CDATA[Checkboxes are boring. Why not bring some excitement into your users' lives with a slick toggle switch implemented in pure CSS as demonstrated in Craig's latest tutorial.]]></description> <content:encoded><![CDATA[<p></p><p>You&#8217;ll find mobile-interface-like toggle switches in various places around the web but I wanted to improve existing examples.</p><p><img
src="http://blogs.sitepointstatic.com/images/tech/819-css3-toggle-switch-example.png" alt="toggle switch" class="center" /></p><p>Specifically, I wanted a solution which:</p><ol><li>progressively enhanced standard checkboxes</li><li>did not use superfluous HTML tags or attributes</li><li>supported input labels</li><li>used only CSS without images or JavaScript</li><li>used relative units so the controls are resizable/responsive</li><li>had some slick animation</li><li>ideally worked in a range of mobile browsers, and</li><li>degraded gracefully so it remained usable in all browsers</li></ol><p><a
href="http://cssdeck.com/labs/full/css3-toggle-switch"><strong>View the demonstration page</strong></a> and <a
href="http://cssdeck.com/labs/css3-toggle-switch">the HTML/CSS code&hellip;</a></p><h2>The HTML</h2><p>We require a <code>input</code> checkbox and a <code>label</code>:</p><pre><code>&lt;div&gt;
	&lt;input type=&quot;checkbox&quot; id=&quot;switch1&quot; name=&quot;switch1&quot; class=&quot;switch&quot; /&gt;
	&lt;label for=&quot;switch1&quot;&gt;first switch&lt;/label&gt;
&lt;/div&gt;
</code></pre><p>The <code>input</code> has a class of &#8220;switch&#8221; assigned. This ensures we can retain normal checkboxes should we need them.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>HTML purists will be horrified to see a wrapper <code>div</code> but it&#8217;s only necessary if you require two or more toggle switches &#8212; you cannot have more than one switch (or further labels) in the the same parent container. Besides, you&#8217;ll probably need <code>div</code> wrappers to separate form elements anyway.</p><p>The HTML will render well in most browsers with minimal styling. IE6, 7 and 8 users will see this:</p><p><img
src="http://blogs.sitepointstatic.com/images/tech/819-css3-toggle-switch-ie8.png" alt="toggle switch" class="center" /></p><h2>The CSS</h2><p>Now for the interesting part. First, we&#8217;ll hide the input box using a negative margin &#8212; this can be preferable to display:none which often disables it on mobile devices:</p><pre><code>input.switch:empty
{
	margin-left: -999px;
}
</code></pre><p>You may have seen the <code>:empty</code> selector used in my recent post, <a
href="/css3-responsive-centered-image/">How to Create a Responsive Centered Image in CSS3</a>. It only matches elements which have no children but, since it&#8217;s not supported in IE8 and below, those browsers won&#8217;t attempt to apply the styles.</p><p>Next, we&#8217;ll style the sibling labels of the input checkbox:</p><pre><code>input.switch:empty ~ label
{
	position: relative;
	float: left;
	line-height: 1.6em;
	text-indent: 4em;
	margin: 0.2em 0;
	cursor: pointer;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}</code></pre><p>The main properties to note are position:relative, the text-indent which provides room for our switch, and the line-height which defines its height.</p><p>The toggle itself is created using <code>:before</code> and <code>:after</code> pseudo-elements for the colored background and the white switch accordingly:</p><ul><li>both elements are absolutely positioned at the left-hand edge of our label</li><li>the white switch is set to a smaller size and has a left margin applied to align it on the background</li><li>a border-radius and inset box-shadow is applied to give some depth, and</li><li>a transition is defined for the animation.</li></ul><pre><code>input.switch:empty ~ label:before,
input.switch:empty ~ label:after
{
	position: absolute;
	display: block;
	top: 0;
	bottom: 0;
	left: 0;
	content: ' ';
	width: 3.6em;
	background-color: #c33;
	border-radius: 0.3em;
	box-shadow: inset 0 0.2em 0 rgba(0,0,0,0.3);
	-webkit-transition: all 100ms ease-in;
	transition: all 100ms ease-in;
}
input.switch:empty ~ label:after
{
	width: 1.4em;
	top: 0.1em;
	bottom: 0.1em;
	margin-left: 0.1em;
	background-color: #fff;
	border-radius: 0.15em;
	box-shadow: inset 0 -0.2em 0 rgba(0,0,0,0.2);
}
</code></pre><p>Finally, when the checkbox is checked, we move the switch to the right-hand edge and change the background color:</p><pre><code>input.switch:checked ~ label:before
{
	background-color: #393;
}
input.switch:checked ~ label:after
{
	margin-left: 2em;
}
</code></pre><p><a
href="http://cssdeck.com/labs/full/css3-toggle-switch"><strong>View the demonstration page</strong></a> and <a
href="http://cssdeck.com/labs/css3-toggle-switch">the HTML/CSS code&hellip;</a></p><p>Everyone likes a toggle switch! Please use the code however you like. A link back to this article or a <em>&#8220;hey Craig, that&#8217;s awesome/awful&#8221;</em> <a
href="http://twitter.com/craigbuckler">tweet</a> is appreciated.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/css3-toggle-switch/feed/</wfw:commentRss> <slash:comments>27</slash:comments> </item> <item><title>5 Ways to Support High-Density Retina Displays</title><link>http://www.sitepoint.com/support-retina-displays/</link> <comments>http://www.sitepoint.com/support-retina-displays/#comments</comments> <pubDate>Mon, 06 May 2013 17:22:46 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Apple]]></category> <category><![CDATA[Browsers]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Responsive Web Design]]></category> <category><![CDATA[UX]]></category> <category><![CDATA[display]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[images]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[Retina]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65653</guid> <description><![CDATA[Are the images on your website looking a little ugly on your new iPad or MacBook Pro? Craig discusses Retina high-density pixel displays and offers a number of pragmatic solutions.]]></description> <content:encoded><![CDATA[<p></p><p>An interesting point was raised by Brendan Davis in my recent post <a
href="/rwd-scrollbars-is-chrome-better/">&#8220;Responsive Web Design and Scrollbars: Is Chrome’s Implementation Better?&#8221;</a>: <em>are RWD breakpoints affected by high pixel-density screens?</em></p><p>The short answer is: no &#8212; but we need to delve a little deeper and look at the problems they can cause.</p><h2>What is Retina?</h2><p>&#8220;Retina&#8221; is Apple&#8217;s brand name for double-density screens but other manufacturers are creating similar displays. The technology is used in recent iPhones, iPads, MacBook Pros and other high-end devices.</p><p>For example, the MacBook Pro 15&#8243; has a resolution of 2,880&#215;1,800 or 220 pixels per inch. At this scale, most people are unable to notice individual pixels at typical viewing distances &#8212; applications and websites would be too small to use.</p><p>Therefore, the device reverts to a standard resolution of 1,440&#215;900 but the additional pixels can be used to make fonts and graphics appear smoother.</p><h2>What&#8217;s the Problem?</h2><p>Standard-resolution bitmap images can look blocky on a Retina display. A 400 x 300 photograph is scaled to 800 x 600 pixels but there&#8217;s no additional detail. This can be noticeable when compared to smooth fonts and other high-resolution images.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>Real-World Usage</h2><p>If you look around the web, you&#8217;d be forgiven for thinking everyone has a Retina display. Currently, it&#8217;s only available in high-end devices, but these are coveted by developers so it leads to a disproportionate volume of online discussion. In the real world, the percentage of people using similar displays is in low single figures.</p><p>Let&#8217;s put it into context: if you&#8217;re not developing for the 1% of IE6/7 users, you probably shouldn&#8217;t be too concerned about people using Rentina &#8212; especially since they can still view your website.</p><p>That said, Retina-like screens will eventually migrate to all devices. There&#8217;s little reason to fret now, but there&#8217;s no harm in some forward planning. Let&#8217;s look at the options in order of recommendation&hellip;</p><h2>1. Use SVGs and CSS3 Effects</h2><p>The clue is in the name but Scalable Vector Graphics are &hellip; <em>scalable!</em> It doesn&#8217;t matter how big an SVG becomes &#8212; it will always be smooth because it&#8217;s defined using vectors (lines and shapes) rather than individual pixels.</p><p>SVG is not practical for photographs but is ideal for logos, diagrams and charts. The primary drawback is a lack of support in IE8 and below but you could always provide a PNG fallback or use a shim such as <a
href="http://raphaeljs.com/">Rapha&euml;l</a> or <a
href="http://code.google.com/p/svgweb/">svgweb</a>. See also: <a
href="http://www.sitepoint.com/add-svg-to-web-page/">How to Add Scalable Vector Graphics to Your Web Page</a>.</p><p>You may also be able to replace some images entirely. For example, titles, gradients, corners or shadows defined as graphics can be reproduced using CSS3 alone. They will render at a better quality, result in fewer HTTP requests and use less bandwidth.</p><h2>2. Use Webfonts Icons</h2><p>The more I use <a
href="http://www.sitepoint.com/webfont-icons/">webfonts icons</a>, the more I love them. Like SVGs, fonts are vectors so they&#8217;re scalable so you can use font sets which contain icons. They&#8217;re ideal for small, frequently used shapes such as email envelopes, telephones, widget controls and social media logos. They also work in every browser including IE6+.</p><p>There are plenty of commercial and free icon font sets available:</p><ul><li><a
href="http://typicons.com/">Typicons</a></li><li><a
href="http://fortawesome.github.io/Font-Awesome/">Font Awesome</a></li><li><a
href="http://somerandomdude.com/work/iconic/">Iconic</a></li><li><a
href="http://www.zurb.com/playground/foundation-icons">Foundation</a></li></ul><p>Or you can use a hosted font service such as <a
href="http://weloveiconfonts.com/">We Love Icon Fonts</a>.</p><p>I recommend creating your own small set of custom icons using online tools such as <a
href="http://fontello.com/">Fontello</a> or <a
href="http://www.sitepoint.com/icomoon-webfont-icon-packs/">IcoMoon</a>.</p><h2>3. Use High-Resolution Images When Practical</h2><p>Retina has four times more pixels than standard screens. If you have a 400 x 300 image (120,000 pixels), you&#8217;d need to use an 800 x 600 alternative (480,000 pixels) to render it well on a high-density display.</p><p>However, the high-resolution file size may not necessarily be four times larger. Every image is different but if it contains solid blocks of color or details which can be omitted, it may be practical to use a 800 x 600 image and scale it in the browser.</p><p>Be pragmatic: if the standard image is 200Kb and the high-resolution version is 250Kb, there is negligible benefit using image replacement techniques. Use the better version throughout.</p><h2>4. Use CSS Image Replacement</h2><p>There will be times when high-resolution versions of your image are four times larger &#8212; or more. In those circumstances you may want to consider image replacement techniques, i.e. the standard image is replaced by larger alternative on Retina displays. The following media query code could be used:</p><pre><code>#myimage {
	width: 400px;
	height: 300px;
	background: url(lo-res.jpg) 0 0 no-repeat;
}
@media
screen and (-webkit-min-device-pixel-ratio: 1.5),
screen and (-moz-min-device-pixel-ratio: 1.5),
screen and (min-device-pixel-ratio: 1.5) {
	#myimage {
		background-image: url(hi-res.jpg);
	}
}
</code></pre><p>The drawbacks:</p><ol><li>You will need to create and maintain two sets of images.</li><li>Some browsers will download both images.</li></ol><p>Remember that many of these users will be using smartphones or tablets on slower mobile networks. Detecting the connection speed would be more beneficial than determining the pixel density.</p><h2>5. Use JavaScript Image Replacement</h2><p>Retina display detection can be implemented using the following code:</p><pre><code>var isRetina = (
	window.devicePixelRatio &gt; 1 ||
	(window.matchMedia &amp;&amp; window.matchMedia(&quot;(-webkit-min-device-pixel-ratio: 1.5),(-moz-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)&quot;).matches)
);
</code></pre><p>Once a Retina display is determined, you could:</p><ol><li>Loop through all page images and extract the URL.</li><li>Append &#8216;@2x&#8217; to the file name and attempt to load the resulting image URL using Ajax.</li><li>If found, replace the current image with the high-resolution alternative.</li></ol><p>Fortunately, the hard work&#8217;s been done for you at <a
href="http://retinajs.com/">retinajs.com</a>. While it only adds 4Kb weight, high-density display devices will download images twice &#8212; although the second time will occur as a background process after the page has loaded.</p><p>My advice: be practical and keep it simple. Don&#8217;t spend inordinate amounts of time attempting to solve minor rendering problems on devices with proportionally few users. Of course, none of that matters when your boss receives his new iPad and starts to complain about image quality&hellip;</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/support-retina-displays/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>Designing Experiences for Responsive Web Sites</title><link>http://www.sitepoint.com/designing-experiences-for-responsive-web-sites/</link> <comments>http://www.sitepoint.com/designing-experiences-for-responsive-web-sites/#comments</comments> <pubDate>Mon, 06 May 2013 09:13:17 +0000</pubDate> <dc:creator>Rahul Lalmalani</dc:creator> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Responsive Web Design]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=66021</guid> <description><![CDATA[When considering how to implement responsive web design techniques, Rahul Lalmalani suggests you take into account how a device might change user expectations of a site’s functionality.]]></description> <content:encoded><![CDATA[<p></p><h2>Before You Get Started</h2><p>Responsive Web design is intended to ensure that a site’s layout and content scale fluidly to the available screen real estate. This is a great approach for focusing your investments on improving site content and user functionality while ensuring that users have a good experience regardless of what device and screen size they use to visit your site. If you didn’t read the first article in this series, “<a
href="http://www.sitepoint.com/why-the-web-is-ready-for-responsive-web-design/" target="_blank">Why the Web Is Ready for Responsive Web Design</a>,” be sure to read it first.</p><p>It’s worth taking a step back, however, to think through your site’s experience and understand whether the device with which a user accesses your site <em>changes the user’s expectations of the site’s functionality</em><i>.</i> Is the user checking your site for quick updates with her cellphone while she’s on the go? Is he sitting down, 10 feet away from a large TV screen, looking to immerse himself in a relatively passive consumption experience of rich content, videos and games? Are other users sitting down at their PCs, looking to get the most from your site content? Most of all, how do these expectations affect the site layout and functionality that you provide at those corresponding screen sizes?<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>What Kind of Site Is This?</h2><p>Planning the content hierarchy for your site across different form factors is definitely the first step to having a great responsive-site experience. Consider the following examples, which evaluate and compare the top experiences that customers want to have when they access your site from a 4-inch phone while they walk or take public transportation, when they’re sitting at their computer desk, and when they’re lounging on their couches in their living rooms.</p><h3>News Site (Content Consumption)</h3><p>People visit ContosoNews.com primarily to do one thing—catch up on the day’s current affairs. When you see how this site is presented on a PC screen, it’s designed to have a layout like a newspaper. More important, the single home page is expected to attract and retain different kinds of readers, with interests in current affairs, business, sports, entertainment and other topics, and show them that ContosoNews has content that will interest them. The home page has a rich layout with slide shows, cycling of recommended articles, various categories of news available below the fold if you scroll down, recommended editorials and even the weather. <b>Figure 1</b> shows a schematic illustration of the site at different resolutions.<br
/> <img
class="alignnone size-full wp-image-66029" alt="Comparing Layouts for ContosoNews.com" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure13.png" width="720" height="480" /></p><p><b>Figure 1. Comparing Layouts for ContosoNews.com</b></p><p>If you visit this site on your mobile phone browser, you see a subset of the content, with menu and link navigation to the remaining content. The content that was available on the PC has been prioritized, and the top headline has been given focus above the fold. The slide show of recommended articles is replaced by a series of blurbs with links. The top articles from the Other Categories section are gone, replaced with a single category picker that navigates away from the home page.</p><p>In this way, users visiting the site on a phone can, in a cursory glance, become aware of the content available for consumption and dig deeper at their convenience.</p><h3>Local Attraction (Hyper-Local Site)</h3><p>Contoso Station is a hip new restaurant in Seattle. When people visit the restaurant’s site on their PC or TV screen, the restaurant proudly shows its latest Yelp reviews, news articles and tweets from users who add the hashtag #i&amp;lt3contoso.</p><p>However, when you visit the site on a smartphone, the company makes a fair assumption that you’re visiting its site on the go with hopes to find its location, hours of operation and phone number. The phone might even request your location and show you a map with the quickest route to the restaurant. Some of the remaining content can be presented with much less detail—for example, the Yelp reviews are boiled down to one-line snippets—and the rest of the content (the Twitter feed, for example) can be hidden altogether for users visiting the site on their phones. <b>Figure 2</b> shows an example of this scenario.</p><p><img
class="alignnone size-full wp-image-66030" alt="Comparing Layouts for Contoso Station" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure21.png" width="720" height="480" /><br
/> <b>Figure 2. Comparing Layouts for Contoso Station</b></p><p>As seen in <b>Figure 2,</b> local businesses should prioritize and show an entirely different set of content to phone users and make their mobile experiences more sensitive to location.</p><h3>Media Site (Rich Audiovisual Content)</h3><p>ContosoTube is a popular Internet service where people share all kinds of videos. Users can see the latest top-rated and most frequently watched content. As they sign-in and explore the site, they can create and edit playlists of videos, get personalized recommendations, subscribe to other users’ playlists and even send each other messages.</p><p>The experience of ContosoTube on a phone is geared toward showing videos that a user has opened from other apps (instant messages, email, Twitter and so on), searching to view a video, and letting logged-in users access their existing subscriptions and playlists. Their experience is very limited for content curation.</p><p>What’s interesting about ContosoTube is that the Xbox site experience is similar to the phone experience from a user-functionality perspective, although the Xbox site is laid out differently based on screen real estate because even when ContosoTube users visit the site on their large screens, they are probably accessing it from their living room and doing so with controls less precise than a mouse. While the screen size of the TV might tempt developers to provide a more PC-like experience in terms of available functionality, it would be highly likely that users accessing ContosoTube on their TVs would focus primarily on watching content and not on creating it, managing it and messaging with others. <b>Figure 3</b> compares site layouts for ContosoTube.</p><p><img
class="alignnone size-full wp-image-66033" alt="ContosoTube on a PC, TV and Smartphone." src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure31.png" width="720" height="297" /><br
/> <b>Figure 3. ContosoTube on a PC, TV and Smartphone.</b></p><h3>HTML5 Games</h3><p>On <a
href="http://buildnewgames.com/a-study-in-adaptive-game-design/" target="_blank">Build New Games</a>, a website that explores HTML technologies for creating immersive gaming experiences on the browser, Jack Lawson provides a great discussion about what a gaming experience might be like for a responsively designed Web site.</p><p>A game is a great example of site design where users expect entirely different experiences based on the context in which they visit the site. For example, if a user visits the site WorldOfContosoCraft.com from his PC, he probably expects a full-fledged gaming experience—he can play the game himself, interact and communicate socially with other players through the in-game chat feature, make customizations and settings to his avatar and even participate in the in-game marketplace to buy upgrades, armor and other goodies.</p><p>On the console, this user might expect a similarly feature-rich experience, but he would also have expectations about being able to use his controller to drive the experience instead of the mouse and keyboard. (There are currently libraries for Chrome and Firefox—although with limited cross-browser support, as Nikhil Suresh points out in his discussion of <a
href="http://buildnewgames.com/console-experience-on-the-web/">controller support in JavaScript libraries</a>.)</p><p>On the phone itself, the user might be looking to perform simpler actions, such as checking up on his inventory and gamer stats, performing some customizations on the avatar and maybe buying some add-ons from the in-game marketplace. Game developers, who can provide such a contextually relevant experience to users who visit their site from their cellphone for a few minutes, can keep their users engaged in the overall experience even when they can’t play the game.</p><h2>Considerations for UI Design (aka Fat Fingers)</h2><p>In addition to information design, you need to think about modes of user input. Today, first and foremost, this means that your site UI be touch-friendly. Visitors are not using touch for your Web site only on phones and tablets; they also use touch-screen-based PCs. Moreover, when you think about users on the Xbox, they’re interacting with the UI elements of your Web page by using a joystick, which is not as precise as a mouse.</p><p>Ideally, you <em>do not</em> want to design and code your user interface elements (buttons, links, form controls and so on) differently for touch (tablets and phones) than for PCs with traditional mouse-keyboard elements. In fact, Windows 8 makes this distinction nonexistent, with users able to run Microsoft Surface with a USB mouse as well as desktops with touch-screens. Moving forward, it’s reasonable to assume that more traditional PCs will be equipped with touch-screen functionality.</p><p>That’s why the best approach is to design a one-size-fits-all interface for user inputs that is comfortable for touch users to access. Mouse and keyboard users can still interact with these pages just fine.</p><p>To highlight some paradigm shifts in this approach, let’s take the example of one of the most common forms of navigation, the drop-down menu, on my favorite local radio station, Contoso Music. (See <b>Figure 4.</b>) This is just one example of a solution to links and navigation menus for touch, but it illustrates the most important considerations we need to take.</p><p><img
class="alignnone size-full wp-image-66034" alt="The Drop-Down Navigation Menu for Contoso Music" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure4.png" width="720" height="305" /></p><p><b>Figure 4. The Drop-Down Navigation Menu for Contoso Music</b></p><p>This navigation menu has a couple of issues that go beyond responsive layout, but they are still an integral part of building a unified site experience that scales across multiple devices.</p><ol
start="1"><li>First, a lot of sites use navigation menus on which links are revealed when a user mouses over the menu titles. This is absolutely unacceptable because a mouse-over does not translate well to touch browsers. In fact, touch-input aside, you shouldn’t rely on a mouse-over to reveal any useful information at all because it is not keyboard accessible and goes against <a
href="http://www.w3.org/TR/WCAG/">W3C accessibility guidelines</a>.</li><li>Second, look at the relative sizes of the links Playlists and DJs. These two pieces of information are supposed to be at the same level in the hierarchy. However, the size of the link is determined by the size of the text. This makes the DJs link less prominent, and also harder to precisely tap on a touch-screen. The DJs link could be as small as 20 px by 40 px, which is not accessible.</li><li>Another subtle problem, which you can see by glancing at the menu list items, is that only the text items themselves are hyperlinks. Here again, the touch user would be better served if the target for the link Foo was the entire width of the flyout menu instead of just the text width.</li></ol><p>Moreover, users on all-in-one devices might utilize the same machine in different device configurations, in which case they might access your site with a mouse at one point and then revisit it later by using touch. It’s beneficial to provide the user with touch-friendly, well-spaced hyperlinks and navigation.</p><p>A common example of touch-friendly navigation that lots of sites use for their menus, especially on mobile apps or in a sidebar for tablets, is shown in <b>Figure 5.</b></p><p><img
class="alignnone size-full wp-image-66035" alt="A Touch-Friendly Redesign of the Contoso Music Navigation Menu" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure5.png" width="400" height="376" /></p><p><b>Figure 5. A Touch-Friendly Redesign of the Contoso Music Navigation Menu </b></p><p>The navigation menu utilizes touch, mouse or keyboard to expand and collapse the accordion-style submenus. All the links are the same width (even the submenu items), and for each link, the entire rectangle is clickable, not just the text.</p><p>A good example of a site that has made this transformation is MSN.com. The old MSN.com (shown in <b>Figure 6</b>) sports a significantly higher content density, with lots of text links (with smaller clickable areas) that are tightly packed (creating room for error when using touch and gaming joysticks), as well as a mouse-over to reveal the subcategories of news (see the menu under Entertainment).</p><p><img
class="alignnone size-full wp-image-66036" alt="The Old MSN.com" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure6.png" width="720" height="516" /></p><p><b>Figure 6. The Old MSN.com</b></p><p><b>Figure 7</b> shows the new touch-friendly version of MSN.com. While currently offered only on Windows 8, the touch-friendly UI will be rolled out across the board for all browsers after testing. Notice the more spacious layout and larger hit targets.</p><p><img
class="alignnone size-full wp-image-66037" alt="The New Look for MSN.com" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure7.png" width="720" height="517" /></p><p><b>Figure 7. The New Look for MSN.com</b></p><h2>One <em>Site</em> Fits All</h2><p>Responsive Web design should not only be about resizing the same content gracefully based on user screen sizes. To best connect with your users across multiple screens, your site should not only be aware of the device’s physical characteristics (such as screen size) but also infer the user’s physical circumstances, modes of input and the kind of information she is seeking.</p><p>In the next article in this series, I’ll cover some implementation techniques for responsive design.</p><div><p><em>This article is part of the HTML5 tech series from the Internet Explorer team. Try-out the concepts in this article with three months of free BrowserStack cross-browser testing @ <a
href="http://modern.ie" target="_blank">http://modern.IE</a>.</em></p></div><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/designing-experiences-for-responsive-web-sites/feed/</wfw:commentRss> <slash:comments>5</slash:comments> <series:name><![CDATA[Responsive Web Design]]></series:name> </item> <item><title>Why the Web Is Ready for Responsive Web Design</title><link>http://www.sitepoint.com/why-the-web-is-ready-for-responsive-web-design/</link> <comments>http://www.sitepoint.com/why-the-web-is-ready-for-responsive-web-design/#comments</comments> <pubDate>Thu, 02 May 2013 00:28:02 +0000</pubDate> <dc:creator>Rahul Lalmalani</dc:creator> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Responsive Web Design]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65981</guid> <description><![CDATA[Former Microsoft engineer Rahul Lalmalani puts the case for implementing responsive web design now, dismissing a few myths and misapprehensions along the way.]]></description> <content:encoded><![CDATA[<p></p><h2>The Mobile Playing Field</h2><p>Today, a large portion of site traffic comes from mobile devices—namely smart phones and tablets—in addition to traditional PCs. Across the globe, mobile devices now account for <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl01" href="http://www.businessinsider.com/state-of-internet-slides-2012-10?op=1">12 percent of Internet traffic</a>, and this is scaling up faster than desktop Internet traffic. The fraction of mobile Web traffic is sufficiently higher in nations with high smartphone penetration (for example, <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl02" href="http://www.phonearena.com/news/Mobile-Browsing-accounts-for-20-of-North-American-web-traffic-according-to-new-report_id30602">20 percent of US-based Web traffic</a> is via mobile browsing). What’s more, this figure is expected to grow significantly over the next 10 years, as smartphones evolve and mature in terms of hardware and software and adoption picks up in South America, Asia and Africa.</p><p>Site owners have begun to take advantage of this trend over the past several years and have primarily relied on native mobile apps for top sites such as <em>Facebook, </em><em>Hulu</em> and t<em>he New York Times.</em> Moreover, up-and-coming Web services such as <em>Pulse, </em><em>Flipboard and others</em> have even taken to a mobile-first approach, by building apps for iOS and other ecosystems before building a Web site experience. Native apps allow developers to create unique phone-first, touch-optimized experiences for users to interact with their content to take advantage of features like camera integration, geo-location and offline data storage.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Targeting users on mobile natively makes good sense, especially within the US, where more than <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl03" href="http://www.engadget.com/2012/05/07/nielsen-smartphone-share-march-2012/">50 percent of mobile users own a smartphone</a>. While mobile apps offer site owners a way to connect with users on new form factors, new ways to monetize across platforms and new mobile-scenario-centric experiences to empower and delight their users, they offer an incomplete opportunity for developers compared to the ubiquity and reach of the Web. There are a couple of problems that affect a native mobile-only approach.</p><h2>Problem 1: Cost of Supporting Multiple Platforms</h2><p>Creating similar content and experiences across multiple platforms is costly and requires site owners to choose platforms for which to optimize. Additionally, this translates to a limited Web site experience for users who seek out your content from other platforms, especially when you need to prioritize your development investments.</p><p>Adopting a <em>responsively designed Web site</em> can help address the investment costs and ensure that your users across all the latest mobile operating systems are enjoying a consistently useful experience.</p><p>Scott Scazafavo, former vice president of product management at <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl04" href="http://allrecipes.com/">Allrecipes.com</a>, whose responsibilities included mobile product development, puts it this way:</p><blockquote><p><em>&#8220;To do a decent job developing a native mobile application that can compete with “best in class” offerings that are powered by live data or content (like we have at MSN and also at my previous employer, Allrecipes.com), it typically takes a minimum initial investment of about $250k to define, design and engineer that native application, and then an annual maintenance investment for that native app of $75K to $100K per platform to keep it evolving, feature wise, to keep consumers interested and adoption numbers healthy. That is over and above any internal work needed for design or engineering to create and maintain the services (APIs) that power those products.</em></p><p><em>The approach we have taken here at MSN for our TMX product (the new touch-first version of MSN.com currently available on IE10) with HTML5, as well as thin-shell apps to help deliver that product into app marketplaces, in addition to mobile browsers, comes only with a small incremental initial investment to what we do with internal resources to create that app product. [That figure is] probably a $25K to $50K initial investment per platform for each app, and a negligible maintenance cost thereafter to maintain those apps.&#8221;</em></p></blockquote><p>Similarly, by using responsive Web design techniques, <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl05" href="http://clipboard.com/">Clipboard.com</a> was able to target many mobile, small device browsers like Internet Explorer 10 on Windows 8 and Safari on iPhone/iPad at <em>half</em> its expected costs to develop when they began the project.</p><h2>Problem 2: Fragmented Ecosystems</h2><p>Even within a given platform, a plethora of device geometries and sizes—as well as supported platform versions—exist. This requires site owners to not only design for near-similar display sizes and resolutions, but also to submit to multiple app stores (Kindle store, Google Play and Nook store, all on the Android platform). Managing multiple assets within the same platform adds complexity to the support matrix. Fix a layout bug in your native app for the Nexus 7, and you might have to fix it again for the Kindle Fire app. This means all your users are not on the same app version, with the same feature set and the same bug fixes.</p><p>Similarly (even within the iOS app ecosystem), top apps like ESPN, Spotify, Angry Birds Space and the App Store itself <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl06" href="http://www.maclife.com/article/gallery/7_big_apps_still_need_iphone_5_optimization#slide-3">did not correctly occupy the full screen</a> when the iPhone 5 was released, instead just showing users a black bar at the top and bottom of the app. The addition of iPhone 5 required developers to ship app updates to address this simple layout bug.</p><p>We’re also still at a stage where vendors are <em>experimenting with new form factors</em>, such as the big screen. For example, more than 25 million Xbox Live users now have access to Internet Explorer 10 on their living room TV screens and are interacting with it not just through a pointer but also through more human-centric mechanisms such as Kinect and Xbox SmartGlass. Today’s technical decision makers are facing a fragmented and very volatile landscape of devices that their users have integrated into their daily routines.</p><h2>A Unifying Approach: Responsive Web Design</h2><p>Responsive Web design aims to provide an optimal viewing/consumption experience—<em>easy reading and navigation with minimum resizing, panning, and scrolling</em> —across the gamut of devices that exist in the market, <em>as well as to future-proof your site for those that are yet to come</em>. There already exist different Web tutorials regarding individual techniques that help a site become more responsive. This series aims not only to provide a unified approach to responsive Web design, it aims to impress upon decision makers and developers the immediate need for adopting responsiveness as part of their reach strategy. According to a crawl of the top 5,000 Web sites by <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl07" href="http://modern.ie/">modern.IE</a>, only about 14 percent of sites have some form of responsive design. It’s not difficult to see why developers think it’s a daunting task to consider.</p><p>Take a look at <strong>Figure 1.</strong> You can see the relative screen resolutions for the Web browsers on popular smartphones and tablets (the devices are identified in <strong>Table 1</strong>). The device resolutions, as well as ratio of CSS pixels to hardware pixels (a concept we’ll explain in part 3), are taken from <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl08" href="http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density">Wikipedia</a>. (Each square corresponds to 100 x 100 px of Web content, laid out at 1x optical zoom.)</p><p><img
class="alignnone size-full wp-image-65982" alt="Sampling of Resolutions for Several Current Devices" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure11.png" width="700" height="270" /><br
/> <strong>Figure 1. Sampling of Resolutions for Several Current Devices</strong></p><p><strong>Table 1. Key to Figure 1</strong></p><table><tbody><tr><td>A</td><td>iPhone 4</td></tr><tr><td>B</td><td>iPhone 5</td></tr><tr><td>C</td><td>Samsung Galaxy S3</td></tr><tr><td>D</td><td>Nokia Lumia 920</td></tr><tr><td>E</td><td>HTC 8X</td></tr><tr><td>1</td><td>Kindle Fire, Nook Color</td></tr><tr><td>2</td><td>Kindle Fire HD</td></tr><tr><td>3</td><td>LG Nexus 7</td></tr><tr><td>4</td><td>Kindle Fire HD 8.9</td></tr><tr><td>5</td><td>iPad and iPad Mini (different hardware resolutions but same number of CSS pixels, more on this in Part 2)</td></tr><tr><td>6</td><td>Microsoft Surface</td></tr></tbody></table><p>&nbsp;<br
/> &nbsp;<br
/> So is cross-browser, cross-device code the solution?</p><p>Traditionally, OS-specific apps have been able to provide more sophisticated user engagement because they have access to valuable user information, such as geo-location, offline storage and even custom font support for customized interfaces.</p><p>However, modern browsers such as Internet Explorer 10, Google Chrome (version 22), Safari 6 and Firefox (version 17) now offer the lion’s share of these experiences as part of their support for HTML5 and CSS3. HTML5 is not your grandpa’s HTML, which was originally designed to let people encode and deliver pieces of textual information across the Internet. HTML5 is intended for developers to write rich Web-based apps for the twenty-first century. Between HTML5 and CSS3, you get access to once-native features such as <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl10" href="http://mediaqueri.es/">media queries</a>, <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl11" href="http://html5demos.com/geo">geo-location</a>, <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl12" href="http://ie.microsoft.com/testdrive/Graphics/OpenType/">custom font support</a>, <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl13" href="http://ietestdrive2.com/OfflineSocialAlbums/Default.html">offline storage</a> and even <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl14" href="http://www.html5rocks.com/en/mobile/touch/">touch events</a>! This way, your sites can have a different look and layout on hardware of different dimensions, provide users with location-aware services and even provide a valuable experience when the user is disconnected from the Internet.</p><h2>HTML5 Myths</h2><p>There are some common HTML5 myths out there. These include:</p><p><strong>I can’t monetize HTML5.</strong></p><p>HTML5 sites have arguably more monetization opportunities than their app equivalents. App monetization today includes app purchases (although most apps in the iOS apps store are in the free to $0.99 range). This is probably the only way in which HTML5 site experiences can’t be directly monetized. Otherwise, developers have a lot of control over advertising and in-app or in-site purchases. More importantly, a lot of apps tend to limit the amount of navigation a user can do. For example, most reader and newspaper/magazine apps offer textual content and don’t provide the “linky-ness” of the Web, which allows users to navigate to related content while consuming the current Web page.</p><p>The Web site experience, when responsively implemented, retains the “linky” nature of the Web and can lead to a higher number of user impressions.</p><p><strong>HTML5 cannot be offline.</strong></p><p>HTML5 has a couple of different solutions for ensuring that users have a great offline experience. First and foremost, Web pages can specify which of their assets should be made available to users when they are disconnected (using <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl15" href="http://www.html5rocks.com/en/tutorials/appcache/beginner/">App Cache</a>). This way, the user can still interact with the page even while offline. Additionally, HTML5 can locally store user information and input using Local Storage, as well as IndexedDB. This data persists even if the user closes the browser and can be synced back to the server at a later point in time when the user relaunches the Web page.</p><p>Check out the demo for this <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl16" href="http://ie.microsoft.com/testdrive/html5/OfflineCalculator/">offline calculator</a>. A user needs to be connected to the Web only the first time he visits it. Subsequently, he can access it offline. Moreover, the user’s calculation and results are stored via Local Storage so he can come back at a later time and continue a calculation.</p><p>The <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl17" href="https://hacks.mozilla.org/2012/11/html5-mythbusting/">Mozilla hacks blog</a> is a great start at busting some common myths about HTML5. It’s important to note here that native apps use APIs that are optimized for device-specific performance. However, HTML5 and CSS3 provide developers with tools to build engaging experiences across a variety of form factors and ensure that you are not missing out on users visiting from other platforms.</p><p><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl18" href="http://caniuse.com/">CanIUse.com</a> is a great resource for understanding the available browser support for specific HTML5 and CSS features.</p><h2>Media Queries and Responsive Design</h2><p>One of the new tools in CSS3 to aid in responsive Web design is called <em>media queries</em>. Media queries allow you to offer your users the same HTML content but enable the browser to detect the size constraints of the device (in pixels) and layout the same content in a different, relevant manner. You can grow or shrink the width of your text and image content, increase or decrease the number of columns in your newspaper-style layout or even hide pieces of information entirely, depending on what you think the right consumption experience is for your user on a given device.</p><p>With a combination of media queries to dictate the layout of your content, as well as browser detection to identify additional constraints of the user experience (for example, if the user is interacting with a site via Xbox 360 on a large TV screen), you can identify your users’ needs and deliver the right experience for the current context in which a user has accessed your content—whether it be to consume it richly on a desktop, interact with it via touch on a slate or quickly skim through it on the go on a phone—and do so gracefully with Web technologies.</p><p>What’s best, most modern mobile devices support HTML5 and CSS3! This way, you can create near-native experiences directly within the browser. Short of DRM support or access to certain device-unique hardware, there’s no limit to the kinds of experiences you can offer through HTML5, CSS3 and JavaScript. Check out <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl19" href="http://atari.com/arcade#%21/arcade/atari-promo" class="broken_link">retro Atari video games</a> to get an idea of the kind of cool experiences you can build purely with standards-compliant Web technologies.</p><p>It should be noted that using media queries alone to build three different fixed-width layouts for your Web site can definitely help you target common screen dimensions today (for example, desktop, tablet and phone). However, <em>this is not truly responsive Web design</em>. It does not provide an optimal experience for users visiting your site with a device that has an intermediate width, nor does it prepare you for the next wave of “it” devices with new geometries and dimensions.</p><h2>Build Once! Deploy Once!</h2><p>If you choose to invest in your site experience, you can design a single HTML5, CSS3 and JavaScript experience that can scale across form factors, from a small smartphone touchscreen to a large cinema display or TV set. We’ll go into the implementation details later in the series, but what’s great to note here is that you never have to choose which of your users you want to delight with that cool new feature, or protect with that high-security patch.</p><p>In addition to simplifying your code base and support matrix, this has the following advantages.</p><h3>Benefit 1: Leave No Users Behind</h3><p>Betting on powerful native apps for the top one or two mobile platforms can mean that some of your users migrate to competitors if they offer a useful Web experience, with more reach, on all platforms.</p><h3>Benefit 2: Unified Ad Story</h3><p>Often, when sites rely on advertising for revenue, they engage with their business partners and sell them advertising piecemeal, based on whether the users are experiencing the full-blown Web version or a limited app version. Also, click-through rates for ads on mobile devices are less than those on desktop PCs, in which case the extra cost of engaging with partners, creating advertising assets for native apps and selling app-specific ad real estate does not justify the additional gains. For example, MSN.com (which has now begun to roll out a unified, media-query-based HTML5 Web site across its international markets) can now unify its ad partnership story across all device types.</p><p>With a single HTML5 experience that responsively scales to different form factors, you can cater to a single ad customer with the same set of ad assets across a variety of devices—in the living room, on the work desk and on the go.</p><h3>Benefit 3: Upgrade Your Site Experience Directly into Your App Experience</h3><p>Occasionally, you might still hit a roadblock where you want to deliver a great mobile experience to your users that takes advantage of their unique hardware—for example, you want users to get new content from your site by shaking their phone. In this case, you need to access the device accelerometer.</p><p>Well, the great news is that you can create a native app by applying a wrapper around your site content and only write the necessary native app code to interact with the additional hardware on the phone. For example, you can host (the responsively scaled down view of) your site content within a WebViewController on an iPhone and just listen for the accelerometer event in your objective-C native code.</p><p>This means that for any fixes/features that you build within the Web layer, you don’t need to go through the trouble of shipping app upgrades!</p><h2>“So, how do I start?”</h2><p>At this point, we have yet to talk about the “how-tos” of responsive Web design. I’ll get to that in the next part of the series, but I hope you’ve had a chance to consider the long-term benefits of a solution for delivering your content to your users that consists of a single code base, written in familiar Web technologies, with ever-growing support of open JavaScript libraries, rich HTML5 device integration and high-quality CSS3 layout and graphic support. If not, you can always look back at the quickly increasing list of devices in <strong>Figure 1</strong>.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/why-the-web-is-ready-for-responsive-web-design/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <series:name><![CDATA[Responsive Web Design]]></series:name> </item> <item><title>Accessible Audio Descriptions for HTML5 Video</title><link>http://www.sitepoint.com/accessible-audio-descriptions-for-html5-video/</link> <comments>http://www.sitepoint.com/accessible-audio-descriptions-for-html5-video/#comments</comments> <pubDate>Mon, 29 Apr 2013 21:32:51 +0000</pubDate> <dc:creator>James Edwards</dc:creator> <category><![CDATA[Accessibility]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[video]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65695</guid> <description><![CDATA[James describes a simple but surprisingly effective technique for synchronising multiple media sources in order to add accessible audio descriptions to an existing video.]]></description> <content:encoded><![CDATA[<p></p><p>A client recently asked me to produce an accessible video player, and one of the features she was very keen to have is <strong>audio descriptions</strong>. Audio descriptions are intended for people who are blind or have impaired vision, providing additional spoken information to describe important visual details.</p><p>Traditionally, audio-described videos have to be made specially, with the audio encoded in a separate track of the single video file. It takes pretty specialised video-editing equipment to encode these audio tracks, and that raises the bar for most content producers beyond a practical level.</p><p>All the audio-described content I&#8217;ve seen on the web is like this. For example, <a
href="http://www.bbc.co.uk/iplayer/">BBC iPlayer</a> has a <a
title="Audio Described programs on BBC iPlayer (bbc.co.uk)" href="http://www.bbc.co.uk/iplayer/tv/categories/audiodescribed">selection of such content</a>, but the video player doesn&#8217;t give you control over the relative volumes, and you can&#8217;t turn the audio-descriptions off — you can only watch separate described or non-described versions of the program.</p><h2>Enter HTML5</h2><p>The <a
title="The video element (whatwg.org)" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html">HTML5 video specification</a> does provide an <code><a
title="Media resources with multiple media tracks (whatwg.org)" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#media-resources-with-multiple-media-tracks">audioTracks</a></code> object, which would make it possible to implement an on/off button, and to control the audio and video volumes separately. But its browser support is virtually non-existent — at the time of writing, only <abbr
title="Internet Explorer 10">IE10</abbr> supports this feature.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>In any case, what my client wanted was <strong>audio descriptions in a separate file</strong>, which could be added to a video without needing to create a separate version, and which would be easy to make without specialised software. And of course, it had to work in a decent range of browsers.</p><p>So my next thought was to use a <a
title="Synchronising multiple media elements (whatwg.org)" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#synchronising-multiple-media-elements">MediaController</a>, which is a feature of <abbr
title="HyperText Markup Language Version 5">HTML5</abbr> audio and video that allows you to synchronise multiple sources. However browser support for this is equally scant — at the time of writing, only Chrome supports this feature.</p><p>But you know — even without that support, it&#8217;s clearly not a problem to <strong>start</strong> two media files at the same time, it&#8217;s just a case of <strong>keeping them in sync</strong>. So can we use existing, widely-implemented features to make that work?</p><h2>Video Events</h2><p>The video <abbr
title="Application Programming Interface">API</abbr> provides a number of events we can hook into, that should make it possible to synchronise audio playback with events from the video:</p><ul><li>The <code>"play"</code> event (which fires when the video is played).</li><li>The <code>"pause"</code> event (which fires when the video is paused).</li><li>The <code>"ended"</code> event (which fires when the video ends).</li><li>The <code>"timeupdate"</code> event (which fires continually while the video is playing).</li></ul><p>It&#8217;s the <code>"timeupdate"</code> event that&#8217;s really crucial. The <em>frequency</em> at which it fires is not specified, and practise it varies considerably — but as a rough, overall average, it amounts to 3–5 times per second, which is enough for our purposes.</p><p>I&#8217;ve seen a similar approach being tried to <a
title="Two videos in sync (html5demos.com)" href="http://html5demos.com/two-videos">synchronise two video files</a>, but it isn&#8217;t particularly successful, because even tiny discrepancies are very obvious. But audio descriptions generally don&#8217;t need to be so precisely in sync — a delay of <code>100ms</code> either way would be acceptable — and playing audio files is far less work for the browser anyway.</p><p>So all we need to do is use the video events we have, to lock the audio and video playback together:</p><ul><li>When the video is played, play the audio.</li><li>When the video is paused, pause the audio.</li><li>When the video ends, pause the video and audio together.</li><li>When the time updates, set the audio time to match the video time, if they&#8217;re different.</li></ul><p>After some experimentation, I discovered that the best results are achieved by comparing the time in whole seconds, like this:</p><pre class="brush: jscript; title: ; notranslate">
if(Math.ceil(audio.currentTime) != Math.ceil(video.currentTime))
{
  audio.currentTime = video.currentTime;
}
</pre><p>This seems counter-intuitive, and initially I had assumed we&#8217;d need as much precision as the data provides, but that doesn&#8217;t seem to be the case. By testing it using a literal audio copy of the video&#8217;s soundtrack (i.e. so the audio and video both produce identical sound), it&#8217;s easy to hear when the synchronisation is good or bad. Experimenting on that basis, I got much better synchronisation when rounding the figures, than not.</p><p>So here&#8217;s the final script. If the browser supports <code>MediaController</code> then we just use that, otherwise we implement manual synchronisation, as described:</p><pre class="brush: jscript; title: ; notranslate">
var video = document.getElementById('video');
var audio = document.getElementById('audio');
if(typeof(window.MediaController) === 'function')
{
  var controller = new MediaController();
  video.controller = controller;
  audio.controller = controller;
}
else
{
  controller = null;
}
video.volume = 0.8;
audio.volume = 1;
video.addEventListener('play', function()
{
  if(!controller &amp;&amp; audio.paused)
  {
    audio.play();
  }
}, false);
video.addEventListener('pause', function()
{
  if(!controller &amp;&amp; !audio.paused)
  {
    audio.pause();
  }
}, false);
video.addEventListener('ended', function()
{
  if(controller)
  {
    controller.pause();
  }
  else
  {
    video.pause();
    audio.pause();
  }
}, false);
video.addEventListener('timeupdate', function()
{
  if(!controller &amp;&amp; audio.readyState &gt;= 4)
  {
    if(Math.ceil(audio.currentTime) != Math.ceil(video.currentTime))
    {
      audio.currentTime = video.currentTime;
    }
  }
}, false);
</pre><p>Note that the <code>MediaController</code> itself is defined only through scripting, whereas it is possible to define a controller using the static <code>"mediagroup"</code> attribute:</p><pre class="brush: xml; title: ; notranslate">
&lt;video mediagroup=&quot;foo&quot;&gt; ... &lt;/video&gt;
&lt;audio mediagroup=&quot;foo&quot;&gt; ... &lt;/audio&gt;
</pre><p>If we did that, then it would work without JavaScript in Chrome. It would sync the media sources, but the user would have <strong>no control over the audio</strong> (including not being able to turn it off), because the browser <em>wouldn&#8217;t know what the audio represents</em>. This is the case in which it would be better to have the audio encoded into the video, because then it could appear in the <code>audioTracks</code> object, and the browser could recognise that and be able to provide native controls.</p><p>But since we have no <code>audioTracks</code> data, that&#8217;s rather a moot point! So if scripting is not available, the audio simply won&#8217;t play.</p><p><strong>Here&#8217;s the final demo</strong>, which will work in any recent version of Opera, Firefox, Chrome, Safari, or <abbr
title="Internet Explorer 9">IE9</abbr> or later:</p><ul><li><strong><a
href="http://jspro.brothercake.com/audio-descriptions/">Audio Descriptions Demo</a></strong></li></ul><p>This is just a simple proof-of-concept demo, of course — there&#8217;s no initial feature detection, and it only has the basic controls provided by the native <code>"controls"</code> attribute. For a proper implementation it would need custom controls, to provide (among other things) a button to switch the audio on and off, and separate volume sliders. The interface should also be accessible to the keyboard, which is not the case in some browsers&#8217; native controls. And it would need to handle buffering properly — as it is, if you seek past the point where the video has preloaded, the audio will continue to play freely until the video has loaded enough to bring it back into sync.</p><p>I might also mention that the descriptions themselves are hardly up to professional standards! That&#8217;s my voice you can hear, recorded and converted using <a
title="Audacity is a free audio editor and recorded" href="http://audacity.sourceforge.net/">Audacity</a>. But such as it is, I think it makes an effective demonstration, of how low the technical barrier-to-entry is with this approach. I didn&#8217;t have to edit the video, and I made the audio in an hour with free software.</p><p>As a proof of concept, I&#8217;d say it was pretty successful — and I&#8217;m sure my client will be very pleased!</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/accessible-audio-descriptions-for-html5-video/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>How to Build an Instagram-like Photo Sharing App with HTML5: Part 2</title><link>http://www.sitepoint.com/how-to-build-an-instagram-like-photo-sharing-app-with-html5-part-2/</link> <comments>http://www.sitepoint.com/how-to-build-an-instagram-like-photo-sharing-app-with-html5-part-2/#comments</comments> <pubDate>Fri, 26 Apr 2013 15:55:52 +0000</pubDate> <dc:creator>Rajasekharan Vengalil</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65642</guid> <description><![CDATA[In Part 1, Rajasekharan Vengalil laid out the implementation details of his InstaFuzz app built with HTML5, CSS and JS. Here, he shows how Drag/Drop, File API, Canvas and Web Workers can be used.]]></description> <content:encoded><![CDATA[<p></p><p>In <a
href="http://www.sitepoint.com/how-to-build-an-instagram-like-photo-sharing-app-with-html5/">part 1</a> we took a look at some of the UI layout implementation details of the <a
href="http://blogorama.nerdworks.in/arbit/InstaFuzz/" target="_blank">InstaFuzz</a> app.  You can get the source code for the app from <a
href="http://sdrv.ms/14B672O" target="_blank">here</a> if you wish to run it locally.  In this installment we’ll take a look at some of the other bits such as how drag/drop, File API, Canvas and Web Workers are used.</p><h2>Drag/Drop</h2><p>One of the things that <i>InstaFuzz</i> supports is the ability to drag and drop image files directly on to the big blackish/blue box.  Support for this is enabled by handling the “drop” event on the CANVAS element.  When a file is dropped onto an HTML element the browser fires the “drop” event on that element and passes in a <a
href="http://aka.ms/dataTransfer"><i>dataTransfer</i></a> object which contains a <a
href="http://aka.ms/filesproperty"><i>files</i> property</a> that contains a reference to the list of files that were dropped.  Here’s how this is handled in the app (“picture” is the ID of the CANVAS element on the page):<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><pre>var pic = $("#picture");
pic.bind("drop", function (e) {
    suppressEvent(e);
    var files = e.originalEvent.dataTransfer.files;
    // more code here to open the file
});
&nbsp;
pic.bind("dragover", suppressEvent).bind("dragenter", suppressEvent);
&nbsp;
function suppressEvent(e) {
    e.stopPropagation();
    e.preventDefault();
}</pre><p>The <i>files</i> property is a collection of <a
href="http://aka.ms/FileObject"><i>File</i> objects</a> that can then subsequently be used with the File API to access the file contents (covered in the next section).  We also handle the <i>dragover</i> and <i>dragenter</i> events and basically prevent those events from propagating to the browser thereby preventing the browser from handling the file drop.  IE for instance might unload the current page and attempt to open the file directly otherwise.</p><h2>File API</h2><p>Once the file has been dropped, the app attempts to open the image and render it in the canvas.  It does this by using the <a
href="http://aka.ms/FileAPI">File API</a>.  The File API is a W3C specification that allows web apps to programmatically access files from the local file system in a secure fashion.  In <i>InstaFuzz</i> we use the <a
href="http://aka.ms/FileReaderObject"><i>FileReader</i> object</a> to read the file contents as a <a
href="http://aka.ms/dataProtocol">data URL</a> string like so using the <a
href="http://aka.ms/readAsDataURLmethod"><i>readAsDataURL</i></a> method:</p><pre>var reader = new FileReader();
reader.onloadend = function (e2) {
    drawImageToCanvas(e2.target.result);
};
reader.readAsDataURL(files[0]);</pre><p>Here, <i>files</i> is the collection of <i>File</i> objects retrieved from the function handling the “drop” event on the CANVAS element. Since we are interested only in a single file we simply pick the first file from the collection and ignore the rest if there are any.  The actual file contents are loaded asynchronously and once the load completes, the <a
href="http://aka.ms/onloadend"><i>onloadend</i></a> event is fired where we get the file contents as a data URL which we then subsequently draw on to the canvas.</p><h2>Rendering the filters</h2><p>Now the core functionality here is of course the application of the filters.  In order to be able to apply the filter to the image we need a way to access the individual pixels from the image.  And before we can access the pixels we need to have actually rendered the image on to our canvas.  So let’s first take a look at the code that renders the image that the user picked on to the canvas element.</p><h3>Rendering images on to the canvas</h3><p>The canvas element supports the rendering of <i>Image</i> objects via the <a
href="http://aka.ms/drawImage"><i>drawImage</i></a> method.  To load up the image file in an <i>Image</i> instance, <i>InstaFuzz</i> uses the following utility routine:</p><pre>App.Namespace.define("InstaFuzz.Utils", {
    loadImage: function (url, complete) {
        var img = new Image();
        img.src = url;
        img.onload = function () {
            complete(img);
        };
    }
});</pre><p>This allows the app to load up image objects from a URL using code such as the following:</p><pre>function drawImageToCanvas(url) {
    InstaFuzz.Utils.loadImage(url, function (img) {
        // save reference to source image
        sourceImage = img;
&nbsp;
        mainRenderer.clearCanvas();
        mainRenderer.renderImage(img);
&nbsp;
        // load image filter previews
        loadPreviews(img);
    });
}</pre><p>Here, <i>mainRenderer</i> is an instance created from the <i>FilterRenderer</i> constructor function defined in <i>filter-renderer.js</i>.  The app uses <i>FilterRenderer</i> objects to manage canvas elements – both in the preview pane as well as the main canvas element on the right.  The <i>renderImage</i> method on the <i>FilterRenderer</i> has been defined like so:</p><pre>FilterRenderer.prototype.renderImage = function (img) {
    var imageWidth = img.width;
    var imageHeight = img.height;
    var canvasWidth = this.size.width;
    var canvasHeight = this.size.height;
    var width, height;
&nbsp;
    if ((imageWidth / imageHeight) &gt;= (canvasWidth / canvasHeight)) {
        width = canvasWidth;
        height = (imageHeight * canvasWidth / imageWidth);
    } else {
        width = (imageWidth * canvasHeight / imageHeight);
        height = canvasHeight;
    }
&nbsp;
    var x = (canvasWidth - width) / 2;
    var y = (canvasHeight - height) / 2;
    this.context.drawImage(img, x, y, width, height);
};</pre><p>That might seem like a lot of code but all it does ultimately is to figure out the best way to render the image in the available screen area considering the aspect ratio of the image.  The key piece of code that actually renders the image on the canvas occurs on the last line of the method.  The <i>context</i> member refers to the 2D context acquired from the canvas object by calling its<a
href="http://aka.ms/getContext"> <i>getContext</i></a> method.</p><h3>Fetching pixels from the canvas</h3><p>Now that the image has been rendered we will need access to the individual pixels in order to apply all the different filters that are available.  This is easily acquired by calling <a
href="http://aka.ms/getImageData"><i>getImageData</i></a> on the canvas’s context object.  Here’s how <i>InstaFuzz</i> calls this from <i>instafuzz.js</i>.</p><pre>var imageData = renderer.context.getImageData(
    0, 0,
    renderer.size.width,
    renderer.size.height);</pre><p>The object returned by <i>getImageData</i> provides access to the individual pixels via its <i>data</i> property which in turn is an array like object that contains a collection of byte values where each value represents the color rendered for a single channel of a single pixel.  Each pixel is represented using 4 bytes that specify values for the red, green, blue and alpha channels.  It also has a <a
href="http://aka.ms/lengthProperty"><i>length</i></a><i> </i>property that returns the length of the buffer.  If you have a 2D co-ordinate you can easily transform that into an index into this array using code such as the following.  The color intensity values of each channel ranges from 0 through 255.  Here’s the utility function from <i>filters.js</i> that accepts as input an image data object along with 2D coordinates for the pixel the caller is interested in and returns an object containing the color values:</p><pre>function getPixel(imageData, x, y) {
    var data = imageData.data, index = 0;
&nbsp;
    // normalize x and y and compute index
    x = (x &lt; 0) ? (imageData.width + x) : x;
    y = (y &lt; 0) ? (imageData.height + y) : y;
    index = (x + y * imageData.width) * 4;
&nbsp;
    return {
        r: data[index],
        g: data[index + 1],
        b: data[index + 2]
    };
}</pre><h3>Applying the filters</h3><p>Now that we have access to the individual pixels, applying the filter is fairly straightforward.  Here, for instance is the function that applies a weighted grayscale filter on the image.  It simply picks intensities from the red, green and blue channels and sums them up after applying a multiplication factor on each channel and then assigns the result for all 3 channels.</p><pre>// "Weighted Grayscale" filter
Filters.addFilter({
    name: "Weighted Grayscale",
    apply: function (imageData) {
        var w = imageData.width, h = imageData.height;
        var data = imageData.data;
        var index;
        for (var y = 0; y &lt; h; ++y) {
            for (var x = 0; x &lt; w; ++x) {
                index = (x + y * imageData.width) * 4;
                var luminance = parseInt((data[index + 0] * 0.3) +
                                         (data[index + 1] + 0.59) +
                                         (data[index + 2] * 0.11));
                data[index + 0] = data[index + 1] =
                    data[index + 2] = luminance;
            }
&nbsp;
            Filters.notifyProgress(imageData, x, y, this);
        }
&nbsp;
        Filters.notifyProgress(imageData, w, h, this);
    }
});</pre><p>Once the filter has been applied we can have that reflected on the canvas by calling the <a
href="http://aka.ms/putImageData"><i>putImageData</i></a> method passing in the modified image data object.  While the weighted grayscale filter is fairly simple most of the other filters use an image processing technique known as <i>convolution</i>.  The code for all the filters is available in <i>filters.js</i> and the convolution filters were ported from the C code available <a
href="http://lodev.org/cgtutor/filtering.html">here</a>.</p><h2>Web Workers</h2><p>As you might imagine doing all this number crunching to apply the filters can potentially take a long time to complete.  The <i>motion blur</i> filter for instance uses a 9&#215;9 filter matrix for computing the new value for every single pixel and is in fact the most CPU intensive filter among them all.  If we were to do all this computation on the UI thread of the browser then the app would essentially freeze every time a filter was being applied.  To provide a responsive user experience the app delegates the core image processing tasks to a background script using the support for W3C <a
href="http://aka.ms/WebWorkers">Web Workers</a> in modern browsers.</p><p>Web workers allow web applications to have scripts run in a background task that executes in parallel along with the UI thread.  Communication between the worker and the UI thread is accomplished by passing messages using the <a
href="http://aka.ms/postMessage"><i>postMessage</i></a> API.  On both ends (i.e. the UI thread and the worker) this manifests as an event notification that you can handle.  You can only pass “data” between workers and the UI thread, i.e., you cannot pass anything that has to do with the user interface  – you cannot for instance, pass DOM elements to the worker from the UI thread.</p><p>In <i>InstaFuzz</i> the worker is implemented in the file <i>filter-worker.js</i>.  All it does in the worker is handle the <a
href="http://aka.ms/onmessage"><i>onmessage</i></a> event and apply a filter and then pass the results back via <i>postMessage</i>.  As it turns out, even though we cannot pass DOM elements (which means we cannot just hand a CANVAS element to the worker to have the filter applied) we can in fact pass the image data object as returned by the <i>getImageData</i> method that we discussed earlier. Here’s the filter processing code from <i>filter-worker.js</i>:</p><pre>importScripts("ns.js", "filters.js");
&nbsp;
var tag = null;
onmessage = function (e) {
    var opt = e.data;
    var imageData = opt.imageData;
    var filter;
&nbsp;
    tag = opt.tag;
    filter = InstaFuzz.Filters.getFilter(opt.filterKey);
&nbsp;
    var start = Date.now();
    filter.apply(imageData);
    var end = Date.now();
&nbsp;
    postMessage({
        type: "image",
        imageData: imageData,
        filterId: filter.id,
        tag: tag,
        timeTaken: end - start
    });
}</pre><p>The first line pulls in some script files that the worker depends on by calling <a
href="http://aka.ms/importScripts"><i>importScripts</i></a>.  This is similar to including a JavaScript file in a HTML document using the SCRIPT tag.  Then we set up a handler for the <i>onmessage</i> event in response to which we simply apply the filter in question and pass the result back to the UI thread by calling <i>postMessage</i>.  Simple enough!</p><p>The code that initializes the worker is in <i>instafuzz.js</i> and looks like this:</p><pre>var worker = new Worker("js/filter-worker.js");</pre><p>Not much is it?  When a message is sent by the worker to the UI thread we handle it by specifying a handler for the <i>onmessage</i> event on the worker object.  Here’s how this is done in <i>InstaFuzz</i>:</p><pre>worker.onmessage = function (e) {
    var isPreview = e.data.tag;
    switch (e.data.type) {
        case "image":
            if (isPreview) {
                previewRenderers[e.data.filterId].
                    context.putImageData(
                        e.data.imageData, 0, 0);
            } else {
                mainRenderer.context.putImageData(
                    e.data.imageData, 0, 0);
            }
&nbsp;
            break;
        // more code here
    }
};</pre><p>The code should be fairly self-explanatory.  It simply picks the image data object sent by the worker and applies it to the relevant canvas’s context object causing the modified image to be rendered on screen.  Scheduling a filter for conversion with the worker is equally simple.  Here’s the routine that performs this function in <i>InstaFuzz</i>:</p><pre>function scheduleFilter(filterId,
                             renderer,
                             img, isPreview,
                             resetRender) {
    if (resetRender) {
        renderer.clearCanvas();
        renderer.renderImage(img);
    }
&nbsp;
    var imageData = renderer.context.getImageData(
        0, 0,
        renderer.size.width,
        renderer.size.height);
&nbsp;
    worker.postMessage({
        imageData: imageData,
        width: imageData.width,
        height: imageData.height,
        filterKey: filterId,
        tag: isPreview
});
}</pre><h2>Wrapping it up</h2><p>The source for <i>InstaFuzz</i> is available for download <a
href="http://sdrv.ms/11110mf">here</a>.  We saw that fairly intricate user experiences are possible today with HTML5 technologies such as Canvas, Drag/Drop, File API and Web Workers.  Support for all of these technologies is quite good in pretty much all modern browsers.  One thing that we did not address here is the question of making the app compatible with older browsers.  That, truth be told, is a non-trivial but necessary task that I will hopefully be able to talk about in a future article.</p><div><p><em>This article is part of the HTML5 tech series from the Internet Explorer team. <a
href="http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200210648">Try-out</a> the concepts in this article with three months of free BrowserStack cross-browser testing @ <a
href="http://modern.ie/">http://modern.IE</a></em></div><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/how-to-build-an-instagram-like-photo-sharing-app-with-html5-part-2/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Should Users Have the Option to Switch Off Responsive Design?</title><link>http://www.sitepoint.com/disable-responsive-design-option/</link> <comments>http://www.sitepoint.com/disable-responsive-design-option/#comments</comments> <pubDate>Fri, 26 Apr 2013 14:19:17 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[Responsive Web Design]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[Responsive Design]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65065</guid> <description><![CDATA[Do all users prefer the mobile-optimized sites we provide via Responsive Web Designs? Should we let them revert to desktop view? Craig starts the debate...]]></description> <content:encoded><![CDATA[<p></p><p>There are few reasons not to use a Responsive Web Design. Unless you have the time, budget and inclination to develop a separate mobile site or app, RWD techniques can assist your users on mobile <a
href="/support-old-browsers-responsive-web-design/">and older</a> devices.</p><p><em>But what if a user doesn&#8217;t want a mobile-optimized view of your site?</em></p><p>This question has been discussed by industry giants including <a
href="http://www.brucelawson.co.uk/2013/turning-off-responsive-web-design/">Bruce Lawson</a> and <a
href="http://www.456bereastreet.com/archive/201303/letting_users_disable_responsive_layout/">Roger Johansson</a>. The possible reasons include:</p><ol><li>The user regularly uses the desktop site but becomes disorientated in mobile view.</li><li>The mobile website hides content or features the user wants to use (admittedly, that may be bad design decisions but many sites do exactly that).</li><li>Modern smartphone browsers render desktop sites reasonably well and a user prefers scanning and zooming.</li><li>It would allow developers or support personnel to view desktop layout issues when using a mobile device.</li><li>Shouldn&#8217;t the user be able to select what&#8217;s best for them?</li></ol><p>On the plus side, the concept appears to tick usability boxes and providing options is a good thing.</p><p><em>Or is it?</em></p><p>How many people would understand the switch? How many would use it? In my experience, non-technical users prefer fewer choices and, ideally, want the software or someone else to select what&#8217;s best for them. In addition, could they hit &#8220;switch to fixed layout&#8221; then find it difficult to revert to mobile view.</p><p>I&#8217;m sure there will be some good use cases but, personally, I think RWD offers more compelling advantages to the majority of users than disadvantages to the minority.</p><p>Perhaps this is a real issue users have encountered with your site? Or perhaps this is an over-engineered solution looking for a problem? I&#8217;m leaning toward the latter, but would love to hear your views&hellip;</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/disable-responsive-design-option/feed/</wfw:commentRss> <slash:comments>54</slash:comments> </item> <item><title>How to Build an Instagram-like Photo Sharing App with HTML5</title><link>http://www.sitepoint.com/how-to-build-an-instagram-like-photo-sharing-app-with-html5/</link> <comments>http://www.sitepoint.com/how-to-build-an-instagram-like-photo-sharing-app-with-html5/#comments</comments> <pubDate>Thu, 25 Apr 2013 14:16:53 +0000</pubDate> <dc:creator>Rajasekharan Vengalil</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65596</guid> <description><![CDATA[Rajaskharan Vengalil set out to see if an app like Instagram could be built using only HTML, CSS and JavaScript. Turns out it is (sorry, belated spoiler alert!).]]></description> <content:encoded><![CDATA[<p></p><p>When I started out on this app I was only really just interested in seeing if the web platform had really evolved to a point where an app like the hugely popular <a
href="http://aka.ms/Instragram">Instagram</a> app could be built using just HTML, JavaScript and CSS.</p><p>As it turns out we can in fact do exactly that.  This article walks you through the technologies that make this possible and shows how it is entirely feasible today to build interoperable web applications that provide a great user experience no matter what brand of browser the user is running.</p><p>If you happen to be one of the two or so people who have not heard about <i>Instagram</i> then you might be pleased to hear that it is a hugely popular photo sharing and social networking service that allows you to take pictures, apply interesting digital filters on them and share them with the world.  The service became so popular that it was <a
href="http://finance.fortune.cnn.com/2012/04/09/breaking-facebook-buying-instagram-for-1-billion/">acquired by Facebook</a> for a bag full of cash and stock in April of 2012.</p><p><a
href="http://aka.ms/InstaFuzz">InstaFuzz</a> is the name of the app I put together and while I don’t expect to be acquired by Facebook or anybody else for a billion green it does, however, make the case that an app such as this one can be built using only standards compliant web technologies such as Canvas, File API, Drag/Drop, Web Workers, ES5 and CSS3 and still manage to run well on modern browsers such as <a
href="http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200210648">Internet Explorer 10</a>, Google Chrome and Firefox.  And you could easily use the code to <a
href="http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200185226">build a Windows Store app</a> too.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>About the app</h2><p>If you’d like to take a look at the app, then here’s where it is hosted:</p><p><a
href="http://aka.ms/InstaFuzz">http://blogorama.nerdworks.in/arbit/InstaFuzz/</a></p><p>As soon as you load it up, you’re presented with a screen that looks like this:</p><p><img
class="alignnone size-full wp-image-65597" alt="Instafuzz default" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/04/figure19.png" width="463" height="384" /></p><p>The idea is that you can load up a photograph into the app either by clicking on the big red “Add” button on the bottom left hand corner or drag and drop an image file into the blackish/blue area on the right. Once you do that you get something that looks like this:</p><p><img
class="alignnone size-full wp-image-65598" alt="Add an image" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/04/figure24.png" width="463" height="385" /></p><p>You’ll note that a list of digital filters listed on the left of the screen shows a preview of what the image would look like if you were to apply the said filter.  Applying a filter is a simple matter of clicking on one of the filter previews on the left.  Here’s what it looks like after applying the “Weighted Grayscale” filter followed by a “Motion Blur”.  As you can tell filters are <i>additive</i> – as you keep clicking on filters, they are applied on top of what was applied earlier:</p><p><img
class="alignnone size-full wp-image-65599" alt="filter applied" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/04/figure34.png" width="462" height="385" /></p><p>Let’s next take a look at how the UI layout has been put together.</p><h2>UI Layout</h2><p>The HTML markup is so little that I can actually reproduce the contents of the BODY tag in its entirety here (excluding the SCRIPT includes):</p><pre>&lt;header&gt;
    &lt;div id="title"&gt;InstaFuzz&lt;/div&gt;
&lt;/header&gt;
&lt;section id="container"&gt;
    &lt;canvas id="picture" width="650" height="565"&gt;&lt;/canvas&gt;
    &lt;div id="controls"&gt;
        &lt;div id="filters-list"&gt;&lt;/div&gt;
        &lt;button id="loadImage"&gt;Add&lt;/button&gt;
        &lt;input type="file" id="fileUpload"
           style="display: none;"
           accept="image/gif, image/jpeg, image/png" /&gt;
    &lt;/div&gt;
&lt;/section&gt;
&amp;nbsp;
&lt;!-- Handlebar template for a filter UI button --&gt;
&amp;nbsp;
&lt;script id="filter-template" type="text/x-handlebars-template"&gt;
    &lt;div data-filter-id="<b>{{</b>filterId<b>}}</b>"&gt;
        &lt;div&gt;<b>{{</b>filterName<b>}}</b>&lt;/div&gt;
        &lt;canvas width="128" height="128"&gt;&lt;/canvas&gt;
    &lt;/div&gt;
&lt;/script&gt;</pre><p>There’s nothing much going on here.  Pretty much everything should be standard fare.  I will however draw attention to the fact that I am using the <a
href="http://handlebarsjs.com/">Handlebars</a> JavaScript templating system here for rendering the markup for the list of filters on the left of the screen.  The template markup is declared in the HTML file (the SCRIPT tag in the snippet shown above) and then used from JavaScript.  The template markup is then bound to a JavaScript object that supplies the values for handlebars expressions such as <i>{{filterId}}</i> and <i>{{filterName}}.</i>  Here’s the relevant piece of JS from the app with a bit of DOM manipulation help from <a
href="http://jquery.com/">jQuery</a>:</p><pre>var templHtml = $("#filter-template").html(),
    template = Handlebars.compile(templHtml),
    filtersList = $("#filters-list");
&amp;nbsp;
var context = {
    filterName: filter.name,
    filterId: index
};
&amp;nbsp;
filtersList.append(template(context));</pre><p>As you can tell from the HTML markup, all the filter preview boxes feature a CANVAS tag, as does the big box on the right where the final output is rendered.  We’ll go into a bit more detail later on in the article as to how canvas technology is used to achieve these effects.</p><p>The app also uses<a
href="http://aka.ms/fontface"> CSS3 @font-face</a> fonts to render the text in the header and the “Add” button.  The fonts have been taken from the excellent <a
href="http://aka.ms/FontSquirrel">Font Squirrel</a> site and here’s what the declaration looks like:</p><pre>@font-face {
    font-family: 'TizaRegular';
    src: url('fonts/tiza/tiza-webfont.eot');
    src: url('fonts/tiza/tiza-webfont.eot?#iefix')
           format('embedded-opentype'),
         url('fonts/tiza/tiza-webfont.woff') format('woff'),
         url('fonts/tiza/tiza-webfont.ttf') format('truetype'),
         url('fonts/tiza/tiza-webfont.svg#TizaRegular') format('svg');
    font-weight: normal;
    font-style: normal;
}</pre><p>This directive causes the user agent to embed the font in the page and make it available under the name assigned to the <i>font-family</i> rule which in this case is “TizaRegular”.  After this we can assign this font to any CSS <i>font-family</i> rule like how we normally do.  In <i>InstaFuzz</i> I use the following rule to assign the font to the header element:</p><pre>font-family: TizaRegular, Cambria, Cochin, Georgia, Times,
    "Times New Roman", serif;</pre><p>You might also have noticed that there is a subtle shadow being dropped on the page by the container element.</p><p>This is made possible using the <a
href="http://aka.ms/boxshadowproperty">CSS3 box-shadow</a> rule and here’s how it’s used in <i>InstaFuzz</i>.</p><pre>-moz-box-shadow: 1px 0px 4px #000000, -1px -1px 4px #000000;
-webkit-box-shadow: 1px 0px 4px #000000, -1px -1px 4px #000000;
box-shadow: 1px 0px 4px #000000, -1px -1px 4px #000000;</pre><p>This causes the browser to render a shadow around the relevant element.  Each comma separated section in the value specifies the following attributes of the shadow:</p><ol><li>Horizontal offset</li><li>Vertical offset</li><li>Spread distance – positive values have the effect of softening the shadow</li><li>Shadow color</li></ol><p>One can specify multiple shadow values separated by comma as in fact has been done above.  Note that I’ve also specified the shadow using vendor prefix syntax for Firefox and Chrome/Safari using the <i>moz</i> and <i>webkit</i> prefixes.  This causes the shadow to continue to work in versions of those browsers where support for this capability was provided using the vendor prefixed version of the rule.  Note that the W3C version of the rule – <i>box-shadow</i> – is specified last.  This is done deliberately to ensure that in case the browser supports both the forms then only the W3C behavior is actually applied to the page.</p><p>One often finds that web developers either fail to include vendor prefixed version of a given CSS3 rule for all the browsers that support that rule and/or fail to include the W3C version as well.  Often developers just put the <i>webkit</i> version of the rule ignoring other browsers and the W3C standard version.  This causes two problems – [1] poor user experience for users who are using non-webkit browsers and [2] it ends up resulting in webkit becoming a de-facto standard for the web.  Ideally we want W3C to be driving the future of the web and not one specific browser implementation.  So here are some things to remember when playing with experimental implementations of CSS features:</p><ol><li>Use vendor prefixed versions of CSS rules by all means but remember to specify the rule for all supported browsers and not just the one that you happen to be testing the page in (if you’re using <a
href="http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200117040" class="broken_link">Visual Studio</a> to edit your CSS then you might be interested in the supremely excellent extension for Visual Studio called <a
href="http://aka.ms/WebEssentials"><i>Web Essentials</i></a> that makes the job of managing vendor prefixes about as simple as it can possibly get).</li><li>Remember to specify the W3C version of the rule as well.</li><li>Remember to order the occurrence of the rules so that the W3C version shows up last.  This is to allow clients that support both the vendor prefixed version and the W3C version to use the W3C specified semantics for the rule.</li></ol><p>That’s all for now.  In the next and final article in this series, we’ll take a look at how the app supports drag/drop of files, the use of File API, how the filters themselves work and how we prevent the UI thread from freezing by delegating the core number crunching work to web workers.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/how-to-build-an-instagram-like-photo-sharing-app-with-html5/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>How to Create a Responsive Centered Image in CSS3</title><link>http://www.sitepoint.com/css3-responsive-centered-image/</link> <comments>http://www.sitepoint.com/css3-responsive-centered-image/#comments</comments> <pubDate>Wed, 24 Apr 2013 13:26:49 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[Responsive Web Design]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[image]]></category> <category><![CDATA[responsive]]></category> <category><![CDATA[Responsive Design]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65391</guid> <description><![CDATA[Do you need a lightbox-like image which is centered and never exceeds the browser's dimensions? Do you want it in CSS3 only without scripting? You're in luck -- Craig has a solution...]]></description> <content:encoded><![CDATA[<p></p><p>Image gallery lightboxes have been around for many years. They generally provide a great user experience until you attempt to load an image which is larger than the viewport dimensions. Developers often forget this important check and you&#8217;re presented with a centered image which is difficult to remove. The problem can be exacerbated on mobile devices.</p><p>Until recently, image lightboxes would need to implement several equations to determine the viewport and image dimensions then size and center accordingly. Fortunately, we can now rely on CSS3 media queries and transforms to do the hard work for us.</p><p><a
href="http://cssdeck.com/labs/responsive-image"><strong>View the demonstration&hellip;</strong></a></p><h2>The HTML</h2><p>Little to see here &#8212; we have an <code>img</code> and we&#8217;ll assign a class of &#8220;ri&#8221; (responsive image):</p><pre><code>&lt;img src=&quot;http://lorempixel.com/600/450/&quot; class=&quot;ri&quot; /&gt;</code></pre><p>Remember to remove any height and width attributes.</p><h2>Fallback CSS</h2><p>IE6/7/8 do not understand media queries or transforms so our image will end up in the wrong location. There are shims and proprietary properties which could solve this but, in my opinion, they often cause more problems than they solve, i.e. increased page weight, degraded performance, maintenance headaches, etc.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Therefore, the following code provides a <em>reasonable</em> fallback for legacy browsers and should work on most landscape-oriented desktop screens:</p><pre><code>img.ri
{
	position: absolute;
	max-width: 80%;
	top: 10%;
	left: 10%;
	border-radius: 3px;
	box-shadow: 0 3px 6px rgba(0,0,0,0.9);
}</code></pre><p>The <code>border-radius</code> and <code>box-shadow</code> won&#8217;t be understood by old IEs either, but they&#8217;ll degrade gracefully.</p><h2>Positioning the Image</h2><p>To center the image, we move its top-left corner to the center of the viewport. To move it back to the true center, we use an appropriate transform (with prefixes for older browsers):</p><pre><code>img.ri:empty
{
	top: 50%;
	left: 50%;
	-webkit-transform: translate(-50%, -50%);
	-moz-transform: translate(-50%, -50%);
	-ms-transform: translate(-50%, -50%);
	-o-transform: translate(-50%, -50%);
	transform: translate(-50%, -50%);
}</code></pre><p>Take note of the selector: <code>img.ri:empty</code> &#8212; <code>empty</code> is a structural pseudo-class which only matches elements which have no children (an image should never have any). This is a CSS3 selector so IE8 and below will not parse the declaration. We could have used an alternative, such as Conditional Comments, but this seems a far more efficient solution and requires just six additional characters.</p><h2>Making the Image Responsive</h2><p>Our image must respond to the viewport dimensions to ensure it never overlaps the edge:</p><ul><li>a maximum width must be defined if the viewport is taller than it is wide, and</li><li>a maximum height must be defined if the viewport is wider than it is tall.</li></ul><p>We can use the media query orientation property to do the hard work for us:</p><pre><code>@media screen and (orientation: portrait) {
  img.ri { max-width: 90%; }
}
@media screen and (orientation: landscape) {
  img.ri { max-height: 90%; }
}</code></pre><p>Simple &#8212; and all done without any complicated JavaScripting. <a
href="http://cssdeck.com/labs/responsive-image"><strong>View the demonstration&hellip;</strong></a></p><p>Please use the code as you like for your own projects. It could be used as the basis of your own modern, lightweight lightbox. Unless you&#8217;d like me to write one and provide a handy tutorial? Please forward your requests to <a
href="http://twitter.com/craigbuckler">@craigbuckler</a>.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/css3-responsive-centered-image/feed/</wfw:commentRss> <slash:comments>19</slash:comments> </item> <item><title>HTML5, Older Browsers and the Shiv</title><link>http://www.sitepoint.com/html5-older-browsers-and-the-shiv/</link> <comments>http://www.sitepoint.com/html5-older-browsers-and-the-shiv/#comments</comments> <pubDate>Tue, 23 Apr 2013 04:22:37 +0000</pubDate> <dc:creator>Dmitri Lau</dc:creator> <category><![CDATA[Browsers]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65558</guid> <description><![CDATA[Dmitri Lau looks at how to use the HTML5Shiv tool to address the inability of certain older browsers to correctly interpret some HTML5 elements.]]></description> <content:encoded><![CDATA[<p></p><p>HTML5 introduced a few semantic elements that are not supported in older browsers. Some of these new elements are no different than generic block elements so they don&#8217;t pose any compatibility problems. All you need to ensure compatibility is to add a CSS rule to your website that causes the relevant elements to behave like block elements.</p><p>But Internet Explorer versions 8 and under pose a challenge. Any element not in the official roster of elements cannot be styled with CSS. That means we cannot make then behave like block elements or give them any formatting.</p><p>For example, the following code will not work.</p><pre class="brush: xml; title: ; notranslate">
&lt;style&gt;
section {display: block}
&lt;/style&gt;
&lt;section&gt;This is on its own line.&lt;/section&gt;
&lt;section&gt;This should appear on a separate line.&lt;/section&gt;
</pre><p>But that&#8217;s not all. These new elements behave as if they don&#8217;t exist. For example, the following CSS won&#8217;t work, since the <code>section</code> element won&#8217;t match the universal selector.</p><pre class="brush: xml; title: ; notranslate">
&lt;style&gt;
body * span {color: red}
&lt;/style&gt;
&lt;body&gt;
  &lt;section&gt;
    &lt;span&gt;This should be red, but won't be red in IE 8.&lt;/span&gt;
  &lt;/section&gt;
&lt;/body&gt;
</pre><p>Fortunately for us, a workaround exists that allows Internet Explorer (IE) to recognize these new elements allowing them to be styled, and thus giving us full use of these new semantic tags. It&#8217;s a tool called <a
href="http://code.google.com/p/html5shiv/">HTML5Shiv</a>.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p><em>As noted on the linked Google page, &#8220;shiv&#8221; and &#8220;shim&#8221; are interchangeable terms in this context.</em></p><p>But how did we go from IE not even acknowledging the existence of this element, to now being able to use it?</p><p>The trick is that calling <code>document.createElement("section")</code> will suddenly cause IE to recognize the <code>section</code> element. No one knows why, but it works and you don&#8217;t even need to use the node returned by that function.</p><p>But you need to make sure to call it early on in your website before any of those elements are used, otherwise it won&#8217;t work.</p><p>You will need to call it for each and every new HTML5 elements like so:</p><pre class="brush: jscript; title: ; notranslate">
&quot;abbr article aside audio bdi canvas data datalist details figcaption figure &quot;+
  &quot;footer header hgroup main mark meter nav output progress section &quot; +
  &quot;summary template time video&quot;
  .replace(/\w+/g, function(a){ document.createElement(a) });
</pre><p>Notice we&#8217;re using the <code>replace</code> method of the <code>string</code> object to succinctly iterate over each contiguous length of characters matched by the regular expression and executing the callback function for each character block which in turn calls <code>createElement</code>.</p><p>Here on in, we&#8217;ll call this method, &#8220;shivving the document&#8221;, so that the document can render the new HTML5 elements.</p><p>Now our previous two HTML examples work. But that&#8217;s not all there is to it.</p><h2>Pitfall 1: HTML5 and innerHTML</h2><p>If HTML is being generated using <code>innerHTML</code> and it is called on a node not currently attached to a document (AKA an orphaned node), then it&#8217;s deja vu all over again. The following two examples will not render the <code>section</code> element, even though it&#8217;s run on a document already shivved.</p><pre class="brush: jscript; title: ; notranslate">
var n1 = document.getElementById(&quot;n1&quot;);
n1.parentNode.removeChild(n1);
n1.innerHTML = &quot;&lt;section&gt;Sect 1&lt;\/section&gt;&quot;;  //won't work
</pre><pre class="brush: jscript; title: ; notranslate">
var n2 = document.createElement(&quot;div&quot;);
n2.innerHTML = &quot;&lt;section&gt;Sect 2&lt;\/section&gt;&quot;;  //won't work
</pre><p>In the second example above, if we append the node to the document first before calling <code>innerHTML</code>, then it will work:</p><pre class="brush: jscript; title: ; notranslate">
var n2 = document.createElement(&quot;div&quot;);
document.body.appendChild(n2);
n2.innerHTML = &quot;&lt;section&gt;Sect 2&lt;\/section&gt;&quot;;  //works
</pre><p>We can conclude that although we shivved the document earlier on, orphaned elements do not benefit from the shiv when calling <code>innerHTML</code>.</p><p>What can we do? For starters, whenever we need to set <code>innerHTML</code> we should append it to the document first. An alternative is to first shiv the <code>document</code> property of the orphan before working with the orphan.</p><p>First let&#8217;s put our shiv in its own function.</p><pre class="brush: jscript; title: ; notranslate">
function iehtml5shiv(doc) {
  &quot;abbr article aside audio bdi canvas data datalist details &quot; +
    &quot;figcaption figure footer header hgroup main mark meter nav &quot; +
    &quot;output progress section summary template time video&quot;
    .replace(/\w+/g, function(a){ doc.createElement(a) });
}
</pre><p>The next time we have an orphan element, we can do this:</p><pre class="brush: jscript; title: ; notranslate">
var n1 = document.createElement(&quot;div&quot;);
iehtml5shiv(n1.document);
n1.innerHTML = &quot;&lt;section&gt;Sect 1&lt;\/section&gt;&quot;;  //works
</pre><p>Notice how it&#8217;s just like shivving the document, but on the <code>document</code> property of the element. And notice we&#8217;re accessing <code>document</code> instead of <code>ownerDocument</code>. Both are different things as shown here:</p><pre class="brush: jscript; title: ; notranslate">
alert(n1.document == document);  //false
alert(n1.ownerDocument == document);  //true
</pre><p>Now we have two methods to make sure our call to <code>innerHTML</code> works when handling HTML5 elements.</p><h2>Pitfall 2: cloneNode</h2><p>It appears our cousin <code>cloneNode</code> is also susceptible to losing its shiv. Any HTML5 elements which are cloned, or have had their parents cloned, will lose their identity.</p><p>Notice how the below element has colons in its <code>nodeName</code>, meaning it&#8217;s being confused for an element from another namespace.</p><pre class="brush: jscript; title: ; notranslate">
var n2 = n1.cloneNode(true);
alert(n2.innerHTML);  //outputs: &lt;:section&gt;Sect 1&lt;/:section&gt;
</pre><p>This happens even if the node was already attached to the document.</p><p>There isn&#8217;t much we can do here except roll out your own implementation of <code>cloneNode</code>, which is trivial enough.</p><h2>Pitfall 3: Printing</h2><p>Whenever you print a webpage, IE appears to generate a new document before printing which means all the shiv workarounds are not preserved.</p><p>There isn&#8217;t much you can do to mitigate this. The HTML5Shiv tool works around this by listening for the <code>onbeforeprint</code> event and replacing all the HTML5 elements on the page with normal elements and then doing the reverse on the <code>onafterprint</code> event.</p><p>Thankfully, the HTML5Shiv tool does that nicely for us.</p><h2>References</h2><ul><li>The HTML5Shiv tool: <a
href="https://github.com/aFarkas/html5shiv">https://github.com/aFarkas/html5shiv</a></li><li>The story of the HTML5 Shiv: <a
href="http://paulirish.com/2011/the-history-of-the-html5-shiv/">http://paulirish.com/2011/the-history-of-the-html5-shiv/</a></li></ul><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/html5-older-browsers-and-the-shiv/feed/</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>What&#8217;s New in jQuery 2.0</title><link>http://www.sitepoint.com/whats-new-in-jquery-2-0/</link> <comments>http://www.sitepoint.com/whats-new-in-jquery-2-0/#comments</comments> <pubDate>Sat, 20 Apr 2013 08:30:51 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Ajax]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[Libraries]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[javascript]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65533</guid> <description><![CDATA[jQuery 2.0 has been released. There is one new feature, but it's a big change. Craig provides the details...]]></description> <content:encoded><![CDATA[<p></p><p>The second branch of the web&#8217;s most popular JavaScript library was released on April 18, 2013. <a
href="http://jquery.com/download/">jQuery 2.0 is now available for download</a> but don&#8217;t rush off and install it just yet &#8212; there is one major change&hellip;</p><h2>No More Support for IE6/7/8</h2><p><em>(or IE9 and IE10 if they&#8217;re used in &#8220;Compatibility View&#8221; mode).</em></p><p>I still think it&#8217;s a little premature to abandon IE8 but the team couldn&#8217;t wait any longer. jQuery 2.0 removes all the legacy IE code for node selection, DOM manipulation, event handling and Ajax.</p><p>This has resulted in a 11% file size reduction from 32,819 bytes to 29,123 bytes. That&#8217;s 3.6Kb for the gzipped minified version &#8212; it&#8217;s unlikely to be noticeable even on a dial-up connection. Admittedly, the team hoped to save more but discovered that Android/Webkit 2.x browsers still required many workarounds.</p><p>If you need to support IE8 and below, stick with jQuery 1.9.x for now. You could conditionally load version 2.0 in all other browsers, but:</p><ol><li>conditional loading will offset any gains in file size reduction and processing, and</li><li>you may encounter differences between the two jQuery branches. The team has pledged to minimize API divergence but there will almost certainly be issues. jQuery 1.10 will address known compatibility problems.</li></ol><h2>Custom Builds</h2><p>The custom build feature has been refined in version 2.0 so you can exclude any of 12 unused modules and shrink jQuery below 10Kb. The modules which can be omitted are:</p><ul><li><strong>ajax</strong>: all Ajax functionality, transports, and event shorthands.</li><li><strong>ajax/xhr</strong>: XMLHTTPRequest Ajax transport only.</li><li><strong>ajax/script</strong>: <code>&lt;script&gt;</code> Ajax transport only.</li><li><strong>ajax/jsonp</strong>: JSONP Ajax transport only (depends on ajax/script).</li><li><strong>css</strong>: The <code>.css()</code> method plus non-animated <code>.show()</code>, <code>.hide()</code> and <code>.toggle()</code>.</li><li><strong>deprecated</strong>: deprecated methods (currently <code>.andSelf()</code> only).</li><li><strong>dimensions</strong>: <code>.width()</code> and <code>.height()</code> methods, including <code>inner-</code> and <code>outer-</code> variations.</li><li><strong>effects</strong>: the <code>.animate()</code> method and its shorthands such as <code>.slideUp()</code>.</li><li><strong>event-alias</strong>: event attaching/triggering shorthands such as <code>.click()</code>.</li><li><strong>offset</strong>: the <code>.offset()</code>, <code>.position()</code>, <code>.offsetParent()</code>, <code>.scrollLeft()</code>, and <code>.scrollTop()</code> methods.</li><li><strong>wrap</strong>: the <code>.wrap()</code>, <code>.wrapAll()</code>, <code>.wrapInner()</code>, and <code>.unwrap()</code> methods.</li><li><strong>sizzle</strong>: the Sizzle selector engine. When this module is excluded, it is replaced by a rudimentary selector engine based on the native <code>querySelectorAll</code> method which does not support some advanced jQuery selectors.</li></ul><p>For example, if you are using CSS3 animations rather than jQuery methods, you could omit the <strong>effects</strong> module and possibly <strong>dimensions</strong>, <strong>offset</strong>, <strong>wrap</strong> and <strong>sizzle</strong>.</p><p>Creating your own custom build is not for the faint-hearted and you&#8217;ll require some knowledge of Git, Node.js and Grunt. <a
href="https://github.com/jquery/jquery/#readme">Full instructions are available</a> but, longer term, I hope the team can implement an online build process similar to <a
href="http://modernizr.com/download/">Modernizr</a>.</p><h2>Should I Upgrade?</h2><p>It&#8217;s important to understand that jQuery 2.0 has API parity with jQuery 1.9. There are a small number of bug fixes but no new features.</p><p>However, if you&#8217;re one of those lucky developers who has dropped support for IE6/7/8, <a
href="http://jquery.com/download/">grab jQuery 2.0</a> and don&#8217;t look back.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/whats-new-in-jquery-2-0/feed/</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>RIP HTML5 &lt;hgroup&gt; Element</title><link>http://www.sitepoint.com/html5-hgroup-element-dropped/</link> <comments>http://www.sitepoint.com/html5-hgroup-element-dropped/#comments</comments> <pubDate>Fri, 19 Apr 2013 12:31:20 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Browsers]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[News]]></category> <category><![CDATA[hgroup]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[w3c]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65203</guid> <description><![CDATA[The hgroup element is being removed from the HTML5 specification. Craig discusses the reasons you never used it...]]></description> <content:encoded><![CDATA[<p></p><p>Do you use the <code>hgroup</code> element in your mark-up? It&#8217;s probably best not to &#8212; the tag is being dropped from the HTML5 specification.</p><p>We normally think of HTML5 specifications receiving additional features, such as the <a
href="/html5-main-element/">new &lt;main&gt; element</a>. However, elements can be removed if they offer no compelling benefits.</p><p><code>hgroup</code> represented the heading of a section and normally contained two or more <code>h1</code> to <code>h6</code> child elements, e.g.</p><pre><code>&lt;hgroup&gt;
&lt;h1&gt;My Main Heading&lt;/h1&gt;
&lt;h2&gt;A sub-heading&lt;/h2&gt;
&lt;/hgroup&gt;</code></pre><p>Did you ever use it? I can recall one occasion and, even then, it was primarily for use as a CSS hook and could have easily been a <code>div</code> or <code>section</code>. The request to remove it came from Steve Faulkner:</p><ul><li><code>hgroup</code> does not convey clearly that a particular heading is a sub-heading</li><li>heading semantics are still exposed regardless of an outer <code>hgroup</code></li><li>the specification stated all <code>hgroup</code> headings must be concatenated for accessibility, i.e. the title would become &#8220;My Main Heading A sub-heading&#8221;</li><li><code>hgroup</code> did not have at least two reasonably complete interoperable implementations, i.e. it was a <code>div</code> by another name</li><li>few sites implement the <code>hgroup</code> element</li></ul><p>No reasonable use-cases were forthcoming so <code>hgroup</code> will ultimately disappear from the HTML5 specification. There is a possibility it will morph into another element offering better semantics, but those debates are yet to occur.</p><h2>No … I Use hgroup On Every Page!</h2><p>The removal of <code>hgroup</code> will make little difference to your daily coding efforts. Most browsers already support it and, even in a new applications, <code>hgroup</code> would be treated the same as any unknown tag. That said, it&#8217;s probably best to avoid using <code>hgroup</code> in new projects since HTML validators will eventually report an error.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/html5-hgroup-element-dropped/feed/</wfw:commentRss> <slash:comments>19</slash:comments> </item> <item><title>Win Free Tickets to Web Directions Code</title><link>http://www.sitepoint.com/win-free-tickets-to-web-directions-code-2013/</link> <comments>http://www.sitepoint.com/win-free-tickets-to-web-directions-code-2013/#comments</comments> <pubDate>Thu, 18 Apr 2013 15:56:58 +0000</pubDate> <dc:creator>Ricky Onsman</dc:creator> <category><![CDATA[Community]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[web directions]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65500</guid> <description><![CDATA[If you're in Melbourne, Australia, May 2-3, and wishing you could go to Web Directions Code, we have not one but TWO $999 tickets to give away.]]></description> <content:encoded><![CDATA[<p></p><p>JavaScript, HTML5, CSS3: it’s a changing landscape. Web Directions brings together practitioners and big thinkers at the leading edge to educate and inspire at a “festival of code”.</p><p>SitePoint is partnering with <a
href="http://code13.webdirections.org/" target="_blank">Web Directions Code 2013</a> in Melbourne, Australia, and we have two free tickets worth $999 each to give away.</p><p>To enter, all you need to do is let us know why would you like to be at this year&#8217;s conference. We will pick the two most creative answers on Wednesday 24th April.</p><h2>Sorry, this promotion is now closed. Winners will be contacted directly.</h2><p>You can still buy tickets to <a
href="http://code13.webdirections.org/" target="_blank">Web Directions Code 2013</a>. Use SITEPOINT as a voucher code to take $150 off the full price.</p><h2 style="clear: both; display:block; padding-top: 30px;">Fine print:</h2><ul><li>Two conference tickets to be given away to the two most creative answers.</li><li>Conference to be held in Melbourne, Australia, 2-3 May, no transport or accommodation included.</li><li>Promotion ends 23th April 2013.</li></ul><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/win-free-tickets-to-web-directions-code-2013/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached
Database Caching 40/73 queries in 0.120 seconds using memcached
Object Caching 1961/2152 objects using memcached

Served from: www.sitepoint.com @ 2013-05-13 14:02:46 --