<?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; CSS</title> <atom:link href="http://www.sitepoint.com/category/css/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>CSS Architectures: Refactor Your CSS</title><link>http://www.sitepoint.com/css-architectures-refactor-your-css/</link> <comments>http://www.sitepoint.com/css-architectures-refactor-your-css/#comments</comments> <pubDate>Fri, 03 May 2013 12:44:33 +0000</pubDate> <dc:creator>Denise Jacobs</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[Programming]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65996</guid> <description><![CDATA[Denise Jacobs continues her series, this time offering a methodical way of debloatifying redundant CSS code: refactoring.]]></description> <content:encoded><![CDATA[<p></p><p>The top scalable and modular approaches I covered <a
href="http://www.sitepoint.com/css-architectures-scalable-and-modular-approaches/">in the previous article</a> in my CSS Architectures series all have pieces of brilliance that can help you change the way you think about and structure your CSS. They also overlap in many areas, which indicates which aspects of the process of improving your CSS are truly critical. Although you could follow any single approach while constructing a new site to great success, the fact of the matter is that what most of us are doing is trying to make sense of existing CSS run amok.</p><p>So, while the approaches I described are great on their own, what we really need is a way to combine the superpowers from them all to combat the evil of crazy code – a sort of “<a
href="http://www.youtube.com/watch?v=ANCjrzSJOsU">Justice</a> <a
href="http://www.youtube.com/watch?v=FLOwCWDlVTg">League</a>” of scalable and modular techniques. Furthermore, just as Rome wasn’t built in a day, it’s a fool’s errand to try to correct in one fell swoop thousands of lines of code that lack rhyme or reason. Thus, it’s a good idea to pass over the code in focused waves through a phased approach.<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>Giving CSS Refactoring a Good Name</h2><p>Last year, I had a project for a client where I was retained to do exactly that. After studying DRY CSS, OOCSS, SMACSS, and CSSG, I endeavored to distill them into their essential practices. In a moment of insight, I realized that all these approaches boiled down to the well-known adage “measure twice, cut once.” Of course! They all encourage looking at patterns, creating portable styles and modules that can be reused and not adding superfluous and redundant selectors or styles.</p><p>Additionally, my client had a lot of code and wanted to have flexibility in terms of the amount of changes that could be made to the CSS.  So, I developed a cohesive, phased plan of attack to reduce the number of lines in my client’s CSS. By the end, all of the practices and techniques for all four scalable CSS frameworks were incorporated, and the process I developed is very effective at reducing lines of CSS.</p><p>Once I created the process, I had to figure out what to name it. Taking “measure twice, cut once” as my base, I added CSS to it and this is what I got:</p><p>measure twice, cut once css → mtco css → meta coa css → MetaCoax!</p><p>So, in this article, I’ll share with you my MetaCoax CSS <a
href="http://aka.ms/CodeRefactoring">refactoring</a> process, designed to “de-bloatify” thousands of lines of redundant CSS—improving the readability, simplicity and extensibility of the CSS while keeping the visible design and functionality of the site the same. (<a
href="http://www.slideshare.net/denisejacobs/scalable-and-modular-css-ftw">Check out the slides</a> from my recent presentation on de-bloatifying CSS.)</p><p>To get yourself ready to refactor CSS, here are some suggestions. First, be conversant with specificity and the cascade – it will make a huge difference. I hope that in the first two articles in this series (<a
href="http://msdn.microsoft.com/en-us/magazine/jj983725.aspx">Part 1</a>, <a
href="http://msdn.microsoft.com/en-us/magazine/dn194516.aspx">Part 2</a>), I’ve driven home that making selectors and rules overly specific limits their reusability. When using descendent selectors especially, specificity can easily and quickly spiral out of control, and that’s precisely what we’re working to avoid. Second, remember inheritance rules: certain properties are inherited by child elements; thus, how these properties cascade down the DOM should always be kept in mind.</p><h2>The MetaCoax Process</h2><p>The MetaCoax process is a four-phased approach. Each phase builds on the previous one, and they all incorporate practices that decrease the amount of code, increase scalability and maintainability and, as an added bonus, lay the foundations for a <a
href="http://futurefriend.ly/">future-friendly</a> site. We’ll look at a detailed breakdown of each phase and the practices and techniques each encompasses. In this article, I’ll cover phases 1 and 2. Details about phases 3 and 4 will appear in the final article in the series.</p><p><b>Note:</b> An excellent tool to use while you’re going through the MetaCoax refactoring process is Nicole Sullivan’s <a
href="http://csslint.net/">CSS Lint</a>, which identifies additional places in the CSS to clean up and gives you ideas on how to do so.</p><h3>Phase 1: Shorten Selectors and Leverage and Layer Rulesets</h3><p>The first phase is focused on a minimum amount of work to improve a site’s CSS. These changes involve modifying the CSS but don’t touch the current HTML for a site’s pages. The goal is to make the stylesheet a little more lightweight and also easier to maintain and update with a small amount of time and effort. The method involves optimizing selectors while reducing redundancy with smarter reuse of rulesets. Even if you apply only the practices from this phase to your CSS, you’ll see an improvement in maintainability.</p><p>Here&#8217;s what we’re going to do:</p><ul><li>Shorten selectors chains<ul><li>Kill qualifiers</li><li>Drop descendants</li><li>Make the selector chain three or less</li></ul></li><li>Leverage and layer declarations<ul><li>Leverage the cascade by relying on inheritance</li><li>Review, revise and reduce !important properties</li><li>DRY (“don’t repeat yourself”) your rulesets</li></ul></li></ul><h3>Shorten Selector Chains</h3><p>To best optimize selectors, the goal is to use a shallow instead of a deep selector chain, making the chain as short as possible. This practice makes the code easier to work with, and the styles become more portable. Other advantages are reducing the chances of selector breakage, reducing location dependency, decreasing specificity and avoiding specificity wars by preventing overuse of !important declarations.</p><p>You have several ways in which you can shorten the selector chain, incorporating practices from all of the scalable architectures I outlined and further applying the “reduce, reuse, recycle” ethos. All of the practices are guaranteed to make the CSS code more forgiving. And isn’t that essentially the goal of updating our stylesheets?</p><h4>Drop Descendent Selectors</h4><p>The descendent selector (a b) is one of the most “expensive” combinatory selectors to use to target an element. Other expensive CSS selectors include the universal selector (*) and the child selector (a &gt; b). What makes them expensive? They are very general, and thus force the browser to look through more page elements to make a match. The longer the selector chain and the more checks required, the longer the browser takes to render the styles on the screen. When matching a descendent selector, the browser must find every instance of the key selector (which is the one on the far right) on the page, and then go up the ancestor tree to make the match.</p><p>While this might not be a problem for a stylesheet of a few hundred lines, it becomes more of an issue when the size of a document nears 10,000 lines or more. Even more important, in adopting a future-friendly and<a
href="http://aka.ms/MobileFirst"> mobile first</a> approach, long selector chains create a situation where small, less capable devices are forced to load and process unnecessarily large CSS documents.</p><p>Overdependence on descendent selectors is a vestige of the days of coding for Internet Explorer 6, as Internet Explorer 6 did not render the other CSS 2.1 combinator selectors at all. Because <a
href="http://aka.ms/ie6countdown">Internet Explorer 6 usage</a> is now almost nonexistent in the United States and other major markets, it’s completely safe to start employing selectors that are compatible with Internet Explorer 7 and Internet Explorer 8 and let go of the heavy use of descendent selectors once and for all. <b>Table 1</b> shows the selectors you can use with Internet Explorer 7. All versions of Internet Explorer since then support all the selectors shown here.</p><div
align="center"><table
width="287" border="1" cellspacing="0" cellpadding="0"><tbody><tr><td
valign="bottom" nowrap="nowrap" width="213"><b>Selector</b></td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center"><b>Internet Explorer 7</b></p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">Universal *</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">y</p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">Child: e &gt; f</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">y</p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">Attribute: e[attribute]</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">y</p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">:first-child</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">y</p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">:hover</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">y</p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">:active</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">y</p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">Sibling/Adjacent: e + f</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">n</p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">:before</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">n</p></td></tr><tr><td
valign="bottom" nowrap="nowrap" width="213">:after</td><td
valign="bottom" nowrap="nowrap" width="74"><p
align="center">n</p></td></tr></tbody></table></div><p><b>Table 1. CSS 2.1 Selectors Safe for Internet Explorer 7</b>.</p><p><b>Note:</b> Check the charts at <a
href="http://caniuse.com/">http://caniuse.com/</a> and <a
href="http://www.findmebyip.com/litmus/">http://www.findmebyip.com/litmus/</a> to determine the browser support of other CSS selectors.</p><p>Instead of the descendent selector, use the child selector. The child selector selects elements that are direct descendants of the parent element—that is, direct children in the first generation—as opposed to a grandchild or great-grandchild, which is what the descendent selector includes. <b>Figure 1</b> illustrates this selection process.</p><p><img
class="alignnone size-full wp-image-65997" alt="A Descendent Selector vs. a Child Selector" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure12.png" width="422" height="288" /></p><p><b>Figure 1.</b> <b>A Descendent Selector vs. a Child Selector</b></p><p>Although the child selector is still an “expensive” selector, it is more specific. This means that the browser won’t search as far down the inheritance chain to match the key selector. Thus, such a selector targets the element you need much better.</p><p>If you must use a descendent selector, eliminate all superfluous elements in it. For example:</p><p><code>.widget li a</code></p><p>would become</p><p><code>.widget a</code></p><p>The style will be applied whether the li is there or not.</p><h4>Kill Qualified Selectors</h4><p>Qualifying both #IDs and .classes with elements causes the browser to slow unnecessarily to search for the additional elements on the page to make a match with the selector. It is never necessary to qualify an ID. An ID has one of the highest specificity weights in CSS because it is unique to whatever page it is on, and it will always have a direct match on its own. Qualified selectors also cause the specificity of the selectors to be ridiculously high, necessitating the use of even more specific selectors and the use of !important to trump these super-specific rulesets.</p><p>Selectors such as</p><p><code>div#widget-nav div#widget-nav-slider</code></p><p>can be simplified to</p><p><code>#widget-nav #widget-nav-slider</code></p><p>and further whittled down to</p><p><code>#widget-nav-slider</code></p><p>Each provides the same outcome.</p><p>Dropping an element class qualifier in selectors lessens the specificity of the selector, which better enables you to correctly use the cascade to override the style if necessary. For example,</p><p><code>li.chapter</code></p><p>would ideally be changed to</p><p><code>.chapter</code></p><p>Even better, because it is more specific to the case of the &lt;li&gt;, you could consider changing the class on your &lt;li&gt; tag, and scoping the CSS to</p><p><code>.li-chapter</code> or <code>.list-chapter</code></p><h4>Make It Three or Less</h4><p>When working on optimizing selectors, institute a “three or less” rule: a combinator selector should have no more than three steps to get to the key selector. For example, take this doozy of a selector:</p><p><code>div#blog-footer div#col2.column div.bestright p.besttitle {margin-bottom: 4px;}</code></p><p>To have three steps or less to get to the key selector, make a change like this:</p><p><code>#col2.column .besttitle {border: 1px solid #eee;}</code></p><h3>Leverage and Layer Declarations</h3><p>The next order of business is to focus on the style declarations themselves. When refactoring bloated CSS down to something more manageable, it’s easy to focus primarily on the selectors and believe that the styles will work themselves out. However, paying attention to what style declarations you’re creating (see <b>Figure 2</b>) and where they go makes a difference as well in moving toward sleek CSS.</p><p><img
class="alignnone size-full wp-image-65998" alt="Anatomy of a CSS Ruleset" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure2.png" width="372" height="139" /></p><p><b>Figure 2.</b> <b>Anatomy of a CSS Ruleset</b></p><h4>Leverage Inheritance</h4><p>Often, we think we know something really well when actually we don’t, and inheritance in CSS may just be one of those areas. You might remember that <a
href="http://www.w3.org/wiki/Inheritance_and_cascade">inheritance is a fundamental concept of CSS</a>, but you might not remember exactly which properties naturally inherit and which do not. <b>Table 2</b> shows the most commonly used properties that get inherited by descendent elements, unless the descendent elements are styled otherwise. (<a
href="http://www.w3.org/TR/CSS21/propidx.html">There are other more obscure properties that are inherited as well</a>.)</p><table
border="0" cellspacing="0" cellpadding="0"><tbody><tr><td
valign="top" width="187"><code>color</code> <code>font-family</code> <code>font-family </code> <code>font-size   </code> <code>font-style</code> <code>font-variant      </code> <code>font-weight       </code> <code>font</code> <code>letter-spacing</code> <code>line-height </code></td><td
valign="top" width="210"><code>list-style-image </code> <code>list-style-position     </code> <code>list-style-type   </code> <code>list-style</code> <code>text-align</code> <code>text-indent       </code> <code>text-transform</code> <code>visibility</code> <code>white-space</code> <code>word-spacing</code></td></tr></tbody></table><p><b>Table 2. Common Elements Inherited by Descendent Elements</b></p><p>These properties are important to keep in mind when you’re looking for redundant styles to consolidate or eliminate. When you’re updating the stylesheet, properties that can be inherited should be placed in the CSS so that they are best utilized and not repeated. With proper placement of these properties, later redundant style declarations could be eliminated completely.</p><h4>Review, Revise and Reduce !important Properties</h4><p>If your CSS boasts an impressive number of !important declarations, then it’s time to reduce it. You should really use !important declarations only in certain instances. Chris Coyier of <a
href="http://aka.ms/CSStricks">CSS Tricks</a> recommends using them with <a
href="http://css-tricks.com/when-using-important-is-the-right-choice/">utility classes or in user stylesheets</a>. If you use them otherwise, you may end up being branded as <a
href="https://twitter.com/stefsull/status/70631020352913408">selfish and lazy</a>, and who wants that?!</p><p>How to cut down on !important? First, keep the specificity of selectors low by following the suggestions I made earlier.  Second, remember that, ideally, new styles should not undo previous rulesets but add to them.</p><p>Here’s what I mean: if you find yourself writing new styles to undo an earlier style (and then using !important to try to trump the style in the event of a specificity war), then you need to rethink the older style, distill it down to its necessities, and then create new styles that augment the original style instead of working to undo what’s already there. This is what I think of as “layering” style rulesets. This can also be referred to as “extending” (or “subclassing”) a style, which is part of creating modules in phase 2.</p><p>If you have a large number of !important properties for the same styles, I bet those properties could be turned into a portable style that could be applied to multiple elements, which I’ll also talk about when I describe phase 2.</p><h4>DRY Your Rulesets</h4><p>To cut down on large numbers of repeated styles in the CSS, a little DRY coding can help. While adopting the full DRY CSS approach may be a bit draconian, being aware of when you repeat the same ruleset and then getting your group on <a
href="http://msdn.microsoft.com/en-us/magazine/dn194516.aspx">is a great practice</a>.</p><h3>Phase 2: Restructure, Adjust, and Modularize</h3><p>The techniques in phase 2 are focused on doing a moderate to high level of work to improve a site’s CSS. The changes encompass altering both the CSS and the HTML of the pages, with the changes to the HTML most likely to involve renaming or reassigning class names. The goal is to give structure and organization to the stylesheet, through grouping styles by category rather than by pages, by removing archaic HTML, clearing the excess from the selectors and creating modules to increase code efficiency.</p><p>This phase will further eliminate redundancy, make the stylesheet more lightweight by improving selector accuracy and efficiency and also aid in maintenance. This level of improvement takes more time and effort than phase 1, but it includes the bulk of the work required to make your CSS better and is estimated to dramatically cut down the number of lines of CSS code.</p><p>Here is what we are going to do:</p><ul><li>Restructure to refactor<ul><li>Categorize CSS rules in the stylesheet</li><li>Restructure styles that rely on qualifiers high in the DOM</li><li>Use class names as key selector</li></ul></li><li>Begin instituting modules<ul><li>Extend module substyles with a double hyphen (&#8211;)</li></ul></li><li>Create portable helper styles<ul><li>Surgical layout helpers</li><li>Typographical styles</li></ul></li><li>Adjust the HTML<ul><li>Eliminate inline styles</li><li>Decrease use of &lt;span&gt; for better semantics</li></ul></li></ul><h3>Restructure to Refactor</h3><p>Let’s not forget that restructuring the CSS is our main objective. These practices start the process of moving away from thinking about and creating styles that are based on and specific to page components and page hierarchy, and moving toward thinking of styles in a portable, reusable and modular manner.</p><h4>Categorize CSS Rules in the Stylesheet</h4><p>In <a
href="http://msdn.microsoft.com/en-us/magazine/jj983725.aspx">the first article in this series</a>, I suggested creating a table of contents to make finding the sections of the styles in your CSS easier. In this phase of CSS refactoring, I recommend stepping up that process several notches by transforming these sections to the types of styles they describe, following the <a
href="http://msdn.microsoft.com/en-us/magazine/dn194516.aspx">SMACSS categories</a>. These categories are:</p><ul><li><b>Base</b> The default styles, usually single element selectors that will cascade through the whole document.</li><li><b>Layout</b> The styles of the page sections.</li><li><b>Module</b> The reusable styles of the various modules of the site: callouts, sidebar sections, product, media, slideshows, lists, and so on.</li><li><b>State </b>The styles that describe how a module or layout looks in a particular state.</li><li><b>Theme</b> The styles that describe how modules or layouts might look.</li></ul><p>So now, your table of contents and document sections will look like this:</p><pre><code>/* Table of Contents</code>
<code>- Base</code>
<code>- Layout</code>
<code>- Module</code>
<code>- State</code>
<code>- Theme</code>
<code>*/</code>
<code>…</code>
<code>(later in the document…)</code>
<code>/* =Layout */ (etc.)</code></pre><p>This reorganization of the stylesheet helps lay the foundation for the rest of the phase 2 practices and is a part of phase 3 as well.</p><h4>Restructure Styles That Rely on Qualifiers High in the DOM</h4><p>This recommendation is one of most important in this whole article: to completely eliminate page specific styles—that is, styles that are based on adding a class to the body element to signify a different page. A style such as this forces the browser to check all the way up the DOM chain to the &lt;body&gt; tag.   Here’s an example:</p><pre><code>body.donations.events div#footer-columns div#col1 div.staff span.slug {</code>
<code>display: block;</code>
<code>margin: 3px 0 0 0;</code>
<code>}</code></pre><p>This practice is the root of long selector chains, super-high specificity of selectors and the need to use !important to override styles higher up the cascade, as in the following example:</p><pre><code>body.video div#lowercontent div.children.videoitem.hover a.title { background: #bc5b29; </code>
<code>color: #fff !important; </code>
<code>text-decoration: none; </code>
<code>}</code></pre><p>In other words, it’s bad. <a
href="http://www.youtube.com/watch?v=E4_tOiLB_Ko">Mmkaay</a>?</p><p>To fix it, you need to follow all of the previous suggestions, such as three or less, kill the qualifiers and reduce specificity. What you could end up with is something more like this:</p><pre><code>.donations-slug {</code>
<code>display: block;</code>
<code>margin: 3px 0 0 0;</code>
<code>}</code></pre><h4>Use Class Names as Key Selector</h4><p>Because IDs are highly specific, you should avoid using them whenever possible, as they cannot be reused as classes can. However, in creating classes you want to keep your class names semantic yet portable. The goal is to make a selector as direct as possible. By doing this, you avoid specificity problems and can then even combine styles to layer them as suggested earlier.</p><p>From SMACSS, you should instill the practice that when you create selectors, the key selector should be a .class instead of a tag name or an #id.  Always keep in mind that the far-right key selector is the most important one. If a selector can be as specific to the element in question as possible, then you’ve hit the jackpot. This way, the styles are targeted more directly because the browser matches only the exact elements.</p><p>Review all places where child selectors are used, and replace them with specific classes when possible. This also avoids having the key selector in the child combinator as an element, which is also discouraged.</p><p>For example, instead of doing this:</p><p><code>#toc &gt; LI &gt; A</code></p><p>it’s better to create a class, as shown next, and then add it to the appropriate elements.</p><p><code>.toc-anchor</code><code> </code></p><h3>Begin Instituting Modules</h3><p>Nothing epitomizes the “measure twice, cut once” adage in the scalable CSS approaches as well as modules, which are the heart and soul of all of them. Modules are components of code that can be abstracted from the design patterns—for example, frequent instances of lists of items with images that float either to the left or right or underneath; these can be abstracted into a module with a base set of styles that every module would share. Then the module can be extended (or skinned) with changes in text, background, font color, borders, floats, and so on, but the structure remains the same.</p><p>The best thing about modules is that they are portable, meaning that they are not location dependent. Abstracting a design pattern into a code module means that you can put in anywhere in any page and it will show up the same way, without you having to reinvent the wheel style-wise. Now <i>that’s</i> what CSS was made for, right?! In addition to my earlier suggestions, modularizing your CSS is one of the best ways to dramatically decrease the amount of code.</p><p>OOCSS provides a great way to think about <a
href="http://aka.ms/ModulesContainerObjects">how to structure</a> and <a
href="http://aka.ms/ModulesBlockStructures">skin a module</a> and also about <a
href="https://github.com/stubbornella/oocss/wiki/_pages">what can be made into a module</a>. SMACSS provides <a
href="http://aka.ms/ModuleRules">clear guidelines on how to name modules and extend them</a>.</p><h4>Extend Substyles with  &#8211;</h4><p>Although SMACSS gives great guidance for thinking about extending modules, I prefer the technique from CSS for Grownups of extending substyles with &#8211;. This makes a lot of sense to me because it is a visual indication that the new style is based on the previous one but is taking it further.</p><p>Here’s an example:</p><pre>#go, #pmgo{
    width: 29px;
    height: 29px;
    margin: 4px 0 0 4px;
    padding: 0;
    border: 0;
    font-size: 0;
    display: block;
    line-height: 0;
    text-indent: -9999px !important;
    background: transparent url("/images/go.jpg") 0 0 no-repeat;
    cursor: pointer; /* hand-shaped cursor */
    x-cursor: hand; /* for IE 5.x */
}
#pmgo{
    margin: 2px 0 0 3px;
    background: transparent url("/images/go.jpg") no-repeat center top;
}</pre><p>This code could be modified and changed into something more like this:</p><pre>.button-search{
    width: 29px;
    height: 29px;
    margin: 4px 0 0 4px;
    padding: 0;
    border: 0;
    font-size: 0;
    display: block;
    line-height: 0;
    text-indent: -9999px !important;
    background: transparent url("/images/go.jpg") 0 0 no-repeat;
    cursor: pointer; /* hand-shaped cursor */
    x-cursor: hand; /* for IE 5.x */
}
.button-search--pm{
margin: 2px 0 0 3px;
background: transparent url("/images/go.jpg") no-repeat center top;
}</pre><h3>Create Portable Helper Styles</h3><p>Along with the process of modularization, portable styles are another handy tool to have in your arsenal. Here are some examples from CSS for Grownups.</p><h4>Surgical Layout Helpers</h4><p>By CSS for Grownups’ standards, there’s no shame in having a little extra layout help. While a grid takes care of a lot of issues, these styles may give elements a little nudge when needed (especially in terms of vertical spacing), while eliminating lines of code.</p><pre><code>.margin-top {margin-top: 5px;}</code>
<code>.margin-bottom {margin-bottom: .5em;}</code></pre><p>Although in most cases we strive to keep names semantic when creating classes, in this instance descriptive names are fine.</p><h4>Typographical Styles</h4><p>Typographical styles are perfect if you find that much of your CSS is devoted to changing the font face, size and/or line height. Both OOCSS and CSS for Grownups suggest dedicated typographical styles that are not tied to the element, such as the following:</p><pre><code>.h-slug {font-size: .8em;}</code>
<code>.h-title {font-size: 1.5em;}</code>
<code>.h-author {font-size: 1em;}</code></pre><p>A great exercise is to search for the properties font, font-size, font-face, and h1 through h6 and marvel at the sheer magnitude of the instances of these properties. Once you’ve had a good laugh, figure out which styles apply to what, which sizes are important, and then start making some portable typographical styles.</p><h3>Adjust the HTML</h3><p>While the practices in phases 1 and 2 that we’ve covered so far offer miracles in terms of CSS cleanup, we can’t forget about the page markup. Most likely, as suggested by Andy Hume in CSS for Grownups, you’ll need to make changes to the HTML beyond adding new class names.</p><h4>Decrease Use of &lt;span&gt; for Better Semantics</h4><p>Do you have a rampant use of the &lt;span&gt; tag where a more semantic tag would be much more appropriate? Remember, the &lt;span&gt; tag is really for inline elements, not block-level elements, as stated by the W3C (<a
href="http://www.w3.org/TR/html401/struct/global.html#h-7.5.4">http://www.w3.org/TR/html401/struct/global.html#h-7.5.4</a>), so using &lt;span&gt; for headers and other elements intended to be block-level is technically incorrect.</p><p>Here, for example, the spans should really be paragraphs or header tags that indicate where this content fits in the document’s hierarchy. Either of those other elements could have provided a base for the class hooks.</p><pre><code>&lt;li&gt;</code>
<code>&lt;a href="/learning/hillman" title=""&gt;</code>
<code>&lt;img src="/images/brenda-hillman.jpg" alt="Air in the Epic" /&gt;</code>
<code>&lt;/a&gt;</code>
<code>&lt;span&gt;Brenda Hillman Essays&lt;/span&gt;</code>
<code>&lt;span&gt;&lt;a href="/learning/hillman" title="Air in the Epic" class="title"&gt;Air in the Epic&lt;/a&gt;&lt;/span&gt;</code>
<code>&lt;span&gt;Brenda Hillman&lt;/span&gt;</code>
<code>&lt;/li&gt;</code></pre><p>The following version of this code would be an improvement from a semantics standpoint:</p><pre><code>&lt;li&gt;</code>
<code>&lt;a href="/learning/hillman" title=""&gt;</code>
<code>&lt;img src="/images/brenda-hillman.jpg" alt="Air in the Epic" /&gt;</code>
<code>&lt;/a&gt;</code>
<code>&lt;p&gt;Brenda Hillman Essays &lt;/p&gt;</code>
<code>&lt;h3&gt;&lt;a href="/learning/hillman" title="Air in the Epic" class="title"&gt;Air in the Epic&lt;/a&gt;&lt;/h3&gt;</code>
<code>&lt;p&gt;Brenda Hillman&lt;/p&gt;</code>
<code>&lt;/li&gt;</code></pre><h4>Eliminate Inline Styles</h4><p>Finally, you need to get rid of inline styles. In this day and age, inline styles should rarely if ever be used. They are much too closely tied to the HTML and are akin to <a
href="http://csszengarden.com/?cssfile=http://www.brucelawson.co.uk/zen/sample.css">the days of yore when &lt;font&gt; tags were running rampant</a>. If you use inline styles to override specificity, then making the changes suggested in this article should already help you avoid specificity wars, effectively eliminating the need for inline styles.</p><p>For example, this inline style:</p><p><code>&lt;span class="text-indent: 1em"&gt;Skittles are tasty&lt;/span&gt;</code></p><p>could easily be turned into its own class that can be applied throughout the document, like so:</p><p><code>.indent {text-indent: 1em:}</code></p><p>Your mission, <a
href="http://www.hark.com/clips/ytqshsltzw-your-mission-jim-should-you-choose-to-accept-it">should you choose to accept it</a>, is to find all the instances of inline styles and see where you can make those styles portable helpers. The property you’re using could easily be made into a portable style that can be reused on the other instances of text.</p><h2>Try It, It Will Be Good for You!</h2><p>At the <a
href="http://oredev.org/">Øredev</a> Web development conference in Malmö, Sweden, I had the pleasure of seeing the brilliant <a
href="http://kytrinyx.com/">Katrina Owen</a> present “<a
href="https://vimeo.com/53154356">Therapeutic Refactoring</a>.” She suggested that when faced with a deadline, she turns to refactoring horrible code to help her gain a sense of control and rightness in the world.</p><p>You can approach restructuring your CSS for the better the same way. By healing what ails your CSS, you can gain a sense of calm and power, while beginning to make the world of your site’s stylesheets a better place, one line of code at a time.</p><p>Stick with me, though, because we aren’t quite finished. We have two more phases to cover in the MetaCoax process that will fully oust the evil from your CSS once and for all, and will also enable you to leave a legacy of goodness behind for all of the front-end devs that come after you.</p><div><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><h2>Links for Further Reading</h2><ul><li><a
href="https://github.com/stubbornella/csslint/wiki/_pages">CSS Lint Pages</a></li><li><a
href="https://vimeo.com/44773888">Breaking Good Habits</a> – Harry Roberts’ talk at Front Trends Conference 2012</li><li><a
href="https://speakerdeck.com/csswizardry/big-css-1">Big CSS</a> – Another great Harry Roberts presentation</li></ul><p><b>&#8212;&#8211;</b></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/css-architectures-refactor-your-css/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <series:name><![CDATA[CSS Architectures]]></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>CSS Architectures: Scalable and Modular Approaches</title><link>http://www.sitepoint.com/css-architectures-scalable-and-modular-approaches/</link> <comments>http://www.sitepoint.com/css-architectures-scalable-and-modular-approaches/#comments</comments> <pubDate>Wed, 01 May 2013 10:29:51 +0000</pubDate> <dc:creator>Denise Jacobs</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[Programming]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65966</guid> <description><![CDATA[Denise Jacobs continues her exploration of where CSS is headed, in this case putting the focus on keeping code manageable by keeping it scalable and modular.]]></description> <content:encoded><![CDATA[<p></p><p>As the online industry matures, so do approaches to dealing with code for large Web sites. <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl01" href="http://msdn.microsoft.com/en-us/magazine/jj983725.aspx">Cleaner CSS</a> is a great starting point, but front-end developers can elevate a site’s stylesheet to another level by applying methodologies that are part of increasingly popular scalable CSS architectures.</p><p>By using an approach in its entirety or by applying selected tenets and practices from them all, you can say good-bye to problems that typically plague the CSS for large sites, such as verbose and difficult to read code that’s painful to maintain and update and the redundancy that creates code bloat.</p><h2>Diagnosing the Origins of Bloated CSS</h2><p>If you recognize any of the following symptoms or ailments, making your stylesheet modular and more scalable is just what the doctor ordered. To get a proper handle on just how bad things are, search for certain properties and see what the numbers tell you. In Nicole Sullivan’s presentation, the <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl02" href="http://www.stubbornella.org/content/2010/07/01/top-5-mistakes-of-massive-css/">Top 5 Mistakes of Massive CSS</a>, she provides a rubric to diagnose the roots of an overabundance of several key properties:<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><ul><li>A large number of floats means there is an ineffective or nonexistent grid.</li><li>A large number of margins means you need a <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl03" href="http://meyerweb.com/eric/tools/css/reset/">reset.css</a> (or <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl04" href="http://necolas.github.com/normalize.css/">normalize.css</a>).</li><li>A large number of padding means that the design parameters aren’t explicit and thus multiple developers have tweaked details a lot.</li><li>A large number of font-size means that the cascade is not being leveraged. Headings are probably hidden within the rule sets with font-size as well.</li><li>A large number of !important means that this property is being used to override specificity and, again, that the cascade is not being leveraged.</li></ul><p>Any of this sound familiar? It’s okay, you’re in good hands, because now that you’ve diagnosed the origins of your CSS bloat, we can talk about some sure-fire cures.</p><h2>Scalable and Modular Approaches: The Essentials</h2><p>The main concepts of the different scalable approaches can be boiled down to two core practices:</p><h3>1. Reduce, Reuse and Recycle</h3><p><em>Reducing</em> means writing the shortest chain of elements possible in selectors, and dropping element qualifiers, much of which I discussed in the <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl05" href="http://www.sitepoint.com/css-architectures-new-best-practices/">previous article</a>. Equally important is creating appropriate selectors by favoring classes over IDs, avoiding the use of elements, and using combinator selectors that more directly target the element you need on the page.</p><p><em>Reusing</em> involves creating generic classes instead of overly specific ones, and combining classes to create different visual outcomes.</p><p><em>Recycling</em> involves better leveraging the cascade to cut down on redundant style declarations, modularizing page components to use throughout the site with minimum code and extending modules through subclassing.</p><h3>2. Organize, Structure and Inform</h3><p>Providing good, well-organized information is critical for clarity and understanding. The practices listed in the <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl06" href="http://www.sitepoint.com/css-architectures-new-best-practices/">first article</a>, like providing developer information in the stylesheet and creating a structure in terms of the document itself (by categorizing styles in the document), play a part in the scalable approaches. However, developers can add even more structure by breaking the style categories into multiple documents, indicating structure and meaning through a naming convention for reusable classes and establishing page structure with grids. Web site style guides are the final component for making sure the team is well informed about styles, structure and nomenclature.</p><h2>An Overview of Scalable and Modular Approaches</h2><p>Now that I’ve introduced the key concepts, let’s take a look at specific practices that support these concepts through an overview of the best-known and most popular approaches to dealing with large CSS projects. The approaches I’ll cover are DRY (Don’t Repeat Yourself) CSS, Object-Oriented CSS (OOCSS), Scalable and Modular Architecture for CSS (SMACSS), and CSS for Grownups.</p><h3 id="dry">DRY CSS</h3><p>The ease of learning and applying CSS is mitigated by the language’s lack of logic. Unlike programming languages that have reusable components like variables and functions, CSS almost encourages flagrant reuse of selectors and property-value pairs. Indeed, even when redundant and bloated, CSS is perfectly functional.</p><p><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl07" href="http://www.slideshare.net/jeremyclarke/dry-css-a-dontrepeatyourself-methodology-for-creating-efficient-unified-and-scalable-stylesheets">DRY CSS</a> is based on taking the “<a
id="ctl00_MTContentSelector1_mainContentContainer_ctl08" href="http://programmer.97things.oreilly.com/wiki/index.php/Don%27t_Repeat_Yourself">don’t repeat yourself</a>” principle of software development very literally. That’s right: when coding CSS, the goal is never to repeat a property-value pair. Ever. I know it seems rather…ah, <em>intense</em>, but it can be done.</p><h4>Get Your Group On (So to Speak)</h4><p>The core of DRY CSS is grouping, which at its roots entails structure, organizing, reducing and recycling. <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl09" href="http://simianuprising.com/">Jeremy Clarke</a>, who devised DRY CSS, suggests creating groups of selectors with shared properties, rather than repeating property-value pairs for each selector separately, as is typical when writing CSS. While a group may have many selectors, each property-value pair is deﬁned only once.</p><p>The groups actually deﬁne shared properties. With DRY CSS, you have to relinquish the deeply ingrained habit of naming classes and IDs based on semantics, like .alert-box for example. Instead, groups use descriptive names based on their appearance or on their role in the design—like .rounded-corners—but then all selectors that share that property should be grouped with that style. While doing this takes away the possibility of mixing and matching, it does lessen the amount of your code.</p><p>How do you create a group? Start by naming the group based on its role in the design. Then use the name of the group as an ID at the top of the list and a class at the bottom. Then add the rest of the selectors that share properties above the descriptive class name that they share. Jeremy gives the example shown in <strong>Figure 1</strong> in his presentation “<a
id="ctl00_MTContentSelector1_mainContentContainer_ctl10" href="http://simianuprising.com/2012/03/07/video-of-my-dry-css-talk/">DRY CSS: A don’t-repeat-yourself methodology for creating efficient, unified and Scalable stylesheets</a>.”</p><p><img
class="alignnone size-full wp-image-65967" alt="DRY CSS groupings" src="http://www.sitepoint.com/wp-content/uploads/1/files/2013/05/figure1.png" width="550" height="662" /><br
/> <strong>Figure 1.</strong><strong>Example of DRY CSS groupings</strong></p><p>What about selectors that don’t immediately seem to be part of a group? Another goal in “drying out” your CSS is to make individual selectors as rare and sparse as possible, employing them only as exceptions. This means you need to perform a mental exercise when you’re coding. As you create a style declaration for a selector, always ask &#8220;Why isn’t this part of a group?&#8221;—and then figure out how to make it part of a group if you can.</p><p>Once you create groups, you need to think about organizing them. Clarke recommends using colors, text, shapes, structures and modules as categories, but he also encourages developers to create whatever categories they feel are best for a project.</p><h4>Benefits</h4><p>In his presentation on DRY CSS, Clarke lists many benefits to the approach. Here are some that I feel are most compelling:</p><ul><li>Decreases the size of CSS files. Clearly, this is the prime objective, and by using DRY CSS you more than achieve it.</li><li>Optimises elements and generalizes selectors. The occurrence of this increases as you see their interrelatedness and how they can be inherited.</li><li>Edits to a group affect all its members, which encourages consistency. You can see the members of a group change at the same time, which is a great advantage over making changes to a lot of individual selectors.</li><li>The HTML remains untouched. This is useful for sites with generated HTML that can’t easily be controlled, such as content management systems or blogging tools.</li><li>Encourages thinking through design elements/styles and design patterns and the consistency thereof. This promotes good design practices and uniform updates.</li></ul><p>Clarke also asserts that DRY CSS integrates with other scalable architectures, such as OOCSS and SMACSS.</p><h4>Successes</h4><p>Clarke had great success applying his approach to the <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl11" href="http://globalvoicesonline.org/">Global Voices site</a>, which also had to support localization into multiple languages. According to Clarke, in developing and applying DRY CSS, the site’s stylesheet went from roughly 4,500 lines to 2,400 lines. That’s an improvement that most front-end developers would welcome.</p><h3 id="oocss">OOCSS</h3><p><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl12" href="https://github.com/stubbornella/oocss/wiki">Object-Oriented CSS</a> starts with pattern recognition: determining what page elements are similarly structured and used frequently on the site. Once a pattern is identified, the design element can be made into a module. Then the module can be skinned for the different ways it shows up across the site.</p><p>OOCSS has two key principles. The first is to separate structure and presentation (or structure from “skin”), which means decoupling the structure of an element from its looks, and treating the looks like “skins.” This principle shouldn’t be too difficult to implement, as it’s similar to one of the foundational tenets of Web standards: the separation of presentation and content.</p><p>The second principle is to separate the container and the content, which means to use styles that are specific to an element and don’t depend on location. All too often, the common way to create CSS selectors is to attach an ID or a class to an element high in the DOM (like &lt;body&gt;), and then to create long-chain selectors to create variations on elements. This practice is responsible for most heinous CSS transgressions that lead to unwieldy and difficult to maintain stylesheets. Instead, in OOCSS, a container is modified by extending it, which effectively alters the container based on the content. In other words, you add an additional CSS class to provide for the differences in appearance only.</p><p>Sullivan <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl13" href="http://www.slideshare.net/stubbornella/the-fast-and-the-fabulous">breaks down the OOCSS approach into the following steps</a>:</p><ol><li>Determine the reusable elements sitewide, such as headings, lists (action list, external link list, product list, or feature list), module headers and footers, grids, buttons, rounded-corner boxes, tabs, carousels, toggle blocks.</li><li>Delineate between:<ul><li>Container and content</li><li>Structure and skin</li><li>Contour and background</li><li>Objects and mixins</li></ul></li><li>Mix and match container and content objects to achieve high-performance design.</li><li>For visual differences, skin the modules. Skins/themes are the module’s presentation—how it looks. The goal is to have very predictable skins, changing only values that can be easily calculated or measured.</li></ol><h3>Modules: The Building Blocks of a Site</h3><p>Much of the practice of OOCSS is built on reusable components. Sullivan likens these components to Legos and refers to them as <em>modules</em>. The goal for a module is that it relies neither on the DOM tree nor on specific element types. It should be flexible enough to adapt to different containers and be skinned easily.</p><p>Identifying, creating and employing a module is a very DRY aspect of OOCSS. By finding common elements and presentations and abstracting them into reusable code modules, front-end developers don’t repeat themselves and really do practice reducing, reusing and recycling.</p><p>An excellent example of a module that can take care of images with text in various forms and incarnations is Sullivan’s .media module. The .media module was developed to handle instances of images floating off to the side of text and related permutations. She gives <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl14" href="http://www.stubbornella.org/content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code/">this example of various forms that the media module can take</a>.</p><p>Here is the HTML that forms the structure of the media module:</p><pre>        &lt;!-- media --&gt;
	&lt;div class="media"&gt;
	  &lt;img class="fixedMedia" src="myimg.jpg" /&gt;
	&nbsp;
	  &lt;div class="text"&gt;
	...
	  &lt;/div&gt;
	&lt;/div&gt;</pre><p>The CSS of the initial module establishes the basis of the style, and any differences come from extending the styles and thus the appearance of the elements.</p><pre>         /* ====== media ====== */
	.media {margin:10px;}
	.media, .bd {overflow:hidden; _overflow:visible; zoom:1;}
	.media .img {float:left; margin-right: 10px;}
	.media .img img{display:block;}
	.media .imgExt{float:right; margin-left: 10px;}</pre><p>The media module is just the tip of the iceberg. Many more modules, including buttons, grids, carousels, and content, are on <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl17" href="https://github.com/stubbornella/oocss/">the OOCSS project on GitHub</a>.</p><h4>Benefits</h4><p>Adopting OOCSS, or at least elements of the system, saves many lines of code. Furthermore, it provides an approach that is easily sandboxed and can be used by everyone on the team.</p><h4>Successes</h4><p>One of the biggest and most famous sites that Sullivan has applied OOCSS to is <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl18" href="http://facebook.com/">Facebook</a>. According to the numbers given in her presentation <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl19" href="http://www.slideshare.net/stubbornella/css-bloat">CSS Bloat</a>, she and the Facebook team cut CSS bytes per page by 19 percent and HTML bytes per page by 44 percent. Just with headers alone, they reduced the number from 958 to 25, and reduced the site’s response time by half.</p><h3 id="SMACSS">SMACSS</h3><p>SMACSS (<a
id="ctl00_MTContentSelector1_mainContentContainer_ctl20" href="https://smacss.com/">https://smacss.com/</a>) is another approach to writing scalable and modular CSS for large-scale sites. According to Jonathan Snook, its creator, “<a
id="ctl00_MTContentSelector1_mainContentContainer_ctl21" href="http://smacss.com/book/prototyping">SMACSS is about identifying patterns in your design and codifying them.</a>” Sure, I’m biased, but we could take “codifying” patterns as simply another way of describing the core tenants (reduce, reuse, and recycle; organize and structure), could we not?</p><p>Snook has several practices for applying organization and structure to large CSS projects. The core of SMACSS is the categorization of CSS rules. Categories help design patterns become more obvious, thus enabling developers to make better definitions for and of these patterns.</p><p>The categories that Snook suggests are:</p><ul><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl22" href="http://smacss.com/book/type-base">Base</a>—These are defaults styles, usually for single element selectors.</li><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl23" href="http://smacss.com/book/type-layout">Layout</a>—Divides the page into sections, usually holding modules together.</li><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl24" href="http://smacss.com/book/type-module">Module</a>—Reusable, modular parts of the design: callouts, sidebar sections, product lists, and so on.</li><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl25" href="http://smacss.com/book/type-state">State</a>—Describes how the module or layout looks in a particular state, also in different page views.</li><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl26" href="http://smacss.com/book/type-theme">Theme</a>—Describes how modules or layouts might look.</li></ul><p>In small projects, these can all be in the same file. In larger projects, multiple files are recommended.</p><p>However, there is a trick with the categories, and it involves thinking about what the styles actually do and what part of the site, design and functionality they apply to. This forces developers to ask during the building process “How are we going to code things, and why are we going to code them this way?” Thus, implicit in the categories are guidelines on how the styles are used, which further helps to prevent mixing styles across categories.</p><h4>What’s in a Name?</h4><p>The next important part of SMACSS is naming style rules. Clear class names are one of the key ways for knowing the category that a style rule is part of and what it does in the grand scheme of the page.</p><p>To indicate the differences between layout, module and state styles, Snook suggests appending prefixes to the class names. For layout, for example, you would add l- or layout-, creating a class name like .l-aside or .layout-aside. To indicate classes that create a state change, use .is-<em>state</em>, such as .is-active or .is-collapsed.</p><p>When creating names for modules, which include navigation bars, carousels, dialogs, widgets, tables, icons and so on, use the name of the module itself. For instance, an example module would be called, appropriately, .example (note that it is a class and not an ID). A callout module would be called .callout. If you need to add a state to a module, you know what to do: add .is-<em>state</em>, so, a collapsed callout module would be .callout.is-collapsed.</p><p>What about extending (or subclassing) a class? Easy. Instead of using a module’s class name as part of a combinator selector (and thus creating specificity issues), create a new class name based on the original class. For example .pod is extended by creating .pod-callout, and then you apply both styles to the element. With the new style, both styles have the same specificity, and thus the new style rules can play well with the first one.</p><h4>Focus on Good, Clean Code, and Don’t Worry About “Classitis”</h4><p>Clearly, one of the objectives of SMACSS (much like OOCSS) is to create shallow instead of deep selectors with the fewest generations of elements, striving for the shallowest selector possible. If you follow the recommendations in the <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl27" href="http://www.sitepoint.com/css-architectures-new-best-practices/">first article</a> in this series, you’re well on your way. But a little reminder never hurts, so to help limit the number of elements in a selector, follow these rules:</p><ul><li>Avoid tag selectors for common elements unless they are completely predictable. Using a class is preferable, even if you think the element is going to stay predictable. This includes qualifying classes with elements.</li><li>Use class names as the right-most (key) selector.</li><li>Use child selectors (e &gt; f) instead of descendent selectors (e f).</li></ul><p>Another goal of creating shallow selectors is to eliminate issues with selector specificity. One of the primary ways to ensure that you won’t have any specificity wars within your CSS is to avoid IDs for selectors. Don’t dismiss IDs completely, however. In SMACSS, it’s okay to use them for layout sections and for JavaScript hooks.</p><p>Some of us have had the old-school best practice “Don’t use too many classes!” deeply ingrained into our front-end development psyche. However, when it comes to SMACSS (and most of the scalable CSS approaches), you’re better off adding classes to the elements in question and repeating the class in the HTML than you are creating and applying a bevy of overly specific styles, which is the true cause of classitis. You’ll find that using multiple well-named classes clarifies intent and increases the semantics of the elements in question.</p><h4>Benefits</h4><p>The benefit of SMACSS is the clarity that comes from being conscious about your coding from the very start. Categories help slash redundancy, and naming conventions greatly aid efficiency in quickly identifying style rules in the CSS.</p><h4>Successes</h4><p>Snook developed SMACSS from his experiences working on enormous Web projects, one of the most notable being the redesign of Yahoo mail. He has had great success applying his principles with large sites built by large teams.</p><h3 id="CSS_for_GrownUps">CSS for Grown Ups</h3><p>Andy Hume, the creator of <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl28" href="https://speakerdeck.com/u/andyhume/p/css-for-grown-ups-maturing-best-practises">CSS for Grown Ups</a>, jokingly refers to his system as “CSS for grumpy old people.” (You can watch a video <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl29" href="http://www.youtube.com/watch?v=ZpFdyfs03Ug">here</a>.) Like many of the creators of scalable approaches, Hume is concerned that our industry has become married to archaic, so-called best practices (most, ironically, created by developers who worked alone). He thinks that front-end developers have trudged unwittingly down a path that creates CSS that is feared and despised in most projects. This front-end code adheres to Web standards at ridiculous lengths to keep content and session separate, but it pays no mind to managing style and project complexity.</p><p>It’s clear that we need to optimize code for change. With CSS for Grown Ups, the goal is to style modules, not pages, and to go a step further by having a style module library that you can reuse.</p><h4>Layers, Like an Onion. Or Cakes (or Parfaits)<a
id="ctl00_MTContentSelector1_mainContentContainer_ctl30" href="http://www.hark.com/clips/psfbxymylw-theres-a-lot-more-to-ogres-than-people-think">*</a></h4><p>Much like the use of categories in SMACSS, CSS for Grown Ups describes styles being in “layers.” A style’s layer is related to:</p><ul><li>Document—From HTML code, element selectors.</li><li>Base styles—Applies to element selectors, typographical styles, colors.</li><li>Module styles—Lists, navigation, promo box, and so on.</li><li>Layout styles—Establishes the grid or columns and page layout.</li></ul><p>When creating selectors, be aware of whether they are document, base or module selectors, and make an effort to keep them all at the modular level. How will you know? If there is a tag as part of the selector, it will be a document style. However, if you create a class for it, you release it from the tag and make it a module style.</p><p>The goal is to try to avoid styles that are document-, base- or layout-related, and to shoot for ones that are module-related instead. Why? Let’s look at an example:</p><pre>         .promo-box h2 { ... }</pre><p>This selector is a module-level selector (.promo-box) combined with a document level selector (h2). This is all well and good at the outset, but what if somewhere down the line the structure of the HTML changes?</p><p>Instead, we should be shooting for the document and the module to be less tightly coupled so that the selector can be scaled in the future. This example does just that:</p><pre>         .promo-box-h { ... }</pre><p>In this instance, the style is not tied to a document’s element, and is thus far more flexible and portable, as it can be applied to anything, even elements that haven’t yet been invented in HTML.</p><h4>Free Your Selector Name, and the Rest Will Follow</h4><p>It should not surprise you that CSS for Grownups epitomizes the tenets of organize, structure and inform. According to Hume, styling with clear, informative class names is “like an API into your document—an API lets you style your document in the most simple and efficient manner.” Class names should be descriptive and should have meaning within the context of the site you’re working on. They should make sense to the members of the team working on the site so that you know which shared terms to reuse.</p><p>Like the other approaches, CSS for Grownups advocates creating and using modules. And like OOCSS and SMACSS approaches, the names of the modules should be descriptive and semantic and not tied to location or appearance:</p><pre>         .promo-box { ... }</pre><p>CSS for Grownups has a methodology for extending or substyling a module. Just use the module’s name, append it with two dashes (&#8211;), and add a clear, informative name for the extension, like so:</p><pre>         .promo-box--light { ... }</pre><p>The two dashes indicate that the style is an extension of the first and also that it is dependent on the first. Thus, it must come after the first style in the source order of the CSS in order to overwrite one or more style rules in the original.</p><h4>Use Helpers. Be a Sharer</h4><p>To handle presentation issues, Hume recommends using “surgical layout helpers,” which are standalone classes that provide either padding or margin. Here’s an example:</p><pre>         .margin-top {margin-top: 1em;}</pre><p>This would be the style you could add to whatever element needed it on the page, instead of wrapping that style into a component. Then these classes can be used on a case-by-case basis when a module needs to be spaced vertically on a page. Use these helper styles in your base stylesheet so that they can be used easily throughout the project.</p><p>Finally, writing online style guides is strongly recommended as a way to codify the naming and structure established and to disseminate this information to the team, making it available for those who will work on, add to and alter the site in the future. The style guide and corresponding module library needs be in code so that team members don’t have to reinvent the wheel to implement repeated visual styles.</p><h4>Benefits</h4><p>As Hume stated in his presentation at SXSW 2012, “Nobody is really smart enough to style web pages.” And because of this, he argues that we need certain constraints and parameters such as those supplied by CSS for Grownups. Constraints are good—they are a way to manage complexity. Hume developed CSS for Grownups as a way to manage complexity of CSS over large sites, over time and amongst teams of developers. Furthermore, CSS for Grownups creates what Hume calls a “design-meets-development touchpoint,” where the design language of an organization is turned into code, and clear collaboration from both teams results in a higher-quality product.</p><h4>Successes</h4><p>CSS for Grownups has roots in the vast amount of work that Hume did while he was at Clearleft, which has had many large clients, such as Channel 4, Amnesty International, and Mozilla. Now that he is at the <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl36" href="http://www.guardiannews.com/">Guardian</a>, he has successfully applied his system to create a framework for the front-end developers there.</p><h2>Progress, Not Perfection</h2><p>In his presentation <a
id="ctl00_MTContentSelector1_mainContentContainer_ctl37" href="https://vimeo.com/44773888">Breaking Good Habits</a>, Harry Roberts accurately states that “CSS is such a mess that even when you clean it up, it’s still a mess.” Our goal is to make our CSS better, not perfect. So look at each of these approaches with an open mind. Remember, the point is not to drive yourself crazy trying to get your CSS to fit perfectly within some methodology. Even if you adopt only some of the techniques, you still gain the benefits of fewer lines of code that will scale.</p><p>The scalable and modular approaches all have pieces of genius and brilliance to them, and are particularly great when you are starting to code a project from scratch. But what do you do when you have to deal with a mountain of existing CSS, whose sheer immensity strikes fear in your heart? The next article will share a process to coax order and sanity into the wildest of CSS beasts, so stay tuned!</p><h2>Links for Further Reading</h2><ul><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl38" href="http://gotofritz.net/blog/geekery/structuring-css/">Structuring CSS – State of Play in 2012</a></li><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl39" href="http://viget.com/inspire/css-squareoff">CSS Strategy Square-off</a></li><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl40" href="http://engineering.appfolio.com/2012/11/16/css-architecture/">CSS Architecture</a></li><li><a
id="ctl00_MTContentSelector1_mainContentContainer_ctl41" href="http://nimbleworks.co.uk/blog/css-id-selectors-never-say-never/">CSS ID Selectors: Never Say Never</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/css-architectures-scalable-and-modular-approaches/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <series:name><![CDATA[CSS Architectures]]></series:name> </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>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> <item><title>Responsive Web Design and Scrollbars: Is Chrome&#8217;s Implementation Better?</title><link>http://www.sitepoint.com/rwd-scrollbars-is-chrome-better/</link> <comments>http://www.sitepoint.com/rwd-scrollbars-is-chrome-better/#comments</comments> <pubDate>Thu, 18 Apr 2013 11:12:39 +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[Web standards]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[Responsive Design]]></category> <category><![CDATA[RWD]]></category> <category><![CDATA[standards]]></category> <category><![CDATA[w3c]]></category> <category><![CDATA[webkit]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65393</guid> <description><![CDATA[Webkit fires media queries differently to Firefox, Opera and IE. But is it more logical? Craig discusses the pros and a few slightly unsettling cons...]]></description> <content:encoded><![CDATA[<p></p><p>In my recent post, <a
href="/responsive-web-design-too-fragile/">Is Your Responsive Web Design too Fragile?</a>, I described an inconsistency between browsers when firing media query events:</p><ul><li>Chrome and Safari <strong>exclude</strong> the scrollbar dimensions.</li><li>Firefox, Opera and IE <strong>include</strong> the scrollbar dimensions.</li></ul><p>Assume we have a media query which detects a minimum width of 800px, e.g.</p><pre><code>@media (min-width: 800px) { ... }</code></pre><p>Chrome and Safari will include those styles when the body width is 800px or greater. However, if your OS shows vertical scrollbars with a width of 20px, other browsers would include the styles at 780px.</p><p>Let&#8217;s read the <a
href="http://www.w3.org/TR/css3-mediaqueries/#width">W3C media query specification for width</a>:</p><blockquote><p> The &#8216;width&#8217; media feature describes the width of the targeted display area of the output device. For continuous media, this is the width of the viewport (as described by CSS2, section 9.1.1 [CSS21]) including the size of a rendered scroll bar (if any).</p></blockquote><p>The Webkit engine is wrong. <em>But is it better?</em></p><p>At first glance, Chrome&#8217;s implementation seems logical but it&#8217;s important to understand that &#8216;width&#8217; refers to the viewport dimensions, i.e. the total area inside the browser window &#8212; <strong>not the page width</strong>. Using the assumptions above, Chrome&#8217;s viewport width is actually 820px (800px body + 20px scrollbar). In other browsers, the viewport width is 800px (780px body + 20px scrollbar).<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>Unfortunately, knowing the viewport width does not aid CSS development since you don&#8217;t know whether the scrollbar is visible or what its dimensions are. However, Chrome&#8217;s alternative is far worse since <em>the introduction or removal of a scrollbar can trigger a media query</em>. This is a little complex, so I&#8217;ll explain with an example:</p><ol><li>Assume you have a simple responsive site which shows a desktop layout at 800px or greater and a mobile site at 799px or less. Scrollbar widths are 20px.</li><li>Currently, the user has their browser window sized to an 810px viewport width. The height is large enough to show the current page (in desktop layout) without scrollbars.</li><li>You click through to another page. Here, the content is longer than the viewport height and a vertical scrollbar appears. This reduces the body width to 790px and Chrome instantly switches from the desktop to mobile layout. The user becomes confused and vows never to return to your site again.</li></ol><p>The situation is exacerbated if you have dynamically generated content. If a page currently fits in the viewport and you display a status message which increases the height, the resulting vertical scrollbar will switch the user from desktop to mobile layout (which could show the message in a different location). Once the status message is removed, the page will return to the desktop layout.</p><p>Firefox, Opera and IE do not exhibit this behavior because the viewport dimensions never change unless the user resizes their browser window. However, Chrome and Safari users could experience different layouts just because your site has slightly more content on one page than another. Nasty.</p><p>Admittedly, this is an edge case:</p><ul><li>Mobile browsers do not normally display permanent scrollbars so the problem is never apparent on those devices.</li><li>A desktop browser user would be unlucky to have window dimensions set at a point where layouts noticeably changed.</li><li>You could prevent Chrome switching layouts by ensuring the vertical scrollbar is always visible, i.e. <code>body { overflow-y: scroll; }</code>.</li></ul><p>That said, I consider it a valid reason for the Webkit and <a
href="/blink-rendering-engine-google-chrome/">Blink</a> teams to address the issue. I suspect media queries were implemented in Webkit before the syntax became a standard. However, we now have a W3C Recommendation; it makes sense to follow the finalized rules and provide a consistent experience for users and developers.</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/rwd-scrollbars-is-chrome-better/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Using CSS Grid Layout and Blend 5 to Build a Game</title><link>http://www.sitepoint.com/using-css-grid-layout-and-blend-5-to-build-a-game/</link> <comments>http://www.sitepoint.com/using-css-grid-layout-and-blend-5-to-build-a-game/#comments</comments> <pubDate>Wed, 17 Apr 2013 01:14:51 +0000</pubDate> <dc:creator>David Rousset</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[Gaming]]></category> <category><![CDATA[HTML]]></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=65462</guid> <description><![CDATA[David Rousset reveals a long-held Microsoft secret about what drove the development of CSS Grid Layout. Tetris is involved.]]></description> <content:encoded><![CDATA[<p></p><p>I’d like to share with you a mysterious internal secret kept within Microsoft for a long time. It’s the real story behind the concept of the <a
href="http://www.w3.org/TR/css3-grid-layout/">CSS Grid Layout</a> imagined by Microsoft for IE10 and Windows Store Apps.</p><p>Most of you probably think that this specification was designed to give developers a better layout engine for their websites and applications. But the original motivation was completely different. The very first aim was to be able to create a Tetris-like game in an easy way!</p><p>I’m sure you’re not convinced yet. That’s why I’m going to prove it to you using Blend 5 as a companion. Ok, let’s go!</p><p><strong><span
style="text-decoration: underline;">Pre-requisites:</span></strong> to follow this tutorial, you need first to:</p><ol><li>Download/buy &amp; install <strong>Windows 8 RTM</strong> on your machine: <a
href="http://msdn.microsoft.com/en-US/windows/apps/br229516.aspx">http://msdn.microsoft.com/en-US/windows/apps/br229516.aspx</a></li><li>Download &amp; install the free edition of <strong>Visual Studio 2012 Express RTM </strong>for Windows 8: <a
href="http://msdn.microsoft.com/en-US/windows/apps/br229516.aspx">http://msdn.microsoft.com/en-US/windows/apps/br229516.aspx</a> that includes Expression Blend 5 for Visual Studio or use the higher versions.</li></ol><h2>Step 1: discover the secret behind the CSS Grid Layout thanks to Blend 5</h2><p>Launch Expression Blend 5 and create a new HTML (Windows Store) project of type Blank App. Name it “<em><strong>TheRealCSSGridStory</strong></em>”:<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><img
alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2502.image_5F00_thumb_5F00_00459BE1.png" width="450" height="352" border="0" /></p><p>Replace:</p><pre class="code"><span style="color: blue;">&lt;</span><span style="color: maroon;">p</span><span style="color: blue;">&gt;</span>Content goes here<span style="color: blue;">&lt;/</span><span style="color: maroon;">p</span><span style="color: blue;">&gt;
</span></pre><p>With:</p><pre class="code"><span style="color: blue;">&lt;</span><span style="color: maroon;">div </span><span style="color: red;">class</span><span style="color: blue;">="mainGrid"&gt;
&lt;/</span><span style="color: maroon;">div</span><span style="color: blue;">&gt;
</span></pre><p>Let’s create a grid containing 10 columns and 20 lines, whatever the screen’s resolution, by using fraction units. For that, add this CSS rule:</p><pre class="code"><span style="color: maroon;">.mainGrid </span>{
    <span style="color: red;">display</span>: <span style="color: blue;">-ms-grid</span>;
    <span style="color: red;">width</span>: <span style="color: blue;">100%</span>;
    <span style="color: red;">height</span>: <span style="color: blue;">100%</span>;
    <span style="color: red;">-ms-grid-columns</span>: <span style="color: blue;">(1fr)[10]</span>;
    <span style="color: red;">-ms-grid-rows</span>: <span style="color: blue;">(1fr)[20]</span>;
}</pre><p>Select in the Live DOM the <em>&lt;div&gt; mainGrid</em> element and you should obtain this:</p><p><img
alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7220.image_5F00_thumb_5F00_1173967B.png" width="640" height="418" border="0" /></p><p>Let’s draw a shape inside this beautiful grid. Add this block of HTML inside the main grid:</p><pre class="code"><span style="color: blue;">&lt;</span><span style="color: maroon;">div </span><span style="color: red;">class</span><span style="color: blue;">="shape1"&gt;
&lt;/</span><span style="color: maroon;">div</span><span style="color: blue;">&gt;
</span></pre><p>And insert this CSS associated with it:</p><pre class="code"><span style="color: maroon;">.shape1 </span>{
    <span style="color: red;">-ms-grid-column</span>: <span style="color: blue;">4</span>;
    <span style="color: red;">-ms-grid-row</span>: <span style="color: blue;">3</span>;
    <span style="color: red;">-ms-grid-column-span</span>: <span style="color: blue;">3</span>;
    <span style="color: red;">-ms-grid-row-span</span>: <span style="color: blue;">2</span>;
    <span style="color: red;">background-color</span>: <span style="color: blue;">red</span>;
}</pre><p>You should now see that in Blend 5:</p><p><img
alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5556.image17_5F00_thumb_5F00_4CB47F2B.png" width="450" height="276" border="0" /></p><p>Cool, but nothing yet looks like to a Tetris gaming piece. Let’s work on that. Add these two DIVs inside the shape1:</p><pre class="code"><span style="color: blue;">&lt;</span><span style="color: maroon;">div </span><span style="color: red;">class</span><span style="color: blue;">="line1shape1"&gt;&lt;/</span><span style="color: maroon;">div</span><span style="color: blue;">&gt;
&lt;</span><span style="color: maroon;">div </span><span style="color: red;">class</span><span style="color: blue;">="line2shape1"&gt;&lt;/</span><span style="color: maroon;">div</span><span style="color: blue;">&gt;
</span></pre><p>and replace the previous <em>.shape1</em> rule with this block of CSS:</p><pre class="code"><span style="color: maroon;">.shape1 </span>{
    <span style="color: red;">-ms-grid-column</span>: <span style="color: blue;">4</span>;
    <span style="color: red;">-ms-grid-row</span>: <span style="color: blue;">3</span>;
    <span style="color: red;">-ms-grid-column-span</span>: <span style="color: blue;">3</span>;
    <span style="color: red;">-ms-grid-row-span</span>: <span style="color: blue;">2</span>;
    <span style="color: red;">display</span>: <span style="color: blue;">-ms-grid</span>;
    <span style="color: red;">-ms-grid-columns</span>: <span style="color: blue;">1fr 1fr 1fr</span>;
    <span style="color: red;">-ms-grid-rows</span>: <span style="color: blue;">1fr 1fr</span>;
    <span style="color: red;">width</span>: <span style="color: blue;">100%</span>;
    <span style="color: red;">height</span>: <span style="color: blue;">100%</span>;
}
<span style="color: maroon;">.line1shape1 </span>{
    <span style="color: red;">-ms-grid-column-span</span>: <span style="color: blue;">2</span>;
    <span style="color: red;">background-color</span>: <span style="color: blue;">red</span>;
}
<span style="color: maroon;">.line2shape1 </span>{
    <span style="color: red;">-ms-grid-column</span>: <span style="color: blue;">2</span>;
    <span style="color: red;">-ms-grid-row</span>: <span style="color: blue;">2</span>;
    <span style="color: red;">-ms-grid-column-span</span>: <span style="color: blue;">2</span>;
    <span style="color: red;">background-color</span>: <span style="color: blue;">red</span>;
}</pre><p>The shape1 is currently spanning on three columns and two rows. I’ll then create a new grid inside this area defined by three columns and two rows in order to have cells having exactly the same size as the cells of the main grid, whatever the resolution might be.</p><p>Once done, I’ll create two lines in order to mimic the Z shape of the Tetris game. You should now have this result:</p><p><img
alt="z-shape in Tetris" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0334.image_5F00_thumb_5F00_520EF183.png" width="450" height="274" border="0" /></p><p>Even better, play with the various views available in the Device tab and you’ll see that our game is already implementing a <a
href="http://en.wikipedia.org/wiki/Responsive_web_design">responsive design</a>! This is freaking cool, isn’t it?</p><p>Here, for instance, is the outputs for the snapped view and the portrait view:</p><p><img
alt="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1488.image_5F00_thumb_5F00_544E09F5.png" width="550" height="262" border="0" /><br
/> <img
alt="z-shape in landscape view" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8345.image_5F00_thumb_5F00_119670D0.png" width="325" height="286" border="0" /></p><p>Let’s now resolve another problem.</p><p>The Tetris grid gaming grid is composed of squares. Our current responsive design is stretching 100% width. Building a Windows 8 application for the Windows Store will most of the time meet widescreen monitors (current tablets are 1366&#215;768 or 1920&#215;1080 and most desktop PC have a 16/9 ratio). Let’s then assume that targeting a widescreen ratio is addressing almost all cases. To compute the proper responsive width, you need to do: 9/16 * 10/20 (the ratio of the main gaming grid) which equals to: <strong>28.125%.</strong></p><p>Add this rule to target the main grid in full screen landscape mode:</p><pre class="code"><span style="color: blue;">@media </span>screen and (-ms-view-state: fullscreen-landscape) {
    <span style="color: maroon;">.mainGrid </span>{
        <span style="color: red;">width</span>: <span style="color: blue;">28.125%</span>;
        }
}</pre><p>Let’s now center the gaming grid by using… the CSS Grid Layout again! (And you should now start to believe it was truly designed for Tetris!)</p><p>Switch the <em>body</em> element to <em>–ms-grid</em> made of one column and one row:</p><pre class="code"><span style="color: maroon;">body </span>{
    <span style="color: red;">display</span>: <span style="color: blue;">-ms-grid</span>;
    <span style="color: red;">-ms-grid-columns</span>: <span style="color: blue;">1fr</span>;
    <span style="color: red;">-ms-grid-rows</span>: <span style="color: blue;">1fr</span>;
    <span style="color: red;">width</span>: <span style="color: blue;">100%</span>;
    <span style="color: red;">height</span>: <span style="color: blue;">100%</span>;
}</pre><p>Now simply add this attribute to the CSS associated to the the main grid:</p><pre class="code"><span style="color: red;">-ms-grid-column-align</span>: <span style="color: blue;">center</span>;</pre><p>And the grid is now centered:</p><p><img
alt="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2553.image_5F00_thumb_5F00_110B1794.png" width="640" height="332" border="0" /></p><p>At this stage, you’re probably already shocked. &#8220;<em>How could I have missed this incredible secret?</em>&#8221; you’re wondering to yourself.</p><p>Take a breath.</p><p>Now that you know THE secret, let’s continue this tutorial together to discover other awesome possibilities delivered by the CSS specifications combined together.</p><h2>Step 2: moving or rotating a shape</h2><p>My first idea was to try avoiding JS by using as much CSS as possible. I then first tried to use <a
href="http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-to-css3-animations.aspx">CSS3 Animations</a> to move and animate the shape on the various rows/columns. But the bad news is that you can’t change the <em>–ms-grid-column</em> or <em>–ms-grid-row</em> values via CSS3 animations. This will then be the job of some JavaScript code.</p><p>I then started to think about how I will rotate the shape. <a
href="http://www.w3.org/TR/css3-transforms/">CSS Transforms</a> seemed to be perfectly adapted for that. Let’s check that by doing some experiments. Blend 5 is really cool for that as you can directly see live the outcome of your changes.</p><p>Add a rotation of 90 degrees on <em>shape1</em> by adding this class to its DIV element:</p><pre class="code"><span style="color: maroon;">.shape1rotated </span>{
    <span style="color: red;">transform</span>: <span style="color: blue;">rotate(90deg)</span>;
}</pre><p>I’m sure you weren’t expecting this:</p><p><img
title="image" alt="Rotated shape" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4666.image_5F00_thumb_5F00_15CE3F67.png" width="240" height="122" /></p><p>Problem: it’s not properly aligned to the gaming grid. To align our shape to the grid, we need some small adjustments:</p><pre class="code"><span style="color: maroon;">.shape1rotated </span>{
    <span style="color: red;">transform-origin</span>: <span style="color: blue;">33% 50%</span>;
    <span style="color: red;">transform</span>: <span style="color: blue;">rotate(90deg) translateX(-33%)</span>;
}</pre><p>And we now have the same rotation as a Tetris-like game. Here are two screenshots before/after the rotation:</p><p><img
alt="z-shape before rotation" src="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3414.image_5F00_22C81F78.png" /><br
/> <img
alt="z-shape after rotation" src="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8272.image_5F00_0E4560AB.png" /></p><p>We can even go further than that by using a transition set on shape1 via this:</p><pre class="code"><span style="color: red;">transition</span>: <span style="color: blue;">all 1s ease-out</span>;</pre><p>And now, removing/adding the <em>.shape1rotated</em> class on the shape1 DIV will trigger a smooth rotation animation.</p><p>Check out the result inside Blend 5 thanks to this short video:</p><div
class="video-js-box"><video
id="MSPointerEventsArticleVideo" class="video-js" poster="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo1.jpg" preload="preload" controls="controls" width="800" height="450"><source
type="video/mp4; codecs=&quot;avc1.42E01E, mp4a.40.2&quot;" src="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo1.mp4" /><source
type="video/webm; codecs=&quot;vp8, vorbis&quot;" src="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo1.webm" /><object
id="flash_fallback_1" class="vjs-flash-fallback" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf"<br /> width="800" type="application/x-shockwave-flash" height="450"><param
name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" /><param
name="allowfullscreen" value="true" /><param
name="flashvars" value="config={&quot;playlist&quot;:[&quot;http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo1.jpg&quot;, {&quot;url&quot;: &quot;http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo1.mp4&quot;,&quot;autoPlay&quot;:false,&quot;autoBuffering&quot;:true}]}" /> <img
title="No video playback capabilities." alt="Poster Image" src="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo1.jpg" width="800" height="450" /> </object></video></p><p
class="vjs-no-video"><strong>Download Video:</strong> <a
href="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo1.mp4">MP4</a>, <a
href="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo1.webm">WebM</a>, <a
href="http://videojs.com">HTML5 Video Player</a> by VideoJS</p></div><p>At this stage, we could think that this approach is the good one to build our game. But this is unfortunately not yet the case. Here’s why. Try moving the shape by simply changing its <em>–ms-grid-column</em> property. Blend 5 will reflect the changes directly. When not rotated, the shape can be moved up to the 8th column:</p><p><img
alt="z-shape moved to the 8th column" src="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0118.image_5F00_4D7445B9.png" /></p><p>So far so good. But when you’re rotating it by adding the <em>.shape1rotated</em> class to the DIV:</p><p><img
alt="z-shape rotated to the 8th column" src="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0525.image_5F00_5A70B67B.png" /></p><p>You see that there is still 1 row available on the right for the shape’s move. If you think we simply need to move it to the 9th row, you’re wrong! Indeed, here is what we’ll obtain on the 9th row:</p><p><img
alt="z-shape gets compressed when moved to the 9th row" src="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1185.image_5F00_27A340B8.png" /></p><p>You probably forgot that we’re currently moving a DIV element displaying a grid layout of three columns and two rows matching exactly the underlying gaming grid. When moving it, we really have the feeling that this is a block part of the main grid we’re moving. But for this trick to work, we need at least three columns available to contain our shape element. If it’s contained in two columns (when set to the 9th column) or less, it will be “compressed”, as in the screenshot.</p><p>There are two ways to resolve that.</p><p>1 – Stop using CSS Transforms and draw the rotated shape using another grid definition. For instance, using three divs inside the shape instead of two. But using such an approach will prevent us having the nice CSS Animations in place.<br
/> 2 – Redefined the main grid to work on 12 columns instead of 10 and we’ll use only the columns from 2 to 11 (a sort of clipping area if you wish). This will resolve our “overflow” problem.</p><p>Let’s implement the second solution.</p><p>Redefine the main grid using this:</p><pre class="code"><span style="color: maroon;">.mainGrid </span>{
    <span style="color: red;">display</span>: <span style="color: blue;">-ms-grid</span>;
    <span style="background-color: #ffff00;"><span style="color: red;">-ms-grid-columns</span>: <span style="color: blue;">(1fr)[12]</span>;</span>
    <span style="color: red;">-ms-grid-rows</span>: <span style="color: blue;">(1fr)[20]</span>;
    <span style="color: red;">-ms-grid-column-align</span>: <span style="color: blue;">center</span>;
    <span style="color: red;">width</span>: <span style="color: blue;">100%</span>;
    <span style="color: red;">height</span>: <span style="color: blue;">100%</span>;
}</pre><p>To also have the proper ratio, you need to update the associated media query:</p><pre class="code"><span style="color: blue;">@media </span>screen and (-ms-view-state: fullscreen-landscape) {
    <span style="color: maroon;">.mainGrid </span>{
        <span style="background-color: #ffff00;"><span style="color: red;">width</span>: <span style="color: blue;">33.75%</span>;</span>
        }
}</pre><p>33.75% = 9/16 *12/20</p><p>Let’s also add a “virtual grid” to delimitate the space where we will be able to move the shapes.  Inside the main grid DIV, insert this one:</p><pre class="code"><span style="color: blue;">&lt;</span><span style="color: maroon;">div </span><span style="color: red;">class</span><span style="color: blue;">="virtualGrid"&gt;
&lt;/</span><span style="color: maroon;">div</span><span style="color: blue;">&gt;
</span></pre><p>Associated with this block of CSS:</p><pre class="code"><span style="color: maroon;">.virtualGrid </span>{
    <span style="color: red;">-ms-grid-column</span>: <span style="color: blue;">2</span>;
    <span style="color: red;">-ms-grid-column-span</span>: <span style="color: blue;">10</span>;
    <span style="color: red;">-ms-grid-row-span</span>: <span style="color: blue;">20</span>;
    <span style="color: red;">border-right-style</span>: <span style="color: blue;">dashed</span>;
    <span style="color: red;">border-left-style</span>: <span style="color: blue;">dashed</span>;
    <span style="color: red;">background-color</span>: <span style="color: blue;">#505A5A</span>;
}</pre><p>It will help to delimit the gaming area with a grey background and some dashed border lines.</p><p>Now, if I’m moving the Z shape on column 9, row 2, here is the result:</p><p><img
alt="z-shape at column 9" src="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4544.image_5F00_21CDE152.png" /></p><p>If I’m rotating it with CSS Transforms, I can move it correctly on column 10:</p><p><img
alt="Rotated z-shape moved correctly to column 9" src="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4048.image_5F00_07FC3BD4.png" /></p><h4>Bonus – handling the Portrait mode:</h4><p>If you’d like to support the portrait mode (which is even better for the Tetris grid game), add this CSS Media Query definition:</p><pre class="code"><span style="color: blue;">@media </span>screen and (-ms-view-state: fullscreen-portrait) {
        <span style="color: maroon;">.mainGrid </span>{
        <span style="color: red;">width</span>: <span style="color: blue;">106.66%</span>;
        }
}</pre><p>As the ratio need to be computed as = 16/9 * 12/20 = 106,66%.</p><p><img
alt="Tetris grid in landscape" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1411.image_5F00_32C79A6A.png" /></p><h2>Step 3: adding some code to handle part of the game logic</h2><p>Now that we’ve solved the graphics part of the game using only some pure CSS &amp; HTML code, we need the help of JavaScript to move/rotate the shape in the gaming area. We’re going to re-implement the CSS logic via a JS object that’s going to be defined thanks to <a
href="http://msdn.microsoft.com/fr-fr/library/windows/apps/br229776.aspx">WinJS.Class</a>.</p><p>Open the &#8220;<em>TheRealCSSGridStory</em>&#8221; in Visual Studio 2012.</p><p>Create a <em>TetrisShapeZ.js</em> file in the JS directory and copy/paste this code:</p><pre>(<span style="color: blue;">function </span>() {
    <span style="color: maroon;">"use strict"</span>;
    <span style="color: blue;">var </span>ShapeZ = WinJS.Class.define(
    <span style="color: #006400;">/// Constructor - columnIndex is optional. If provided, defines the column the shape starts in
        </span><span style="color: blue;">function </span>(columnIndex) {
            <span style="color: #006400;">// We're creating the equivalent of this HTML block :
            // &lt;div class="shape1 "&gt;
            //     &lt;div class="line1shape1"&gt;&lt;/div&gt;
            //     &lt;div class="line2shape1"&gt;&lt;/div&gt;
            // &lt;/div&gt;
            </span><span style="color: blue;">this</span>._shape1 = document.createElement(<span style="color: maroon;">"div"</span>);
            <span style="color: blue;">var </span>line1 = document.createElement(<span style="color: maroon;">"div"</span>);
            <span style="color: blue;">var </span>line2 = document.createElement(<span style="color: maroon;">"div"</span>);
            <span style="color: blue;">this</span>._shape1.className = <span style="color: maroon;">"shape1"</span>;
            line1.className = <span style="color: maroon;">"line1shape1"</span>;
            line2.className = <span style="color: maroon;">"line2shape1"</span>;
            <span style="color: blue;">this</span>._shape1.appendChild(line1);
            <span style="color: blue;">this</span>._shape1.appendChild(line2);
            <span style="color: #006400;">// Boolean to indicate if the shape is in its default orientation mode or not
            // True means not rotated, false means rotated
            </span><span style="color: blue;">this</span>._defaultOrientation = <span style="color: blue;">true</span>;
            <span style="color: #006400;">// Setting the column position in the main grid
            </span><span style="color: blue;">if </span>(columnIndex) {
                <span style="color: blue;">this</span>._currentColPos = columnIndex;
                <span style="color: blue;">this</span>._shape1.style.msGridColumn = <span style="color: blue;">this</span>._currentColPos;
            }
            <span style="color: blue;">else </span>{
                <span style="color: blue;">this</span>._currentColPos = 1;
            }
            <span style="color: #006400;">// We always start at line 1
            </span><span style="color: blue;">this</span>._currentLinePos = 1;
            <span style="color: #006400;">// Boolean to know if the shape can be move/rotate or not
            // If true, this means we've reached the last line possible
            </span><span style="color: blue;">this</span>._fixed = <span style="color: blue;">false</span>;
        },
        {
            <span style="color: #006400;">/// Specify in which HTML element displayed in CSS Grid you'd like to work with
            /// width is the number of columns of the grid &amp; height is the number of lines
            </span>insertIntoGrid: <span style="color: blue;">function </span>(element, width, height) {
                element.appendChild(<span style="color: blue;">this</span>._shape1);
                <span style="color: blue;">this</span>._gridWidth = width;
                <span style="color: blue;">this</span>._gridHeight = height;
                <span style="color: #006400;">// These are the left &amp; bottom max limit for this shape
                // when displayed in default orientation mode
                </span><span style="color: blue;">this</span>._maxLeft = width - 3;
                <span style="color: blue;">this</span>._maxBottom = height - 1;
            },
            <span style="color: #006400;">/// Rotate the Z shape 90 degrees anti/clockwise using CSS Transforms
            /// by simply removing/adding the shape1rotated class
            </span>rotate: <span style="color: blue;">function </span>() {
                <span style="color: blue;">if </span>(!<span style="color: blue;">this</span>._fixed &amp;&amp; <span style="color: blue;">this</span>._defaultOrientation) {
                    <span style="color: #006400;">// rotating 90 degrees clockwise, it will trigger also the CSS Transition
                    </span>WinJS.Utilities.addClass(<span style="color: blue;">this</span>._shape1, <span style="color: maroon;">"shape1rotated"</span>);
                    <span style="color: blue;">this</span>._defaultOrientation = <span style="color: blue;">false</span>;
                    <span style="color: #006400;">// the left limit is now +1 vs the default orientation
                    </span><span style="color: blue;">this</span>._maxLeft = <span style="color: blue;">this</span>._gridWidth - 2;
                }
                <span style="color: blue;">else </span>{
                    <span style="color: blue;">if </span>(!<span style="color: blue;">this</span>._fixed &amp;&amp; <span style="color: blue;">this</span>._currentColPos &lt; <span style="color: blue;">this</span>._maxLeft) {
                        <span style="color: #006400;">// removing the shape1rotated will automatically reset the shape
                        // to its initial matrix and again the CSS Transition will do the
                        // animation for you
                        </span>WinJS.Utilities.removeClass(<span style="color: blue;">this</span>._shape1, <span style="color: maroon;">"shape1rotated"</span>);
                        <span style="color: blue;">this</span>._defaultOrientation = <span style="color: blue;">true</span>;
                        <span style="color: blue;">this</span>._maxLeft = <span style="color: blue;">this</span>._gridWidth - 3;
                    }
                }
            },
            <span style="color: #006400;">// Internal function called by public moveLeft/moveRight
            </span>_moveHorizontally: <span style="color: blue;">function </span>(direction) {
                <span style="color: blue;">if </span>(!<span style="color: blue;">this</span>._fixed &amp;&amp; (<span style="color: blue;">this</span>._currentColPos &lt; <span style="color: blue;">this</span>._maxLeft || direction === -1) &amp;&amp;
                (<span style="color: blue;">this</span>._currentColPos &gt; 2 || direction === 1)) {
                    <span style="color: blue;">this</span>._currentColPos = <span style="color: blue;">this</span>._currentColPos + direction;
                    <span style="color: blue;">this</span>._shape1.style.msGridColumn = <span style="color: blue;">this</span>._currentColPos;
                }
            },
            <span style="color: #006400;">/// Move the shape on the immediate left column
            /// Test if you've reached the left limit or not
            </span>moveLeft: <span style="color: blue;">function </span>() {
                <span style="color: blue;">this</span>._moveHorizontally(-1);
            },
            <span style="color: #006400;">/// Move the shape on the immediate right column
            /// Test if you've reached the right limit or not
            </span>moveRight: <span style="color: blue;">function </span>() {
                <span style="color: blue;">this</span>._moveHorizontally(1);
            },
            <span style="color: #006400;">/// Move the shape down on the immediate below line
            /// Test if you've reached the bottom limit or not
            </span>moveDown: <span style="color: blue;">function </span>() {
                <span style="color: blue;">if </span>(!<span style="color: blue;">this</span>._fixed) {
                    <span style="color: blue;">this</span>._currentLinePos = <span style="color: blue;">this</span>._currentLinePos + 1;
                    <span style="color: blue;">this</span>._shape1.style.msGridRow = <span style="color: blue;">this</span>._currentLinePos;
                    <span style="color: blue;">if </span>(<span style="color: blue;">this</span>._currentLinePos === <span style="color: blue;">this</span>._maxBottom) {
                        <span style="color: blue;">this</span>._fixed = <span style="color: blue;">true</span>;
                    }
                }
            }
        }
    );
    WinJS.Namespace.define(<span style="color: maroon;">"CSSTetris"</span>, { ShapeZ: ShapeZ });
} ());</pre><p>Simply read the code to understand what it’s doing. It should be commented enough to be self-explicit.</p><p>Add a reference to this script file in <em>default.html </em>and keep only this block of HTML inside the body:</p><pre class="code"><span style="color: blue;">&lt;</span><span style="color: maroon;">div </span><span style="color: red;">class</span><span style="color: blue;">="mainGrid"&gt;
    &lt;</span><span style="color: maroon;">div </span><span style="color: red;">class</span><span style="color: blue;">="virtualGrid"&gt;
    &lt;/</span><span style="color: maroon;">div</span><span style="color: blue;">&gt;
