<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D08DQXYyfyp7ImA9WhRUFks.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551</id><updated>2012-01-27T04:04:30.897-08:00</updated><title>Luis Cameroon</title><subtitle type="html">user-centred design, usability, user experience, interaction design, creativity, interactive media, social media,information architecture, management, work process, content management, seo, sem, user-generated content, multimedia content, cross-platform, mobile</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://luiscameroon.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://luiscameroon.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>120</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/LuisCameroon" /><feedburner:info uri="luiscameroon" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D08DQXc7cSp7ImA9WhRUFks.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-1111497846072859448</id><published>2012-01-27T04:04:00.000-08:00</published><updated>2012-01-27T04:04:30.909-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-27T04:04:30.909-08:00</app:edited><title>Modular front-end development with LESS</title><content type="html">&lt;p&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2012/01/Less.jpg" alt="Modular front-end development with LESS" width="580" height="315" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I am constantly looking for ways to make my work as a front-end developer easier and more efficient, but it is only recently that I have paid my good friend CSS any real attention. The whole movement to make this sector of front-end development easier started with grid systems and the idea of &lt;a href="https://github.com/stubbornella/oocss/wiki"&gt;object-oriented CSS&lt;/a&gt;, and has since been made easier with extensions to the language itself in the form of CSS pre-processors — the two most well-known being &lt;a href="http://lesscss.org/"&gt;LESS&lt;/a&gt; and &lt;a href="http://sass-lang.com/"&gt;Sass&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This article will explore the benefit of organizing your code efficiently while keeping it reusable and modular. Let’s get started!&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div style="clear:both"&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;The tools of speedy CSS development&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Object-oriented CSS&lt;/strong&gt; is one of the best ways to make sure you are writing code that you can use almost anywhere, keeping the development time on future projects low. The basic principles of OOCSS are that your code should:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Separate structure and skin&lt;/strong&gt;. Have separate classes for defining the way an element fits into the layout, and the way it is stylized.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Avoid location-dependent styling.&lt;/strong&gt; The &lt;a href="https://github.com/stubbornella/oocss/wiki"&gt;OOCSS GitHub project&lt;/a&gt; explains this best, by saying that instead of writing &lt;strong&gt;.container h2&lt;/strong&gt; you should use &lt;strong&gt;h2.tagline&lt;/strong&gt; or whatever works semantically. This ensures that all &lt;strong&gt;h2&lt;/strong&gt; elements look the same.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;When writing object-oriented CSS, keep in mind what you’re going to be using as your HTML markup. While you could write something like this:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;div class="blog-post"&amp;gt;&lt;br /&gt; &amp;lt;h1&amp;gt;Article title&amp;lt;/h1&amp;gt;&lt;br /&gt; &amp;lt;div class="meta"&amp;gt;&lt;br /&gt;  &amp;lt;p&amp;gt;Date published: &amp;lt;span class="date"&amp;gt;12 January 2012&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt; &amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div class="post-body"&amp;gt;&lt;br /&gt;  &amp;lt;p&amp;gt;...&amp;lt;/p&amp;gt;&lt;br /&gt; &amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;It would be better to write:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;article class="blog-post col_8"&amp;gt;&lt;br /&gt; &amp;lt;h1 class="headline"&amp;gt;Article title&amp;lt;/h1&amp;gt;&lt;br /&gt; &amp;lt;p class="meta-information blog-post-meta"&amp;gt;Date published: &amp;lt;time class="blog-date" datetime="2012-01-12"&amp;gt;12 January 2012&amp;lt;/time&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt; &amp;lt;section class="post-body text"&amp;gt;&lt;br /&gt;  &amp;lt;p&amp;gt;...&amp;lt;/p&amp;gt;&lt;br /&gt; &amp;lt;/section&amp;gt;&lt;br /&gt;&amp;lt;/article&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And use CSS like this:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;h1 { ... }&lt;br /&gt; .headline { ... }&lt;br /&gt;.meta-information { ... }&lt;br /&gt; .blog-post-meta { ... }&lt;br /&gt;time { ... }&lt;br /&gt; .blog-date { ... }&lt;br /&gt;.text { ... }&lt;br /&gt; .post-body { ... }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Instead of prefixing each of these CSS rules with .blog-post, and thus making it too specific to reuse. But there are still some problems with this: you’re writing a bit too much HTML, and everything seems much too specific for a simple blog post. This is where LESS comes in, greatly simplifying the process.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;LESS&lt;/strong&gt; is a CSS pre-processor that extends the CSS language with unbelievably useful features. Ever since adopting it, styling web pages has been a breeze, and fun at that! While LESS boasts many useful features, the main three I’ll be concentrating on today are:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Variables.&lt;/strong&gt; Define any variable like so: &lt;strong&gt;@color1: #df0290;&lt;/strong&gt;and use it later in your code:&lt;br /&gt;&lt;pre&gt;.container { background: @color1 url('img/bg_gradient.png'); }&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Mixins.&lt;/strong&gt;Define useful functions with or without parameters:&lt;br /&gt;&lt;pre&gt;.box (@w: 500px, @h: 200px) {&lt;br /&gt; display: block;&lt;br /&gt; width: @w;&lt;br /&gt; height: @h;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And use them later in your code:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;.modal-dialog ( .box(400px, 700px); }&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Nested rules.&lt;/strong&gt;Pretty self-explanatory, as I’m sure this is something you’ve been wishing for in CSS since you started using it:&lt;br /&gt;&lt;pre&gt;article {&lt;br /&gt; font-family: serif;&lt;br /&gt; line-height: 1.4;&lt;br /&gt; h1 {&lt;br /&gt;  font: 2em bold sans-serif;&lt;br /&gt; }&lt;br /&gt; h2 {&lt;br /&gt;  font-size: 1.5em;&lt;br /&gt;  &amp;amp;.category { color: #666; }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;An ampersand (&lt;strong&gt;&amp;amp;&lt;/strong&gt;) refers to the parent rule. So &lt;strong&gt;&amp;amp;.category&lt;/strong&gt; would translate to &lt;strong&gt;article h2.category&lt;/strong&gt; once the LESS code had been compiled.&lt;/p&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;Using LESS, our blog post case study above can be simplified in the HTML to just this:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;article class="blog-post"&amp;gt;&lt;br /&gt; &amp;lt;h1&amp;gt;Article title&amp;lt;/h1&amp;gt;&lt;br /&gt; &amp;lt;p class="meta"&amp;gt;Date published: &amp;lt;time datetime="2012-01-12"&amp;gt;12 January 2012&amp;lt;/time&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt; &amp;lt;section class="post-body"&amp;gt;&lt;br /&gt;  &amp;lt;p&amp;gt;...&amp;lt;/p&amp;gt;&lt;br /&gt; &amp;lt;/section&amp;gt;&lt;br /&gt;&amp;lt;/article&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And the CSS would be:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;/* Reusable global styles */&lt;br /&gt;h1 { ... }&lt;br /&gt;.headline { ... }&lt;br /&gt;p { ... }&lt;br /&gt;.meta-information { ... }&lt;br /&gt;.col (@width) { width: 10% * @width; }&lt;br /&gt;.date-published { ... }&lt;br /&gt;.text { ... }&lt;br /&gt;&lt;br /&gt;article {&lt;br /&gt; .col(8);&lt;br /&gt; h1 { .headline; }&lt;br /&gt; p.meta {&lt;br /&gt; .meta-information;&lt;br /&gt;  time { .date-published; }&lt;br /&gt; }&lt;br /&gt; .post-body { .text; }&lt;br /&gt;&lt;br /&gt; &amp;amp;.blog-post {&lt;br /&gt;  // perhaps some blog specific rules here?&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;The need for organization in CSS&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;While the above is a very simple example, the case for organization in CSS becomes much more persuasive once you realize how large some web development projects are, and how multitudinous their need for styling is. A dialog in one place may look &lt;em&gt;slightly&lt;/em&gt; different than in another, but that’s no reason to rewrite the whole rule! We can simply use a combination of LESS and OOCSS to achieve styling code that is modular, but specific, as demonstrated above.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;One of the main benefits of putting this much thought into how you organize your style code is that you can separate the various functions of design. With this idea in mind, you might create a CSS (or, in this case, LESS) library that looked something like this:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;/project/css/&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;- &lt;strong&gt;reset.css&lt;/strong&gt; — &lt;em&gt;resets default browser styling&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;- &lt;strong&gt;grid.less&lt;/strong&gt; — &lt;em&gt;supplies mixins for a grid system, such as the .col(@width) mixin above&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;- &lt;strong&gt;type.less&lt;/strong&gt; — &lt;em&gt;supplies mixins for font styling as well as @font-face rules&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;- &lt;strong&gt;colorscheme.less&lt;/strong&gt; — &lt;em&gt;LESS variables for the design’s various colors&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;- &lt;strong&gt;interface.less&lt;/strong&gt; — &lt;em&gt;mixins for interface features like buttons, forms, and dialogs&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;- &lt;strong&gt;layout.less&lt;/strong&gt; — &lt;em&gt;design-specific layout of the site&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;- &lt;strong&gt;style.less&lt;/strong&gt; — &lt;em&gt;the main stylesheet, including all of the above and adding in whatever site-specific styles are otherwise necessary&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This level of organization is certainly overkill for very small pages, or one-page apps, but not for very large projects with many different pages. For even larger projects, you may have page- or function-specific styling files such as &lt;strong&gt;search.less&lt;/strong&gt; or &lt;strong&gt;profile_page.less&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Be careful, though, about loading too many LESS files on a production server. Follow these guidelines for condensing your LESS code:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Make sure you always write nicely styled CSS. Go all out for development, and don’t take shortcuts in your code style. You’ll thank me later.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use // comments instead of /* */ comments in LESS. These are removed by a LESS compiler.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Always use parametric mixins. Even when your LESS mixins don’t have variables, include an empty set of parentheses, like so: .border () { border: 1px solid black; } This will ensure that all LESS mixins aren’t included in the compiled code.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Compile LESS code, and then minify it with a CSS minifier. LESS has its own compiler, written for node.js. There is also a PHP compiler (and an online demo of that compiler). I have heard reports of the PHP LESS compiler having some definitive errors, but I haven’t noticed any myself.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Building style libraries to speed up front-end development&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;One of the main advantages you can have in development time is drawing from code that’s already been written. If you are working on a web application, don’t hesitate to start with &lt;a href="http://twitter.github.com/bootstrap/"&gt;Bootstrap&lt;/a&gt; — it supplies a lot of what you already need, and is probably the best and most comprehensive CSS framework out there, and it’s written in LESS!&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Other LESS frameworks you might want to pay attention to are &lt;a href="http://markdotto.com/bootstrap/"&gt;Preboot&lt;/a&gt; and &lt;a href="http://lesselements.com/"&gt;Elements&lt;/a&gt;, both of which provide very useful mixins for you.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;But depending on the type of work you do, the best way to build your library is to write the code yourself. To make this as efficient as possible, try and make every line of LESS code you write applicable in multiple contexts, and then save it for later. Obviously, you won’t be able to make every line of code context-independent, but much of the code you write can and should be used on multiple projects, so long as it is encapsulated in a LESS mixin and stored in a central location.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Another strategy is to use LESS templates, because styling a website goes much more quickly if you are used to the framework within which you’re working. An example of a &lt;strong&gt;colorscheme.less&lt;/strong&gt; might be:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;@background:   #ffffff;&lt;br /&gt;@textcolor:   #252525;&lt;br /&gt;@textcolor-strong: #090909;&lt;br /&gt;@textcolor-em:  #666666;&lt;br /&gt;@textcolor-blockquote: #aaaaaa;&lt;br /&gt;&lt;br /&gt;@accent1:  #2d9681;&lt;br /&gt;@accent2:  #f8a34b;&lt;br /&gt;&lt;br /&gt;@warning:  #d4230f;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And so forth. By using a template like this for every project, you internalize the variable names and are able to quickly create style documents without thinking about the colors, but instead the function of each element. The same can be said of typography. If you have defined @font-headline in your &lt;strong&gt;type.less&lt;/strong&gt; file, you can use it in an H1 or H2 element without having to consider exactly what font is necessary.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And it goes without saying that updating colors, fonts, and other crucial elements of the site’s design becomes so much easier and practically guarantees consistency.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;A game plan&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;It may be hard to remember all of the particulars of what I’ve written above, but most of it can be extrapolated given just two general principles:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Abstraction and consistency.&lt;/strong&gt; Keep your code modular so you can use it everywhere. Use patterns so you can remember them. Separate function from style, and details from big ideas. Don’t use location-dependent code unless you really have to.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Organize everything.&lt;/strong&gt; Don’t just write reusable code — save it! In the directory where I keep my web projects, I have a &lt;strong&gt;lib &lt;/strong&gt;directory that contains all reusable code, including libraries others have written, like Twitter Bootstrap and LESS Elements.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;By following the techniques I’ve outlined, you’ll be able to build up a standardized library of LESS code that cuts down development time drastically. After abstracting away all the general functionality and styling of a website, you’re able to focus on what matters far more to the end user — how everything looks.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;Post: &lt;/em&gt;&lt;em&gt;&lt;/em&gt;&lt;a href="http://tympanus.net/codrops/2012/01/27/modular-front-end-development-with-less/"&gt;Modular front-end development with LESS&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-1111497846072859448?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ysVAKIFrdX0--2iGI5eeKZEX5S8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ysVAKIFrdX0--2iGI5eeKZEX5S8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ysVAKIFrdX0--2iGI5eeKZEX5S8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ysVAKIFrdX0--2iGI5eeKZEX5S8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/B4--A5Ua-k0" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/1111497846072859448?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/1111497846072859448?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/B4--A5Ua-k0/modular-front-end-development-with-less.html" title="Modular front-end development with LESS" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/modular-front-end-development-with-less.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIMRXc7eCp7ImA9WhRVF0Q.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-3370674957566303130</id><published>2012-01-17T02:36:00.000-08:00</published><updated>2012-01-17T02:36:24.900-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-17T02:36:24.900-08:00</app:edited><title>CSS Buttons with Pseudo-elements</title><content type="html">&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2012/01/cssbuttons_main1.jpg" alt="cssbuttons_main" title="" width="580" height="315" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/"&gt;View demo&lt;/a&gt; &lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/CSSButtonsPseudoElements.zip"&gt;Download source&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Hola, amigos. For the last month or so, I’ve been experimenting with the power of CSS pseudo-elements, specially when it comes to mixing them with buttons and that way recreating some great effects that were only possible to do with sprites, in the past.&lt;/p&gt;&lt;p&gt;In this tutorial, I’ll show you how to create buttons with a twist, using just one anchor tag per button and the great power of CSS.&lt;/p&gt;&lt;p&gt;The font used is ‘Open Sans’ by &lt;a href="https://profiles.google.com/107777320916704234605/about"&gt;Steve Matteson&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;I’ll not be using CSS vendor prefixes in this tutorial or else it would be crazy long, but you will find them in the downloadable files.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;I avoided CSS transitions since, right now, Firefox is the only browser that supports them on pseudo-elements. Plus, I believe that these buttons work just fine without them.&lt;/p&gt;&lt;div&gt;&lt;/div&gt;&lt;div style="clear:both"&gt;&lt;/div&gt;&lt;h4&gt;Markup&lt;/h4&gt;&lt;p&gt;The structure of all these buttons needs just one anchor tag for it to work, since we will be creating the other elements with the ::before pseudo-class.&lt;/p&gt;&lt;pre&gt;&lt;a href="http://tympanus.net/codrops#"&gt;&lt;br /&gt;    Click me!&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Example 1&lt;/h3&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2012/01/cssbuttons_01.jpg" alt="cssbuttons_01" title="" width="580" height="250" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I think this is the easiest one, with a very regular CSS.&lt;/p&gt;&lt;h4&gt;CSS&lt;/h4&gt;&lt;p&gt;First of all, we will give the general style of the button, including its active state. It is important to notice the relative positioning, since it will help us later with the positioning of the ::before element:&lt;/p&gt;&lt;pre&gt;.a_demo_one {&lt;br /&gt; background-color:#ba2323;&lt;br /&gt; padding:10px;&lt;br /&gt; position:relative;&lt;br /&gt; font-family: 'Open Sans', sans-serif;&lt;br /&gt; font-size:12px;&lt;br /&gt; text-decoration:none;&lt;br /&gt; color:#fff;&lt;br /&gt; border: solid 1px #831212;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(171,27,27) 0%, rgb(212,51,51) 100%);&lt;br /&gt; border-radius: 5px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_one:active {&lt;br /&gt; padding-bottom:9px;&lt;br /&gt; padding-left:10px;&lt;br /&gt; padding-right:10px;&lt;br /&gt; padding-top:11px;&lt;br /&gt; top:1px;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(171,27,27) 100%, rgb(212,51,51) 0%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Then, we create the gray container using the ::before pseudo-element. Absolute positioning makes our life easier to, believe it or not, position our element:&lt;/p&gt;&lt;pre&gt;.a_demo_one::before {&lt;br /&gt; background-color:#ccd0d5;&lt;br /&gt; content:"";&lt;br /&gt; display:block;&lt;br /&gt; position:absolute;&lt;br /&gt; width:100%;&lt;br /&gt; height:100%;&lt;br /&gt; padding:8px;&lt;br /&gt; left:-8px;&lt;br /&gt; top:-8px;&lt;br /&gt; z-index:-1;&lt;br /&gt; border-radius: 5px;&lt;br /&gt; box-shadow: inset 0px 1px 1px #909193, 0px 1px 0px #fff;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Example 2&lt;/h3&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/index2.html"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2012/01/cssbuttons_021.jpg" alt="cssbuttons_02" title="" width="580" height="250" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This one is a little bit more complex because of the 3D’ish look. This button is outside of its ‘container’, but when you click it, it goes down:&lt;/p&gt;&lt;h4&gt;CSS&lt;/h4&gt;&lt;pre&gt;.a_demo_two {&lt;br /&gt; background-color:#6fba26;&lt;br /&gt; padding:10px;&lt;br /&gt; position:relative;&lt;br /&gt; font-family: 'Open Sans', sans-serif;&lt;br /&gt; font-size:12px;&lt;br /&gt; text-decoration:none;&lt;br /&gt; color:#fff;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(100,170,30) 0%, rgb(129,212,51) 100%);&lt;br /&gt; box-shadow: inset 0px 1px 0px #b2f17f, 0px 6px 0px #3d6f0d;&lt;br /&gt; border-radius: 5px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_two:active {&lt;br /&gt; top:7px;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(100,170,30) 100%, rgb(129,212,51) 0%);&lt;br /&gt; box-shadow: inset 0px 1px 0px #b2f17f, inset 0px -1px 0px #3d6f0d;&lt;br /&gt; color: #156785;&lt;br /&gt; text-shadow: 0px 1px 1px rgba(255,255,255,0.3);&lt;br /&gt; background: rgb(44,160,202);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;And here’s the tricky part: &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Since the position of the pseudo-element depends on its parent, once the parent moves down a few pixels, you have to move up the pseudo-element that same amount of pixels.&lt;/p&gt;&lt;pre&gt;.a_demo_two::before {&lt;br /&gt; background-color:#072239;&lt;br /&gt; content:"";&lt;br /&gt; display:block;&lt;br /&gt; position:absolute;&lt;br /&gt; width:100%;&lt;br /&gt; height:100%;&lt;br /&gt; padding-left:2px;&lt;br /&gt; padding-right:2px;&lt;br /&gt; padding-bottom:4px;&lt;br /&gt; left:-2px;&lt;br /&gt; top:5px;&lt;br /&gt; z-index:-1;&lt;br /&gt; border-radius: 6px;&lt;br /&gt; box-shadow: 0px 1px 0px #fff;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_two:active::before {&lt;br /&gt; top:-2px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Example 3&lt;/h3&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/index3.html"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2012/01/cssbuttons_03.jpg" alt="cssbuttons_03" title="" width="580" height="250" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I think this one is my favorite since it was the first one I ever made this way and people seem to really like it. It is a divided button that “breaks” once you click it.&lt;/p&gt;&lt;h4&gt;CSS&lt;/h4&gt;&lt;p&gt;Again, the first thing we have to do is create the lighter part. In here, you’ll notice a right margin, this is in order to compensate for the width of the pseudo-element if you want to center the button. You don’t need it if that is not a problem for you.&lt;/p&gt;&lt;pre&gt;.a_demo_three {&lt;br /&gt; background-color:#3bb3e0;&lt;br /&gt; font-family: 'Open Sans', sans-serif;&lt;br /&gt; font-size:12px;&lt;br /&gt; text-decoration:none;&lt;br /&gt; color:#fff;&lt;br /&gt; position:relative;&lt;br /&gt; padding:10px 20px;&lt;br /&gt; border-left:solid 1px #2ab7ec;&lt;br /&gt; margin-left:35px;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(44,160,202) 0%, rgb(62,184,229) 100%);&lt;br /&gt; border-top-right-radius: 5px;&lt;br /&gt; border-bottom-right-radius: 5px;&lt;br /&gt; box-shadow: inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #156785, 0px 10px 5px #999;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_three:active {&lt;br /&gt; top:3px;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(62,184,229) 0%, rgb(44,160,202) 100%);&lt;br /&gt; box-shadow: inset 0px 1px 0px #2ab7ec, 0px 2px 0px 0px #156785, 0px 5px 3px #999;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;And then the pseudo-element’s CSS:&lt;/p&gt;&lt;pre&gt;.a_demo_three::before {&lt;br /&gt; content:"·";&lt;br /&gt; width:35px;&lt;br /&gt; max-height:29px;&lt;br /&gt; height:100%;&lt;br /&gt; position:absolute;&lt;br /&gt; display:block;&lt;br /&gt; padding-top:8px;&lt;br /&gt; top:0px;&lt;br /&gt; left:-36px;&lt;br /&gt; font-size:16px;&lt;br /&gt; font-weight:bold;&lt;br /&gt; color:#8fd1ea;&lt;br /&gt; text-shadow:1px 1px 0px #07526e;&lt;br /&gt; border-right:solid 1px #07526e;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(10,94,125) 0%, rgb(14,139,184) 100%);&lt;br /&gt; border-top-left-radius: 5px;&lt;br /&gt; border-bottom-left-radius: 5px;&lt;br /&gt; box-shadow:inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #032b3a, 0px 10px 5px #999 ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_three:active::before {&lt;br /&gt; top:-3px;&lt;br /&gt; box-shadow:inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #032b3a, 1px 1px 0px 0px #044a64, 2px 2px 0px 0px #044a64, 2px 5px 0px 0px #044a64, 6px 4px 2px #0b698b, 0px 10px 5px #999 ;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Example 4&lt;/h3&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/index4.html"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2012/01/cssbuttons_04.jpg" alt="cssbutton_04" title="" width="580" height="250" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This time, we will use the pseudo-element as a pointer, using one image as a background, though you can use some of those great &lt;a href="http://css-tricks.com/examples/IconFont/"&gt;icon fonts&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;CSS&lt;/h4&gt;&lt;pre&gt;.a_demo_four {&lt;br /&gt; background-color:#4b3f39;&lt;br /&gt; font-family: 'Open Sans', sans-serif;&lt;br /&gt; font-size:12px;&lt;br /&gt; text-decoration:none;&lt;br /&gt; color:#fff;&lt;br /&gt; position:relative;&lt;br /&gt; padding:10px 20px;&lt;br /&gt; padding-right:50px;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(62,51,46) 0%, rgb(101,86,78) 100%);&lt;br /&gt; border-radius: 5px;&lt;br /&gt; box-shadow: inset 0px 1px 0px #9e8d84, 0px 5px 0px 0px #322620, 0px 10px 5px #999;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_four:active {&lt;br /&gt; top:3px;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(62,51,46) 100%, rgb(101,86,78) 0%);&lt;br /&gt; box-shadow: inset 0px 1px 0px #9e8d84, 0px 2px 0px 0px #322620, 0px 5px 3px #999;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_four::before {&lt;br /&gt; background-color:#322620;&lt;br /&gt; background-image:url(../images/right_arrow.png);&lt;br /&gt; background-repeat:no-repeat;&lt;br /&gt; background-position:center center;&lt;br /&gt; content:"";&lt;br /&gt; width:20px;&lt;br /&gt; height:20px;&lt;br /&gt; position:absolute;&lt;br /&gt; right:15px;&lt;br /&gt; top:50%;&lt;br /&gt; margin-top:-9px;&lt;br /&gt; border-radius: 50%;&lt;br /&gt; box-shadow: inset 0px 1px 0px #19120f, 0px 1px 0px #827066;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_four:active::before {&lt;br /&gt; top:50%;&lt;br /&gt; margin-top:-12px;&lt;br /&gt; box-shadow: inset 0px 1px 0px #827066, 0px 3px 0px #19120f, 0px 6px 3px #382e29;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Example 5&lt;/h3&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/index5.html"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2012/01/cssbuttons_05.jpg" alt="cssbuttons_05" title="" width="580" height="250" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This example is a bit cheesy, I know, but you can use it in so many and really useful ways.&lt;/p&gt;&lt;h4&gt;CSS&lt;/h4&gt;&lt;pre&gt;.a_demo_five {&lt;br /&gt; background-color:#9827d3;&lt;br /&gt; width:150px;&lt;br /&gt; display:inline-block;&lt;br /&gt; font-family: 'Open Sans', sans-serif;&lt;br /&gt; font-size:12px;&lt;br /&gt; text-decoration:none;&lt;br /&gt; color:#fff;&lt;br /&gt; position:relative;&lt;br /&gt; margin-top:40px;&lt;br /&gt; padding-bottom:10px;&lt;br /&gt; padding-top:10px;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(168,48,232) 100%, rgb(141,32,196) 0%);&lt;br /&gt; border-bottom-right-radius: 5px;&lt;br /&gt; border-bottom-left-radius: 5px;&lt;br /&gt; box-shadow: inset 0px 1px 0px #ca73f8, 0px 5px 0px 0px #6a1099, 0px 10px 5px #999;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_five:active {&lt;br /&gt; top:3px;&lt;br /&gt; background-image: linear-gradient(bottom, rgb(168,48,232) 0%, rgb(141,32,196) 100%);&lt;br /&gt; box-shadow: inset 0px 4px 1px #7215a3, 0px 2px 0px 0px #6a1099, 0px 5px 3px #999;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_five::before {&lt;br /&gt; background-color:#fff;&lt;br /&gt; background-image:url(../images/heart.gif);&lt;br /&gt; background-repeat:no-repeat;&lt;br /&gt; background-position:center center;&lt;br /&gt; border-left:solid 1px #CCC;&lt;br /&gt; border-top:solid 1px #CCC;&lt;br /&gt; border-right:solid 1px #CCC;&lt;br /&gt; content:"";&lt;br /&gt; width:148px;&lt;br /&gt; height:40px;&lt;br /&gt; position:absolute;&lt;br /&gt; top:-30px;&lt;br /&gt; left:0px;&lt;br /&gt; margin-top:-11px;&lt;br /&gt; z-index:-1;&lt;br /&gt; border-top-left-radius: 5px;&lt;br /&gt; border-top-right-radius: 5px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.a_demo_five:active::before {&lt;br /&gt; top: -33px;&lt;br /&gt; box-shadow: 0px 3px 0px #ccc;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;In the end&lt;/h3&gt;&lt;p&gt;And well, this is it, for now. Remember that these buttons are still kind of experimental, so not every browser supports them that well.&lt;/p&gt;&lt;p&gt;Thank you for reading this tutorial and I hope that you find it useful.&lt;/p&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/"&gt;View demo&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tympanus.net/Tutorials/CSSButtonsPseudoElements/CSSButtonsPseudoElements.zip"&gt;Download source&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://tympanus.net/codrops/2012/01/11/css-buttons-with-pseudo-elements/"&gt;CSS Buttons with Pseudo-elements&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-3370674957566303130?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/p6OONCJ0WWXrkjFo3UDaNoyt5cE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p6OONCJ0WWXrkjFo3UDaNoyt5cE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/p6OONCJ0WWXrkjFo3UDaNoyt5cE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p6OONCJ0WWXrkjFo3UDaNoyt5cE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/McPnKAPXU4k" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/3370674957566303130?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/3370674957566303130?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/McPnKAPXU4k/css-buttons-with-pseudo-elements.html" title="CSS Buttons with Pseudo-elements" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/css-buttons-with-pseudo-elements.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMCSX4zeCp7ImA9WhRVF0Q.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-6791431401571050580</id><published>2012-01-17T02:34:00.000-08:00</published><updated>2012-01-17T02:34:28.080-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-17T02:34:28.080-08:00</app:edited><title>5 Things Every Mobile Design Should Have</title><content type="html">&lt;p&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2012/01/5-Things-Every-Mobile-Design-Should-Have.jpg" alt="5-Things-Every-Mobile-Design-Should-Have" title="" width="580" height="315" /&gt;&lt;/p&gt;&lt;p&gt;Okay, so it looks like this whole mobile web fad just isn’t going away any time soon. I’m starting to get the feeling that we’ll need to start designing more mobile friendly websites. As much as we think &lt;strong&gt;mobile web design&lt;/strong&gt; is very different from full screen web design, it really isn’t. Although the screens are smaller and you can touch them, most of the basic principles of design still apply.&lt;/p&gt;&lt;p&gt;But there are some &lt;strong&gt;considerations&lt;/strong&gt; that you may wish to take when designing for mobile browsers to compensate for some of these little differences. I’ve tried to boil it down to &lt;em&gt;5 main elements&lt;/em&gt; that every mobile site MUST have:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;em&gt;Meaningful Navigation&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Focused Content&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Feedback&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Clear Branding&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Plenty of Space&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Now I know there is probably some more elements that every mobile must have, but I feel like these 5 elements are critical pieces that shouldn’t be overlooked and are things we must consider when designing our mobile versions.&lt;/p&gt;&lt;p&gt;All examples provided by &lt;a title="mobileawesomeness.com" href="http://mobileawesomeness.com/"&gt;mobileawesomeness.com&lt;/a&gt;.&lt;/p&gt;&lt;div&gt;&lt;/div&gt;&lt;div style="clear:both"&gt;&lt;/div&gt;&lt;h3&gt;1- Meaningful Navigation&lt;/h3&gt;&lt;p&gt;&lt;a href="http://www.thejtsite.com/"&gt;&lt;img title="http://www.thejtsite.com" src="http://tympanus.net/codrops/wp-content/uploads/2012/01/nav_opt.jpg" alt="http://www.thejtsite.com" width="580" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Getting from screen to screen on a mobile device can actually be a fun experience. So make it enjoyable and meaningful. Simply removing clicks (&lt;em&gt;or taps&lt;/em&gt;) on the screen doesn’t make your mobile app easier to use or more meaningful. The navigation should be about what the user needs to do and providing a clear path to getting it done. A mobile user will tap a time or two more if they know where they are going and what they are heading for.&lt;/p&gt;&lt;p&gt;&lt;em&gt;First&lt;/em&gt;, make sure your navigation looks &lt;strong&gt;visually clickable&lt;/strong&gt;. Make them look like buttons or list items or even make sure they have arrows or “grips” on them to indicate that this little graphical box does something more than just sit there. You don’t have the crutch of a hover state and title tags to help the user, so make sure things look like they can be pushed.&lt;/p&gt;&lt;p&gt;Labels are important, make sure they mean something to the user. Everyone knows what “back” means, &lt;em&gt;so use it&lt;/em&gt;. If you have a path that requires a few taps, instead of labeling the back button with the previous page title, just name it “back”. Keep the labels simple and meaningful. Also, avoid lumping all the misc stuff you don’t know what to do with in some about or info tab. These are potential dungeons that trap the user. Keep in mind that less navigation &lt;strong&gt;doesn’t mean easy&lt;/strong&gt;, so adding an extra nav button or two for “My Profile” or “Passwords” is better than burying it in the “settings” basement.&lt;/p&gt;&lt;p&gt;Icons are a great simple way of communicating meaning. Not that text is hard to read on a phone or takes too much time, but because graphic representations create a better visual balance. Mobile is a &lt;strong&gt;fun environment&lt;/strong&gt; to use and well crafted icons can improve the overall experience for the user. Plus, icons combined with clear labels create even more meaning for the user and give them a clear navigation path.&lt;/p&gt;&lt;h3&gt;2- Focused Content&lt;/h3&gt;&lt;p&gt;&lt;a href="http://m.yasalam.ae/"&gt;&lt;img title="http://m.yasalam.ae" src="http://tympanus.net/codrops/wp-content/uploads/2012/01/content_opt.jpg" alt="http://m.yasalam.ae" width="580" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Just as removing taps doesn’t actually make things easier or faster, simply removing content doesn’t make your &lt;strong&gt;mobile easier&lt;/strong&gt; to use either. If you remove content between your web site and your mobile site, you may be removing content that your user may need or even want to have. You need to focus your content more — this will help with both your web site and your mobile site.&lt;/p&gt;&lt;p&gt;Instead of removing “non-important” content, just refocus or re-purpose it. You may be able to get away with using large chunks of text on a large display and for the most part on the mobile display, but just to make reading easier for everyone, re-purpose that into &lt;strong&gt;smaller paragraphs&lt;/strong&gt; or even bullets. Also, break up large text areas with other things like quotes, lines or either design elements that make large blocks of text more enjoyable. Instead of deleting large chunks of content from the mobile view, just break it down into smaller bites.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Consider using visual elements to complement text elements:&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use title icons alongside the header text.&lt;/li&gt;&lt;li&gt;Use graphics date elements instead of just listing the dates.&lt;/li&gt;&lt;li&gt;Use small info graphics that re-enforce what is being explained.&lt;/li&gt;&lt;li&gt;Use differing text/header colors instead of font size to make the distinction.&lt;/li&gt;&lt;li&gt;Use light background color to define different elements of content.&lt;/li&gt;&lt;li&gt;Use highlights to emphasize important areas.&lt;/li&gt;&lt;li&gt;Use padding and negative space to emphasize or separate areas of text.&lt;/li&gt;&lt;li&gt;Use different “views” to break up large bits of content into smaller ones.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Your users still want all your content so give it to them, just make it easier to access by breaking it up and re-enforcing it with other visual mechanisms.&lt;/p&gt;&lt;h3&gt;3- Feedback&lt;/h3&gt;&lt;p&gt;&lt;a href="http://m.ridesnowboards.com/"&gt;&lt;img title="http://m.ridesnowboards.com" src="http://tympanus.net/codrops/wp-content/uploads/2012/01/feedback_opt.jpg" alt="http://m.ridesnowboards.com" width="580" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Okay, this one is actually not just important to mobile web sites but to all websites. User feedback is huge and it gets even more important for mobile because you have no browser crutches to rely on.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Browser feedback&lt;/strong&gt; crutches like hover states and animation don’t really exist on mobile touch devices. Mobile devices really just sit there until they are touched. So providing clear feedback when something is touched, has been touched or is active, is very important. If I have a list view of items I can touch, I expect it to react visually the same way I would touch something in real life and have it react texturally.&lt;/p&gt;&lt;p&gt;When I touch, for instance, the button on an ATM machine I get generally two or three forms of feedback from the machine: the display will visually react somehow, the button may make a slight noise (either machine generated or just a physical noise form the movement), and I will be able to feel the cold metal button on my finger tips. This is how the machine acknowledges to me that I am doing something with it. On most mobile devices, we are generally only given the one options — &lt;em&gt;visual reaction&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Consider using visual feedback mechanisms to communicate user actions:&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use color to highlight areas that have been selected or activated.&lt;/li&gt;&lt;li&gt;Use fade in and fade out animations as users touch one element and another.&lt;/li&gt;&lt;li&gt;Use subtle border colors and gradients on buttons that react when touched.&lt;/li&gt;&lt;li&gt;Use differing button or text colors to symbolize changes in states.&lt;/li&gt;&lt;li&gt;Use a turning/turned arrow when drop downs are selected.&lt;/li&gt;&lt;li&gt;Use slide or fade animations between views to indicated changing states.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;4- Clear Branding&lt;/h3&gt;&lt;p&gt;&lt;a href="http://www.drpepper.com/mobile"&gt;&lt;img title="http://www.drpepper.com/mobile" src="http://tympanus.net/codrops/wp-content/uploads/2012/01/branding_opt.jpg" alt="http://www.drpepper.com/mobile" width="580" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;As much as we like to design incredibly fantastical web designs so that we can show off our design knowledge and skills, one of the biggest most important elements in any design is the branding. Don’t forget the branding. Despite the lack of real estate on mobile devices &lt;strong&gt;you can’t forget&lt;/strong&gt; to constantly brand them — there is always room for a company logo.&lt;/p&gt;&lt;p&gt;There are plenty of style and branding elements that go along with any company or app. But the two main, key design elements that make up a clear brand are the logo/wordmark and the color scheme that represents the company. For mobile web design, it’s crucial to make sure that these elements are present. The logo positioning may differ from the full screen version and may even only be present on the home view of the web application. Which makes the &lt;strong&gt;color scheme&lt;/strong&gt; really important to carry the branding throughout the app.&lt;/p&gt;&lt;p&gt;Another small, but important thing to consider is that mobile browsers don’t have a title bar or URL bar at the top that contain a site title and favicon. This small but important detail allows full screen browsers the ability to remind the user where they are and where they have been. The absence of the title and URL bar on mobile devices make branding your design more important because the user doesn’t have the &lt;em&gt;convenience&lt;/em&gt; to simply look up and see where they are.&lt;/p&gt;&lt;h3&gt;5- Plenty of Space&lt;/h3&gt;&lt;p&gt;&lt;a href="http://www.burton.com/"&gt;&lt;img title="http://www.burton.com" src="http://tympanus.net/codrops/wp-content/uploads/2012/01/whitespace_opt.jpg" alt="http://www.burton.com" width="580" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Don’t let the small screen size fool you, you still need white space. White space is a key element of design in any good design. In mobile design, white space becomes even more critical than in a full size design because you don’t have that much space to deal with. For your mobile design to be &lt;strong&gt;effective&lt;/strong&gt;, usable and readable, all elements in the design (&lt;em&gt;buttons, navigation, icons, text, etc&lt;/em&gt;) need to be separated clearly and be framed properly.&lt;/p&gt;&lt;p&gt;Better user experience doesn’t mean that you have to limit content to afford white space, it doesn’t mean that you have to use large fonts in order to be readable, and it doesn’t mean that you should avoid padding to better use the &lt;strong&gt;limited screen size&lt;/strong&gt;. Mobile websites require more UI planning than larger screen designs. White space plays a huge role in planning this effective user experience.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Consider these ways of using white space to create a better user experience:&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use smaller fonts with more space around them, not larger fonts squished together.&lt;/li&gt;&lt;li&gt;Use plenty of padding around all box elements to frame text blocks or icons.&lt;/li&gt;&lt;li&gt;Use a clear grid with plenty of white between each element to clearly separate elements.&lt;/li&gt;&lt;li&gt;Use plenty of padding around the entire view to wrap all elements and keep elements from floating off into unreachable/untouchable places.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Post: &lt;a href="http://tympanus.net/codrops/2012/01/12/5-things-every-mobile-design-should-have/"&gt;5 Things Every Mobile Design Should Have&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-6791431401571050580?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zmmszasExOJpDNLuBXAmKj23Fwc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zmmszasExOJpDNLuBXAmKj23Fwc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zmmszasExOJpDNLuBXAmKj23Fwc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zmmszasExOJpDNLuBXAmKj23Fwc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/kceMJtTS764" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6791431401571050580?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6791431401571050580?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/kceMJtTS764/5-things-every-mobile-design-should.html" title="5 Things Every Mobile Design Should Have" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/5-things-every-mobile-design-should.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MEQnozfSp7ImA9WhRVF08.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-4798262235957529718</id><published>2012-01-16T07:56:00.000-08:00</published><updated>2012-01-16T07:56:43.485-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-16T07:56:43.485-08:00</app:edited><title>Textarea Auto Resize</title><content type="html">&lt;p&gt;&lt;img src="http://cdn.impressivewebs.com/2012-01/textarea-auto-resize.jpg" alt="Textarea Auto Resize" title="Textarea Auto Resize" width="184" height="184" /&gt;On a current project, I was trying to find a way to auto-resize a textarea according to some content that would be loaded in dynamically via Ajax. I didn’t know the height of the content and the textarea element doesn’t resize naturally like other HTML elements, so I needed to update the height of the element with JavaScript each time the content changed.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It seemed like a simple task. After doing a search to see what types of plugins and scripts were floating around to do this, the examples I found seemed a little overly complex. While most solutions seemed to incorporate some complex math calculations, I thought of a better way.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Using a Hidden Clone Element&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;A &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element will naturally stretch to fit the height of its content (assuming no floats or absolutely positioned elements are involved). So to get the height of the textarea, I just need to do the following:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Grab the content loaded into the textarea&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Create an invisible clone div&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Give the clone the same width and typographical properties as the textarea&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Place the content into the clone&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Get the height of the clone&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Apply the height of the clone to the height of the textarea&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;The Code&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;One of the keys to this solution is the CSS. As mentioned, the invisible clone needs to have the same typographical properties as the textarea. Not only does this include stuff line &lt;code&gt;font-size&lt;/code&gt; and &lt;code&gt;font-family&lt;/code&gt;, but also the &lt;code&gt;white-space&lt;/code&gt; and &lt;code&gt;word-wrap&lt;/code&gt; properties of the clone need to be set to mimic what happens inside the textarea.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;First here’s the CSS for the textarea:&lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;textarea {&lt;br /&gt;   width: 500px;&lt;br /&gt;   min-height: 50px;&lt;br /&gt;   font-family: Arial, sans-serif;&lt;br /&gt;   font-size: 13px;&lt;br /&gt;   color: #444;&lt;br /&gt;   padding: 5px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.noscroll {&lt;br /&gt;   overflow: hidden;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Take note that I’ve added a separate class with &lt;code&gt;overflow: hidden&lt;/code&gt;, to prevent scrollbars from appearing. Normally this would not be a good thing to add to a textarea element, but because I’ll be resizing it with JavaScript, it’s fine. This class will be added to the textarea with JavaScript, to ensure that if JavaScript is turned off, the textarea will scroll normally.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here is the CSS I’ll be applying to the hidden clone element:&lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;.hiddendiv {&lt;br /&gt;   display: none;&lt;br /&gt;   white-space: pre-wrap;&lt;br /&gt;   width: 500px;&lt;br /&gt;   min-height: 50px;&lt;br /&gt;   font-family: Arial, sans-serif;&lt;br /&gt;   font-size: 13px;&lt;br /&gt;   padding: 5px;&lt;br /&gt;   word-wrap: break-word;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;A quick break-down: First, I set it to &lt;code&gt;display: none&lt;/code&gt; because I don’t want it visible to the user. I believe this should be fine for screen readers, because I don’t want it read out to them either. If anyone has a better solution for hiding it for assistive devices, let me know.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I’ve also set the &lt;code&gt;white-space&lt;/code&gt; property to a value of “pre-wrap”. This ensures that lines will wrap correctly, but everything else gets pre-formatted. I’ve also set the width to be equal to the textarea, and duplicated a few typographical properties. In both examples, I’m giving the clone and the textarea a &lt;code&gt;min-height&lt;/code&gt; so it will always start out at a standard, usable height.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now for the JavaScript (which is using jQuery, &lt;a href="http://www.impressivewebs.com/why-use-jquery-simple-tutorials/"&gt;sorry&lt;/a&gt;):&lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;$(function() {&lt;br /&gt; var txt = $('#comments'),&lt;br /&gt; hiddenDiv = $(document.createElement('div')),&lt;br /&gt; content = null;&lt;br /&gt;&lt;br /&gt; txt.addClass('noscroll');&lt;br /&gt; hiddenDiv.addClass('hiddendiv');&lt;br /&gt;&lt;br /&gt; $('body').append(hiddenDiv);&lt;br /&gt;&lt;br /&gt; txt.bind('keyup', function() {&lt;br /&gt;&lt;br /&gt;     content = txt.val();&lt;br /&gt;     content = content.replace(/\n/g, '&amp;lt;br&amp;gt;');&lt;br /&gt;     hiddenDiv.html(content);&lt;br /&gt;&lt;br /&gt;     txt.css('height', hiddenDiv.height());&lt;br /&gt;&lt;br /&gt; });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;This code assumes we’re targeting a single textarea element on the page. If you need this to affect more than one element, then just change the first line inside the function that defines the element we’re working with.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I’m dynamically changing the height based on jQuery’s &lt;code&gt;keyup&lt;/code&gt; event. You could easily change this to respond to an Ajax request instead, if you happen to be loading the content that way.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Using &lt;code&gt;keyup&lt;/code&gt;, however, is a good solution because it’s the most likely reason that you’ll want to auto-resize a textarea — user-entered data.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;What About IE6-8?&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;I almost didn’t write this article, because the code wasn’t working at all in IE6-8. The reason for this had to do with the &lt;a href="http://www.quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html"&gt;poor way IE handles grabbing content using innerHTML&lt;/a&gt;. So after I had written this simple solution that seemed to work in all the newer browsers, I came across &lt;a href="http://javascriptly.com/examples/jquery-grab-bag/autogrow-textarea.html" rel="nofollow"&gt;this jQuery plugin&lt;/a&gt;. That solution uses the exact same method that I’m using (the cloned element), and it worked (mostly) in IE.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So the line that I borrowed from that example that (mostly) fixed mine in IE was:&lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;// fixes the IE innerHTML problem&lt;br /&gt;content = content.replace(/\n/g, '&amp;lt;br&amp;gt;');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;But even after adding this line, there was still an issue: Long, unbroken strings of text wouldn’t affect the height of the textarea (which isn’t a big problem, really). A simple fix was adding &lt;code&gt;word-wrap: break-word&lt;/code&gt; to the CSS for the clone element.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Bugs? Problems?&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Like the other solutions floating around, this could easily be turned into a plugin. In that case, I’d have to add a little more jQuery so that the characteristics of the clone element aren’t dependent on the CSS. Also, if the width of the textarea is fluid, then you’d have to use jQuery to grab that, and then apply it to the clone.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The solution I linked to in the previous section is just about perfect — you just need to add the &lt;code&gt;word-wrap&lt;/code&gt; fix that I mentioned.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;For a demo, you can view my JSFiddle using the link below. Just be sure to hit the “run” button before you test it. Let me know if you find any problems with it.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://jsfiddle.net/ImpressiveWebs/fGNNT/16/" title="View Demo"&gt;View Demo&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.impressivewebs.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&amp;amp;post_id=5346" width="1" height="1" /&gt;&lt;p&gt;Related posts:&lt;/p&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.impressivewebs.com/css3-resize/" rel="bookmark" title="The CSS3 Resize Property"&gt;The CSS3 Resize Property&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.impressivewebs.com/word-wrap-css3/" rel="bookmark" title="Word-Wrap: A CSS3 Property That Works in Every Browser"&gt;Word-Wrap: A CSS3 Property That Works in Every Browser&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div&gt;Post: &lt;a href="http://www.impressivewebs.com/textarea-auto-resize/"&gt;Textarea Auto Resize&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-4798262235957529718?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GwNHy9H7DtNVH0UQ6IvzV_DVB4Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GwNHy9H7DtNVH0UQ6IvzV_DVB4Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GwNHy9H7DtNVH0UQ6IvzV_DVB4Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GwNHy9H7DtNVH0UQ6IvzV_DVB4Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/Ley5ETRx3MA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/4798262235957529718?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/4798262235957529718?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/Ley5ETRx3MA/textarea-auto-resize.html" title="Textarea Auto Resize" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/textarea-auto-resize.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAER3w-fip7ImA9WhRVF08.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-5769705793865053438</id><published>2012-01-16T05:31:00.000-08:00</published><updated>2012-01-16T05:31:46.256-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-16T05:31:46.256-08:00</app:edited><title>HTML5 Video vs. HTML Video</title><content type="html">&lt;img width="50" height="50" src="http://cdn.sitepoint.com/wp-content/uploads/2012/01/feature1-50x50.png" alt="feature" title="feature" /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Nowadays, designers and developers have several options for integrating video into a web page. You can design your own video player, use free widgets, embed YouTube video code or buy a fancy flash pop-up player.&lt;/p&gt;&lt;p&gt;There are many forms, shapes and layouts for online video players – all designed to enhance your web presence. But no matter which player you use, the key purpose is to provide quick access to your video content for &lt;em&gt;all&lt;/em&gt; your visitors.&lt;/p&gt;&lt;p&gt;That means each user should be able to play video without receiving an unfriendly “Install Flash plug-in to watch this video” message. Alerts like that impair the user experience and raise a website’s bounce rate.&lt;/p&gt;&lt;p&gt;Contemplating this, you might tend towards HTML5 video technology. After all, HTML5 promises to play video directly in the browser without any plug-ins. At first sight, it looks like the ultimate video solution. But before you switch your website video to HTML5, let’s compare the pros and cons of classic HTML video and innovative HTML5 video integration.&lt;/p&gt;&lt;p&gt;Flash is HTML video middleware. It’s now the most traditional way to embed video into a website. The &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt; tag and Flash plug-ins help to play video in the browser.&lt;/p&gt;&lt;div&gt;   &lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Here’s some typical HTML video embed code:&lt;/p&gt;&lt;pre&gt;&amp;lt;object id=0 type="application/x-shockwave-flash" data=player_flv_maxi.swf width=512 height=384&amp;gt;&lt;br /&gt;&amp;lt;param name="movie" value=player_flv_maxi.swf /&amp;gt;&lt;br /&gt;&amp;lt;param name="wmode" value="opaque" /&amp;gt;&lt;br /&gt;&amp;lt;param name="allowFullScreen" value="true" /&amp;gt;&lt;br /&gt;&amp;lt;param name="allowScriptAccess" value="sameDomain" /&amp;gt;&lt;br /&gt;&amp;lt;param name="quality" value="high" /&amp;gt;&lt;br /&gt;&amp;lt;param name="menu" value="true" /&amp;gt;&lt;br /&gt;&amp;lt;param name="autoplay" value="false" /&amp;gt;&lt;br /&gt;&amp;lt;param name="autoload" value="false" /&amp;gt;&lt;br /&gt;&amp;lt;param name="FlashVars" value="flv=movie1.flv&amp;amp;width=512&amp;amp;height=384&amp;amp;autoplay=0&amp;amp;autoload=0&amp;amp;&lt;br /&gt; buffer=5&amp;amp;buffermessage=&amp;amp;playercolor=464646&amp;amp;loadingcolor=999898&amp;amp;buttoncolor=ffffff&amp;amp;&lt;br /&gt; buttonovercolor=dddcdc&amp;amp;slidercolor=ffffff&amp;amp;sliderovercolor=dddcdc&amp;amp;showvolume=1&amp;amp;showfullscreen=1&amp;amp;&lt;br /&gt; playeralpha=100&amp;amp;title=movie1.flv&amp;amp;margin=0&amp;amp;buffershowbg=0" /&amp;gt;&lt;br /&gt;&amp;lt;/object&amp;gt;&lt;/pre&gt;&lt;p&gt;As with all middleware, Adobe Flash plug-ins lag behind and do require constant updates.&lt;/p&gt;&lt;p&gt;HTML5 does not need any plug-ins or updates. With the new &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tag you’re able to &lt;a href="http://www.sitepoint.com/how-to-embed-video-using-html5/"&gt;insert video in a page&lt;/a&gt; like this:&lt;/p&gt;&lt;pre&gt;&amp;lt;video width="320"&lt;br /&gt;   height="240"&lt;br /&gt;   poster="intro.jpg"&lt;br /&gt;   autoplay&lt;br /&gt;   controls&lt;br /&gt;   loop&amp;gt;&lt;br /&gt;   This content appears if the video tag or the codec is not supported.&lt;br /&gt;   &amp;lt;source src="intro.mp4" type="video/mp4" /&amp;gt;&lt;br /&gt;   &amp;lt;source src="intro.webm" type="video/webm" /&amp;gt;&lt;br /&gt;   &amp;lt;source src="intro.ogv" type="video/ogg" /&amp;gt;&lt;br /&gt;   &amp;lt;/video&amp;gt;&lt;/pre&gt;&lt;p&gt;As you see, when using HTML5, videos should be offered in three main formats: H.264 (.mp4), WebM and Theora OGG. Covering all three formats gives you the best chance of correct playback on all devices.&lt;/p&gt;&lt;p&gt;However, HTML5 does not guarantee playback in &lt;em&gt;all&lt;/em&gt; browsers. Internet Explorer 6, 7 and 8 cannot play HTML5 video. This becomes relevant when you know you have site visitors who use such browsers.Therefore, you should thoroughly examine your site traffic statistics to count the percentage of users of Internet Explorer versions prior to HTML5 video migration. Google Analytics is a great tool for this.&lt;/p&gt;&lt;p&gt;It may turn out that 60% of your audience sticks to old-fashioned browsers and thus HTML5 may not be a good video remedy for your website. Alternatively, if the majority of your visitors are mobile web consumers, HTML5 video is worth embedding in your site.&lt;/p&gt;&lt;p&gt;The table below summarizes the most frequent HTML/HTML5 advantages and disadvantages to take into account:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;HTML Video vs. HTML5 Video&lt;/strong&gt;&lt;/p&gt;&lt;table width="641" border="1" cellspacing="0" cellpadding="0" style="font-size:85%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;&lt;p align="center"&gt;&lt;strong&gt;Markup&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;&lt;p align="center"&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="213"&gt;&lt;p align="center"&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td rowspan="4" style="padding:10px" width="214"&gt;&lt;p align="center"&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;HTML Video&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;Well-known, time-proven markup language&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="213"&gt;Flash plug-in is a must&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;Supported by all desktop browsers: Internet Explorer, Firefox, Chrome, Opera, Safari&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="213"&gt;Constant plug-in updates&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;Many video hosting options: own server, YouTube, Vimeo, etc&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="213"&gt;Slow, high-load videos&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;Lots of video embedding methods: from advanced coding to simple YouTube copy-paste code&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="213"&gt;No video playback on mobiles like iPad and iPhone&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td rowspan="3" style="padding:10px" width="214"&gt;&lt;p align="center"&gt;&lt;strong&gt;HTML5&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;No plug-ins needed&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="213"&gt;Not supported by Internet Explorer 6, 7, 8&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;Works on both desktop and mobile devices&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="213"&gt;Requires video conversion&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" style="padding:10px" width="214"&gt;Flexible player settings: users can move and rotate web players&lt;/td&gt;&lt;td valign="top" style="padding:10px" width="213"&gt;No stable specification. You have to study new markup principles&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;At first glance, HTML5 video seems to have more drawbacks than assets. But if you delve into HTML5 video further, you will see that the emerging web technology is not so obscure. It already has a solid toolbox for developers to benefit from.&lt;/p&gt;&lt;p&gt;It’s true that HTML5 video is not supported by Internet Explorer 6,7 or 8. So, for those users, provide a fallback direct link to YouTube or a download so site visitors can watch the standard Flash video:&lt;/p&gt;&lt;pre&gt;&amp;lt;video width="640" height="360" controls&amp;gt;&lt;br /&gt;   &amp;lt;source src="__VIDEO__.MP4"  type="video/mp4" /&amp;gt;&lt;br /&gt;   &amp;lt;source src="__VIDEO__.OGV"  type="video/ogg" /&amp;gt;&lt;br /&gt;   &amp;lt;object width="640" height="360" type="application/x-shockwave-flash" data="__FLASH__.SWF"&amp;gt;&lt;br /&gt;       &amp;lt;param name="movie" value="__FLASH__.SWF" /&amp;gt;&lt;br /&gt;       &amp;lt;param name="flashvars" value="controlbar=over&amp;amp;amp;image=__POSTER__.JPG&amp;amp;amp;file=__VIDEO__.MP4" /&amp;gt;&lt;br /&gt;       &amp;lt;img src="__VIDEO__.JPG" width="640" height="360" alt="__TITLE__" title="No video playback&lt;br /&gt;           capabilities, please download the video below" /&amp;gt;&lt;br /&gt;   &amp;lt;/object&amp;gt;&lt;br /&gt;&amp;lt;/video&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;     &amp;lt;strong&amp;gt;Download Video:&amp;lt;/strong&amp;gt;&lt;br /&gt;             Closed Format:         &amp;lt;a href="__VIDEO__.MP4"&amp;gt;"MP4"&amp;lt;/a&amp;gt;&lt;br /&gt;             Open Format:            &amp;lt;a href="__VIDEO__.OGV"&amp;gt;"Ogg"&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/p&amp;gt;&lt;/pre&gt;&lt;p&gt;Converting HTML5 into the three formats (H.264, OGG and WebM) is not as scary as it might sound. There are several free solutions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://handbrake.fr/"&gt;HandBrake Video Converter&lt;/a&gt; for Mac&lt;/strong&gt;. Free, this famous video conversion software can deal with HTML5 video conversion&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.freemake.com/free_video_converter/"&gt;Freemake Video Converter 3.0&lt;/a&gt; for Windows&lt;/strong&gt;. It’s 100% free video converting tool. Select a video, click “HTML5” button and you get video files in all three formats and video player code for embedding. Video Converter by Freemake does all work for you (disclosure: I work for Freemake).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://zamzar.com/"&gt;Zamzar&lt;/a&gt;.&lt;/strong&gt; Free online video converter. Zamzar encoding is bit slow. Besides, you will get files by email.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So, even the cons do not mean you cannot&lt;a href="http://www.sitepoint.com/5-reasons-why-you-can-use-html5-today/%22"&gt; use HTML5 today&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;On the contrary, the HTML cons are actually harder to avoid. The vulnerable Adobe Flash plug-in, inappropriate for handheld gadgets, is a stumbling block for streaming video integration. the most popular mobile hardware does not support Flash video. Recently, &lt;a href="http://www.sitepoint.com/adobe-abandons-mobile-flash/"&gt;Adobe has even canceled further Flash plugin development&lt;/a&gt; and turned to the HTML5 / CSS3 eco-system with their Adobe Edge design tool.&lt;/p&gt;&lt;p&gt;Obviously, HTML5 is well on its way to fame and fortune, but it’s too early to declare a complete HTML5 victory over Flash video, as Flash still dominates on streaming web services. At least we should be well equipped to transfer smoothly from one markup to another without traffic losses.&lt;/p&gt;&lt;p&gt;What methods are you using to implement video on a webpage?&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://feedproxy.google.com/~r/SitepointFeed/~3/wWgG3RbE0-I/"&gt;HTML5 Video vs. HTML Video&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-5769705793865053438?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gLedAP-cMRQiP5rZ_gxyfq3AAR8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gLedAP-cMRQiP5rZ_gxyfq3AAR8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gLedAP-cMRQiP5rZ_gxyfq3AAR8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gLedAP-cMRQiP5rZ_gxyfq3AAR8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/6IzZcWw2nYw" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/5769705793865053438?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/5769705793865053438?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/6IzZcWw2nYw/html5-video-vs-html-video.html" title="HTML5 Video vs. HTML Video" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/html5-video-vs-html-video.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIBR3w-eSp7ImA9WhRVE08.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-4186220829325050570</id><published>2012-01-11T14:55:00.000-08:00</published><updated>2012-01-11T14:55:56.251-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-11T14:55:56.251-08:00</app:edited><title>Responsive Data Table Roundup</title><content type="html">&lt;p&gt;There has been a bunch of takes on responsive data tables since I &lt;a href="http://css-tricks.com/responsive-data-tables/"&gt;first published about it&lt;/a&gt;. &lt;span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2012/01/orig.jpg" alt="" title="orig" width="1055" height="526" /&gt; &lt;a href="http://css-tricks.com/examples/ResponsiveTables/responsive.php"&gt;View Demo&lt;/a&gt; &lt;p&gt;The idea of the original was to abandon the grid layout of the table and make each cell it's own line. Each of those lines is labeled with a pseudo element. This creates a much taller table, requiring more vertical scrolling, but does not require horizontal scrolling. It's easier to browse the data without losing context of what's what. The downside is that you might lose the context of data comparison, since you no longer see see cells of data right next to other cells of that type.&lt;/p&gt;&lt;p&gt;Mobifreaks published a &lt;a href="http://www.mobifreaks.com/user-interface/responsive-and-seo-friendly-data-tables/"&gt;very similar idea&lt;/a&gt;, which uses the same layout change and pseudo element labeling. They used HTML5 data-* attributes for the labeling, which removes the need to have custom CSS for  different tables. I don't buy into the SEO part, but the code is good.&lt;/p&gt;&lt;p&gt;Derek Pennycuff took the original and &lt;a href="http://jsbin.com/arixic"&gt;applied the "mobile first" concept&lt;/a&gt;. Instead of starting with table markup it starts with definition list markup, then forces it into a table layout when the screen is large enough to accomodate it. While I love the thinking here, I'm not sure I like what it takes to get it done. The markup is much heavier and (ironically) I don't think it's semantic. Tabular data should be marked up as a table. I think the philosophy behind "mobile first" is keeping things simple and lighter by default and heavier and more complex for larger screens. This demo starts out and stays heavy.&lt;/p&gt;&lt;p&gt;Scott Jehl cooked up two clever ideas. One was to build a chart from the data in the table. In this demo it's pie chart that is much narrower than the complete data table and thus more suitable for small screens.&lt;/p&gt;  &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2012/01/responsivetabletochart.jpeg" alt="" title="responsivetabletochart" width="570" height="369" /&gt; &lt;a href="http://jsbin.com/emexa4"&gt;View Demo&lt;/a&gt; &lt;p&gt;Pretty cool, but clearly all tables can't be converted into charts. I'd also argue a data table and a chart are pretty different things. If you are going to go through the trouble of making a chart, it would probably be good to show that to the larger screen as well as it provides context in an useful alternative way. Or at least have an option to see it.&lt;/p&gt;&lt;p&gt;Scott's other idea focuses on the problem that large data tables can stretch out the width of a parent container beyond what a small screen is capable of displaying. So to prevent this, a media query is used to hide the table on small screens, replaced with a small mock-table and a link to view the full table.&lt;/p&gt;  &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2012/01/taptoviewtable.jpeg" alt="" title="taptoviewtable" width="570" height="502" /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/apane6/14"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Stewart Curry had the idea of &lt;a href="http://www.irishstu.com/stublog/2011/12/13/tables-responsive-design-part-2-nchilds/"&gt;just hiding less important columns&lt;/a&gt; for smaller screens. One of people's earliest gripes of mobile-specific sites was that just because they are on a mobile device doesn't mean they deserve a less-than-full experience than a user with a larger screen (especially since these devices are totally capable of maneuvering around "full" sites).&lt;/p&gt;  &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2012/01/stu.jpg" alt="" title="stu" width="688" height="502" /&gt; &lt;a href="http://www.irishstu.com/stublog/wp-content/uploads/2011/12/table-childs.html"&gt;View Demo&lt;/a&gt; &lt;p&gt;I think Stewart was on to something though. Using small screens to focus information to the most important things is great, it just shouldn't lock away information with no recourse. Maggie Costello Wachs of Filament Group also had the idea of &lt;a href="http://filamentgroup.com/lab/responsive_design_approach_for_complex_multicolumn_data_tables/"&gt;hiding non-essential columns on smaller screens&lt;/a&gt;, but also providing a dropdown menu where you can re-enable them if you wish (which you can get to see with horizontal scrolling).&lt;/p&gt;  &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2012/01/filament.jpg" alt="" title="filament" width="700" height="582" /&gt; &lt;a href="http://filamentgroup.com/examples/rwd-table-patterns/"&gt;View Demo&lt;/a&gt; &lt;p&gt;David Bushell also tackled the idea of not altering the basic table format, but still solving the "too wide" problem. His concept &lt;a href="http://dbushell.com/2012/01/05/responsive-tables-2/"&gt;flips the table on it's side&lt;/a&gt; and applies &lt;code&gt;overflow-x: auto&lt;/code&gt; to the &lt;code&gt;tbody&lt;/code&gt; meaning the data cells can scroll left and right if it breaks out of a small screen, but you still always see the headers (as if they were fixed position).&lt;/p&gt;  &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2012/01/david.jpg" alt="" title="david" width="690" height="533" /&gt; &lt;a href="http://dbushell.com/demos/tables/rt_05-01-12.html"&gt;View Demo&lt;/a&gt; &lt;p&gt;Brad Czerniak has an idea he calls &lt;a href="http://hawidu.com/2011/04/27/another-responsive-data-tables-approach/"&gt;Rainbow Tables&lt;/a&gt; where on smaller screens the grid structure of the table is abandoned and the data cells are squished into each other as tight as they will go, while still being a "row". Then instead of the data be identified by which column it is in, the data is color coded to match a key.&lt;/p&gt;  &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2012/01/rainbow.jpg" alt="" title="rainbow" width="700" height="424" /&gt; &lt;a href="http://hawidu.com/responsivetables/"&gt;View Demo&lt;/a&gt; &lt;p&gt;If you've seen or have an idea for more possibilities for responsive data tables, let us know in the comments below. I'll keep this post updated with all the design patterns for this I know about.&lt;/p&gt;&lt;p&gt;&lt;a href="http://css-tricks.com/responsive-data-table-roundup/"&gt;Responsive Data Table Roundup&lt;/a&gt; is a post from &lt;a href="http://css-tricks.com/"&gt;CSS-Tricks&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-4186220829325050570?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/diXhp0fmHHmK6muKMATy6_nbM9A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/diXhp0fmHHmK6muKMATy6_nbM9A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/diXhp0fmHHmK6muKMATy6_nbM9A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/diXhp0fmHHmK6muKMATy6_nbM9A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/m8EI1jSApjg" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/4186220829325050570?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/4186220829325050570?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/m8EI1jSApjg/responsive-data-table-roundup.html" title="Responsive Data Table Roundup" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/responsive-data-table-roundup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAESXYzfip7ImA9WhRVEU0.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-6912729503973657390</id><published>2012-01-09T03:31:00.000-08:00</published><updated>2012-01-09T03:31:48.886-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-09T03:31:48.886-08:00</app:edited><title>Introducing Video Player Sample</title><content type="html">&lt;a href="http://feedproxy.google.com/~r/GoogleCodeNews/~3/RuvwkDGw9Ko/introducing-video-player-sample.html"&gt;Introducing Video Player Sample&lt;/a&gt;: Have you ever wanted a fun and beautiful way to publish videos on your own site like the new &lt;a href="https://chrome.google.com/webstore/detail/imjhdahelgojehmfmkmdfjcpfbglbfmj"&gt;60 Minutes&lt;/a&gt; or&lt;a href="https://chrome.google.com/webstore/category/home"&gt; RedBull.tv&lt;/a&gt; apps from the &lt;a href="https://chrome.google.com/webstore/category/home"&gt;Chrome Web Store&lt;/a&gt;? I'm excited to announce the release of &lt;a href="http://code.google.com/p/video-player-sample/"&gt;The Video Player Sample&lt;/a&gt;! The Video Player Sample is an open source video player web app built using the same architecture as the 60 Minutes and RedBull.tv apps. It can be customized, extended, or just used out of the box and populated with your own content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-aUmnVCdSFRU/TwdQs66csYI/AAAAAAAAAds/Blw-yv2nhOA/s1600/player-full.png"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-aUmnVCdSFRU/TwdQs66csYI/AAAAAAAAAds/Blw-yv2nhOA/s320/player-full.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How it works&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;When a user opens the Video Player Sample web app, they can choose to watch a single video or create a playlist of videos/episodes from a list that they have uploaded and populated to the app. &lt;a href="http://video-player-sample.appspot.com/"&gt;The Video Player Sample&lt;/a&gt; is configured and information about the videos is stored in JSON files (config.json and data.json respectively), both of which are located in the data directory.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Key features&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;A beautiful video watching experience, including a full screen view&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ability to subscribe to shows, watch episodes, create play lists&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for multiple video formats depending on what the user’s browser supports (including WebM, Ogg, MP4, and even a Flash fallback)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A &lt;a href="http://video-player-sample.appspot.com/#/shows"&gt;Categories&lt;/a&gt; page with an overview of the different shows/categories available in the app&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Notifications of new episodes (when the app is installed via the Chrome Web Store)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Built in support for sharing to Google+, Twitter and Facebook&lt;/li&gt;&lt;br /&gt;&lt;li&gt;To ensure easy customization, all source files, including the Photoshop PSD’s, are included&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-umRYybDHsRQ/TwdUrgsFVAI/AAAAAAAAAeM/63KNBf2O6Wc/s1600/player-shows.png" style="margin-left:1em;margin-right:1em"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-umRYybDHsRQ/TwdUrgsFVAI/AAAAAAAAAeM/63KNBf2O6Wc/s320/player-shows.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How it's built&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The Google Video Application is written for the open web platform using HTML and JavaScript, broadly following the MVC (&lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;Model View Controller&lt;/a&gt;) pattern and structure.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;It is built using the open source Google &lt;a href="http://code.google.com/closure/"&gt;Closure JavaScript library&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Compiled with the &lt;a href="http://code.google.com/closure/compiler/"&gt;Closure Compiler&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Distributed through the Chrome Web Store to take advantage of notifications&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Browser Support&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In addition to working as an app that can be installed through the Chrome Web Store, the Video Player Web App has been tested and works in all of the modern browsers.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Try it out&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You can see a demo of the video player in action in the &lt;a href="http://video-player-sample.appspot.com/"&gt;demo app&lt;/a&gt;, or by &lt;a href="https://chrome.google.com/webstore/detail/jhojbofcldbpmilfcnlihpknapnaagce"&gt;Adding it to Chrome&lt;/a&gt; through the Chrome Web Store. To learn more about how the app works, check out the &lt;a href="http://docs.video-player-sample.appspot.com/"&gt;documentation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can grab the code from &lt;a href="http://code.google.com/p/video-player-sample/"&gt;Google Code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;By Pete LePage, Chrome Web Store Developer Relations Team&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-6912729503973657390?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BwD6KgYQD5NuezDGP9ntFpoRfE4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BwD6KgYQD5NuezDGP9ntFpoRfE4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BwD6KgYQD5NuezDGP9ntFpoRfE4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BwD6KgYQD5NuezDGP9ntFpoRfE4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/7EW_fkz02d8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6912729503973657390?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6912729503973657390?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/7EW_fkz02d8/introducing-video-player-sample.html" title="Introducing Video Player Sample" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-aUmnVCdSFRU/TwdQs66csYI/AAAAAAAAAds/Blw-yv2nhOA/s72-c/player-full.png" height="72" width="72" /><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/introducing-video-player-sample.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cBRH44eyp7ImA9WhRWGEo.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-6584265718430341437</id><published>2012-01-06T10:37:00.000-08:00</published><updated>2012-01-06T10:37:35.033-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-06T10:37:35.033-08:00</app:edited><title>Introducing the New Cursor Styles in CSS3</title><content type="html">&lt;img width="50" height="50" src="http://cdn.sitepoint.com/wp-content/uploads/2011/11/601-css3-cursor-styles-50x50.png" alt="601-css3-cursor-styles" title="601-css3-cursor-styles" /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The early days of web development were a thrill as new technologies and techniques were discovered. We experienced a few stagnant years in the middle of last decade but, thanks to HTML5, web development has become exciting again. In particular, CSS3 is evolving rapidly and you’ll find some interesting gems in the specifications.&lt;/p&gt;&lt;p&gt;In this article, we’re going to examine the CSS cursor property which, as you’d expect, allows you to change the cursor style as the mouse moves over an element. It’s become increasingly important for interactive web applications…&lt;/p&gt;&lt;h2&gt;CSS2 Cursor Styles&lt;/h2&gt;&lt;p&gt;CSS2 offered relatively few options &lt;em&gt;(hover over any element to see how the cursor changes)&lt;/em&gt;:&lt;/p&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: auto&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: inherit&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: crosshair&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: default&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: help&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: move&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: pointer &lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: progress&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: text&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: wait&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: e-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: ne-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: nw-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: n-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: se-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: sw-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: s-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: w-resize&lt;/pre&gt;&lt;h2&gt;CSS3 Cursor Styles&lt;/h2&gt;&lt;p&gt;We have more styles to choose from in CSS3. These work in IE9 and the latest versions of Firefox, Chrome, Safari and Opera except where indicated:&lt;/p&gt;&lt;div&gt;   &lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: none (not IE, Safari, Opera)&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: context-menu (not Firefox, Chrome)&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: cell (not Safari)&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: vertical-text&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: alias (not Safari)&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: copy (not Safari)&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: no-drop&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: not-allowed&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: ew-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: ns-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: nesw-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: nwse-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: col-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: row-resize&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: all-scroll&lt;/pre&gt;&lt;h2&gt;Browser-Specific Cursors&lt;/h2&gt;&lt;p&gt;Mozilla and some editions of Chrome and Safari offer a number of vendor-prefixed cursor styles which are likely to become part of the CSS3 specification:&lt;/p&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: -webkit-grab; cursor: -moz-grab;&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: -webkit-grabbing; cursor: -moz-grabbing;&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: -webkit-zoom-in; cursor: -moz-zoom-in;&lt;/pre&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: -webkit-zoom-out; cursor: -moz-zoom-out;&lt;/pre&gt;&lt;h2&gt;Creating Your Own Cursor&lt;/h2&gt;&lt;p&gt;Finally, you can create your own cursor graphic, e.g.&lt;/p&gt;&lt;pre style="margin:1px 0;border:1px solid #000"&gt;cursor: url(images/cursor.cur);&lt;br /&gt;cursor: url(images/cursor.png) x y, auto;&lt;/pre&gt;&lt;p&gt;Note:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Internet Explorer requires a Windows cursor file (.cur).&lt;/li&gt;&lt;li&gt;Firefox, Chrome and Safari require an image — I’d recommend a 24-bit alpha-transparent PNG.&lt;/li&gt;&lt;li&gt;Firefox also requires a second non-URL cursor fallback value.&lt;/li&gt;&lt;li&gt;It’s not supported in Opera.&lt;/li&gt;&lt;li&gt;x and y are optional properties in Firefox, Chrome and Safari which define the precise pointer position from the top-left of the graphic. If omitted, 0 0 is assumed.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Nice, but it sounds like too much effort to me! I’ll be sticking with the standard cursor styles…&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://feedproxy.google.com/~r/SitepointFeed/~3/-6AC0qJchPQ/"&gt;Introducing the New Cursor Styles in CSS3&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-6584265718430341437?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RvnX74aWmVsjlWW-1rQSyrxbPfk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RvnX74aWmVsjlWW-1rQSyrxbPfk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RvnX74aWmVsjlWW-1rQSyrxbPfk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RvnX74aWmVsjlWW-1rQSyrxbPfk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/_sHDq2GnJHQ" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6584265718430341437?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6584265718430341437?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/_sHDq2GnJHQ/introducing-new-cursor-styles-in-css3.html" title="Introducing the New Cursor Styles in CSS3" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/introducing-new-cursor-styles-in-css3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0EGRHczcSp7ImA9WhRWF00.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-5589818900221085399</id><published>2012-01-04T10:27:00.000-08:00</published><updated>2012-01-04T10:27:05.989-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-04T10:27:05.989-08:00</app:edited><title>When good back-ends go bad</title><content type="html">&lt;p&gt;There has been a fair amount of &lt;a href="http://www.yuiblog.com/blog/2006/11/28/performance-research-part-1/"&gt;research&lt;/a&gt; that tells us that 80-90% of the time spent loading web pages is spent on the “front-end” (browser pulling in external resources like css, javascript and images) and only 10-20% of the time for a typical page is spent on the back-end.  While that is true “in general”, and there are a lot of tools that focus on giving you suggestions on improving your front-end code (&lt;a href="http://www.webpagetest.org/"&gt;WebPagetest&lt;/a&gt;, &lt;a href="http://code.google.com/speed/page-speed/"&gt;Page Speed&lt;/a&gt;, &lt;a href="http://developer.yahoo.com/yslow/"&gt;Y-Slow&lt;/a&gt;), it is not uncommon to see back-end performance issues, particularly as you move away from the top Internet sites into the long tail of the Internet.&lt;/p&gt;&lt;p&gt;This is not entirely unexpected because the top sites tend to have dedicated developers who custom-built the back-end code for serving pages and have dedicated operations teams that watch the performance of the systems and databases and spend a lot of time focused on the performance and scalability of the back-ends.&lt;/p&gt;&lt;p&gt;As you move out of the top tier of Internet publishers you start running into sites that are running on off-the-shelf content systems (Drupal, WordPress, Joomla, etc) and with owners who either contracted for the site development at one point in time or used and tweaked an available template and then used a collection of plugins to put together their site (often not knowing how the plugins themselves work).  The hosting for these sites also varies wildly from dedicated servers to VPS systems to running on shared hosting (by far the most common) where they have little to no insight on the performance of the actual systems their site is running on.&lt;/p&gt;&lt;p&gt;As a result, it’s not uncommon to see something like this:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img alt="30 Second TTFB" src="http://images.patrickmeenan.com/perf2011/30sec.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Yes, that is a 30+ second time to first byte (TTFB) with all of the time being spent somewhere on the back-end to assemble and produce the page.  This wasn’t an outlier either.  For this page, EVERY page load takes 30+ seconds before the browser even gets the first bit of HTML to work on.&lt;/p&gt;&lt;p&gt;This isn’t unique to this site or the Content Management System (CMS) it runs on (though it is an extreme example).  It is not uncommon to see 8-20 second back-end times from virtually all of the different CMS systems.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img alt="12 Second TTFB" src="http://images.patrickmeenan.com/perf2011/12sec.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This is really painful for users (assuming any of them actually wait that long for the site) but it also causes scaling problems for the back-end because the application is tied up for a long time processing each request making fewer resources available for other users.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;What is a good back-end time?&lt;/h3&gt;&lt;p&gt;A good target for just the processing time for back-end requests is on the order of 100ms (0.1 seconds).  That doesn’t mean you should expect a TTFB of 100ms, just that the back-end processing time shouldn’t take longer than that.  It is important to remember that the user can’t see ANYTHING at all before the TTFB so any improvements there go directly to the user experience.&lt;/p&gt;&lt;p&gt;When figuring out the back-end time from a front-end tool like WebPagetest, you need to remember to include the network latency.  For that I usually use the socket connect time to the server (orange bar) as the RTT and then use that as a baseline for everything else.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img alt="1.5 Second TTFB" src="http://images.patrickmeenan.com/perf2011/1sec.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In this case, the DNS lookup time (teal bar) is taking longer than I would expect but you want to compare the size of the orange bar to the size of the light green bar.  The length of the orange bar is the fastest the server would be able to reply and assumes 0 back-end processing time so if they are reasonably close in size then you’re in pretty good shape.&lt;/p&gt;&lt;p&gt;Eyeballing waterfalls is good for a general feeling but if you want to see the specifics, you can get the individual component times in a data table below the waterfalls on &lt;a href="http://www.webpagetest.org/"&gt;WebPagetest&lt;/a&gt;:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img alt="Request Timing Details" src="http://images.patrickmeenan.com/perf2011/timings.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In this case you just subtract the initial connection time from the TTFB and you have the amount of time that was spent on the back-end (436ms here).&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Figuring out what is going on&lt;/h3&gt;&lt;p&gt;So, you know you have a back-end issue, how do you figure out what is causing the problem?&lt;/p&gt;&lt;p&gt;The problem is almost certainly caused by one of these issues:&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Web server configuration that is out of available clients to process requests&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Slow database queries&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Back-end calls to external services&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;Unfortunately, most of the performance tools you are used to using don’t have any visibility into those components and they become a black box.  At this point you need a developer and a sysadmin (or someone with the skillset to do both) because fixing it is going to involve code or site configuration changes.  Even just finding the source of the problem requires a pretty decent skillset.&lt;/p&gt;&lt;p&gt;There are commercial solutions that will identify the issue for you really quickly with minimal work.  Actually, there is a whole sector focused on it (called Application Performance Management or APM).  I’ll use &lt;a href="http://newrelic.com/"&gt;New Relic&lt;/a&gt; as an example here because it is what I use on webpagetest.org but &lt;a href="http://www.dynatrace.com/"&gt;Dynatrace&lt;/a&gt; is another common solution.  All of them require that you install binary code on the server though so if you are on shared hosting these may not be available options (and once you get through the free trial phase most cost more than shared hosting plans anyway).&lt;/p&gt;&lt;p&gt;Once configured, the APM tools will monitor your production systems and tell you how much time your server is spending in the various different tiers:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img alt="New Relic Summary" src="http://images.patrickmeenan.com/perf2011/nr_summary.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I’ve done a fair bit of tuning to WebPagetest so there’s not a whole lot to see here.  Average response times are ~10ms and the database is only used for the forums so the bulk of the time is spent in the actual application code.&lt;/p&gt;&lt;p&gt;From there you can drill into each band to see exactly where that time is going:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img alt="New Relic Transactions" src="http://images.patrickmeenan.com/perf2011/nr_transactions.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In my case, most of the CPU time is spent generating thumbnail images (which includes waterfall thumbnails) for the results pages.  Not completely unexpected since they are all generated dynamically by code.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The thumbnail generation is something I spent a fair amount of time optimizing because it used to be a LOT more resource intensive and took close to 80% of the time.  The tools let you keep drilling in to see what specific functions contribute to the time:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img alt="New Relic Thumbnail Details" src="http://images.patrickmeenan.com/perf2011/nr_thumbnail.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;They let you do the same for database calls and for particularly slow requests they will provide diagnostics for individual requests instead of just aggregate results so you can also drill into slow outliers easily.&lt;/p&gt;&lt;p&gt;If you aren’t fortunate enough to be able to use the tools then you have to look into what is available for your platform to see if there are free diagnostic tools or you have to start instrumenting the code yourself.  In WordPress, for example, there are several plugins that will debug the database queries and tell you how long they are taking.&lt;/p&gt;&lt;p&gt;W3 Total Cache is a useful plugin for improving WordPress performance but it also provides debugging information that will help you identify any slow database calls:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img alt="W3 Total Cache Debug Settings" src="http://images.patrickmeenan.com/perf2011/w3tc_options.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;When you enable the debug information, details about every database query (and cache operation) will be logged into the page HTML as a comment that you can view by visiting the page and viewing the page source:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt="W3 Total Cache Debug Data" src="http://images.patrickmeenan.com/perf2011/query_debug.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;You’ll get the overall time spent in database queries as well as timings and details for each and every query.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Fixing it&lt;/h3&gt;&lt;p&gt;Great, so now that you’ve identified the issues the real hard work starts.  The most common “solution” people use is to add caching to hide the problem.  This can be in the form of a plugin like W3 Total Cache that will let you cache all sorts of different operations to custom query caches using memcache.  Caches are absolutely necessary but you should improve the underlying issue as much as possible before enabling caching, that way 100% of the requests will get improved performance.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Finally&lt;/h3&gt;&lt;p&gt;As they say in carpentry, measure twice, cut once.  Don’t go optimizing your site until you have measured the user experience and then use the measurements to guide your work, not grades or scores from various tools ñ they may not be relevant to your particular situation.  Just because sites &lt;i&gt;normally&lt;/i&gt; spend most of their time on the front end doesn’t mean that is necessarily the case for yours.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://calendar.perfplanet.com/2011/when-good-back-ends-go-bad/"&gt;When good back-ends go bad&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-5589818900221085399?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rjhrlTNrLeFSCoKKQhXjlWOguGg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rjhrlTNrLeFSCoKKQhXjlWOguGg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rjhrlTNrLeFSCoKKQhXjlWOguGg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rjhrlTNrLeFSCoKKQhXjlWOguGg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/42eTTMfNixU" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/5589818900221085399?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/5589818900221085399?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/42eTTMfNixU/when-good-back-ends-go-bad.html" title="When good back-ends go bad" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/when-good-back-ends-go-bad.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8ERHkyfip7ImA9WhRWFkQ.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-5232977717750096701</id><published>2012-01-04T09:06:00.000-08:00</published><updated>2012-01-04T09:06:45.796-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-04T09:06:45.796-08:00</app:edited><title>Fullscreen Background Image Slideshow with CSS3</title><content type="html">&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3FullscreenSlideshow/"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2011/12/CSS3FullscreenSlideshow.jpg" alt="CSS3FullscreenSlideshow" width="580" height="315" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3FullscreenSlideshow/"&gt;View demo&lt;/a&gt; &lt;a href="http://tympanus.net/Tutorials/CSS3FullscreenSlideshow/CSS3FullscreenSlideshow.zip"&gt;Download source&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Happy new year, everybody! Today we will create a CSS-only fullscreen background image slideshow. We’ll create different image transitions and also make a title appear using CSS animations.&lt;/p&gt;&lt;p&gt;The images are by &lt;a href="http://www.flickr.com/photos/markjsebastian/"&gt;Mark Sebastian&lt;/a&gt; and they are licensed under the &lt;a href="http://creativecommons.org/licenses/by-sa/2.0/deed.en"&gt;Creative Commons Attribution-ShareAlike 2.0 Generic License&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Note that this will only work in browsers supporting &lt;a href="http://www.w3.org/TR/css3-animations/"&gt;CSS animations&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This tutorial is a part of our latest CSS3 experiments; you can find more of those here:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://tympanus.net/codrops/2011/11/02/original-hover-effects-with-css3/" title="Original Hover Effects with CSS3"&gt;Original Hover Effects with CSS3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tympanus.net/codrops/2011/11/07/animated-buttons-with-css3/" title="Animated Buttons with CSS3"&gt;Animated Buttons with CSS3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tympanus.net/codrops/2011/12/07/splash-and-coming-soon-page-effects-with-css3/" title="Splash and Coming Soon Page Effects with CSS3"&gt;Splash and Coming Soon Page Effects with CSS3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tympanus.net/codrops/2011/12/12/experiments-with-background-clip-text/" title="Experiments with background-clip: text"&gt;Experiments with background-clip: text&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tympanus.net/codrops/2011/12/19/experimental-css3-animations-for-image-transitions/" title="Experimental CSS3 Animations for Image Transitions"&gt;Experimental CSS3 Animations for Image Transitions&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tympanus.net/codrops/2011/12/21/slopy-elements-with-css3/" title="Slopy Elements with CSS3"&gt;Slopy Elements with CSS3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tympanus.net/codrops/2011/12/26/css3-lightbox/" title="CSS3 Lightbox"&gt;CSS3 Lightbox&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;/div&gt;&lt;div style="clear:both"&gt;&lt;/div&gt;&lt;h3&gt;The Markup&lt;/h3&gt;&lt;p&gt;We’ll use an unordered list for the slideshow and we’ll add a span for each image and a division with a heading:&lt;/p&gt;&lt;pre&gt;&amp;lt;ul class="cb-slideshow"&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;&lt;br /&gt;  &amp;lt;span&amp;gt;Image 01&amp;lt;/span&amp;gt;&lt;br /&gt;  &amp;lt;div&amp;gt;&lt;br /&gt;   &amp;lt;h3&amp;gt;re·lax·a·tion&amp;lt;/h3&amp;gt;&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;&amp;lt;!--...--&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;&amp;lt;!--...--&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The spans are going to be the elements that will have the background images of the slideshow.&lt;/p&gt;&lt;h3&gt;The CSS&lt;/h3&gt;&lt;p&gt;Let’s style the unordered list first. It will be fixed and we will stretch it over the viewport. We’ll also use a :after pseudo-element in order to place a pattern on top of the image:&lt;/p&gt;&lt;pre&gt;.cb-slideshow,&lt;br /&gt;.cb-slideshow:after {&lt;br /&gt;   position: fixed;&lt;br /&gt;   width: 100%;&lt;br /&gt;   height: 100%;&lt;br /&gt;   top: 0px;&lt;br /&gt;   left: 0px;&lt;br /&gt;   z-index: 0;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow:after {&lt;br /&gt;   content: '';&lt;br /&gt;   background: transparent url(../images/pattern.png) repeat top left;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;We’ll use a repeated dot pattern but you could as well use, for example, a css gradient with some transparency.&lt;/p&gt;&lt;p&gt;The span that will contain a slideshow image will be positioned absolutely and have a width and height of 100%. Since we have some text inside, we’ll make the color transparent because we don’t want to see it. The background-size property value “cover” will make sure that the background image covers all the area of the element and hence it is the size of the screen, it will cover all the visible viewport. The opacity is set to 0. We’ll then change that in our animation:&lt;/p&gt;&lt;pre&gt;.cb-slideshow li span {&lt;br /&gt;   width: 100%;&lt;br /&gt;   height: 100%;&lt;br /&gt;   position: absolute;&lt;br /&gt;   top: 0px;&lt;br /&gt;   left: 0px;&lt;br /&gt;   color: transparent;&lt;br /&gt;   background-size: cover;&lt;br /&gt;   background-position: 50% 50%;&lt;br /&gt;   background-repeat: none;&lt;br /&gt;   opacity: 0;&lt;br /&gt;   z-index: 0;&lt;br /&gt;   animation: imageAnimation 36s linear infinite 0s;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The animation for each span will last 36 seconds and run an inifinite number of times. But let’s look at the details in a while, first, we will style the division with the headline:&lt;/p&gt;&lt;pre&gt;.cb-slideshow li div {&lt;br /&gt;   z-index: 1000;&lt;br /&gt;   position: absolute;&lt;br /&gt;   bottom: 30px;&lt;br /&gt;   left: 0px;&lt;br /&gt;   width: 100%;&lt;br /&gt;   text-align: center;&lt;br /&gt;   opacity: 0;&lt;br /&gt;   color: #fff;&lt;br /&gt;   animation: titleAnimation 36s linear infinite 0s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li div h3 {&lt;br /&gt;   font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;&lt;br /&gt;   font-size: 240px;&lt;br /&gt;   padding: 0;&lt;br /&gt;   line-height: 200px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The animation for the title division will also take 36 seconds.&lt;/p&gt;&lt;p&gt;Now, we will define the background images for all the spans and the animation delay, so that each following slideshow image and title appear after 6 second of the previous one:&lt;/p&gt;&lt;pre&gt;.cb-slideshow li:nth-child(1) span {&lt;br /&gt;   background-image: url(../images/1.jpg)&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(2) span {&lt;br /&gt;   background-image: url(../images/2.jpg);&lt;br /&gt;   animation-delay: 6s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(3) span {&lt;br /&gt;   background-image: url(../images/3.jpg);&lt;br /&gt;   animation-delay: 12s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(4) span {&lt;br /&gt;   background-image: url(../images/4.jpg);&lt;br /&gt;   animation-delay: 18s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(5) span {&lt;br /&gt;   background-image: url(../images/5.jpg);&lt;br /&gt;   animation-delay: 24s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(6) span {&lt;br /&gt;   background-image: url(../images/6.jpg);&lt;br /&gt;   animation-delay: 30s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.cb-slideshow li:nth-child(2) div {&lt;br /&gt;   animation-delay: 6s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(3) div {&lt;br /&gt;   animation-delay: 12s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(4) div {&lt;br /&gt;   animation-delay: 18s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(5) div {&lt;br /&gt;   animation-delay: 24s;&lt;br /&gt;}&lt;br /&gt;.cb-slideshow li:nth-child(6) div {&lt;br /&gt;   animation-delay: 30s;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Now, let’s have a look at the slideshow animation. Each span will have an animation time of 36 seconds. In those 36 seconds we will change the opacity from 0 to 1 when the animation reaches 8%. And then this opacity gets kept until 17% are reached. When reaching 25% the opacity should already be 0 again and stay like that until the end.&lt;/p&gt;&lt;p&gt;Now, why those values? We want each image to be visible for 6 seconds and we know that at the end of a cycle, we want the first image to show again. We have 6 images, so we will need 36 seconds for a whole cycle to finish. Now, we need to “time” the opacity values accordingly. Knowing that our second image will start animating at 6 seconds, we need to know at what percentile of the animation this will require the first image to fade out. Dividing 6 by 36 gives us 0.166… which would be 16% for our keyframe step. Now, because we don’t want out image to just fade all the time, we’ll define an inbetween step, which we’ll set at half of what we calculated, i.e. 8%. That’s the point that we want to show the image completely and we only want to start fading it out at 17%, making it disappear completely at 25%.&lt;/p&gt;&lt;pre&gt;@keyframes imageAnimation {&lt;br /&gt;   0% { opacity: 0; animation-timing-function: ease-in; }&lt;br /&gt;   8% { opacity: 1; animation-timing-function: ease-out; }&lt;br /&gt;   17% { opacity: 1 }&lt;br /&gt;   25% { opacity: 0 }&lt;br /&gt;   100% { opacity: 0 }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;We have the same reasoning for the title, just that we want it to disappear a bit quicker, hence the opacity 0 at 19%:&lt;/p&gt;&lt;pre&gt;@keyframes titleAnimation {&lt;br /&gt;   0% { opacity: 0 }&lt;br /&gt;   8% { opacity: 1 }&lt;br /&gt;   17% { opacity: 1 }&lt;br /&gt;   19% { opacity: 0 }&lt;br /&gt;   100% { opacity: 0 }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;For browsers that don’t support animations, we’ll simply show the last slideshow image by setting the opacity of the span to 1:&lt;/p&gt;&lt;pre&gt;.no-cssanimations .cb-slideshow li span{&lt;br /&gt; opacity: 1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The &lt;strong&gt;no-cssanimations&lt;/strong&gt; class is added by &lt;a href="http://www.modernizr.com/"&gt;Modernizr&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Let’s as well take care of the title’s font size when the viewport is smaller. We’ll use &lt;a href="http://www.w3.org/TR/css3-mediaqueries/"&gt;media queries&lt;/a&gt; in order to set the font size smaller at specific widths:&lt;/p&gt;&lt;pre&gt;@media screen and (max-width: 1140px) {&lt;br /&gt;   .cb-slideshow li div h3 { font-size: 140px }&lt;br /&gt;}&lt;br /&gt;@media screen and (max-width: 600px) {&lt;br /&gt;   .cb-slideshow li div h3 { font-size: 80px }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;And that’s all for the simple version of the slideshow! Now, let’s see how we can spice up the transitions a bit.&lt;/p&gt;&lt;h3&gt;Alternative animation example&lt;/h3&gt;&lt;p&gt;Now, we can play a bit with the animations for showing the images and their titles.&lt;/p&gt;&lt;p&gt;The following animation will make the image scale up a bit and rotate it slightly:&lt;/p&gt;&lt;pre&gt;@keyframes imageAnimation {&lt;br /&gt; 0% {&lt;br /&gt;     opacity: 0;&lt;br /&gt;     animation-timing-function: ease-in;&lt;br /&gt; }&lt;br /&gt; 8% {&lt;br /&gt;     opacity: 1;&lt;br /&gt;     transform: scale(1.05);&lt;br /&gt;     animation-timing-function: ease-out;&lt;br /&gt; }&lt;br /&gt; 17% {&lt;br /&gt;     opacity: 1;&lt;br /&gt;     transform: scale(1.1) rotate(3deg);&lt;br /&gt; }&lt;br /&gt; 25% {&lt;br /&gt;     opacity: 0;&lt;br /&gt;     transform: scale(1.1) rotate(3deg);&lt;br /&gt; }&lt;br /&gt; 100% { opacity: 0 }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The title will slide in from the right (we’ll have to change the text-align for the title division to “right”), and disappear by sliding to the left and fading out:&lt;/p&gt;&lt;pre&gt;@keyframes titleAnimation {&lt;br /&gt; 0% {&lt;br /&gt;     opacity: 0;&lt;br /&gt;     transform: translateX(200px);&lt;br /&gt; }&lt;br /&gt; 8% {&lt;br /&gt;     opacity: 1;&lt;br /&gt;     transform: translateX(0px);&lt;br /&gt; }&lt;br /&gt; 17% {&lt;br /&gt;     opacity: 1;&lt;br /&gt;     transform: translateX(0px);&lt;br /&gt; }&lt;br /&gt; 19% {&lt;br /&gt;     opacity: 0;&lt;br /&gt;     transform: translateX(-400px);&lt;br /&gt; }&lt;br /&gt; 25% { opacity: 0 }&lt;br /&gt; 100% { opacity: 0 }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;There are many possibilities for the image and title transitions, just experiment!&lt;/p&gt;&lt;h3&gt;Demos&lt;/h3&gt;&lt;p&gt;Here you can find some demos with alternative animations:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3FullscreenSlideshow/index.html"&gt;Demo 1: Simple Fade in, fade out&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3FullscreenSlideshow/index2.html"&gt;Demo 2: Slight rotation, title slides from the right&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3FullscreenSlideshow/index3.html"&gt;Demo 3: Image moves up, title moves down&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3FullscreenSlideshow/index4.html"&gt;Demo 4: Image scales, title moves up, scales and fades out&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;em&gt;Currently, the animations are smoothest in Webkit broswers like Chrome and especially Safari.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;I hope you enjoyed this tutorial and find it useful and inspiring!&lt;/p&gt;&lt;div&gt;&lt;/div&gt; Post: &lt;a href="http://tympanus.net/codrops/2012/01/02/fullscreen-background-image-slideshow-with-css3/"&gt;Fullscreen Background Image Slideshow with CSS3&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-5232977717750096701?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_0RrdaIUIwR1NOzJBdH9t0rSs1U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_0RrdaIUIwR1NOzJBdH9t0rSs1U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_0RrdaIUIwR1NOzJBdH9t0rSs1U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_0RrdaIUIwR1NOzJBdH9t0rSs1U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/BqB1_XDtgpE" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/5232977717750096701?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/5232977717750096701?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/BqB1_XDtgpE/fullscreen-background-image-slideshow.html" title="Fullscreen Background Image Slideshow with CSS3" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/fullscreen-background-image-slideshow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcEQX46fCp7ImA9WhRWFko.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-8118842597105048942</id><published>2012-01-04T02:13:00.000-08:00</published><updated>2012-01-04T02:13:20.014-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-04T02:13:20.014-08:00</app:edited><title>Using the Geolocation API</title><content type="html">&lt;p&gt;The following is probably the last long-form article you’ll see here for a while. I’m in full on &lt;a href="http://htmlcssjavascript.com/web/im-writing-a-book/"&gt;book mode&lt;/a&gt; for the next couple of months, so I’m not expecting to be writing a ton here for the foreseeable future.&lt;/p&gt;&lt;p&gt;Anyway, the following is actually inspired by the kind of work we’re going to be doing for the book. I’m not actually doing any code-heavy writing for the book, so I wanted to get my hands dirty with this sort of content. It’s fun.&lt;/p&gt;&lt;p&gt;As an aside, I’ll have another (short) post about the book shortly. I’ve got a full allotment of co-authors and I’d like to give them, and the project, a little shine before I turn into a writing hermit.&lt;/p&gt;&lt;p&gt;And now… Geolocation&lt;/p&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;p&gt;One of the most powerful aspects of mobile web app development is  the ability to blur the line between the real world and the world on the screen.  Allowing users to interact with physical places in novel ways is driving  startups across the world and is infiltrating some of the most popular sites  and applications on the web. Facebook, Foursquare, Twitter, Google+ and  countless other services have built the idea of location into the core of their  applications. You too can do the same in your mobile web app by taking  advantage of the well-supported &lt;a href="http://dev.w3.org/geo/api/spec-source.html"&gt;Geolocation API&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Whether it’s interaction with your own location based services or  with a third party API, like the Google Maps API in use in this recipe, the  journey begins with getting the user’s latitude and longitude.&lt;/p&gt;&lt;p&gt;In this article  you’ll learn how to:&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Use the W3C Geolocation API to get a user’s  latitude and longitude&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Smoothly handle devices without Geolocation  support, providing a reasonable fallback for older devices&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use the Google Maps API to place a marker  indicating the user’s location, labeled with a friendly place name&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;The Basics of the Geolocation API&lt;/h2&gt;&lt;p&gt;Before we dive into the heart of the example let’s quickly look  at the Geolocation API.&lt;/p&gt;&lt;p&gt;The elevator pitch is to the point- the W3C’s Geolocation API  allows developers to retrieve the geographical location of a device. It became  a Candidate Recommendation, the level at which the W3C deems features and  functionality pretty much settled, in September of 2010 and already has support  across a variety of devices and browsers. At the present time it’s supported  all the major smartphone browsers and even on the desktop it’s supported by all  major browsers except Internet Explorer 6, 7, 8 and Safari 3.2 and 4.0.&lt;/p&gt;&lt;p&gt;As a note, the Geolocation API was heavily influenced by the  analogous functionality provided by the Google Gears plugin. This is why you  often see the mothballed Google Gears plugin referenced as a fallback in many  geolocation examples.&lt;/p&gt;&lt;p&gt;The API itself is straightforward.  It provides a &lt;code&gt;navigator.geolocation&lt;/code&gt;  object which in turn provides two methods (&lt;code&gt;watchPosition&lt;/code&gt;  and &lt;code&gt;getCurrentPosition&lt;/code&gt;) which allow the browser to query the  device’s location through the use of location information servers.  If you’re getting a location for use in a  search or in a check-in, then &lt;code&gt;getCurrentPosition&lt;/code&gt;  is the method you want to use as it’s designed for a single  location lookup. If you’re tracking a user’s location over time, then &lt;code&gt;watchPosition&lt;/code&gt; is the way  to go since it’s designed to be used over a longer period of time.&lt;/p&gt;&lt;p&gt;Location information is pulled from a variety of sources  including IP address, device GPS, Wi-Fi and Bluetooth MAC address, RFID, or  Wi-Fi connection location. The different level of precision inherent in these  several methods is exposed by the API as an &lt;code&gt;accuracy&lt;/code&gt;  property.&lt;/p&gt;&lt;p&gt;Now that we’ve taken a look at the Geolocation API, let’s walk through  our code in depth.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Getting Started with the Geolocation API&lt;/h2&gt;&lt;p&gt; While the Geolocation API is straightforward, getting it up and  running smoothly in the real world is a little bit tricky. Accounting for a  successful result is one thing, making sure there’s a decent response for  browsers without geolocation capability or in other instances where geolocation  isn’t available is another.&lt;/p&gt;&lt;p&gt;Our example will touch on ways to minimize these issues and will  illustrate the basics of a successful request. &lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Testing for the Geolocation object and Querying  the User’s Location&lt;/h3&gt;&lt;p&gt;The first thing you’ll need to do when working with Geolocation  is to test whether or not it’s actually available in the browser. This is done  by testing against the presence of the &lt;code&gt;navigator.geolocation&lt;/code&gt; object. As you’ll  see in the following code sample, this is a simple &lt;code&gt;if…else&lt;/code&gt;  block with a call to the &lt;code&gt;navigator.getCurrentPosition()&lt;/code&gt;  method when the object is present and a fallback when it’s not available.&lt;/p&gt;&lt;p&gt;The method &lt;code&gt;getCurrentPosition()&lt;/code&gt;  takes three arguments:&lt;/p&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;the function to run on a successful location  request&lt;/li&gt;&lt;br /&gt;&lt;li&gt;the function to run as when the request fails&lt;/li&gt;&lt;br /&gt;&lt;li&gt;a &lt;code&gt;PositionOptions&lt;/code&gt; object containing other  optional configuration objects. &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;In our case we’re passing in two named functions, &lt;code&gt;success&lt;/code&gt; and &lt;code&gt;failure&lt;/code&gt;, and an optional  timeout of five seconds, which will keep things moving if something goes awry  with the request.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Listing 1 Testing for  the presence of the navigator.geolocation object&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;if (navigator.geolocation){  // does the geolocation object exist?            &lt;br /&gt; navigator.geolocation.getCurrentPosition(&lt;br /&gt;   success,&lt;br /&gt;   failure,&lt;br /&gt;   {timeout:5000}&lt;br /&gt; );         &lt;br /&gt;} else {&lt;br /&gt; failure(); &lt;br /&gt;}     &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;  In addition to the timeout  seen in the previous example the &lt;code&gt;PositionOptions&lt;/code&gt;  object accepts two other options- &lt;code&gt;enableHighAccuracy&lt;/code&gt;  and &lt;code&gt;maximumAge&lt;/code&gt;. &lt;code&gt;enableHighAccuracy&lt;/code&gt;  indicates that you would like receive the best possible results at the  potential cost of speed or battery performance. &lt;code&gt;maximumAge&lt;/code&gt; sets a limit, in  milliseconds, for the age of a cached position object. The browser caches  recent position location responses. Setting &lt;code&gt;maximumAge&lt;/code&gt; to 0 will immediately force  the browsers to try to obtain a new location.&lt;/p&gt;&lt;h3&gt;Handling a successful geolocation request&lt;/h3&gt;&lt;p&gt;The first function we’ll look at it is our success function. You can  see it in Listin 1.2&lt;/p&gt;&lt;p&gt;In our example we’re using the Google Maps API to display a  marker with the user’s current location.&lt;/p&gt;&lt;p&gt; The function accepts a single &lt;code&gt;data&lt;/code&gt; argument. This argument is  automatically passed into the function by the geolocation API. This is object  is defined in the specification to contain two properties &lt;code&gt;coords&lt;/code&gt; and &lt;code&gt;timestamp&lt;/code&gt;.  &lt;code&gt;timestamp&lt;/code&gt; is, as expected, a timestamp indicating the age of the position  information. For this example we’re most interested in the &lt;code&gt;coords&lt;/code&gt; object which  contains a latitude/longitude pair indicating the user’s position.&lt;/p&gt;&lt;p&gt; Moving on from the single  argument, you’ll see several Google Maps specific variables.&lt;/p&gt;&lt;p&gt;The first, &lt;code&gt;GM&lt;/code&gt;,represents  a simple technique to speed up JavaScript. By creating a local representation  of the &lt;code&gt;google.maps&lt;/code&gt; object we save lookups to the global space. In general,  local variables are faster. This is especially important with mobile which devices don’t have the fastest JavaScript engines.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Every little bit helps.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The most important piece, from a geolocation perspective, is the  use of two properties, &lt;code&gt;data.coords.latitude&lt;/code&gt; and &lt;code&gt;data.coords.longitude&lt;/code&gt;, to build  a new Google Maps LatLng object. The LatLng object is a core component of  Google Maps. At its core it’s a latitude/longitude pair enhanced with methods  and properties used throughout the API. To create one in our example you simply  pass it the two properties of the data.coords object. We store that in our position variable.&lt;/p&gt;&lt;p&gt; We now have our user’s location, ready to place on the map.&lt;/p&gt;&lt;p&gt;  The next section we’re using the Google Maps Geocoder to get a  friendly label for the user’s location. Geocoding works in two ways. Normal  geocoding means you pass the service an address string and it will return a  series of geographical results. In our case we’re doing reverse geocoding,  which means we pass the service a latitude/longitude pair and the service  returns whatever it knows about the location.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Listing 2 Successfully handling a geolocation  request&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;var success = function( data ){ //the data object, passed into success&lt;br /&gt; var GM = google.maps,&lt;br /&gt;     mapOptions = {&lt;br /&gt;       zoom: 12,&lt;br /&gt;       center:  defaultPosition,&lt;br /&gt;       mapTypeId:  GM.MapTypeId.ROADMAP&lt;br /&gt;     },&lt;br /&gt;     map = new GM.Map(  document.getElementById('map'), mapOptions),&lt;br /&gt;     position = new GM.LatLng(&lt;br /&gt;       data.coords.latitude, //accessing the coords property&lt;br /&gt;       data.coords.longitude&lt;br /&gt;     ),     &lt;br /&gt;     niceAddress = "Your location",&lt;br /&gt;     geocoder = new GM.Geocoder();&lt;br /&gt;     geocoder.geocode( { 'latLng' : position  },&lt;br /&gt;       function( results, status ) {&lt;br /&gt;         if ( status == GM.GeocoderStatus.OK ) {&lt;br /&gt;           if (results[0]) {&lt;br /&gt;             niceAddress = results[0].formatted_address;&lt;br /&gt;           }&lt;br /&gt;         }&lt;br /&gt;         var infowindow = new GM.InfoWindow({&lt;br /&gt;           map: map,&lt;br /&gt;           position: position,&lt;br /&gt;           content: niceAddress&lt;br /&gt;         });&lt;br /&gt;       });&lt;br /&gt;     map.setCenter(position);&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Handling a Geolocation Failure&lt;/h3&gt;&lt;p&gt;  Our &lt;code&gt;failure&lt;/code&gt;  function handles two negative situations. If the user doesn’t have a  geolocation enabled browser or if there’s an error in the geolocation lookup,  this function is ready to step in and save the day. The &lt;code&gt;failure&lt;/code&gt;  function can be seen in Listing 3&lt;/p&gt;&lt;p&gt;You’ll see the setup is similar to the success  function with a Google Maps object being created with some smart defaults.&lt;/p&gt;&lt;p&gt;The major difference is in the way we get the latitude and  longitude for the map. Instead of getting the coordinates from a geolocation  response we create a simple form to allow the user to enter their location.  Inside the &lt;code&gt;formResponse&lt;/code&gt;  function we use then use the Google Maps Geocoding service to get a latitude  and longitude pair corresponding to the location in the form submission.&lt;/p&gt;&lt;p&gt; Additionally we use the geolocation error  response, if it exists, to build out a slightly more useful error message. If a  browser supports geolocation and has some issue with the location request it should  return an error response as the single argument to the provided callback  function.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Listing 3 The failure Function&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;var failure = function( error ){ //The potential error response&lt;br /&gt; var  GM = google.maps,&lt;br /&gt;      mapOptions = {&lt;br /&gt;        zoom: 12,&lt;br /&gt;        center:  defaultPosition,&lt;br /&gt;        mapTypeId:  GM.MapTypeId.ROADMAP&lt;br /&gt;      },&lt;br /&gt;      map = new GM.Map(  document.getElementById('map'), mapOptions),&lt;br /&gt;      formResponse = function(e){&lt;br /&gt;        var geocoder = new GM.Geocoder(),&lt;br /&gt;            position = defaultPosition,&lt;br /&gt;            niceAddress =  "Sorry We Couldn't Find Your Location";&lt;br /&gt;        geocoder.geocode(&lt;br /&gt;          { 'address':  document.getElementById("location").value },&lt;br /&gt;          function( results, status ) {&lt;br /&gt;            if ( status ==  GM.GeocoderStatus.OK ) {&lt;br /&gt;              if (results[0]) {&lt;br /&gt;                niceAddress =  results[0].formatted_address;&lt;br /&gt;                position = new GM.LatLng(&lt;br /&gt;                  results[0].geometry.location.lat(),&lt;br /&gt;                  results[0].geometry.location.lng()&lt;br /&gt;                )&lt;br /&gt;              }&lt;br /&gt;            }&lt;br /&gt;          var options = {&lt;br /&gt;            map : map,&lt;br /&gt;            position :  position,&lt;br /&gt;            content :  niceAddress&lt;br /&gt;           },&lt;br /&gt;          infowindow = new  google.maps.InfoWindow(options);&lt;br /&gt;          map.setCenter(options.position);&lt;br /&gt;          document.getElementById("geocode").style.display="none";&lt;br /&gt;        }&lt;br /&gt;      )&lt;br /&gt;    return false;&lt;br /&gt;  }&lt;br /&gt;  var  fallback = document.createElement("form");&lt;br /&gt;  fallback.id="geocode";&lt;br /&gt;  if ( error ) {&lt;br /&gt;    switch(error.code) {//Error Handling based on error.code  &lt;br /&gt;     //HANDLE ERRORS//&lt;br /&gt;  }     &lt;br /&gt;} &lt;br /&gt;fallback.innerHTML  = "&amp;lt;label for='location'&amp;gt;Eneter Your Location" +&lt;br /&gt; "&amp;lt;input  type='text' id='location' /&amp;gt;&amp;lt;/label&amp;gt;&amp;lt;input type='submit'  /&amp;gt;";&lt;br /&gt;fallback.onsubmit  = formResponse;&lt;br /&gt;document.getElementById("main").appendChild(  fallback );&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The error response contains a code  object indicating the type of error and a human readable message string that’s  defined to be used in debugging or for error logs. There are four potential  values for the &lt;code&gt;error.code&lt;/code&gt;. These can be seen in Table 1:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Table 1 Possible error response  codes&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="62" valign="top"&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;     Code &lt;/div&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="231" valign="top"&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;p&gt;Name &lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="230" valign="top"&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;p&gt;Definition&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="62" valign="top"&gt;&lt;br /&gt;&lt;p&gt;0&lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="231" valign="top"&gt;&lt;br /&gt;&lt;p&gt;UNKNOWN_ERROR &lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="230" valign="top"&gt;&lt;br /&gt;&lt;p&gt;The location lookup failed due to an undefined error&lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="62" valign="top"&gt;&lt;br /&gt;&lt;p&gt;1&lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="231" valign="top"&gt;&lt;br /&gt;&lt;p&gt;PERMISSION_DENIED &lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="230" valign="top"&gt;&lt;br /&gt;&lt;p&gt;The location lookup failed because the application does    not have permission to use the Geolocation API.&lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="62" valign="top"&gt;&lt;br /&gt;&lt;p&gt;2&lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="231" valign="top"&gt;&lt;br /&gt;&lt;p&gt;POSITION_UNAVAILABLE &lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="230" valign="top"&gt;&lt;br /&gt;&lt;p&gt;The position of the device could not be determined. &lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="62" valign="top"&gt;&lt;br /&gt;&lt;p&gt;3&lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="231" valign="top"&gt;&lt;br /&gt;&lt;p&gt;TIMEOUT&lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;td width="230" valign="top"&gt;&lt;br /&gt;&lt;p&gt;The location lookup took longer than the length of time    defined in &lt;/p&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;h3&gt;Putting it all together&lt;/h3&gt;&lt;p&gt; Listing 4 shows the completed function. In it we’ve wrapped  our two methods into a larger function called &lt;code&gt;loadMap&lt;/code&gt;.  Doing so allows us to streamline the code by  creating a single set of defaults for the map and to encapsulate all of the  functionality under a single function so as to keep the global namespace as  neat as possible.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Listing 4 The Completed Function&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;var loadMap = function(){&lt;br /&gt; var GM = google.maps,&lt;br /&gt;     defaultPosition = new GM.LatLng(42, -71),&lt;br /&gt;     mapOptions = {&lt;br /&gt;     zoom: 12,&lt;br /&gt;     center: defaultPosition,&lt;br /&gt;     mapTypeId: GM.MapTypeId.ROADMAP},&lt;br /&gt;   map = new GM.Map(&lt;br /&gt;     document.getElementById('map'),&lt;br /&gt;     mapOptions&lt;br /&gt;   ),&lt;br /&gt;   success = function( data ){&lt;br /&gt;     var position = new GM.LatLng(&lt;br /&gt;       data.coords.latitude,&lt;br /&gt;       data.coords.longitude&lt;br /&gt;     ),&lt;br /&gt;        niceAddress = 'Your location',&lt;br /&gt;        geocoder = new GM.Geocoder();&lt;br /&gt;     geocoder.geocode({&lt;br /&gt;       'latLng': position },&lt;br /&gt;        function( results, status ) {&lt;br /&gt;          if ( status == GM.GeocoderStatus.OK ){&lt;br /&gt;            if (results[0]) {&lt;br /&gt;              niceAddress = results[0].formatted_address;&lt;br /&gt;            }&lt;br /&gt;          }&lt;br /&gt;          var infowindow = new GM.InfoWindow({&lt;br /&gt;            map: map,&lt;br /&gt;            position: position,&lt;br /&gt;            content: niceAddress&lt;br /&gt;          });&lt;br /&gt;        }&lt;br /&gt;      );&lt;br /&gt;     map.setCenter( position );&lt;br /&gt;   },&lt;br /&gt;   failure = function( error ){&lt;br /&gt;     var formResponse = function(){&lt;br /&gt;       var geocoder = new GM.Geocoder(),&lt;br /&gt;           position = defaultPosition,&lt;br /&gt;           niceAddress = 'Sorry We Couldn't Find Your Location';&lt;br /&gt;       geocoder.geocode({&lt;br /&gt;    'address':document.getElementById('location').value&lt;br /&gt;   },&lt;br /&gt;         function( results, status ) {&lt;br /&gt;           if ( status == GM.GeocoderStatus.OK ){&lt;br /&gt;             if (results[0]) {&lt;br /&gt;               niceAddress = results[0].formatted_address;&lt;br /&gt;               position = new GM.LatLng(&lt;br /&gt;                 results[0].geometry.location.lat(),&lt;br /&gt;                 results[0].geometry.location.lng()&lt;br /&gt;               )&lt;br /&gt;              }&lt;br /&gt;            }&lt;br /&gt;            var options = {&lt;br /&gt;               map: map,&lt;br /&gt;               position: position,&lt;br /&gt;               content: niceAddress&lt;br /&gt;             },&lt;br /&gt;             infowindow = new google.maps.InfoWindow(options);&lt;br /&gt;             map.setCenter(options.position);&lt;br /&gt;             document.getElementById('geocode').style.display='none';&lt;br /&gt;          }&lt;br /&gt;        )&lt;br /&gt;      return false;&lt;br /&gt;    }&lt;br /&gt;    var fallback = document.createElement('form');&lt;br /&gt;    fallback.id='geocode';&lt;br /&gt;     if ( error ) {&lt;br /&gt;      switch(error.code) {&lt;br /&gt;        case error.PERMISSION_DENIED:&lt;br /&gt;         fallback.innerHTML += "&amp;lt;p&amp;gt;You chose not share geolocation data. Please, use the form below. &amp;lt;/p&amp;gt;" ; &lt;br /&gt;        break; &lt;br /&gt;  case error.POSITION_UNAVAILABLE:&lt;br /&gt;           fallback.innerHTML += "&amp;lt;p&amp;gt;Sorry, we couldn't determine your location. Please, use the form below. &amp;lt;/p&amp;gt;" ;&lt;br /&gt;        break; &lt;br /&gt;        case error.TIMEOUT:&lt;br /&gt;           fallback.innerHTML += "&amp;lt;p&amp;gt;Sorry, the location request time out. Please, use the form below. &amp;lt;/p&amp;gt;" ;&lt;br /&gt;        break; &lt;br /&gt;        default:&lt;br /&gt;           fallback.innerHTML += "&amp;lt;p&amp;gt;Sorry, there was an error. Please use the form below. &amp;lt;/p&amp;gt;" ;&lt;br /&gt;        break;&lt;br /&gt;      }   &lt;br /&gt;   }&lt;br /&gt;   fallback.innerHTML += "&amp;lt;label for='location'&amp;gt;Eneter Your Location &amp;lt;input type='text' id='location' /&amp;gt;&amp;lt;/label&amp;gt;&amp;lt;input type='submit' /&amp;gt;";&lt;br /&gt;   fallback.onsubmit = formResponse;&lt;br /&gt;   document.getElementById("main").appendChild( fallback );&lt;br /&gt; };&lt;br /&gt; if (navigator.geolocation){&lt;br /&gt;   navigator.geolocation.getCurrentPosition( success, failure, {timeout:5000} ) ;&lt;br /&gt; } else {&lt;br /&gt;   failure();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/code&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;With that we’ve walked through the basics of the geolocation  API. While our example utilizes the Google Maps API, any exploration of location  based services can be based on the same pattern. Use the &lt;code&gt;navigator.geolocation&lt;/code&gt;  object where available, and then design in a simple fallback for non-supporting  browsers and devices.  &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://feedproxy.google.com/~r/HtmlCssJavascript/~3/6p72YedKwFc/"&gt;Using the Geolocation API&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/HtmlCssJavascript/~4/6p72YedKwFc" height="1" width="1" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-8118842597105048942?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/E1cP4UOPITidyll2FGSPA4HpG-c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/E1cP4UOPITidyll2FGSPA4HpG-c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/E1cP4UOPITidyll2FGSPA4HpG-c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/E1cP4UOPITidyll2FGSPA4HpG-c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/qJExwCWt8X4" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/8118842597105048942?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/8118842597105048942?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/qJExwCWt8X4/using-geolocation-api.html" title="Using the Geolocation API" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2012/01/using-geolocation-api.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cEQ3Y4eip7ImA9WhRWEUo.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-463770336774256068</id><published>2011-12-29T08:10:00.000-08:00</published><updated>2011-12-29T08:10:02.832-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-29T08:10:02.832-08:00</app:edited><title>Get Value of CSS Rotation through JavaScript</title><content type="html">&lt;p&gt;A &lt;a href="http://css-tricks.com/snippets/css/text-rotation/#comment-137014"&gt;comment by aditya&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Is there a way to get the angle [through JavaScript] by which the element is rotated?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Seems like a reasonable request. So we have some HTML:&lt;/p&gt;&lt;pre rel="HTML"&gt;&lt;code&gt;&amp;lt;div id="i-am-rotated"&amp;gt;text&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And it's rotated through CSS:&lt;/p&gt;&lt;pre rel="CSS"&gt;&lt;code&gt;#i-am-rotated {&lt;br /&gt; -webkit-transform: rotate(30deg);&lt;br /&gt; -moz-transform:    rotate(30deg);&lt;br /&gt; -ms-transform:     rotate(30deg);&lt;br /&gt; -o-transform:      rotate(30deg);&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Our goal is to get the number "30" from that element via JavaScript. The modern way to access styling information from an element is &lt;code&gt;getComputedStyle()&lt;/code&gt; (Supported in all modern browsers and IE 9+, older IE &lt;a href="http://www.quirksmode.org/dom/getstyles.html"&gt;supported&lt;/a&gt; &lt;code&gt;currentStyle()&lt;/code&gt;). Let's try and get it with getComputedStyle():&lt;/p&gt;&lt;pre rel="JavaScript"&gt;&lt;code&gt;var el = document.getElementById("i-am-rotated");&lt;br /&gt;&lt;br /&gt;var st = window.getComputedStyle(el, null);&lt;br /&gt;&lt;br /&gt;var tr = st.getPropertyValue("-webkit-transform") ||&lt;br /&gt;        st.getPropertyValue("-moz-transform") ||&lt;br /&gt;        st.getPropertyValue("-ms-transform") ||&lt;br /&gt;        st.getPropertyValue("-o-transform") ||&lt;br /&gt;        st.getPropertyValue("transform") ||&lt;br /&gt;        "Either no transform set, or browser doesn't do getComputedStyle";&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You might think the value returned would be "rotate(30deg)" and we could run &lt;code&gt;parseInt()&lt;/code&gt; on it and get "30". But unfortunately that doesn't work. The actual value we get back is this:&lt;/p&gt;&lt;pre rel="JavaScript"&gt;&lt;code&gt;console.log(tr);&lt;br /&gt;// matrix(0.8660254037844387, 0.49999999999999994, -0.49999999999999994, 0.8660254037844387, 0, 0)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The browser turns the CSS rotation transform into a matrix transform. I imagine it does this to simplify what could be multiple transforms on the single element into one value. So what are we to do?&lt;/p&gt;&lt;p&gt;&lt;a href="http://nicolasgallagher.com/"&gt;Nicolas Gallager&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Rotation_matrix#Properties_of_a_rotation_matrix"&gt;researched&lt;/a&gt; the matrix transformation for a rotate. Which is essentially &lt;a href="http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined"&gt;this&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;rotate(Xdeg) = matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We really just need one of these to make a quick equation. We just need to un-sin (opposite of sin, arc sin, asin, sin&lt;sup&gt;-1&lt;/sup&gt;) on of the values we have to get the &lt;strong&gt;radians&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;First we get our hands on the separate individual matrix values:&lt;/p&gt;&lt;pre rel="JavaScript"&gt;&lt;code&gt;var values = tr.split('(')[1].split(')')[0].split(',');&lt;br /&gt;&lt;br /&gt;var a = values[0]; // 0.866025&lt;br /&gt;var b = values[1]; // 0.5&lt;br /&gt;var c = values[2]; // -0.5&lt;br /&gt;var d = values[3]; // 0.866025&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we know &lt;code&gt;sin(X) == 0.5&lt;/code&gt; so &lt;code&gt;asin(0.5) == radians&lt;/code&gt; and &lt;code&gt;degrees == radians * 180/π&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;So:&lt;/p&gt;&lt;pre rel="JavaScript"&gt;&lt;code&gt;var angle = Math.round(Math.asin(b) * (180/Math.PI));&lt;br /&gt;console.log(angle);&lt;br /&gt;// 30&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Yay!&lt;/p&gt;&lt;p&gt;Nicolas took it a bit further by accounting for scale as well. With the full code below, the rotation value can be extracted with any number of other transforms applied.&lt;/p&gt;&lt;pre rel="CSS"&gt;&lt;code&gt;#complex-transform {&lt;br /&gt; -webkit-transform: rotate(30deg) scale(1.2) skew(10deg) translate(5px, 5px);&lt;br /&gt; -moz-transform:    rotate(30deg) scale(1.2) skew(10deg) translate(5px, 5px);&lt;br /&gt; -ms-transform:     rotate(30deg) scale(1.2) skew(10deg) translate(5px, 5px);&lt;br /&gt; -o-transform:      rotate(30deg) scale(1.2) skew(10deg) translate(5px, 5px);&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;pre rel="JavaScript"&gt;&lt;code&gt;var el = document.getElementById("complex-transform");&lt;br /&gt;var st = window.getComputedStyle(el, null);&lt;br /&gt;var tr = st.getPropertyValue("-webkit-transform") ||&lt;br /&gt;        st.getPropertyValue("-moz-transform") ||&lt;br /&gt;        st.getPropertyValue("-ms-transform") ||&lt;br /&gt;        st.getPropertyValue("-o-transform") ||&lt;br /&gt;        st.getPropertyValue("transform") ||&lt;br /&gt;        "fail...";&lt;br /&gt;&lt;br /&gt;// With rotate(30deg)...&lt;br /&gt;// matrix(0.866025, 0.5, -0.5, 0.866025, 0px, 0px)&lt;br /&gt;console.log('Matrix: ' + tr);&lt;br /&gt;&lt;br /&gt;// rotation matrix - http://en.wikipedia.org/wiki/Rotation_matrix&lt;br /&gt;&lt;br /&gt;var values = tr.split('(')[1].split(')')[0].split(',');&lt;br /&gt;var a = values[0];&lt;br /&gt;var b = values[1];&lt;br /&gt;var c = values[2];&lt;br /&gt;var d = values[3];&lt;br /&gt;&lt;br /&gt;var scale = Math.sqrt(a*a + b*b);&lt;br /&gt;&lt;br /&gt;// arc sin, convert from radians to degrees, round&lt;br /&gt;// DO NOT USE: see update below&lt;br /&gt;var sin = b/scale;&lt;br /&gt;var angle = Math.round(Math.asin(sin) * (180/Math.PI));&lt;br /&gt;&lt;br /&gt;// works!&lt;br /&gt;console.log('Rotate: ' + angle + 'deg');&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; Turns out this line is way more reliable for calculating angle:&lt;/p&gt;&lt;pre rel="JavaScript"&gt;&lt;code&gt;var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://jsfiddle.net/chriscoyier/459jS/112/"&gt;View Demo&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Thanks &lt;a href="http://nicolasgallagher.com/"&gt;Nicolas&lt;/a&gt;, &lt;a href="http://nimbupani.com/index.html"&gt;Divya&lt;/a&gt;, and &lt;a href="http://oli.jp/"&gt;Oli&lt;/a&gt; for behind-the-scenes help.&lt;/p&gt;&lt;p&gt;&lt;a href="http://css-tricks.com/get-value-of-css-rotation-through-javascript/"&gt;Get Value of CSS Rotation through JavaScript&lt;/a&gt; is a post from &lt;a href="http://css-tricks.com/"&gt;CSS-Tricks&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-463770336774256068?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5K8Wnbp_DuQ-GuF2LgSBAXutEaw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5K8Wnbp_DuQ-GuF2LgSBAXutEaw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5K8Wnbp_DuQ-GuF2LgSBAXutEaw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5K8Wnbp_DuQ-GuF2LgSBAXutEaw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/tPNx0tl8skY" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/463770336774256068?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/463770336774256068?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/tPNx0tl8skY/get-value-of-css-rotation-through.html" title="Get Value of CSS Rotation through JavaScript" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/get-value-of-css-rotation-through.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04AQXwzeCp7ImA9WhRWEUs.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-4605102436077998755</id><published>2011-12-29T05:39:00.000-08:00</published><updated>2011-12-29T05:39:00.280-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-29T05:39:00.280-08:00</app:edited><title>Beyond Bandwidth: UI Performance</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;p&gt;Traditionally, older performance studies were concerned with speeding up things on the server side, but a few years back Steve Souders famously started research on the idea that the main performance bottleneck happened on the client side.  In particular, in the way bytes were pushed to the client from the server.  “Reduce HTTP requests” has become a general maxim for speeding up frontend performance, and that is a concern that’s even more relevant in today’s world of mobile browsers (often running on networks that are an order of magnitude slower than broadband connections).&lt;/p&gt;&lt;p&gt;These studies have been concerned with latency and bandwidth, and this still continues to be the focus of performance research today.  You are probably already familiar with the standard HTTP waterfall chart:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/google-http-waterfall-chart.png" width="650" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;However, we’re slowly starting to see a shift to other frontend concerns for each component of the frontend stack (HTML/CSS/JS).  In particular, there’s been a great focus on JavaScript performance, a fact attested to by the popularity of &lt;a href="http://jsperf.com/"&gt;jsPerf&lt;/a&gt; and the rise of JavaScript profilers.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;After the page loads: the UI layer&lt;/h3&gt;&lt;p&gt;This is all well and good, but we’re missing something: the presentation (UI) layer.  Ok, that’s actually a bit of an exaggeration.  UI performance tips have been disseminated throughout the community for years, but often as an aside, with bandwidth and latency concerns much more at the forefront.  For instance, where CSS is even a concern, &lt;a href="http://www.stevesouders.com/blog/2010/07/03/velocity-top-5-mistakes-of-massive-css/"&gt;the focus is on reducing CSS filesizes&lt;/a&gt;.  But what about expensive selectors?  Or CSS that may cause the page to lag horribly?&lt;/p&gt;&lt;p&gt;One of the reasons UI performance has been downplayed is perhaps because of its inability to be quantified.  As engineers, it’s a bit disconcerting to say that as a result of many hours of improvements, a website “feels” more responsive, or scrolls more smoothly.  We would rather say “this site was originally rated at a 6/10 for responsiveness, but now it’s rated 8/10 for responsiveness!”  But how on earth can we do gauge that?  Well, now we can!&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;UI Profilers&lt;/h3&gt;&lt;p&gt;Recently we’ve been given the tools to measure UI performance.  A new CSS profiler is available in Opera’s developer tools, and one is on the way for WebKit browsers.  Here’s the new face of performance profiling:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/opera-css-profiler.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here’s a few tools that should come in handy when testing UI performance:&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;CSS Stress Test&lt;/h4&gt;&lt;p&gt;&lt;a href="http://andy.edinborough.org/CSS-Stress-Testing-and-Performance-Profiling"&gt;CSS Stress Test&lt;/a&gt; (by Andy Edinborough) is a bookmarklet that figures out which CSS declarations are slowing down the page by selectively removing each one, then timing the scroll speed performance.  The result is a bookmarklet that’s a bit jarring to watch, but seems quite useful in tracking down rogue CSS bottlenecks.  Note to self: apparently applying border-radius to a ton of elements isn’t a very good idea, performance-wise.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;CSS Profilers&lt;/h4&gt;&lt;p&gt;A &lt;a href="http://bricss.net/post/13884376788/the-css-profilers-are-coming"&gt;CSS profiler&lt;/a&gt; is coming to a browser near you, which will give us much more insight into the actual speed of the CSS we write, moving us forward from vague and mysterious rules.  Is the universal selector (*) really that expensive?  Are border-radius, box shadow, and rgba values really performance drains?  Now we have ways to measure those concerns!&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;CSS Lint&lt;/h4&gt;&lt;p&gt;&lt;a href="http://csslint.net/"&gt;CSS Lint&lt;/a&gt; (by Nicole Sullivan and Nicholas Zakas) is a set of &lt;a href="https://github.com/stubbornella/csslint/wiki/Rules"&gt;best practices&lt;/a&gt; (you may not agree with them all, but that’s ok), including a few helpful rules that target UI performance specifically.  Run your stylesheets through and it’ll give you some helpful tips on what to improve.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;DOM Monster&lt;/h4&gt;&lt;p&gt;&lt;a href="http://mir.aculo.us/dom-monster/"&gt;DOM Monster&lt;/a&gt; (by Amy Hoy and Thomas Fuchs) is intended as a JavaScript profiler companion, but remember that the complexity of the DOM (Document Object Model) will also affect UI repaints and reflows.  Reducing that bloat is better for data down the wire, as well as UI rendering and JavaScript DOM access.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Perception of Speed&lt;/h3&gt;&lt;p&gt;If you think about it, all of performance is concerned with how performance is perceived by the user.  While we’re mostly concerned with real performance improvements, we have to recognize the limitations and realize that we don’t always have control over bandwidth, latency, or the speed of a user’s browser.  Where we’ve already done our best elsewhere, here we sometimes have to fake it.  Fake it ’till you make it!&lt;/p&gt;&lt;p&gt;What do I mean by faking it?  This might mean preloading content where possible, which is what Gmail mobile does before the user clicks on the “Show more messages…” button.  After the user clicks, the content has already been loaded – it only needs to change the UI to show the new content, and this happens extremely fast.  It doesn’t really matter how long it took to make the original HTTP request, because either way the experience is the same for the user, and their &lt;i&gt;perception&lt;/i&gt; is that the interface is extremely fast.  This is an example of a great marriage of good user experience design with good engineering.&lt;/p&gt;&lt;p&gt;“Faking it” might also mean simply being responsive and quickly showing the user a visual indicator after they take an action.  It doesn’t matter how well you optimize HTTP requests or how fast the connection is – if you don’t give an indication after the user performs an action, they will likely repeat their action (a click or another tap on the touchscreen) and come away with the impression that it’s a sluggish interface.&lt;/p&gt;&lt;p&gt;UI responsiveness also &lt;a href="http://www.youtube.com/watch?v=05C0GQPKA4g"&gt;became a concern for Flickr when they switched to YUI3&lt;/a&gt; – though they took advantage of combining HTTP requests, the initial unprimed cache page load meant that a user might start taking actions before the JavaScript was fully loaded, parsed, and executed.  Because Flickr progressively enhances their webpages, this means that without JavaScript ready, the user gets taken to pages that were put in place for users with JavaScript disabled.  Their solution was to load a mini-library in the page to capture all events on the page and queue them back to be replayed later.  Most importantly, this small library also provides a UI (a loading spinner) to give the user feedback after taking actions, even if it means nothing had happened, short of the event being queued up to be replayed later when the JavaScript is ready.  Fake it ’till you make it!&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Tidbits&lt;/h3&gt;&lt;p&gt;As I mentioned before, UI performance tips have been circulating for quite a while, but they have been somewhat downplayed compared to latency and bandwidth issues.&lt;/p&gt;&lt;p&gt;Here’s a collection of tidbits to give you an idea of some of the concerns that are out there:&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://blog.vlad1.com/2009/06/22/to-sprite-or-not-to-sprite/"&gt;Sprites save HTTP requests, but large sprites hog up memory&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://calendar.perfplanet.com/2011/pure-css3-images-hmm-maybe-later/"&gt;Pure CSS3 images? Hmm, maybe later (Marcel Duran)&lt;/a&gt; – pure CSS3 images are awesome but perhaps impractical, as they trade less bandwidth for decreased rendering speed (it turns out that images render faster)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Microsoft’s &lt;a href="http://www.microsoft.com/taiwan/promo/ie9/bow/fish_demo/FishTank_demo.html"&gt;FishIE Tank&lt;/a&gt; is a nice benchmark to test Canvas rendering speed, measured in frames per second.  You may even find that &lt;a href="http://29a.ch/2011/5/27/fast-html5-canvas-on-iphone-mobile-safari-performance"&gt;tweaking the viewport tag on mobile devices may speed up rendering times&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://lea.verou.me/2011/08/css-gradients-are-much-faster-than-svg/"&gt;CSS gradients are faster than SVG backgrounds&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Older WebKit browsers had &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=22102"&gt;scrolling/rendering lag with large box shadows&lt;/a&gt; – not all CSS3 stuff is ready for prime time, and sometimes images might be the way to go – better UI performance at the expense of more data down the wire&lt;/li&gt;&lt;br /&gt;&lt;li&gt;CSS radial gradients may be awesome and save the request of an image, but they might have rendering problems in some browsers, &lt;a href="http://code.google.com/p/android/issues/detail?id=767"&gt;particularly Android&lt;/a&gt;.  We save bandwidth by not requesting an image, but the user experience suffers&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Avoid IE CSS filters, as they have a performance hit&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use hardware-accelerated CSS animations over JavaScript animations where possible, but be aware of limitations (&lt;a href="http://joehewitt.com/2011/10/05/fast-animation-with-ios-webkit"&gt;maximum sizes of 1024x1024px in WebKit&lt;/a&gt;).  If you do end up needing to animate from JavaScript, try using &lt;a href="http://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/"&gt;requestAnimationFrame&lt;/a&gt; as opposed to setTimeout/setInterval&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Call for a focus on UI performance&lt;/h3&gt;&lt;p&gt;Performance is more than pushing bytes over a fence into a browser!  Much of the user’s experience happens after a page loads, so we should still be concerned about the performance of a “loaded page” experience.  This applies to our JavaScript, but equally as important is our CSS and its impact on scroll speed and overall UI responsiveness.&lt;/p&gt;&lt;p&gt;This might mean that we are sometimes better off using images instead of new CSS fanciness that’s not yet ready for primetime, and it’s up to us to weigh the cost and understand the tradeoff!  It also helps us appreciate new CSS features or fancy demos while remaining skeptical of their practical use.&lt;/p&gt;&lt;p&gt;More than anything, if you struggled with a UI performance issue and overcame it, the world could learn from your experience!  When you blog about it, you save other folks some time – time that could be spending with their families, which is definitely more important.  We need more articles from folks like &lt;a href="http://calendar.perfplanet.com/2011/pure-css3-images-hmm-maybe-later/"&gt;Marcel&lt;/a&gt; and &lt;a href="http://calendar.perfplanet.com/2011/mobile-ui-performance-considerations/"&gt;Estelle&lt;/a&gt;, who understand that performance goes beyond saving bytes.&lt;/p&gt;&lt;p&gt;So get to it!  But first, enjoy your time off.  Happy holidays and merry Christmas!&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://calendar.perfplanet.com/2011/beyond-bandwidth-ui-performance/"&gt;Beyond Bandwidth: UI Performance&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-4605102436077998755?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-Sm-DofBtFZD9h5i1qaKT0rOZ0w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-Sm-DofBtFZD9h5i1qaKT0rOZ0w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-Sm-DofBtFZD9h5i1qaKT0rOZ0w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-Sm-DofBtFZD9h5i1qaKT0rOZ0w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/w2etNgwywLA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/4605102436077998755?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/4605102436077998755?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/w2etNgwywLA/beyond-bandwidth-ui-performance.html" title="Beyond Bandwidth: UI Performance" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/beyond-bandwidth-ui-performance.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8HQ3o4cCp7ImA9WhRWEEU.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-53249005890831736</id><published>2011-12-28T06:50:00.000-08:00</published><updated>2011-12-28T06:50:32.438-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-28T06:50:32.438-08:00</app:edited><title>Say Hello to Webkit Filters</title><content type="html">&lt;p&gt;Earlier this month, a new specification, &lt;a href="https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html"&gt;Filter Effects 1.0&lt;/a&gt;, was released. It presents some exciting new Photoshop-like effects that we can use in the browser. Even better, &lt;a href="http://tools.google.com/dlpage/chromesxs"&gt;Webkit&lt;/a&gt; has already landed support (in the nightlies)!&lt;/p&gt;&lt;h2&gt;According to the Spec…&lt;/h2&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;     “A filter effect is a graphical operation that is applied to an element as it is drawn into the document. It is an image-based effect, in that it takes zero or more images as input, a number of parameters specific to the effect, and then produces an image as output.”&lt;br /&gt; &lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;Now, at least at this point, I wouldn’t presume to be able to show you everything that’s possible with these new filters. I’m still learning them myself! That said, I’ll show you a handful of the new filters, how we can use them in our projects, and then, hopefully, we can all brainstorm and learn from each other within the comments. Let’s get started.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Filters are typically associated with images (though they can also be applied to video). As such, for the handful of demos below, we’ll be using the Nettuts+ logo as input.&lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;&lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/nt-logo.jpg" alt="Nettuts+ Logo" /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt; &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/nt-logo.jpg" alt="Nettuts+ Logo" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;Remember: these effects aren’t yet available in the public releases of Webkit browsers. For now, &lt;a href="http://tools.google.com/dlpage/chromesxs"&gt;download Canary&lt;/a&gt; when testing these demos.&lt;/p&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;h2&gt;hue-rotate &lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Ever played around with the Hue/Saturation panel in Photoshop? Well now you can play around with it in the browser. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;  -webkit-filter: hue-rotate(50deg);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;If specifying this value in degrees seems confusing, just imagine a color wheel. The number of degrees you specify determines where that wheel stops. This means, that &lt;code&gt;0deg&lt;/code&gt; won’t do a thing, while &lt;code&gt;50deg&lt;/code&gt; will turn the dial, accordingly. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;In this case, the Nettuts+ logo will take on a blu-ish hue. &lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/hue.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Or, let’s say that you want your image to continuously change colors. Likely, in a real-world project, the color transitions will be far more subtle, but for this demo, we’ll be a bit obnoxious. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;  -webkit-animation: adjustHue 1s alternate infinite;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@-webkit-keyframes adjustHue {&lt;br /&gt;  0% { -webkit-filter: hue-rotate(30deg); }&lt;br /&gt;  50% { -webkit-filter: hue-rotate(60deg); }&lt;br /&gt;  100% { -webkit-filter: hue-rotate(90deg); }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Simple enough. &lt;a href="http://jsbin.com/ohuhek/65"&gt;View Demo&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;h2&gt;grayscale&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;We’ve used a variety of hacks in the past to transition an image from black and white to color in the browser. One technique calls for two images stacked on top of one another. Another option is to use canvas. Or… we can use the &lt;code&gt;grayscale&lt;/code&gt; filter. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;  -webkit-filter: grayscale(100%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;When applying a percentage to the &lt;code&gt;grayscale&lt;/code&gt; function, just think to yourself, “On a scale of 0 to 100%, how gray do I want this image to be? &lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/gray.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/2"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;When used in tandem with CSS3 transitions, we can apply a nice and clean hover effect. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt; -webkit-transition: -webkit-filter 1s;&lt;br /&gt;}&lt;br /&gt;img:hover {&lt;br /&gt;   -webkit-filter: grayscale(100%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;In the future, you’ll want to provide prefixes for the other browsers, however, it’s not necessary at this point. No need in applying Mozilla transitions to accomodate for a filter that’s only implemented in Webkit (so far). &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://jsbin.com/ohuhek/3"&gt;View Demo&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;h2&gt;sepia&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Enjoy the sepia-flavored Instagram effect? Let’s see what Nettuts+ looked like in the old west. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: sepia(100%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/sepia.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/4"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Typically, though, this effect is applied to photos. Let’s see how the greatest artist who ever lived  looks in sepia. &lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/justin-bieber.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/4"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Excellent. &lt;/p&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;h2&gt;blur&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;By passing a radius, we can blur an image in the browser with ease.&lt;br /&gt;&lt;/p&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: blur(2px);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/blur1.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/5"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Or by upping the blur radius to &lt;code&gt;50px&lt;/code&gt;. &lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/blur2.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/14"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;h2&gt;brightness&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;We use the &lt;code&gt;brightness&lt;/code&gt; filter to specify…wait for it…how bright the input image should appear. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: brightness(15%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/brightness.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/6"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Think of 100% as home base. &lt;code&gt;brightness(100%)&lt;/code&gt; keeps the image unchanged. As we reduce this percentage, however, the image will continue to darken. &lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;Don’t forget: you can combine all of these filters. &lt;/p&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: brightness(60%) sepia(100%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/sepiaBrightness.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/7"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;h2&gt;contrast&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;We can now adjust the contrast of an image quite easily. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: contrast(200%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/contrast.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/9"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Once again, think of &lt;code&gt;100%&lt;/code&gt; as resting position. We can then reduce or increase this value to adjust the contrast of the image. According to the spec, applying a value of &lt;code&gt;0%&lt;/code&gt; should make the image 100% black, similar to what you might expect from &lt;code&gt;-webkit-filter: brightness(0%);&lt;/code&gt;. However, I’m seeing more of a dark gray. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: contrast(0%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/contrast0.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/8"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Now if we up the percentage considerably, to &lt;code&gt;2000%&lt;/code&gt;: &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: contrast(2000%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/contrast2000.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/10"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Just for fun, let’s create a throbbing Matrix version of the Nettuts+ logo. We’ll combine CSS3 animations and filters. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;   -webkit-animation: bluePill 1s alternate infinite;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@-webkit-keyframes bluePill {&lt;br /&gt;  0% { -webkit-filter: contrast(2000%); }&lt;br /&gt;  100% { -webkit-filter: contrast(100%); }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://jsbin.com/ohuhek/12"&gt;View Demo&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;h2&gt;invert &lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Mac users: press &lt;code&gt;Control + Option + Command + 8&lt;/code&gt;. Notice how it inverts your screen (of course you noticed). I use this trick late at night when I’m reading on the computer, and my eyes are sore. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;By applying a percentage of 100 to the new &lt;code&gt;invert&lt;/code&gt; filter, we can achieve the exact same effect. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: invert(100%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/invert.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/13"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Note that 0% will leave the image unchanged. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now, you could technically apply this to, say, the body of your website, and it would work. However, you’ll notice considerable slow down, and lose the ability to scroll the page. AKA – Don’t do it, except for fun.&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/invertPage.jpg" alt="" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;h2&gt;saturate &lt;/h2&gt;&lt;br /&gt;&lt;p&gt;In addition to setting &lt;code&gt;grayscale(100%)&lt;/code&gt;, we could also achieve a similar effect by desaturating the image entirely. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;In this case, 100% is the unchanged state, at which point you can either decrease or increase this value. As such, reducing this value to 0% should remove all color from the image. &lt;/p&gt;&lt;br /&gt;&lt;pre name="code"&gt;img {&lt;br /&gt;     -webkit-filter: saturate(0%);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/deaturate.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/15"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Or, by upping the value to 700%: &lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;img src="http://d2o0t5hpnwv4c1.cloudfront.net/1111_filters/saturate700.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsbin.com/ohuhek/16"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;hr /&gt;&lt;p&gt;&lt;/p&gt;Post: &lt;a href="http://feedproxy.google.com/~r/nettuts/~3/Q1m6n7ln_D0/"&gt;Say Hello to Webkit Filters&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-53249005890831736?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PnXMkAv7gGRn8e5Nm1-Y58c-6xo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PnXMkAv7gGRn8e5Nm1-Y58c-6xo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PnXMkAv7gGRn8e5Nm1-Y58c-6xo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PnXMkAv7gGRn8e5Nm1-Y58c-6xo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/2SKttkRsmTQ" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/53249005890831736?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/53249005890831736?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/2SKttkRsmTQ/say-hello-to-webkit-filters.html" title="Say Hello to Webkit Filters" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/say-hello-to-webkit-filters.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMMRnk7eCp7ImA9WhRWEEo.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-1873835149365039227</id><published>2011-12-28T04:14:00.000-08:00</published><updated>2011-12-28T04:14:47.700-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-28T04:14:47.700-08:00</app:edited><title>Lossy Image Compression</title><content type="html">&lt;p&gt;Images are the one of the oldest items on the web (right after HTML) and still so little has changed since we started to use them. Yes, we now got JPEG and PNG in addition to original GIF, but other then that there were not many improvements to make them better.&lt;/p&gt;&lt;p&gt;That if you don’t count lots of creative talent that went into creating them, so much in fact that it created the web as we know now, reach, shiny and full of marketing potential! Without images we wouldn’t have the job of building the web, and without images we wouldn’t worry about web performance because there would be no users to care about experience and no business people to pay for improvements.&lt;/p&gt;&lt;p&gt;That being said, images on our websites are the largest payload sent back and forth across the wires of the net taking big part in slowing down user experience.&lt;/p&gt;&lt;p&gt;&lt;a href="http://httparchive.org/interesting.php#bytesperpage"&gt;According to HTTPArchive&lt;/a&gt;, JPEGs, GIFs and PNGs account for &lt;b&gt;63% of overall page size&lt;/b&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://httparchive.org/interesting.php#bytesperpage"&gt;&lt;img width="400" height="225" src="http://chart.apis.google.com/chart?chs=400x225&amp;amp;cht=p&amp;amp;chco=007099&amp;amp;chd=t:42,598,172,33,90,30&amp;amp;chds=0,598&amp;amp;chdlp=b&amp;amp;chdl=total%20965%20kB&amp;amp;chl=HTML+-+42+kB%7CImages+-+598+kB%7CScripts+-+172+kB%7CStylesheets+-+33+kB%7CFlash+-+90+kB%7COther+-+30+kB&amp;amp;chma=%7C5&amp;amp;chtt=Average+Bytes+per+Page+by+Content+Type" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;and overall image size has &lt;a href="http://httparchive.org/interesting.php#onLoad"&gt;0.64 correlation with overall page load time&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://httparchive.org/interesting.php#onLoad"&gt;&lt;img width="500" height="225" src="http://chart.apis.google.com/chart?chxl=1:%7CTotal+Xfer+Size%7CTotal+Reqs%7CImage+Xfer+Size%7CImage+Reqs%7CJS+Reqs&amp;amp;chxr=0,0,1&amp;amp;chxs=1,676767,11.5,0,lt,67676700&amp;amp;chxtc=1,5&amp;amp;chxt=y,x&amp;amp;chbh=60,30,30&amp;amp;chs=500x225&amp;amp;cht=bvg&amp;amp;chco=80C65A&amp;amp;chds=0,1&amp;amp;chd=t:0.73,0.66,0.64,0.62,0.42&amp;amp;chm=N,676767,0,,12,,::4&amp;amp;chtt=Highest+Correlation+to+Load+Time" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Still we can safely assume that &lt;b&gt;we are going to have only more images and they will only grow bigger&lt;/b&gt;, along with the screen resolutions on desktop computers.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Lossy compression&lt;/h2&gt;&lt;p&gt;There are a few different ways to optimize images including compression, spriting, picking appropriate format, resizing and so on. There are many other aspects of handling images that include postloading, caching, URL versioning, CDNs and etc.&lt;/p&gt;&lt;p&gt;In this article I wanted to concentrate on &lt;b&gt;lossy compression&lt;/b&gt; where &lt;b&gt;quality characteristics of the images are changed&lt;/b&gt; without significant visual differences for the user, but &lt;b&gt;with significant changes to performance&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;By now most of us are familiar with loss-less compression, thanks to &lt;a href="http://www.phpied.com/"&gt;Stoyan&lt;/a&gt; and &lt;a href="http://www.stubbornella.org/"&gt;Nicole&lt;/a&gt; who first introduced us to image optimization for web performance with an awesome on-line tool called &lt;a href="http://www.smushit.com/ysmush.it/"&gt;Smush.it&lt;/a&gt; (now ran by Yahoo). There are a few other tools now that have similar functionality for PNG, for example.&lt;/p&gt;&lt;p&gt;With smush.it and alike image quality is preserved as is with only unnecessary meta-data removed, it often saves up to 30-40% of file size. It is a safe choice and images will be intact when you do that. This seems the only way to go, especially for your design department who believe that once image comes out of their computers it is sacred and must be preserved absolutely the same.&lt;/p&gt;&lt;p&gt;In reality, quality of the image is not set in stone – JPEG was invented as a format that allowed for size reduction at a price of quality. Web got popular because of images, it wouldn’t be here if they were in BMP, TIFF or PCX formats that were dominating prior to JPEG.&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.sergeychernyshev.com/lossy/photoshow_export_for_web_and_devices.png" width="373" height="205" style="float:right;margin:0.5em 0 0.5em 0.5em" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This is why we need to actually start using this feature of JPEG where quality is adjustable. You probably even saw it in settings if you used export functionality of photo editors – here’s the screenshot of quality adjusting section of “export for web and devices” screen in Adobe Photoshop.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Quality setting ranges from 1 to 100 with 75 usually being enough for all of the photos with some of them looking good enough even with the value of 30. In Photoshop and other tools you can usually see the differences using your own eyes and adjust appropriately making sure quality never degrades below certain point that mainly depends on the image.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Resulting image size heavily depends on the original source of the image and visual features of the picture sometimes saving up to 80% of the size without significant degradation.&lt;/p&gt;&lt;p&gt;I know these numbers sound pretty vague, but that is exactly the problem that all of us faced when &lt;b&gt;we needed to automate image optimization&lt;/b&gt;. All images are different and without having a person looking at them, it’s &lt;b&gt;impossible to predict&lt;/b&gt; if fixed quality setting will be damaging the images or not saving enough. Unfortunately having a human editor in the middle of the process is costly, time consuming and sometimes simply impossible, for example when UGC (user-generated content) is used on the site.&lt;/p&gt;&lt;p&gt;I was bothered by this problem since I saw smush.it doing great job for lossless compression. Luckily, this year two tools emerged that allow for automation of lossy image compression: one open source tool was developed specifically for WPO purposes by my former co-worker, Ryan Flynn and called &lt;a href="https://github.com/rflynn/imgmin"&gt;ImgMin&lt;/a&gt; and another is a commercial tool called &lt;a href="http://www.jpegmini.com/"&gt;JPEGmini&lt;/a&gt; which came out of consumer photo size reduction.&lt;/p&gt;&lt;p&gt;I can’t talk for JPEGmini, &lt;a href="http://www.jpegmini.com/main/technology"&gt;their technology&lt;/a&gt; is private with patents pending, but ImgMin uses a simple approach of trying different quality settings and then picking the result that has the picture difference within a certain threshold. There are a few other simple heuristics, for more details you can read &lt;a href="https://github.com/rflynn/imgmin#readme"&gt;ImgMin’s documentation on Github&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Both of the tools work pretty well providing different results with ImgMin in it’s simplicity being less precise. JPEGmini offers dedicated server solution with cloud service coming soon.&lt;/p&gt;&lt;p&gt;In this table you can see my twitter userpic and how it was &lt;b&gt;automatically&lt;/b&gt; optimized using loss-less (smush.it) and loss-y (JPEGmini) compression:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="5" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.sergeychernyshev.com/lossy/sergey_reasonably_small.jpg" width="128" height="128" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://www.sergeychernyshev.com/lossy/sergey_reasonably_small_smushit.jpg" width="128" height="128" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://www.sergeychernyshev.com/lossy/sergey_reasonably_small_jpegmini.jpg" width="128" height="128" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr valign="top"&gt;&lt;td&gt;Original:10028 bytes&lt;/td&gt;&lt;td&gt;Lossless:9834 bytes2% savings&lt;/td&gt;&lt;td&gt;&lt;b&gt;Lossy:4238 bytes58% savings&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;Notice no perceivable quality degradation between original and optimized images. Results are astonishingly similar on larger photos as well.&lt;/p&gt;&lt;p&gt;This is great news as &lt;b&gt;it will finally allow us to automate lossy compression&lt;/b&gt; which was always a manual process – now you can rely on a tool and reliably build it into your image processing pipeline!&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://calendar.perfplanet.com/2011/lossy-image-compression/"&gt;Lossy Image Compression&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-1873835149365039227?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2o1_0AWV11t4fK_BtKstutpRDB8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2o1_0AWV11t4fK_BtKstutpRDB8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2o1_0AWV11t4fK_BtKstutpRDB8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2o1_0AWV11t4fK_BtKstutpRDB8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/ZKlzYWt1MKI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/1873835149365039227?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/1873835149365039227?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/ZKlzYWt1MKI/lossy-image-compression.html" title="Lossy Image Compression" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/lossy-image-compression.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8DSXY-eSp7ImA9WhRWEEo.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-4724315638697257836</id><published>2011-12-28T03:14:00.000-08:00</published><updated>2011-12-28T03:14:38.851-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-28T03:14:38.851-08:00</app:edited><title>Lazy evaluation of CommonJS modules</title><content type="html">&lt;p&gt;About two years ago, the mobile Gmail team posted an article focused on &lt;a href="http://googlecode.blogspot.com/2009/09/gmail-for-mobile-html5-series-reducing.html"&gt;reducing the startup latency&lt;/a&gt; of their HTML5 application. It described a technique which enabled bypassing parsing and evaluation of JavaScript until it was needed by placing it inside comments. &lt;a href="http://www.okito.net/"&gt;Charles Jolley&lt;/a&gt; of &lt;a href="http://sproutcore.com/"&gt;SproutCore&lt;/a&gt; fame was quick to jump on the idea. He &lt;a href="http://blog.sproutcore.com/faster-loading-through-eval/"&gt;experimented with it&lt;/a&gt; and found that similar performance gains could be achieved by putting the code inside of a string rather then commenting it. Then, despite &lt;a href="http://www.okito.net/post/8409610016/on-sproutcore-2-0"&gt;promises&lt;/a&gt; of building it into SproutCore, this technique pretty much fell into oblivion. That’s a shame because it’s an interesting alternative to lazy loading that suits CommonJS modules really well.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Close encounters of the text/javascript type&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;To understand how this technique works, let’s look at what happens when the browser’s parser encounters a &lt;code&gt;script&lt;/code&gt; element with a valid &lt;code&gt;src&lt;/code&gt; attribute. First, a request is sent to the server. Hopefully the server responds and the browser proceeds to download (and cache) the requested file. Once these steps are completed the file still needs to be parsed and evaluated.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/perf_cal/fig_1.png" alt="Fig. 1" title="" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;For comparison, here’s the same request hitting a warm HTTP cache:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/perf_cal/fig_2.png" alt="Fig. 2" title="" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;What’s worth noticing here—other than the obvious benefits of caching—is that parsing and evaluation of the JavaScript file still happen on every page load, regardless of caching. While these steps are blazing fast on modern desktop computers, they aren’t on mobile. Even on recent, high-end devices. Consider the following graph which compares the cost of parsing and evaluating jQuery on the iPhone 3, 4, 4S, iPad, iPad 2, a Nexus S and a Mac Book Pro. (Note that these results are indicative only. They were gathered using the test hosted at &lt;a href="http://lazyeval.org/"&gt;lazyeval.org&lt;/a&gt;, which at this point is still very much alpha.)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/perf_cal/graph_1.png" alt="Graph 1" title="" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Remember that these times come on top of whatever networking costs you’re already facing. Furthermore, they’ll be incurred on &lt;em&gt;every single page load&lt;/em&gt;, regardless of whether or not the file was cached. Yes, you’re reading this right. On an iPhone 4, parsing and evaluating jQuery takes over 0.3 seconds, &lt;em&gt;every single time the page is loaded&lt;/em&gt;. Arguably, those results have substantially improved with more recent devices, but you can’t count on your whole user base owning last generation smartphones, can you?&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Lazy loading&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;A commonly suggested solution to the problem of startup latency is to load scripts on demand (for example, following a user interaction). The main advantage of this technique is that it delays the cost of downloading, parsing and evaluating until the script is needed. Note that in practice—and unless you can delay &lt;em&gt;all&lt;/em&gt; your JavaScript files—you’ll end up having to pay round trip costs twice.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/perf_cal/fig_3.png" alt="Fig. 3" title="" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;There are a number of downsides to this approach, however. First of all, the code isn’t guaranteed to be delivered: the network or the server can become unavailable in the meantime. Secondly, the speed at which the code is transferred is subject to the network’s quality and can thus vary widely. Lastly, the code is delivered asynchronously. These downsides force the developer to build both defensively and with asynchronicity in mind, irremediably tying the implementation to it’s delivery mechanism in the process. Unless the whole codebase is built on these premises—which is probably something you want to avoid—deferring the loading of a chunk of code becomes a non-trivial endeavor.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Lazy evaluation to the rescue.&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Lazy evaluation avoids these issues altogether by focusing on delaying the parsing and evaluation stages only. The script can be either bundled with the initial payload or inlined. It is prevented from being evaluated during initial page load by being either commented-out or escaped and turned into a string (“stringified”?). In both cases, the content is simply evaluated when required.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/perf_cal/fig_4.png" alt="Fig. 4" title="" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And again. for comparison, hitting a warm HTTP cache:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/perf_cal/fig_5.png" alt="Fig. 5" title="" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As the following graph of an iPad 2 parsing and evaluating jQuery shows, both options consistently out-perform regular evaluation by at least a factor of ten. Similar tenfold performance improvements were observed on all tested devices.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/perf_cal/graph_2.png" alt="Graph 2" title="" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Commented-out code has slightly better performance indices than “stringified” code does. It can however be quite complicated to extract when not inlined. It is also more brittle: some phone operators are known to &lt;a href="http://www.mysociety.org/2011/08/11/mobile-operators-breaking-content/"&gt;strip out JavaScript comments&lt;/a&gt;. “Stringified” code, on the other hand is both more robust and a lot easier to access, that’s why its preferred. &lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Building lazy evaluation into CommonJS modules&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;It turns out that the &lt;a href="http://wiki.commonjs.org/wiki/Modules/1.1"&gt;CommonJS module&lt;/a&gt;’s extra level of indirection (the &lt;code&gt;require&lt;/code&gt; call) makes it an ideal candidate for lazy evaluation. Since lazy evaluation is synchronous, the whole process can be made completely transparent to the developer. Enabling lazy evaluation becomes a one-liner in a config file, not a large architectural change. Even better, the dependency graph built through static analysis can be leveraged to automatically lazy evaluate all of the selected module’s dependencies.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Implementation wise, enabling lazy evaluation of CommonJS modules requires modifying the runtime so that it correctly evaluates and wraps modules which are transported in their “stringified” form. In &lt;a href="https://github.com/tobie/modulr-node/"&gt;modulr&lt;/a&gt;, my CommonJS module dependencies resolver, this is done &lt;a href="https://github.com/tobie/modulr-node/blob/v0.6.1/assets/modulr.sync.js#L26-29"&gt;like so&lt;/a&gt;:&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;typeof&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; === &lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt; &lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;require&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;exports&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;This implies lazy evaluated modules be &lt;a href="https://github.com/tobie/modulr-node/blob/v0.6.1/lib/collector.js#L56-61"&gt;escaped&lt;/a&gt; and &lt;a href="https://github.com/tobie/modulr-node/blob/v0.6.1/lib/collector.js#L76"&gt;surrounded by quotes&lt;/a&gt; at build time on the server-side, before transport.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The initial results are promising, but at this point, it is merely work in progress. Future plans for modulr include enabling full minification of it’s output (just minifying the output won’t do as it would miss modules transported as strings), instrumenting the runtime to be able to gather perf data and experimenting with a Souders-inspired &lt;a href="http://www.stevesouders.com/blog/2011/09/26/app-cache-localstorage-survey/"&gt;per module localStorage cache&lt;/a&gt;. If there’s interest, I’d also like to automate &lt;a href="http://lazyeval.org/"&gt;lazyeval.org&lt;/a&gt; to allow it to measure performance gain of applying this technique onto other JavaScript libraries and reporting those results to &lt;a href="http://www.browserscope.org/"&gt;browserscope.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://calendar.perfplanet.com/2011/lazy-evaluation-of-commonjs-modules/"&gt;Lazy evaluation of CommonJS modules&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-4724315638697257836?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/D4dfy0HmSo6h2PTXzzlD9PMZsuA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/D4dfy0HmSo6h2PTXzzlD9PMZsuA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/D4dfy0HmSo6h2PTXzzlD9PMZsuA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/D4dfy0HmSo6h2PTXzzlD9PMZsuA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/WXV1XY4xQ6Y" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/4724315638697257836?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/4724315638697257836?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/WXV1XY4xQ6Y/lazy-evaluation-of-commonjs-modules.html" title="Lazy evaluation of CommonJS modules" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/lazy-evaluation-of-commonjs-modules.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcHR3k8eip7ImA9WhRWEEo.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-2378861694060998483</id><published>2011-12-28T03:00:00.000-08:00</published><updated>2011-12-28T03:00:36.772-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-28T03:00:36.772-08:00</app:edited><title>Playing with the clipboard in iOS safari</title><content type="html">&lt;p&gt;So the other day it hit me that since iOS safari supports contenteditbale it should surely have support the clipboard events and other handy bits and pieces. Like any good hacker I created a &lt;a href="http://www.thecssninja.com/demo/clipboard/"&gt;testcase&lt;/a&gt; to find out basic support of events and getting selection range values, and as expected the support is pretty good. Let’s dive deeper. &lt;/p&gt;&lt;div&gt;&lt;a href="http://www.thecssninja.com/demo/clipboard/" title="Playing with the clipboard in iOS safari"&gt;View a live demo&lt;/a&gt; | &lt;a href="http://www.thecssninja.com/demo/clipboard/clipboard.zip" title="Download the source of the Playing with the clipboard in iOS safari demo"&gt;Download the source files&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Clipboard events&lt;/h2&gt;&lt;p&gt;The testcase above hooks into six events that will trigger when the user does a clipboard operation, unfortunately the before[cut/copy/paste] events don’t seem to trigger.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Range objects&lt;/h2&gt;&lt;p&gt;Range objects are what you’ve selected on the page allowing you to alter the selection or simply just return what a user has selected. Ranges also allow you to programmatically set a selection within your document, both of these work in iOS safari.&lt;/p&gt;&lt;p&gt;When setting a range iOS Safari won’t actually show the selection as highlighted but if you were to check the document selection it would return the correct content, desktop browsers will show the range selected in the document.&lt;/p&gt;&lt;p&gt;However if you do the same with a user action like tapping the “set selection range” button in the demo the iOS highlight will show up. Another interesting quirk is if I tap the content and bring the keyboard up but don’t dismiss it then refresh the page the programmatically set selection will show the iOS selection highlight.&lt;/p&gt;&lt;p&gt;Another interesting find is if you perform &lt;code&gt;execCommand&lt;/code&gt;, which I’ll touch on later in the article, like bold it will apply the command to the selection made and make the iOS selection UI appear.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;span&gt;var&lt;/span&gt; &lt;span&gt;sel&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;window&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getSelection&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;br /&gt;   &lt;span&gt;range&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createRange&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;range&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setStart&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;"h1"&lt;/span&gt;&lt;span&gt;)[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;].&lt;/span&gt;&lt;span&gt;firstChild&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;5&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;range&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setEnd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;"p"&lt;/span&gt;&lt;span&gt;)[&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;].&lt;/span&gt;&lt;span&gt;firstChild&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;50&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;sel&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;removeAllRanges&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;sel&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addRange&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;range&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;You’ll notice that when selecting an element I get its &lt;code&gt;firstChild&lt;/code&gt;, which is a textnode, this is so the offset value will work and allows you to select half a textnode.&lt;/p&gt;&lt;p&gt;The code is saying create a range starting at the documents first h1 element offsetting the selection by 5 characters and ending at the 3rd paragraph offsetting the end of the paragraph by 50 characters.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Setting clipboard data&lt;/h2&gt;&lt;p&gt;Accessing the clipboard is an incredibly sporadic task, there is sort of access in some browsers. IE has the most consistent behaviour similar to how DnD data setting works you have a &lt;code&gt;clipboardData&lt;/code&gt; interface which has get and &lt;code&gt;setData&lt;/code&gt; methods on it. Other browsers have semi-reversed engineered the IE API with the exception that &lt;code&gt;clipboardData&lt;/code&gt; is on the event object rather than the window. iOS Safari allows you to get the clipboard data on a paste event but doesn’t allow you to set it.&lt;/p&gt;&lt;p&gt;There is hope that clipboard access will one day have some consistent support through the &lt;a href="http://dev.w3.org/2006/webapi/clipops/"&gt;Clipboard API editor spec&lt;/a&gt; but that’s a long way off for now.&lt;/p&gt;&lt;p&gt;In the demo if you’ve copied text from another location and paste it it will alert the clipboard contents before being pasted.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;"clipboardData"&lt;/span&gt; &lt;span&gt;in&lt;/span&gt; &lt;span&gt;e&lt;/span&gt; &lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span&gt;e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type&lt;/span&gt; &lt;span&gt;===&lt;/span&gt; &lt;span&gt;"paste"&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span&gt;alert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;"Clipboard data: "&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;clipboardData&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getData&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;'text/plain'&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;WYSIWYG&lt;/h2&gt;&lt;p&gt;By adding support for the contenteditable attribute comes a whole swoth of API’s available for manipulating the contents, one of those is execCommand.&lt;/p&gt;&lt;p&gt;&lt;code&gt;execCommand&lt;/code&gt; allows you to do a whole bunch things to the content. Take a look at this &lt;a href="http://help.dottoro.com/larpvnhw.php"&gt;great resource&lt;/a&gt; which shows all the commands available and its support in the major browsers. These commands allow you to manipulate the style and html of the editable content (this is how all those fancy WYSIWYG editors work).&lt;/p&gt;&lt;p&gt;I would be keen to know if this works on other smart phone browsers, leave a comment if you know more details.&lt;/p&gt;&lt;p&gt;Short URL: &lt;a href="http://cssn.in/ja/037"&gt;http://cssn.in/ja/037&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-2378861694060998483?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RtNX2aINYrkYleL4d_uSYO7zjcI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RtNX2aINYrkYleL4d_uSYO7zjcI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RtNX2aINYrkYleL4d_uSYO7zjcI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RtNX2aINYrkYleL4d_uSYO7zjcI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/8BREfogrdw4" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/2378861694060998483?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/2378861694060998483?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/8BREfogrdw4/playing-with-clipboard-in-ios-safari.html" title="Playing with the clipboard in iOS safari" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/playing-with-clipboard-in-ios-safari.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4ARn4zeip7ImA9WhRWEEs.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-6232511230329981457</id><published>2011-12-28T02:42:00.000-08:00</published><updated>2011-12-28T02:42:27.082-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-28T02:42:27.082-08:00</app:edited><title>Batman.js for Building Rich Single-Page Browser Apps</title><content type="html">&lt;p&gt;&lt;a title="Batman.js" href="http://batmanjs.org/"&gt;Batman.js&lt;/a&gt; is a &lt;strong&gt;framework for building rich single-page browser applications&lt;/strong&gt;. It is written in CoffeeScript and its API is developed with CoffeeScript in mind, but of course you can use plain old JavaScript too.&lt;/p&gt;&lt;p&gt;It got a stateful MVC architecture, a powerful binding system, routable controller actions, pure HTML views, toolchain support built on node.js and cake. The APIs are heavily inspired by Rails and designed to make Rails devs feel right at home. It has been tested on Chrome, Safari 4+, Firefox 3+, and IE 7+ for compatibility.&lt;/p&gt;&lt;p style="text-align:center"&gt;&lt;a title="Batman.js" href="http://batmanjs.org/"&gt;&lt;img title="batman-js" src="http://maxcdn.webappers.com/img/2011/12/batman-js.png" alt="batman-js" width="480" height="216" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Requirements: -&lt;br /&gt;Demo: &lt;a title="demo" rel="nofollow" href="http://batmanjs.org/"&gt;http://batmanjs.org/&lt;/a&gt;&lt;br /&gt;License: MIT License&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;Sponsors&lt;/h3&gt;&lt;p&gt;&lt;a href="http://www.webiconset.com/?utm_source=WebAppers&amp;amp;utm_medium=cpc&amp;amp;utm_campaign=WebAppers%2BRSS"&gt;Professional Web Icons for Your Websites and Applications&lt;/a&gt;&lt;/p&gt;&lt;div&gt;Post: &lt;a href="http://feedproxy.google.com/~r/Webappers/~3/LSkGlNMhDAQ/"&gt;Batman.js for Building Rich Single-Page Browser Apps&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-6232511230329981457?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Gahgus9S1adPEYy7MAtG2orJU7U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gahgus9S1adPEYy7MAtG2orJU7U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Gahgus9S1adPEYy7MAtG2orJU7U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gahgus9S1adPEYy7MAtG2orJU7U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/x1ht_5dFmRo" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6232511230329981457?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6232511230329981457?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/x1ht_5dFmRo/batmanjs-for-building-rich-single-page.html" title="Batman.js for Building Rich Single-Page Browser Apps" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/batmanjs-for-building-rich-single-page.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAMRXY6fCp7ImA9WhRXGUU.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-5186897587937920823</id><published>2011-12-27T04:09:00.000-08:00</published><updated>2011-12-27T04:09:44.814-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-27T04:09:44.814-08:00</app:edited><title>CSS3 Lightbox</title><content type="html">&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3Lightbox/"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2011/12/CSS3Lightbox.jpg" alt="CSS3Lightbox" width="580" height="315" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3Lightbox/"&gt;View demo&lt;/a&gt; &lt;a href="http://tympanus.net/Tutorials/CSS3Lightbox/CSS3Lightbox.zip"&gt;Download source&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Today we want to show you how to create a neat lightbox effect using only CSS. The idea is to have some thumbnails that are clickable, and once clicked, the respective large image is shown. Using CSS transitions and animations, we can make the large image appear in a fancy way.&lt;/p&gt;&lt;p&gt;With the help of the pseudo-class &lt;a href="http://www.w3.org/TR/css3-selectors/#target-pseudo"&gt;:target&lt;/a&gt;, we will be able to show the lightbox images and navigate through them.&lt;/p&gt;&lt;p&gt;The beautiful images are by &lt;a href="http://www.behance.net/qstra"&gt;Joanna Kustra&lt;/a&gt; and they are licensed under the &lt;a href="http://creativecommons.org/licenses/by-nc/3.0/"&gt;Attribution-NonCommercial 3.0 Unported Creative Commons License&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Please note that this will only work with browsers that support the :target pseudo class.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Let’s do it!&lt;/p&gt;&lt;div&gt;&lt;/div&gt;&lt;div style="clear:both"&gt;&lt;/div&gt;&lt;h3&gt;The Markup&lt;/h3&gt;&lt;p&gt;We want to show a set of thumbnails, each one having a title that will appear on hover. When clicking on a thumbnail, we want to show a large version of the image in an overlay container that will make the background a bit more opaque. So, let’s use an unordered list where each list item will contain a thumbnail and a division for the overlay with the respective large version of the image:&lt;/p&gt;&lt;pre&gt;&amp;lt;ul class="lb-album"&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;&lt;br /&gt;  &amp;lt;a href="#image-1"&amp;gt;&lt;br /&gt;   &amp;lt;img src="images/thumbs/1.jpg" alt="image01"&amp;gt;&lt;br /&gt;   &amp;lt;span&amp;gt;Pointe&amp;lt;/span&amp;gt;&lt;br /&gt;  &amp;lt;/a&amp;gt;&lt;br /&gt;  &amp;lt;div class="lb-overlay" id="image-1"&amp;gt;&lt;br /&gt;   &amp;lt;img src="images/full/1.jpg" alt="image01" /&amp;gt;&lt;br /&gt;   &amp;lt;div&amp;gt;&lt;br /&gt;    &amp;lt;h3&amp;gt;pointe &amp;lt;span&amp;gt;/point/&amp;lt;/h3&amp;gt;&lt;br /&gt;    &amp;lt;p&amp;gt;Dance performed on the tips of the toes&amp;lt;/p&amp;gt;&lt;br /&gt;    &amp;lt;a href="#image-10" class="lb-prev"&amp;gt;Prev&amp;lt;/a&amp;gt;&lt;br /&gt;    &amp;lt;a href="#image-2" class="lb-next"&amp;gt;Next&amp;lt;/a&amp;gt;&lt;br /&gt;   &amp;lt;/div&amp;gt;&lt;br /&gt;   &amp;lt;a href="#page" class="lb-close"&amp;gt;x Close&amp;lt;/a&amp;gt;&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;&lt;br /&gt;  &amp;lt;!-- ... --&amp;gt;&lt;br /&gt; &amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2011/12/CSS3Lightbox02.jpg" alt="CSS3Lightbox01" width="580" height="246" /&gt;&lt;/p&gt;&lt;p&gt;The anchor for the thumbnail will point to the element with the id &lt;strong&gt;image-1&lt;/strong&gt; which is the division with the class &lt;strong&gt;lb-overlay&lt;/strong&gt;. In order to navigate through the images, we will add two link elements that point to the previous and next (large) image.&lt;br /&gt;In order to “close” the lightbox, we will somply click on the link with the class &lt;strong&gt;lb-close&lt;/strong&gt; which points to the element with the ID &lt;strong&gt;page&lt;/strong&gt; which is our body.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Note that we only use a navigation in the last demo.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Let’s beautify this naked markup.&lt;/p&gt;&lt;h3&gt;The CSS&lt;/h3&gt;&lt;p&gt;&lt;em&gt;I’ll omit the vendor prefixes for some of the new properties here in order not to bloat the tutorial. You can, of course, find them in the download files.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Let’s give some basic layout to our unordered list and the thumbnails:&lt;/p&gt;&lt;pre&gt;.lb-album{&lt;br /&gt; width: 900px;&lt;br /&gt; margin: 0 auto;&lt;br /&gt; font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;&lt;br /&gt;}&lt;br /&gt;.lb-album li{&lt;br /&gt; float: left;&lt;br /&gt; margin: 5px;&lt;br /&gt; position: relative;&lt;br /&gt;}&lt;br /&gt;.lb-album li &amp;gt; a,&lt;br /&gt;.lb-album li &amp;gt; a img{&lt;br /&gt; display: block;&lt;br /&gt;}&lt;br /&gt;.lb-album li &amp;gt; a{&lt;br /&gt; width: 150px;&lt;br /&gt; height: 150px;&lt;br /&gt; position: relative;&lt;br /&gt; padding: 10px;&lt;br /&gt; background: #f1d2c2;&lt;br /&gt; box-shadow: 1px 1px 2px #fff, 1px 1px 2px rgba(158,111,86,0.3) inset;&lt;br /&gt; border-radius: 4px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The title for each thumbnail will be invisible and we’ll add a transitions for the opacity which will change to 1 once we hover over the thumbnail anchor. We’ll use a smooth radial gradient as background:&lt;/p&gt;&lt;pre&gt;.lb-album li &amp;gt; a span{&lt;br /&gt; position: absolute;&lt;br /&gt; width: 150px;&lt;br /&gt; height: 150px;&lt;br /&gt; top: 10px;&lt;br /&gt; left: 10px;&lt;br /&gt; text-align: center;&lt;br /&gt; line-height: 150px;&lt;br /&gt; color: rgba(27,54,81,0.8);&lt;br /&gt; text-shadow: 0px 1px 1px rgba(255,255,255,0.6);&lt;br /&gt; font-size: 24px;&lt;br /&gt; opacity: 0;&lt;br /&gt; background:&lt;br /&gt;  radial-gradient(&lt;br /&gt;   center,&lt;br /&gt;   ellipse cover,&lt;br /&gt;   rgba(255,255,255,0.56) 0%,&lt;br /&gt;   rgba(241,210,194,1) 100%&lt;br /&gt;  );&lt;br /&gt; transition: opacity 0.3s linear;&lt;br /&gt;}&lt;br /&gt;.lb-album li &amp;gt; a:hover span{&lt;br /&gt; opacity: 1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The overlay will have the same radial gradient and we’ll set its position to fixed, with zero height and width:&lt;/p&gt;&lt;pre&gt;.lb-overlay{&lt;br /&gt; width: 0px;&lt;br /&gt; height: 0px;&lt;br /&gt; position: fixed;&lt;br /&gt; overflow: hidden;&lt;br /&gt; left: 0px;&lt;br /&gt; top: 0px;&lt;br /&gt; padding: 0px;&lt;br /&gt; z-index: 99;&lt;br /&gt; text-align: center;&lt;br /&gt; background:&lt;br /&gt;  radial-gradient(&lt;br /&gt;   center,&lt;br /&gt;   ellipse cover,&lt;br /&gt;   rgba(255,255,255,0.56) 0%,&lt;br /&gt;   rgba(241,210,194,1) 100%&lt;br /&gt;  );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Once we click on a thumbnail, we’ll cover the whole screen with the overlay, but first, let’s take a look at the children.&lt;/p&gt;&lt;p&gt;Let’s style the division for the main title and the description:&lt;/p&gt;&lt;pre&gt;.lb-overlay &amp;gt; div{&lt;br /&gt; position: relative;&lt;br /&gt; color: rgba(27,54,81,0.8);&lt;br /&gt; width: 550px;&lt;br /&gt; height: 80px;&lt;br /&gt; margin: 40px auto 0px auto;&lt;br /&gt; text-shadow: 0px 1px 1px rgba(255,255,255,0.6);&lt;br /&gt;}&lt;br /&gt;.lb-overlay div h3,&lt;br /&gt;.lb-overlay div p{&lt;br /&gt; padding: 0px 20px;&lt;br /&gt; width: 200px;&lt;br /&gt; height: 60px;&lt;br /&gt;}&lt;br /&gt;.lb-overlay div h3{&lt;br /&gt; font-size: 36px;&lt;br /&gt; float: left;&lt;br /&gt; text-align: right;&lt;br /&gt; border-right: 1px solid rgba(27,54,81,0.4);&lt;br /&gt;}&lt;br /&gt;.lb-overlay div h3 span,&lt;br /&gt;.lb-overlay div p{&lt;br /&gt; font-size: 16px;&lt;br /&gt; font-family: Constantia, Palatino, serif;&lt;br /&gt; font-style: italic;&lt;br /&gt;}&lt;br /&gt;.lb-overlay div h3 span{&lt;br /&gt; display: block;&lt;br /&gt; line-height: 6px;&lt;br /&gt;}&lt;br /&gt;.lb-overlay div p{&lt;br /&gt; font-size: 14px;&lt;br /&gt; text-align: left;&lt;br /&gt; float: left;&lt;br /&gt; width: 260px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;We’ll position the link element for closing the lightbox absolutely above the image:&lt;/p&gt;&lt;pre&gt;.lb-overlay a.lb-close{&lt;br /&gt; background: rgba(27,54,81,0.8);&lt;br /&gt; z-index: 1001;&lt;br /&gt; color: #fff;&lt;br /&gt; position: absolute;&lt;br /&gt; top: 43px;&lt;br /&gt; left: 50%;&lt;br /&gt; font-size: 15px;&lt;br /&gt; line-height: 26px;&lt;br /&gt; text-align: center;&lt;br /&gt; width: 50px;&lt;br /&gt; height: 23px;&lt;br /&gt; overflow: hidden;&lt;br /&gt; margin-left: -25px;&lt;br /&gt; opacity: 0;&lt;br /&gt; box-shadow: 0px 1px 2px rgba(0,0,0,0.3);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The image will have a maximum height of 100%. That’s one way of making the image somewhat reponsive and nicely fittin into the viewport (i.e our overlay). We’ll also add a transition for the opacity level. Once we “open” a large image, the opacity will get animated. We’ll see later how we can use an animation for the image.&lt;/p&gt;&lt;pre&gt;.lb-overlay img{&lt;br /&gt; max-height: 100%;&lt;br /&gt; position: relative;&lt;br /&gt; opacity: 0;&lt;br /&gt; box-shadow: 0px 2px 7px rgba(0,0,0,0.2);&lt;br /&gt; transition: opacity 0.5s linear;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Let’s style the navigation elements:&lt;/p&gt;&lt;pre&gt;.lb-prev, .lb-next{&lt;br /&gt; text-indent: -9000px;&lt;br /&gt; position: absolute;&lt;br /&gt; top: -32px;&lt;br /&gt; width: 24px;&lt;br /&gt; height: 25px;&lt;br /&gt; left: 50%;&lt;br /&gt; opacity: 0.8;&lt;br /&gt;}&lt;br /&gt;.lb-prev:hover, .lb-next:hover{&lt;br /&gt; opacity: 1;&lt;br /&gt;}&lt;br /&gt;.lb-prev{&lt;br /&gt; margin-left: -30px;&lt;br /&gt; background: transparent url(../images/arrows.png) no-repeat top left;&lt;br /&gt;}&lt;br /&gt;.lb-next{&lt;br /&gt; margin-left: 6px;&lt;br /&gt; background: transparent url(../images/arrows.png) no-repeat top right;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2011/12/CSS3Lightbox01.jpg" alt="CSS3Lightbox01" width="580" height="400" /&gt;&lt;/p&gt;&lt;p&gt;When we click on a thumbnail anchor, it will point to the respective large version of the image which is in the division with the class &lt;strong&gt;lb-overlay&lt;/strong&gt;. So, in order to address this element we can use the pseudo class &lt;strong&gt;:target&lt;/strong&gt;. We’ll add a padding to the overlay and “stretch it” over the whole viewport by setting the width and height to auto (it’s actually not needed explicitely) and set the right and bottom to 0px. Remember, we’ve already set the top and left before.&lt;/p&gt;&lt;pre&gt;.lb-overlay:target {&lt;br /&gt; width: auto;&lt;br /&gt; height: auto;&lt;br /&gt; bottom: 0px;&lt;br /&gt; right: 0px;&lt;br /&gt; padding: 80px 100px 120px 100px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Now we will also set the opacity of the image and the closing link to 1. The image will fade in, because we’ve set a transition:&lt;/p&gt;&lt;pre&gt;.lb-overlay:target img,&lt;br /&gt;.lb-overlay:target a.lb-close{&lt;br /&gt; opacity: 1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;And that’s all the style!&lt;br /&gt;Let’s take a look at the two alternatives that we are using in demo 1 and demo 2.&lt;/p&gt;&lt;p&gt;In the first demo we make the image appear by using an animation that scales it up and increases it’s opacity value:&lt;/p&gt;&lt;pre&gt;.lb-overlay:target img {&lt;br /&gt; animation: fadeInScale 1.2s ease-in-out;&lt;br /&gt;}&lt;br /&gt;@keyframes fadeInScale {&lt;br /&gt; 0% { transform: scale(0.6); opacity: 0; }&lt;br /&gt; 100% { transform: scale(1); opacity: 1; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;In the second demo we’ll create the opposite effect, i.e. scale the image down:&lt;/p&gt;&lt;pre&gt;.lb-overlay:target img {&lt;br /&gt; animation: scaleDown 1.2s ease-in-out;&lt;br /&gt;}&lt;br /&gt;@-webkit-keyframes scaleDown {&lt;br /&gt; 0% { transform: scale(10,10); opacity: 0; }&lt;br /&gt; 100% { transform: scale(1,1); opacity: 1; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Demos&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3Lightbox/index.html"&gt;Demo 1: Scale-up / fade-in animation&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3Lightbox/index2.html"&gt;Demo 2: Scale-down / fade-in animation&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3Lightbox/index3.html"&gt;Demo 3: Fade-in &amp;amp; navigation&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;You will see that each browser performs quite differently when it comes to the transitions/animations. Adjusting duration, timing functions and delays, one can make the effects smoother, i.e. you can change the timing for Firefox only by changing the -moz- properties. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;And that’s it! I hope you enjoyed this tutorial and find it inspiring!&lt;/p&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/CSS3Lightbox/"&gt;View demo&lt;/a&gt; &lt;a href="http://tympanus.net/Tutorials/CSS3Lightbox/CSS3Lightbox.zip"&gt;Download source&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://tympanus.net/codrops/2011/12/26/css3-lightbox/"&gt;CSS3 Lightbox&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-5186897587937920823?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mxNfHkYCPD5qgoFnqvPzDtHIDuI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mxNfHkYCPD5qgoFnqvPzDtHIDuI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mxNfHkYCPD5qgoFnqvPzDtHIDuI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mxNfHkYCPD5qgoFnqvPzDtHIDuI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/_mhQqPArC9c" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/5186897587937920823?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/5186897587937920823?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/_mhQqPArC9c/css3-lightbox.html" title="CSS3 Lightbox" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/css3-lightbox.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4CSH47cSp7ImA9WhRXGU8.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-2317361997529658426</id><published>2011-12-26T11:32:00.000-08:00</published><updated>2011-12-26T11:32:49.009-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-26T11:32:49.009-08:00</app:edited><title>There’s No Formula for Great Designs</title><content type="html">&lt;p&gt;Before he combined them with fluid images and CSS3 media queries to coin responsive design, &lt;a href="http://24ways.org/authors/ethanmarcotte"&gt;Ethan Marcotte&lt;/a&gt; described &lt;a href="http://www.alistapart.com/articles/fluidgrids/"&gt;fluid grids&lt;/a&gt; — one of the most enjoyable parts of responsive design. Enjoyable that is, if you like working with math(s). But fluid grids aren’t perfect and, unless we’re careful when applying them, they can sometimes result in a design that feels disconnected.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;h3&gt;Recapping fluid grids&lt;/h3&gt; &lt;p&gt;If you haven’t read Ethan’s &lt;a href="http://www.alistapart.com/articles/fluidgrids/"&gt;Fluid Grids&lt;/a&gt;, now would be a good time to do that. It centres around a simple formula for converting pixel widths to percentages:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;(target ÷ context) × 100 = result&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;How does that work in practice? Well, take that Fireworks or Photoshop comp you’re working on (I call them static design visuals, or just visuals.) Of course, everything on that visual — column divisions, inline images, navigation elements, everything — is measured in pixels. Now:&lt;/p&gt; &lt;ol&gt;&lt;br /&gt;  &lt;li&gt;Pick something in the visual and measure its width. That’s our target.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Take that target measurement and divide it by the width of its parent (context).&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Multiply what you’ve got by 100 (shift two decimal places).&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;What you’re left with is a percentage width to drop into your style sheets.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt; &lt;p&gt;For example, divide this 300px wide sidebar division by its 948px parent and then multiply by 100: your original 300px is neatly converted to 31.646%.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;.content-sub {&lt;br /&gt;width : 31.646%; /* 300px ÷ 948px = .31646 */ }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;That formula makes it surprisingly simple for even die-hard fixed width aficionados to convert their visuals to percentage-based, fluid layouts.&lt;/p&gt; &lt;p&gt;It’s a handy formula for those who still design using static visuals, and downright essential for those situations where one person in an organization designs in Fireworks or Photoshop and another develops with &lt;span&gt;CSS&lt;/span&gt;. Why?&lt;/p&gt; &lt;p&gt;Well, although I think that &lt;a href="http://24ways.org/2009/make-your-mockup-in-markup"&gt;designing in a browser&lt;/a&gt; makes the best sense — particularly when designing for multiple devices — I’ll wager most designers still make visuals in Fireworks or Photoshop and use them for demonstrations and get feedback and sign-off. That’s OK. If you haven’t made the transition to content-out designing in a browser yet, the fluid grids formula helps you carry on pushing pixels a while longer.&lt;/p&gt; &lt;p&gt;You can carry on moving pixel width measurements from your visuals to your style sheets, too, in the same way you always have. You can be precise to the pixel and even apply a grid image as a &lt;span&gt;CSS&lt;/span&gt; background to help you keep everything lined up perfectly.&lt;/p&gt; &lt;p&gt;Once you’re done, and the fixed width layout in the browser matches your visual, loop back through your style sheets and convert those pixels to percentages using the fluid grids formula. With very little extra work, you’ll have a fluid implementation of your fixed width layout.&lt;/p&gt; &lt;p&gt;The fluid grids formula is simple and incredibly effective, but not long after I started working responsively I realized that the formula shouldn’t (always) be a one-fix, set-and-forget calculation. I noticed that unless we compensate for problems it sometimes creates, the result can be a disconnected design.&lt;/p&gt;&lt;br /&gt; &lt;h3&gt;Staying connected&lt;/h3&gt; &lt;p&gt;Good design relies on connectedness, a feeling of natural balance between elements and the grid they’re placed on. Give an element greater prominence or position in a visual hierarchy and you can fundamentally alter the balance and sometimes the meaning of a design.&lt;/p&gt; &lt;p&gt;Different from a browser’s page zooming feature — where images, text and overall layout change size by the same ratio — fluid grids flex a layout in response to a window or device width. Columns expand and contract, and within them fluid media (images and videos) can also change size. This can be one of the most impressive demonstrations of responsive design.&lt;/p&gt; &lt;p&gt;But not every element within a fluid grid can change size along with the window or device width. For example, type size and leading won’t change along with a column’s width.&lt;/p&gt;When columns and elements within them change width, all too easily a visual hierarchy can be broken and along with it the relationship between element sizes and the outer window or viewport. This can happen quickly if you make just one set of fluid grid calculations and use those percentages across every screen width, from smartphones through tablets and up to large desktops.&lt;br /&gt;&lt;br /&gt;The answer? Make several sets of fluid grids calculations, each one at a significant window or device width breakpoint. Then apply those new percentages, when needed, to help keep elements in proportion and maintain balance and connectedness. Here’s how I work.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;h3&gt;Avoiding disconnection&lt;/h3&gt;I’ve never been entirely happy with grid frameworks such as the &lt;a href="http://960.gs/"&gt;960 Grid System&lt;/a&gt;, so I start almost every project by creating a custom grid to inform my layout decisions. Here’s a &lt;a href="http://media.24ways.org/2011/clarke/1.png"&gt;plain version of a grid from a recent project&lt;/a&gt; that I’ll use as an illustration.&lt;br /&gt;&lt;br /&gt;This project’s grid comprises 84px columns and 24px gutters. This creates an odd number of columns at common tablet and desktop widths, and allows for 300px fixed width assets — useful when I need to fit advertising into a desktop layout’s sidebar.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;&lt;img src="http://media.24ways.org/2011/clarke/2s.png" alt="" /&gt; &lt;span&gt;Showing common advertising sizes (&lt;a href="http://media.24ways.org/2011/clarke/2.png"&gt;Larger image&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;For this project I chose three &lt;a href="http://www.stuffandnonsense.co.uk/projects/320andup/"&gt;320 and Up&lt;/a&gt; breakpoints above 320px and, after placing as many columns as would fit those breakpoint widths, I derived three content widths:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;table&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;th&gt;Breakpoint &lt;/th&gt;   &lt;th&gt;Columns &lt;/th&gt;   &lt;th&gt;Content width &lt;/th&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;th&gt;768px &lt;/th&gt;   &lt;td&gt; 7 &lt;/td&gt;   &lt;td&gt; 732px &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;th&gt;992px &lt;/th&gt;   &lt;td&gt; 9 &lt;/td&gt;   &lt;td&gt; 948px &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;th&gt;1,382px &lt;/th&gt;   &lt;td&gt; 13 &lt;/td&gt;   &lt;td&gt; 1,380px &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;Here’s my grid again, this time with pixel measurements and breakpoints overlaid.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;&lt;img src="http://media.24ways.org/2011/clarke/3s.png" alt="" /&gt; &lt;span&gt;Showing pixel measurements and breakpoints (&lt;a href="http://media.24ways.org/2011/clarke/3.png"&gt;Larger image&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;Now cast your mind back to the fluid grids calculation I made earlier. I divided a 300px element by 948px and arrived at 31.646%. For some elements it’s possible to use that percentage across all screen widths, but others will feel too small in relation to a narrower 768px and too large inside 1,380px.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;To help maintain connectedness, I make a set of fluid grids calculations based on each of the content widths I established earlier. Now I can shift an element’s percentage width up or down when I switch to a new breakpoint and content width. For example:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;ul&gt;&lt;br /&gt;  &lt;li&gt;300px is 40.984% of 732px&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;300px is 31.646% of 948px&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;300px is 21.739% of 1,380px&lt;/li&gt;&lt;br /&gt; &lt;/ul&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;I’ll add all those fluid grid percentages to my grid image and save it for quick reference.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;&lt;img src="http://media.24ways.org/2011/clarke/4s.png" alt="" /&gt; &lt;span&gt;Showing percentages at all breakpoints (&lt;a href="http://media.24ways.org/2011/clarke/4.png"&gt;Larger image&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;Then I can apply those different percentage widths to elements at each breakpoint using CSS3 media queries. For example, that sidebar division again:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;/*  732px, 7-column width */&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;@media only screen and (min-width: 768px) {&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;    .content-sub {&lt;br /&gt;       width : 40.983%; /* 300px ÷ 732px = .40983 */ }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;/*  948px, 9-column width */&lt;br /&gt;@media only screen and (min-width: 992px) {&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;    .content-sub {&lt;br /&gt;       width : 31.645%; /* 300px ÷ 948px = .31645 */ }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;/*  1380px, 13-column width */&lt;br /&gt;@media only screen and (min-width: 1382px) {&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;    .content-sub {&lt;br /&gt;       width : 21.739%; /* 300px ÷ 1380px = .21739 */ }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt; &lt;p&gt;The number of changes you make to a layout at different breakpoints will, of course, depend on the specifics of the design you’re working on. Yes, this is additional work, but the result will be a layout that feels better balanced and within which elements remain in harmony with each other while they respond to new screen or device widths.&lt;/p&gt;&lt;br /&gt; &lt;h3&gt;Putting the design in responsive web design&lt;/h3&gt; &lt;p&gt;Until now, many of the conversations around responsive web design have been about aspects of technical implementation, rather than design. I believe we’re only beginning to understand what’s involved in designing responsively. In future, we’ll likely be making design decisions not just about proportions but also about responsive typography. We’ll also need to learn how to adapt our designs to device characteristics such as touch targets and more.&lt;/p&gt;Sometimes we’ll make decisions to improve function, other times because they make a design ‘feel’ right. You’ll know when you’ve made a right decision. You’ll feel it.&lt;br /&gt; &lt;p&gt;After all, there really is no formula for making great designs.&lt;/p&gt;Post: &lt;a href="http://feedproxy.google.com/~r/24ways/~3/9jGFD0oBQek/theres-no-formula-for-great-designs"&gt;There’s No Formula for Great Designs&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-2317361997529658426?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wJkW1q73Ax86HRPn9Ay2CL8m_Kg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wJkW1q73Ax86HRPn9Ay2CL8m_Kg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wJkW1q73Ax86HRPn9Ay2CL8m_Kg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wJkW1q73Ax86HRPn9Ay2CL8m_Kg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/3vArDfT8vhY" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/2317361997529658426?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/2317361997529658426?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/3vArDfT8vhY/theres-no-formula-for-great-designs.html" title="There’s No Formula for Great Designs" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/theres-no-formula-for-great-designs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEAQnoyfSp7ImA9WhRXFUs.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-7883461306793842595</id><published>2011-12-22T07:27:00.000-08:00</published><updated>2011-12-22T07:27:23.495-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-22T07:27:23.495-08:00</app:edited><title>Introducing mod_spdy, a SPDY module for the Apache HTTP server</title><content type="html">&lt;p&gt;At Google, we strive to make the whole web fast. Our work in this area includes &lt;a href="https://developers.google.com/pagespeed/"&gt;Page Speed Online&lt;/a&gt;, &lt;a href="http://code.google.com/p/modpagespeed/"&gt;mod_pagespeed&lt;/a&gt;, &lt;a href="http://code.google.com/speed/pss/"&gt;Page Speed Service&lt;/a&gt;, &lt;a href="https://www.google.com/chrome"&gt;Google Chrome&lt;/a&gt;, &lt;a href="http://code.google.com/speed/articles/tcp_initcwnd_paper.pdf"&gt;making TCP faster&lt;/a&gt;, and the &lt;a href="http://dev.chromium.org/spdy/spdy-whitepaper"&gt;SPDY protocol&lt;/a&gt;, among other efforts. The SPDY (pronounced “SPeeDY”) protocol allows web sites to be transmitted more efficiently to the web browser, resulting in &lt;a href="http://blog.chromium.org/2009/11/2x-faster-web.html"&gt;page load time improvements&lt;/a&gt; of as much as 55%. To make it easier for web sites to realize the benefits of SPDY, we’re releasing the &lt;a href="http://code.google.com/p/mod-spdy/"&gt;source code for mod_spdy&lt;/a&gt;, an open-source module for the Apache HTTP server.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Getting Started with mod_spdy&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;mod_spdy is still in early beta, and is not yet recommended for deployment in production environments. If you’d like to test out mod_spdy and help us to make it better, please consult our &lt;a href="http://code.google.com/p/mod-spdy/wiki/GettingStarted"&gt;Getting Started&lt;/a&gt; guide. We hope to make it production-ready sometime in early 2012. Stay tuned by subscribing to our &lt;a href="http://groups.google.com/group/mod-spdy-discuss"&gt;discussion forum&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;SPDY and Apache&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;mod_spdy is an Apache 2.2-compatible module that provides SPDY support for Apache HTTP servers. Multiplexing is an important performance feature of SPDY which allows for multiple requests in a single SPDY session to be processed concurrently, and their responses interleaved down the wire.  However, due to the serialized nature of the HTTP/1.1 protocol, the Apache HTTP server provides a one-request-per-connection architecture. Apache’s connection and request processing normally happens in a single thread, like so:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/without-mod-spdy2.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This works well for HTTP, but it presents a problem for multiplexed protocols like SPDY because in this flow, each connection can only process one request at a time. Once Apache starts processing a request, control is transferred to the request handler and does not return to the connection handler until the request is complete.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To allow for SPDY multiplexing, mod_spdy separates connection processing and request processing into different threads. The connection thread is responsible for decoding SPDY frames and dispatching new SPDY requests to the mod_spdy request thread pool. Each request thread can process a different HTTP request concurrently. The diagram below shows the high-level architecture. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://calendar.perfplanet.com/wp-content/uploads/2011/12/with-mod-spdy2.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To learn more about how mod_spdy works within Apache, consult our &lt;a href="http://code.google.com/p/mod-spdy/wiki/HowItWorks"&gt;wiki&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Help to improve mod_spdy&lt;/h3&gt;&lt;p&gt;You can help us to make mod_spdy better by doing compatibility and performance testing, by &lt;a href="http://code.google.com/p/mod-spdy/source/browse/trunk/src#src%2Fmod_spdy%2Fcommon"&gt;reviewing the code&lt;/a&gt; and sending us feedback on the &lt;a href="https://groups.google.com/group/mod-spdy-discuss"&gt;mod_spdy discussion list&lt;/a&gt;. We look forward to your contributions and feedback!&lt;/p&gt;&lt;p&gt;Post: &lt;a href="http://calendar.perfplanet.com/2011/introducing-mod_spdy-a-spdy-module-for-the-apache-http-server/"&gt;Introducing mod_spdy, a SPDY module for the Apache HTTP server&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-7883461306793842595?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/axMVL3490wJgdMsDm3oH_PNlt9E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/axMVL3490wJgdMsDm3oH_PNlt9E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/axMVL3490wJgdMsDm3oH_PNlt9E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/axMVL3490wJgdMsDm3oH_PNlt9E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/DrccQT4PL-c" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/7883461306793842595?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/7883461306793842595?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/DrccQT4PL-c/introducing-modspdy-spdy-module-for.html" title="Introducing mod_spdy, a SPDY module for the Apache HTTP server" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/introducing-modspdy-spdy-module-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMFQn0yeCp7ImA9WhRXFUs.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-7863726456757007258</id><published>2011-12-22T06:00:00.000-08:00</published><updated>2011-12-22T06:00:13.390-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-22T06:00:13.390-08:00</app:edited><title>Stuff you can do with the “Checkbox Hack”</title><content type="html">&lt;p&gt;The "Checkbox Hack" is where you use a connected label and checkbox input and usually some other element you are trying to control, like this:&lt;/p&gt;&lt;pre rel="HTML"&gt;&lt;code&gt;&amp;lt;label for="toggle-1"&amp;gt;Do Something&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;input type="checkbox" id="toggle-1"&amp;gt;&lt;br /&gt;&amp;lt;div&amp;gt;Control me&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then with CSS, you hide the checkbox entirely. Probably by kicking it off the page with absolute positioning or setting its opacity to zero. But just because the checkbox is hidden, clicking the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; still toggles its value on and off. Then you can use the adjacent sibling combinator to style the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; differently based on the &lt;code&gt;:checked&lt;/code&gt; state of the input.&lt;/p&gt;&lt;pre rel="CSS"&gt;&lt;code&gt;input[type=checkbox] {&lt;br /&gt;  position: absolute;&lt;br /&gt;  top: -9999px;&lt;br /&gt;  left: -9999px;&lt;br /&gt;  /* For mobile, it's typically better to position checkbox on top of clickable&lt;br /&gt;     area and turn opacity to 0 instead. */&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* Default State */&lt;br /&gt;div {&lt;br /&gt;  background: green;&lt;br /&gt;  width: 400px;&lt;br /&gt;  height: 100px;&lt;br /&gt;  line-height: 100px;&lt;br /&gt;  color: white;&lt;br /&gt;  text-align: center;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* Toggled State */&lt;br /&gt;input[type=checkbox]:checked ~ div {&lt;br /&gt;  background: red;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://dabblet.com/gist/1506530"&gt;View Demo&lt;/a&gt;&lt;/p&gt;&lt;p&gt;So you can style an element completely differently depending on the state of that checkbox, which you don't even see. Pretty neat. Let's look at a bunch of things the "Checkbox Hack" can do.&lt;/p&gt;&lt;div&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; Some of this stuff crosses the line of what you "should" do with CSS and introduces some bad semantics. It's still wicked fun to play with and cool that it's possible, but in general functional behavior should be controlled by JavaScript.&lt;/div&gt;&lt;h3&gt;Custom Designed Radio Buttons and Checkboxes&lt;/h3&gt; &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2011/12/5762393149.png" alt="" title="5762393149" width="607" height="335" /&gt;&lt;p&gt;Hide the default UI of a radio button or checkbox, and display a custom version right on top of it. Probably not generally good practice, as users are familiar with default form elements and how they work. But can be good for enforcing cross browser consistency or in situations where the UI is so obvious anyway it's just for fun.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.thecssninja.com/css/custom-inputs-using-css"&gt;Pioneered by Ryan Seddon&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://acidmartin.wordpress.com/2011/02/24/custom-crossbrowser-styling-for-checkboxes-and-radio-buttons/"&gt;Similar by Martin Ivanov&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.wufoo.com/2011/06/13/custom-radio-buttons-and-checkboxes/"&gt;For use on Wufoo forms by me&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;File system like "tree menu"&lt;/h3&gt; &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2011/12/treemenu.png" alt="" title="treemenu" width="207" height="355" /&gt; &lt;a href="http://www.thecssninja.com/css/css-tree-menu"&gt;Demo by Ryan Seddon&lt;/a&gt; &lt;h3&gt;Tabbed Areas&lt;/h3&gt;&lt;p&gt;The "tabs" design pattern is just toggling on and off of areas, perfect for the checkbox hack. But instead of checkboxes, in which any checkbox can be on or off independently of one another, these tabs use radio buttons in which only one per group can be on at a time (like how only one tab can be active at a time).&lt;/p&gt; &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2011/12/tabcat.jpeg" alt="" title="tabcat" width="424" height="238" /&gt; &lt;a href="http://css-tricks.com/functional-css-tabs-revisited/"&gt;Functional CSS tabs revisited&lt;/a&gt; &lt;h3&gt;Dropdown Menus&lt;/h3&gt; &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2011/12/dropdowns.png" alt="" title="dropdowns" width="358" height="251" /&gt; &lt;a href="http://jsfiddle.net/paullferguson/Sv54G/3/"&gt;Original by paullferguson&lt;/a&gt; and then &lt;a href="http://dabblet.com/gist/1507175"&gt;Forked for betterness by me&lt;/a&gt; &lt;h3&gt;Push Toggles&lt;/h3&gt; &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2011/12/pushtoggles.png" alt="" title="pushtoggles" width="385" height="243" /&gt; From &lt;a href="http://www.weblaunchr.com/whatsmympg/"&gt;What's My MPG?&lt;/a&gt;  &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2011/12/dabblettoggles.png" alt="" title="dabblettoggles" width="446" height="217" /&gt; Options from &lt;a href="http://dabblet.com/"&gt;Dabblet&lt;/a&gt; &lt;h3&gt;FAQ Answer Revealing&lt;/h3&gt; &lt;img src="http://cdn.css-tricks.com/wp-content/uploads/2011/12/faq.png" alt="" title="faq" width="476" height="224" /&gt;&lt;br /&gt;&lt;a href="http://dabblet.com/gist/1507019"&gt;View Demo&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://css-tricks.com/the-checkbox-hack/"&gt;Stuff you can do with the “Checkbox Hack”&lt;/a&gt; is a post from &lt;a href="http://css-tricks.com/"&gt;CSS-Tricks&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-7863726456757007258?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ts29cWwZHjF8WqN4Aoq057U6iQo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ts29cWwZHjF8WqN4Aoq057U6iQo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ts29cWwZHjF8WqN4Aoq057U6iQo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ts29cWwZHjF8WqN4Aoq057U6iQo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/zgehf90yiJA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/7863726456757007258?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/7863726456757007258?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/zgehf90yiJA/stuff-you-can-do-with-checkbox-hack.html" title="Stuff you can do with the “Checkbox Hack”" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/stuff-you-can-do-with-checkbox-hack.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUANRH4zfyp7ImA9WhRXFE0.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-8209195944834330371</id><published>2011-12-20T11:00:00.000-08:00</published><updated>2011-12-20T11:03:15.087-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-20T11:03:15.087-08:00</app:edited><title>Skills for Front-End Developers</title><content type="html">&lt;br /&gt;
&lt;div style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: left;"&gt;
&lt;img alt="Don't use the N Word" height="184" src="http://cdn.impressivewebs.com/2011-12/ninja.jpg" title="Don't use the N Word" width="184" /&gt;&lt;/div&gt;
&lt;div style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: left;"&gt;
As a front-end developer, I’m constantly trying to learn new skills and technologies and adding to what I already know. Front-end developer job postings, however, vary from posting to posting so the list of different languages, libraries, and technologies that could theoretically fall under the category of front-end developer skills is quite large.&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://www.impressivewebs.com/skills-front-end-developers/"&gt;Skills for Front-End Developers&lt;/a&gt;: &lt;br /&gt;
&lt;br /&gt;
Here’s a list (that I’ll continue to update) containing a wide variety of skills and technologies that I think all front-end developers should be working on learning, at least to some extent. I certainly don’t know all of these, nor do I expect anyone else to.&lt;br /&gt;
&lt;br /&gt;
The list is not necessarily in any particular order, but I tried to keep the more rudimentary stuff at or near the top. Also, many of the items overlap others, so there’s a lot of cross-over within the list. And of course the list has lots of potential for improvements (more on that below).&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;XHTML / HTML5&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;CSS2.1 / CSS3&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;JavaScript / Ajax&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;jQuery&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;HTML5 Boilerplate&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Modernizr&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;YUI Library&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;OOCSS&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;CSS Grids&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;CSS Frameworks / Resets&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Progressive Enhancement / Graceful Degradation&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;HTML and CSS Specifications (W3C / WHATWG)&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;UX / Usability&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Website Speed / Performance&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Dojo / MooTools / Prototype&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Responsive Web Design&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Mobile Web Development&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Mobile Web Performance&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Cross-Browser / Cross-Platform Development&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Document Object Model (DOM)&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;IE6-IE8 Bugs and Inconsistencies&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;CSS Pre-Processors (LESS / Sass)&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Version Control (Git / GitHub / CVS / Subversion)&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;HTML5 APIs&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;OOP&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Ruby on Rails&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;MySql&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;WAI-ARIA&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Microdata / Microformats&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Internationalization&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;HTML5/CSS3 Polyfills&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Functional Programming&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Localization&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Content Strategy&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Offline Web Apps&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
I may eventually turn this post into an extended list divided into categories plus links to articles and tutorials where these subjects can be learned or mastered — but for now you’ll just have to trust your Google searching abilities if you want to learn more on any of these.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Please Contribute&lt;/h2&gt;
&lt;br /&gt;
The list is a rough first draft, and I’d be happy to update it and refine it based on any feedback. So please offer your suggestions on how it could be improved and/or expanded and I’ll make any necessary updates.&lt;br /&gt;
&lt;br /&gt;
&lt;img height="1" src="http://www.impressivewebs.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&amp;amp;post_id=5150" width="1" /&gt;&lt;br /&gt;
Related posts:&lt;br /&gt;
&lt;ol&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href="http://www.impressivewebs.com/study-html5-design-principles/" rel="bookmark" title="Why Developers Should Be Studying HTML5′s Design Principles"&gt;Why Developers Should Be Studying HTML5′s Design Principles&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;&lt;a href="http://www.impressivewebs.com/video-for-everybody/" rel="bookmark" title="Video For Everybody — Except Developers!"&gt;Video For Everybody — Except Developers!&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;&lt;a href="http://www.impressivewebs.com/health-tips-for-web-developers/" rel="bookmark" title="Health Tips for Web Developers"&gt;Health Tips for Web Developers&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-8209195944834330371?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HRhu-XBn7DHJS3YAvPoMnGNReR8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HRhu-XBn7DHJS3YAvPoMnGNReR8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HRhu-XBn7DHJS3YAvPoMnGNReR8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HRhu-XBn7DHJS3YAvPoMnGNReR8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/nJc3NA7K8WU" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/8209195944834330371?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/8209195944834330371?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/nJc3NA7K8WU/skills-for-front-end-developers.html" title="Skills for Front-End Developers" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/skills-for-front-end-developers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IAQ3Y5fSp7ImA9WhRXE00.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-6793639219615249909</id><published>2011-12-19T05:32:00.000-08:00</published><updated>2011-12-19T05:32:22.825-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-19T05:32:22.825-08:00</app:edited><title>iOS 5 Style Switch Control</title><content type="html">&lt;p&gt;The final result of this post will run in iOS 5, Safari 5.1, as well as the latest versions of Chrome, Firefox and Opera.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Previously I had created a version of the switch control in iOS. With the launch of iOS5 Apple complete updated the look of the switch control. They went with a rounded style, which they also did with most controls in their desktop operating system, Lion. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;After playing around with the early betas of iOS5, I came up with the following reproduction of the new switch control look using just HTML5, CSS3 and some JavaScript for the interactive part. Functionally the switch control is nothing more than a fancier way of presenting a checkbox. So, for our purposes we are going to use a checkbox. Except that we need a couple of tags to wrap the checkbox so we can make it look like the switch control. Fortunately the amount of wrapper is really minimal. If you examine the picture below, you will notice that the switch control really has only two parts: the oblong base and the circular thumb. In our case we need a third part: a checkbox input.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-1.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-1.png?w=200&amp;amp;h=300" alt="Switch Control" title="Switch Control" width="200" height="300"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We’re going to make a minor tweak to this default look. You’ll notice that the version above is in English. Actually, only the English version has labels for “On” and “Off”, everyone else uses the international symbols instead. They look like this:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-2.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-2.png?w=200&amp;amp;h=300" alt="International version of Switch Control" title="International version of Switch Control" width="200" height="300"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If we ignore the “On/Off” parts and just look at the colored areas we can see that we’re only really dealing with a simple vertical gradient on the thumb and some inset box shadows on the switch control base. This makes our styling really easy. For the “On/Off” parts we don’t need extra markup. You’ll notice that they exist in relation to the switch control’s thumb. We can use CSS pseudo elements on the thumb to create them.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To recreate the iOS5 switch control all we need is the following markup:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; &amp;lt;div class=&amp;quot;switch&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;span class=&amp;quot;thumb&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Without styling, this gives us a very normal checkbox:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-3.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-3.png?w=630" alt="Unstyled switch control" title="Unstyled switch control"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We know what the dimensions need to be by measuring the screenshots, so we can give the switch control base some styling:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch {&lt;br /&gt;  height: 28px;&lt;br /&gt;  width: 77px;&lt;br /&gt;  border: 1px solid #979797;&lt;br /&gt;  border-radius: 20px;&lt;br /&gt;  overflow: hidden;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This will give us the following:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-4.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-4.png?w=630" alt="Switch control with rounded border" title="Switch control with rounded border"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It looks kind of funny with the checkboxes. We don’t need to see them. We will be setting their checked state with JavaScript later on anyway. So for now we can hide them:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch input[type=checkbox] {&lt;br /&gt;  display: none;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now let’s add some color. How to re-create that gray shadow area? We’ll use a series of inset box shadows. Like gradients, you can define multiple box shadows on an element. These stack up like layers, the last one being the bottom-most and the first being the top-most. We need to create a sizable gray choke inside the switch base, so we’ll use a box shadow with four values instead of three to create that effect:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; box-shadow: inset 0 12px 3px 2px rgba(232, 232, 232, 0.5);&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To this we’ll add a second inset box shadow to create a darker shadow along the top inside of the switch control:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; box-shadow: inset 0 1px 3px #BABABA, inset 0 12px 3px 2px rgba(232, 232, 232, 0.5);&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-5.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-5.png?w=630" alt="Switch control with gray box shadow" title="Switch control with gray box shadow"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here’s the complete CSS definition for the switch control:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch {&lt;br /&gt;  height: 28px;&lt;br /&gt;  width: 77px;&lt;br /&gt;  border: 1px solid #979797;&lt;br /&gt;  border-radius: 20px;&lt;br /&gt;  margin-top: -5px;&lt;br /&gt;  box-shadow: inset 0 1px 3px #BABABA, inset 0 12px 3px 2px rgba(232, 232, 232, 0.5);&lt;br /&gt;  cursor: pointer;&lt;br /&gt;  overflow: hidden;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now for a tricky part. This gray inset box shadow is for the off state. How do we implement the bluish on state? Well, first of all we need to decide how to represent the states in markup. We’ll do this by added a class of “on” to the switch control base. That means that the base will have a class of “switch on” for when it’s flipped on and just “switch” when it’s off. We can use a pseudo element on the switch base to create the blue state and position it in view or out of view based on the presence of the “on” class. Of course we’re going to need a little JavaScript to set and remove the “on” class when the user clicks. So, here’s the CSS for the on state. We create an empty text node and give it the height we need to match the base. We don’t give it a width just yet since that will get set when the switch has the “on” class. We give it a bluish background color and inset box shadow. The absolute positioning is so that when it’s show, it doesn’t push the thumb out of the switch but instead sits independently inside the switch.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch::before {&lt;br /&gt;  content: &amp;quot;&amp;quot;;&lt;br /&gt;  display: block;&lt;br /&gt;  height: 28px;&lt;br /&gt;  width: 0px;&lt;br /&gt;  position: absolute;&lt;br /&gt;  border-radius: 20px;&lt;br /&gt;  box-shadow: inset 0 1px 2px #0063B7, inset 0 12px 3px 2px rgba(0, 127, 234, 0.5);&lt;br /&gt;  background-color: #64B1F2;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To show the “on” state we just need to give the blue pseudo element the same width as the base:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch.on::before {&lt;br /&gt;  width: 77px;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If we add the “on” class to one of our switches, we can see how the on state looks:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; &amp;lt;div class=&amp;quot;switch on&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;span class=&amp;quot;thumb&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;  &lt;br /&gt; &amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-6.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-6.png?w=630" alt="Switch control with &amp;#39;on&amp;#39; state" title="Switch control with &amp;#39;on&amp;#39; state"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;That’s all we need for the switch control’s base. Now let’s tackle the thumb. We’ll make the span a block element with dimensions, set its positioning to relative so we can give it a higher z-index than the other elements in the switch control, specifically, the blue on state pseudo element. Next up: border, box shadow and gradient, very straightforward. And finally, because we want to have the thumb slide back and forth when the switch is clicked, we need to enable a CSS transition and give it a default translate value. Note: you will need to add an appropriate vendor prefix for the gradient, transition and transform.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch &amp;amp;gt; .thumb {&lt;br /&gt;  display: block;&lt;br /&gt;  width: 26px;&lt;br /&gt;  height: 26px;&lt;br /&gt;  position: relative;&lt;br /&gt;  top: 0;&lt;br /&gt;  z-index: 3;&lt;br /&gt;  border: solid 1px #919191;&lt;br /&gt;  border-radius: 28px;&lt;br /&gt;  box-shadow: inset 0 2px 1px white, inset 0 -2px 1px white;&lt;br /&gt;  background-color: #CECECE;&lt;br /&gt;  background-image: linear-gradient(top, #CECECE, #FBFBFB);&lt;br /&gt;  transition: all 0.125s ease-in-out;&lt;br /&gt;  transform: translate3d(0,0,0);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This gives us the following:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-7.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-7.png?w=630" alt="Switch control with thumb" title="Switch control with thumb"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As you can see, all thumbs are in the same place. We need to define a translate value for their “On” state:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch.on &amp;amp;gt; .thumb {&lt;br /&gt;  -webkit-transform: translate3d(49px,0,0);&lt;br /&gt;  -o-transform: translateX(49px);&lt;br /&gt;  -moz-transform: translateX(49px);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Which gives us:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-8.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-8.png?w=630" alt="Switch control thumb in &amp;#39;on&amp;#39; state" title="Switch control thumb in &amp;#39;on&amp;#39; state"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now the only thing left is to create the “on/off” indicators. We’ll start with the “on” one. It’s really quite simple. a vertical stripe with a border around it. We’ll create a pseudo element that has an empty text node, style it and position it beside the thumb. Here’s the CSS:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch &amp;amp;gt; .thumb::before {&lt;br /&gt;  content: &amp;quot;&amp;quot;;&lt;br /&gt;  display: block;&lt;br /&gt;  height: 14px;&lt;br /&gt;  width: 2px;&lt;br /&gt;  background-color: white;&lt;br /&gt;  box-shadow: 0px -1px 1px #666;&lt;br /&gt;  border: none;&lt;br /&gt;  position: absolute;&lt;br /&gt;  top: 6px;&lt;br /&gt;  left: -24px;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-9.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-9.png?w=630" alt="Switch control with &amp;#39;on&amp;#39; state indicator" title="Switch control with &amp;#39;on&amp;#39; state indicator"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And for the “off” indicator, we create a pseudo element with an empty text node styles as a circle positioned to the right of the thumb:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; .switch &amp;amp;gt; .thumb::after {&lt;br /&gt;  content: &amp;quot;&amp;quot;;&lt;br /&gt;  display: block;&lt;br /&gt;  height: 10px;&lt;br /&gt;  width: 10px;&lt;br /&gt;  border-radius: 10px;&lt;br /&gt;  border: solid 2px #777;&lt;br /&gt;  position: absolute;&lt;br /&gt;  right: -32px;&lt;br /&gt;  top: 6px;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://rmbiggs.files.wordpress.com/2011/12/switch_control-10.png"&gt;&lt;img src="http://rmbiggs.files.wordpress.com/2011/12/switch_control-10.png?w=630" alt="Switch control with &amp;#39;off&amp;#39; state indicator" title="Switch control with &amp;#39;off&amp;#39; state indicator"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now we have a fully styled switch control with minimal markup. We just need to add some interactivity. For that we’ll have to write some JavaScript. Since this is a self-contained example, I’m going to use the very latest version of ECMAScript 5. This gives me an easy way to get DOM elements and toggle classes on elements. If you want to reuse this you’ll need to switch those parts out for whatever methods your chosen JavaScript library provides.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So, first up I’m going to wrap everything up in an anonymous function:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; (function() {&lt;br /&gt; &lt;br /&gt; })();&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Next I need a convenience method to get a collection of nodes and turn it into an array so I can iterate over it. I use call slice method of the Array object and pass in the results of querySelectorAll. That will convert the node collection into an array:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; (function() {&lt;br /&gt;  var $ = function(selector) {&lt;br /&gt;   return Array.prototype.slice.call(document.querySelectorAll(selector));&lt;br /&gt;  }&lt;br /&gt; })();&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now I want to define an event that executes when the DOM is fully loaded:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; (function() {&lt;br /&gt;  var $ = function(selector) {&lt;br /&gt;   return Array.prototype.slice.call(document.querySelectorAll(selector));&lt;br /&gt;  }&lt;br /&gt;  document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function() {&lt;br /&gt;  &lt;br /&gt;  }, false);&lt;br /&gt; })();&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;After getting an array of all switch controls in the document, we iterate through them with the **forEach** method and bind a click event listener. The listener will execute a function that toggles the class “on”. ECMAScript 5 introduces a new token collection for classes called classList. This has several useful functions: add, remove, contains and toggle. To accomplish these methods with straight JavaScript you would need to use regular expressions. Instead I can just use **Element.classList.toggle(“on”)** to add and remove the class when the user clicks:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; (function() {&lt;br /&gt;  var $ = function(selector) {&lt;br /&gt;   return Array.prototype.slice.call(document.querySelectorAll(selector));&lt;br /&gt;  }&lt;br /&gt;  document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function() {&lt;br /&gt;   $(&amp;quot;.switch&amp;quot;).forEach(function(switchControl) {&lt;br /&gt;    switchControl.addEventListener(&amp;quot;click&amp;quot;, function toggleSwitch() {&lt;br /&gt;     switchControl.classList.toggle(&amp;quot;on&amp;quot;);&lt;br /&gt;    }, false);&lt;br /&gt;   });&lt;br /&gt;  }, false);&lt;br /&gt; })();&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;With the above JavaScript in our document, when the user clicks a switch control, the class “on” will be added to or removed from the switch, causing its thumb to slide to the left or right accordingly. This handily takes care of our visual requirements for the functionality of the switch control. However, we do need to manage the checked state of the checkbox. The first thing we’ll do is make sure any switch controls that had the class “on” during page load have their checkboxes set to chekced. Since the checkbox is the last element in the switch control div, we can reference it that way:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; (function() {&lt;br /&gt;  var $ = function(selector) {&lt;br /&gt;   return Array.prototype.slice.call(document.querySelectorAll(selector));&lt;br /&gt;  }&lt;br /&gt;  document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function() {&lt;br /&gt;   if (switchControl.classList.contains(&amp;quot;on&amp;quot;)) {&lt;br /&gt;    switchControl.lastElementChild.checked = true;&lt;br /&gt;   }  &lt;br /&gt;   $(&amp;quot;.switch&amp;quot;).forEach(function(switchControl) {&lt;br /&gt;    switchControl.addEventListener(&amp;quot;click&amp;quot;, function toggleSwitch() {&lt;br /&gt;     switchControl.classList.toggle(&amp;quot;on&amp;quot;);&lt;br /&gt;    }, false);&lt;br /&gt;   });&lt;br /&gt;  }, false);&lt;br /&gt; })();&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Next we need to update a switch controls checkbox when the switch control itself is clicked. We just need to again get a reference to the checkbox and set its clicked state to the opposite of what it was when the user clicked:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;&lt;br /&gt; (function() {&lt;br /&gt;  var $ = function(selector) {&lt;br /&gt;   return Array.prototype.slice.call(document.querySelectorAll(selector));&lt;br /&gt;  }&lt;br /&gt;  document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function() {&lt;br /&gt;   var checkbox;&lt;br /&gt;   if (switchControl.classList.contains(&amp;quot;on&amp;quot;)) {&lt;br /&gt;    switchControl.lastElementChild.checked = true;&lt;br /&gt;   }  &lt;br /&gt;   $(&amp;quot;.switch&amp;quot;).forEach(function(switchControl) {&lt;br /&gt;    switchControl.addEventListener(&amp;quot;click&amp;quot;, function toggleSwitch() {&lt;br /&gt;     checkbox = switchControl.lastElementChild;&lt;br /&gt;     checkbox.checked = !checkbox.checked;&lt;br /&gt;     switchControl.classList.toggle(&amp;quot;on&amp;quot;);&lt;br /&gt;    }, false);&lt;br /&gt;   });&lt;br /&gt;  }, false);&lt;br /&gt; })();&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And that’s all you need to make the switch controls work. The final example has some extra JavaScript to output some text when the user flips a switch on to show them working. For Safari, Chrome and Opera, I use innerText to set the text value, but Firefox uses textContent. So the code has to deal with those differences.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;You can try the &lt;a href="http://vxjs.org/switch.html" title="Working example of switch control"&gt;working example&lt;/a&gt;. If you want the code, just save that page to your desktop. Everything is self-contained in the page.&lt;/p&gt;&lt;br /&gt;&lt;br&gt; &lt;br /&gt;&lt;p&gt;Post: &lt;a href="http://css3wizardry.com/2011/12/18/ios-5-style-switch-control/"&gt;iOS 5 Style Switch Control&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-6793639219615249909?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bilWhHQk52s8xTXOYQLCvPI6TMo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bilWhHQk52s8xTXOYQLCvPI6TMo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bilWhHQk52s8xTXOYQLCvPI6TMo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bilWhHQk52s8xTXOYQLCvPI6TMo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/anOwMSME0A8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6793639219615249909?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/6793639219615249909?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/anOwMSME0A8/ios-5-style-switch-control.html" title="iOS 5 Style Switch Control" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/ios-5-style-switch-control.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMDRHgzeCp7ImA9WhRXE00.&quot;"><id>tag:blogger.com,1999:blog-3176943100655981551.post-3749156284478212544</id><published>2011-12-19T05:14:00.000-08:00</published><updated>2011-12-19T05:14:35.680-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-19T05:14:35.680-08:00</app:edited><title>Item Blur Effect with CSS3 and jQuery</title><content type="html">&lt;a href="http://tympanus.net/codrops/2011/12/14/item-blur-effect-with-css3-and-jquery/"&gt;Item Blur Effect with CSS3 and jQuery&lt;/a&gt;: &lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/ItemBlur/"&gt;&lt;img src="http://tympanus.net/codrops/wp-content/uploads/2011/12/ItemBlurEffect1.jpg" alt="ItemBlurEffect" width="580" height="315"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/ItemBlur/"&gt;View demo&lt;/a&gt; &lt;a href="http://tympanus.net/Tutorials/ItemBlur/ItemBlur.zip"&gt;Download source&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Today we want to show you how to create a simple blur effect for text-based items. The idea is to have a set of text boxes that will get blurred and scaled down once we hover over them. The item in focus will scale up. This will create some kind of “focus” effect that drwas the attention to the currently hovered item.&lt;/p&gt;&lt;p&gt;We’ll be using CSS3 transitions and some jQuery to apply the respective classes. Since CSS3 transitions are not supported in order browsers, the demo should be best viewed in Safari or Chrome (here we got the smoothest transitions).&lt;/p&gt;&lt;p&gt;&lt;em&gt;Since we will be using transitions, this effect will only work properly in &lt;a href="http://www.w3schools.com/css3/css3_transitions.asp"&gt;browsers that support them&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;So let’s start!&lt;/p&gt;&lt;div&gt;&lt;/div&gt;&lt;div style="clear:both"&gt;&lt;/div&gt;&lt;h3&gt;The Markup&lt;/h3&gt;&lt;p&gt;The structure will be a section with some articles in i. Each article item will have a header and a paragraph:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;section class=&amp;quot;ib-container&amp;quot; id=&amp;quot;ib-container&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;article&amp;gt;&lt;br /&gt;  &amp;lt;header&amp;gt;&lt;br /&gt;   &amp;lt;h3&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Some Headline&amp;lt;/a&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;   &amp;lt;span&amp;gt;Some other text&amp;lt;/span&amp;gt;&lt;br /&gt;  &amp;lt;/header&amp;gt;&lt;br /&gt;  &amp;lt;p&amp;gt;Some introduction&amp;lt;/p&amp;gt;&lt;br /&gt; &amp;lt;/article&amp;gt;&lt;br /&gt; &amp;lt;article&amp;gt;&lt;br /&gt;  &amp;lt;!-- ... --&amp;gt;&lt;br /&gt; &amp;lt;/article&amp;gt;&lt;br /&gt; &amp;lt;!-- ... --&amp;gt;&lt;br /&gt;&amp;lt;/section&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Let’s look at the style.&lt;/p&gt;&lt;h3&gt;The CSS&lt;/h3&gt;&lt;p&gt;The main container will be of fixed width and centered:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container{&lt;br /&gt; position: relative;&lt;br /&gt; width: 800px;&lt;br /&gt; margin: 30px auto;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Let’s clear the floats (out articles will be floating) &lt;a href="http://css-tricks.com/9516-pseudo-element-roundup/"&gt;with the help&lt;/a&gt; of the :before and :after pseudo elements:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container:before,&lt;br /&gt;.ib-container:after {&lt;br /&gt;    content:"";&lt;br /&gt;    display:table;&lt;br /&gt;}&lt;br /&gt;.ib-container:after {&lt;br /&gt;    clear:both;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Now, let’s style the article items. We’ll make them float and add two box shadows, of which the white one will have a large spread distance. Also, we’ll add the transition for three properties: opacity, transform (we want to scale it) and box-shadow:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container article{&lt;br /&gt; width: 140px;&lt;br /&gt; height: 220px;&lt;br /&gt; background: #fff;&lt;br /&gt; cursor: pointer;&lt;br /&gt; float: left;&lt;br /&gt; border: 10px solid #fff;&lt;br /&gt; text-align: left;&lt;br /&gt; text-transform: none;&lt;br /&gt; margin: 15px;&lt;br /&gt; z-index: 1;&lt;br /&gt; box-shadow:&lt;br /&gt;  0px 0px 0px 10px rgba(255,255,255,1),&lt;br /&gt;  1px 1px 3px 10px rgba(0,0,0,0.2);&lt;br /&gt; transition:&lt;br /&gt;  opacity 0.4s linear,&lt;br /&gt;  transform 0.4s ease-in-out,&lt;br /&gt;  box-shadow 0.4s ease-in-out;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;For Webkit browsers we’ll also add&lt;pre&gt;-webkit-backface-visibility: hidden&lt;/pre&gt;&lt;p&gt; to avoid a short flicker. (You can remove this if you prefer to have a crisp looking text, though).&lt;/p&gt;&lt;p&gt;Let’s style the text elements and create some nice typography. The color and the text-shadow of each element will be matching:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container h3 a{&lt;br /&gt; font-size: 16px;&lt;br /&gt; font-weight: 400;&lt;br /&gt; color: rgba(0, 0, 0, 1);&lt;br /&gt; text-shadow: 0px 0px 0px rgba(0, 0, 0, 1);&lt;br /&gt; opacity: 0.8;&lt;br /&gt;}&lt;br /&gt;.ib-container article header span{&lt;br /&gt; font-size: 10px;&lt;br /&gt; font-family: "Big Caslon", "Book Antiqua", "Palatino Linotype", Georgia, serif;&lt;br /&gt; padding: 10px 0;&lt;br /&gt; display: block;&lt;br /&gt; color: rgba(255, 210, 82, 1);&lt;br /&gt; text-shadow: 0px 0px 0px rgba(255, 210, 82, 1);&lt;br /&gt; text-transform: uppercase;&lt;br /&gt; opacity: 0.8;&lt;br /&gt;}&lt;br /&gt;.ib-container article p{&lt;br /&gt; font-family: Verdana, sans-serif;&lt;br /&gt; font-size: 10px;&lt;br /&gt; line-height: 13px;&lt;br /&gt; color: rgba(51, 51, 51, 1);&lt;br /&gt; text-shadow: 0px 0px 0px rgba(51, 51, 51, 1);&lt;br /&gt; opacity: 0.8;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;And now we’ll add the transition to all three. Again, we’ll have three properties: opacity, text-shadow and color:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container h3 a,&lt;br /&gt;.ib-container article header span,&lt;br /&gt;.ib-container article p{&lt;br /&gt; transition:&lt;br /&gt;  opacity 0.2s linear,&lt;br /&gt;  text-shadow 0.5s ease-in-out,&lt;br /&gt;  color 0.5s ease-in-out;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The &lt;strong&gt;blur&lt;/strong&gt; class will be applied to all the siblings of the currently hovered item. We want to scale them down a bit and add a big white box shadow, to make the box look blurry. We’ll also decrease the opacity a bit:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container article.blur{&lt;br /&gt; box-shadow: 0px 0px 20px 10px rgba(255,255,255,1);&lt;br /&gt; transform: scale(0.9);&lt;br /&gt; opacity: 0.7;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;In order to make the text elements look blurry, we’ll make the color transparent by setting the opacity of the rgba value to 0, and  we’ll enlarge the text-shadow blur distance:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container article.blur h3 a{&lt;br /&gt; text-shadow: 0px 0px 10px rgba(0, 0, 0, 0.9);&lt;br /&gt; color: rgba(0, 0, 0, 0);&lt;br /&gt; opacity: 0.5;&lt;br /&gt;}&lt;br /&gt;.ib-container article.blur header span{&lt;br /&gt; text-shadow: 0px 0px 10px rgba(255, 210, 82, 0.9);&lt;br /&gt; color: rgba(255, 210, 82, 0);&lt;br /&gt; opacity: 0.5;&lt;br /&gt;}&lt;br /&gt;.ib-container article.blur  p{&lt;br /&gt; text-shadow: 0px 0px 10px rgba(51, 51, 51, 0.9);&lt;br /&gt; color: rgba(51, 51, 51, 0);&lt;br /&gt; opacity: 0.5;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The currently hovered item will be slightly enlarged and adjust the box shadow. We’ll also set a high z.index to guarantee that the item will always be on top of the other ones when we hover over it:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container article.active{&lt;br /&gt; transform: scale(1.05);&lt;br /&gt; box-shadow:&lt;br /&gt;  0px 0px 0px 10px rgba(255,255,255,1),&lt;br /&gt;  1px 11px 15px 10px rgba(0,0,0,0.4);&lt;br /&gt; z-index: 100;&lt;br /&gt; opacity: 1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Last, but not least, we’ll set the opacity of the text elements to 1:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.ib-container article.active h3 a,&lt;br /&gt;.ib-container article.active header span,&lt;br /&gt;.ib-container article.active p{&lt;br /&gt; opacity; 1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;And that’s all the style! Let’s have a look at the JavaScript.&lt;/p&gt;&lt;h3&gt;The JavaScript&lt;/h3&gt;&lt;p&gt;So, when we hover over an article, we will give all the other articles the class &lt;strong&gt;blur&lt;/strong&gt; and the current one will receive the class &lt;strong&gt;active&lt;/strong&gt;:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;var $container = $('#ib-container'),&lt;br /&gt; $articles = $container.children('article'),&lt;br /&gt; timeout;&lt;br /&gt;&lt;br /&gt;$articles.on( 'mouseenter', function( event ) {&lt;br /&gt;&lt;br /&gt; var $article = $(this);&lt;br /&gt; clearTimeout( timeout );&lt;br /&gt; timeout = setTimeout( function() {&lt;br /&gt;&lt;br /&gt;  if( $article.hasClass('active') ) return false;&lt;br /&gt;&lt;br /&gt;  $articles.not($article).removeClass('active').addClass('blur');&lt;br /&gt;&lt;br /&gt;  $article.removeClass('blur').addClass('active');&lt;br /&gt;&lt;br /&gt; }, 75 );&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;$container.on( 'mouseleave', function( event ) {&lt;br /&gt;&lt;br /&gt; clearTimeout( timeout );&lt;br /&gt; $articles.removeClass('active blur');&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;And that’s all! I hope you enjoyed this little tutorial and find it useful!&lt;/p&gt;&lt;p&gt;&lt;a href="http://tympanus.net/Tutorials/ItemBlur/"&gt;View demo&lt;/a&gt; &lt;a href="http://tympanus.net/Tutorials/ItemBlur/ItemBlur.zip"&gt;Download source&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3176943100655981551-3749156284478212544?l=luiscameroon.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/s4HTGhBLvqN8wN6dRHYrf1eNkUo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s4HTGhBLvqN8wN6dRHYrf1eNkUo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/s4HTGhBLvqN8wN6dRHYrf1eNkUo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s4HTGhBLvqN8wN6dRHYrf1eNkUo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/LuisCameroon/~4/T5XikY7s-NA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/3749156284478212544?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3176943100655981551/posts/default/3749156284478212544?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LuisCameroon/~3/T5XikY7s-NA/item-blur-effect-with-css3-and-jquery.html" title="Item Blur Effect with CSS3 and jQuery" /><author><name>Luis Cameroon</name><uri>https://profiles.google.com/102108735867113000521</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-gq5DKKDUuZI/AAAAAAAAAAI/AAAAAAAAAXc/GTUwCOm-u-w/s512-c/photo.jpg" /></author><feedburner:origLink>http://luiscameroon.blogspot.com/2011/12/item-blur-effect-with-css3-and-jquery.html</feedburner:origLink></entry></feed>