&lt;/</span><span style="color: maroon;">div</span><span style="color: blue;">&gt;
</span></pre><p>Jump into <em>default.js</em>.</p><p>The cool part of having well-documented code is that we now have interesting IntelliSense details like for the <strong>constructor</strong>:</p><p><img
alt="Intellisense for ShapeZ(columnIndex) constructor" src="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0574.image_5F00_3C57958D.png" /></p><p>or the <strong>rotate</strong> function:</p><p><img
alt="Intellisense for the rotate function" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0160.image_5F00_1BD2E68C.png" /></p><p>To properly use this code, add this block of JS just after <em>processAll</em> call:</p><pre class="code">document.addEventListener(<span style="color: maroon;">"keydown"</span>, OnKeyDown, <span style="color: blue;">false</span>);
mainGrid = document.getElementsByClassName(<span style="color: maroon;">"mainGrid"</span>)[0];
myShape = <span style="color: blue;">new </span>CSSTetris.ShapeZ(4);
myShape.insertIntoGrid(mainGrid, 12, 20);
init();</pre><p>And add these two functions:</p><pre class="code"><span style="color: blue;">function </span>init() {
    setInterval(<span style="color: blue;">function </span>() {
        myShape.moveDown();
    }, 1000);
}
<span style="color: blue;">function </span>OnKeyDown(event) {
    <span style="color: blue;">switch </span>(event.keyCode) {
        <span style="color: blue;">case </span>KEYCODE_X:
            myShape.rotate();
            <span style="color: blue;">break</span>;
        <span style="color: blue;">case </span>KEYCODE_LEFT:
            myShape.moveLeft();
            <span style="color: blue;">break</span>;
        <span style="color: blue;">case </span>KEYCODE_RIGHT:
            myShape.moveRight();
            <span style="color: blue;">break</span>;
        <span style="color: blue;">case </span>KEYCODE_DOWN:
            myShape.moveDown();
            <span style="color: blue;">break</span>;
    }
}</pre><p>And we’re done! We now have a very basic game using CSS Grid Layout coupled with CSS Transforms &amp; Animations for the graphics part and a couple of JS lines of code to have the beginning of the basics of a Tetris-like game.</p><p>Here is a short video demonstrating the final result:</p><div
class="video-js-box"><video
id="MSPointerEventsArticleVideo" class="video-js" poster="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo2.jpg" preload="preload" controls="controls" width="705" height="450"><source
type="video/mp4; codecs=&quot;avc1.42E01E, mp4a.40.2&quot;" src="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo2.mp4" /><source
type="video/webm; codecs=&quot;vp8, vorbis&quot;" src="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo2.webm" /><object
id="flash_fallback_1" class="vjs-flash-fallback" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf"<br /> width="705" type="application/x-shockwave-flash" height="450"><param
name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" /><param
name="allowfullscreen" value="true" /><param
name="flashvars" value="config={&quot;playlist&quot;:[&quot;http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo2.jpg&quot;, {&quot;url&quot;: &quot;http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo2.mp4&quot;,&quot;autoPlay&quot;:false,&quot;autoBuffering&quot;:true}]}" /><br
/> <img
title="No video playback capabilities." alt="Poster Image" src="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo2.jpg" width="705" height="450" /><br
/> </object></video></p><p
class="vjs-no-video"><strong>Download Video:</strong> <a
href="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo2.mp4">MP4</a>, <a
href="http://david.blob.core.windows.net/videos/TheRealCSSGridStoryVideo2.webm">WebM</a>, <a
href="http://videojs.com">HTML5 Video Player</a> by VideoJS</p></div><p>You can download the final Visual Studio solution corresponding to the three steps of this tutorial here: <a
title="http://david.blob.core.windows.net/win8/TheRealCSSGridStory.zip" href="http://david.blob.core.windows.net/win8/TheRealCSSGridStory.zip">http://david.blob.core.windows.net/win8/TheRealCSSGridStory.zip</a></p><p>So, are you now convinced that CSS Grid Layout was made to simplify the creation of Tetris-like games?</p> <footer><hr
/><p>This article is part of the HTML5 tech series from the Internet Explorer team. Try-out the concepts in this article with 3 months of free BrowserStack cross-browser testing @ <a
href="http://modern.IE">http://modern.IE</a>.</p><hr
/><p>This article originally appeared on David Rousset&#8217;s MSDN blog, Coding4Fun on <a
href="http://blogs.msdn.com/b/davrous/archive/2013/02/12/coding4fun-build-a-tetris-like-game-using-css-grid-layout-amp-blend-5.aspx">12 Feb 2013</a>.</p> </footer><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/using-css-grid-layout-and-blend-5-to-build-a-game/feed/</wfw:commentRss> <slash:comments>1</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 38/65 queries in 0.121 seconds using memcached
Object Caching 1939/2050 objects using memcached

Served from: www.sitepoint.com @ 2013-05-13 13:29:47 --