<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Paul Hayes &#187; Code</title>
	<atom:link href="http://www.paulrhayes.com/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.paulrhayes.com</link>
	<description>The web musings and experiments of.</description>
	<lastBuildDate>Sun, 06 Nov 2011 11:31:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Use CSS transitions to link Media Queries and JavaScript</title>
		<link>http://www.paulrhayes.com/2011-11/use-css-transitions-to-link-media-queries-and-javascript/</link>
		<comments>http://www.paulrhayes.com/2011-11/use-css-transitions-to-link-media-queries-and-javascript/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 14:06:51 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[media-queries]]></category>
		<category><![CDATA[transitions]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=145</guid>
		<description><![CDATA[With CSS transitionEnd events we can marry up media queries and JavaScript perfectly.]]></description>
			<content:encoded><![CDATA[<p>A common problem in responsive design is the linking of CSS3’s media queries and JavaScript. For instance on a larger screen we can restyle, but it might be useful to use JavaScript and pull in different content at the same time, e.g. higher quality images. With CSS transitions, specifically their transitionEnd events, we can marry up our media queries and JavaScript perfectly, without resorting to window resize events.</p>
<p>We need a way of testing media query rules in JavaScript, and a way of generating events when a new rule matches. There’s a specification for exactly this: there’s <a href="http://www.w3.org/TR/cssom-view/#extensions-to-the-window-interface">matchMedia</a> to see if a query matches, and <a href="http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface">MediaQueryList</a> with MediaQueryListeners to detect and respond to changes. </p>
<p>matchMedia has support in Chrome, Firefox 6+ and Safari 5.1+ and there’s even a <a href="https://github.com/paulirish/matchMedia.js/blob/master/matchMedia.js">polyfill</a> (by Scott Jehl, Paul Irish, Nicholas Zakas) for other browsers. So we can happily perform our one off tests in JavaScript (probably on page load):</p>
<pre>
if (matchMedia('only screen and (max-width: 480px)').matches) {
  // iphone specific JS
}
</pre>
<p>However media query list listeners (that’s a mouthful) are only supported in Firefox 6+. This is the magic of firing events when something changes, it completes the circle.</p>
<p>All is not lost, there is another way of using CSS to generate events and that’s through CSS transitions. When a CSS transition ends it fires a transitionEnd event (webkitTransitionEnd, oTransitionEnd, transitionend) on the appropriate element. Now consider <strong>a transition that occurs only when a media query is applied</strong>. Hey presto, we have a <strong>JavaScript event triggered by media query rules</strong>, however complicated or convoluted that rule may be. <strong>This rocks</strong> and can form the basis of a MediaQueryList polyfill.</p>
<h3>Simple transition CSS and event listener</h3>
<pre>
.mq {
-webkit-transition: width 0.001ms;
-moz-transition: width 0.001ms;
-o-transition: width 0.001ms;
transition: width 0.001ms;
width: 0;
}

@media all and (max-width: 480px) {
.mq {
width: 1px;
}
}
</pre>
<pre>
var mq = document.querySelectorAll('.mq')[0],
mq.addEventListener('webkitTransitionEnd', function() {
	/* Transition ends, media query matched */
}, false);
</pre>
<h3>Proof of concept</h3>
<p>I’ve taken the excellent <a href="https://github.com/paulirish/matchMedia.js">matchMedia polyfill</a> and <i>quickly</i> hacked together a version that includes transition events and a callback. </p>
<p><a href="/experiments/media-query-transitions/">Proof of concept demo</a><br />
(and on <a href="https://github.com/fofr/matchMedia.js">Github</a>)</p>
<pre>
mql('all and (max-width: 700px)', callback);
</pre>
<p>Pass in a media query string and callback. It immediately returns the test result and the callback will fire whenever the test result changes, the only argument being the MediaQueryList object. This isn’t a polyfill because it doesn’t yet match the specification, if it did the originally returned MQL object would have addListener and removeListener functions (that’s a work in progress).</p>
<p>The CSS transitions are instantaneous via a duration of a little larger than 0, I’ve chosen 0.001ms. </p>
<p>Element transitions are bidirectional, so the event fires when the rule matches and when it no longer matches. Every time the event fires a test is performed to determine state, this is easy using matchMedia.</p>
<p>The CSS transition event tells us which element triggered the transition but no details about the media query rules that governed it. So we use unique elements for each rule to connect the dots.</p>
<pre>
.mq {
-webkit-transition: width 0.001ms;
-moz-transition: width 0.001ms;
-o-transition: width 0.001ms;
transition: width 0.001ms;
width: 0;
}
</pre>
<pre>
mql = (function(doc, undefined){

  var bool,
      docElem  = doc.documentElement,
      refNode  = docElem.firstElementChild || docElem.firstChild,
      idCounter = 0;

  return function(q, cb){

	var id = 'mql-' + idCounter++,
	    callback = function() {
		cb({ matches: (div.offsetWidth == 42), media: q });
	    },
	    div = doc.createElement('div');

	div.className = 'mq';
	div.style.cssText = "position:absolute;top:-100em";
	div.id = id;
        div.innerHTML = '&amp;shy;&lt;style media=&quot;&#39;+q+&#39;&quot;&gt; #&#39;+id+&#39; { width: 42px; }&lt;/style&gt;';

	div.addEventListener('webkitTransitionEnd', callback, false);
	div.addEventListener('transitionend', callback, false); //Firefox
	div.addEventListener('oTransitionEnd', callback, false); //Opera

        docElem.insertBefore(div, refNode);
        //don't delete the div, we need to listen to events
        return { matches: div.offsetWidth == 42, media: q };
  };

})(document);
</pre>
<h3>Demo code</h3>
<pre>
$(function() {

    var $dynamic = $('.dynamic');
    mql('all and (max-width: 700px)', change);
    mql('all and (max-width: 500px)', change);
    mql('all and (min-width: 1200px)', change);

    function change(mql) {
        console.log(mql);
        $dynamic.prepend(&#39;&lt;p&gt;&#39; + mql.media + &#39; &amp;mdash; &#39; + mql.matches + &#39;&lt;/p&gt;&#39;);
    }
});
</pre>
<h3>Support</h3>
<p>Obviously for this to work we need both CSS transitions and media query support in the browser. Looking at <a href="http://caniuse.com">caniuse.com</a> and <a href="http://www.quirksmode.org/webkit.html#t03">QuirksMode</a> this technique should be supported by: Chrome, Android (2.1+), Opera (10.6+), Opera Mobile (10.0+), Firefox (4+), Safari (3.2+) and iOS (3.2+). Samsung’s Dolfin and Blackberry 6 support CSS animations, I presume that means transitions too, but I can’t easily test. </p>
<p>Of course, IE is lagging behind, as always. IE9 supports media queries but it has no transition support, that’s coming in IE10.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-11/use-css-transitions-to-link-media-queries-and-javascript/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>CSS Modal follow up</title>
		<link>http://www.paulrhayes.com/2011-04/css-modal-follow-up/</link>
		<comments>http://www.paulrhayes.com/2011-04/css-modal-follow-up/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 21:43:51 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[modal]]></category>
		<category><![CDATA[transformations]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=141</guid>
		<description><![CDATA[A cross browser modal box with CSS animations. Supported in IE7+ it's now being used to add comments.]]></description>
			<content:encoded><![CDATA[<p>In <a href="/2011-03/css-modal/">my original post</a> I explained how to create a CSS only modal pop-up using :target, pseudo-elements and pointer events. This had a number of caveats, any browser that didn’t support pointer events would see a non-clickable page and the forward/back controls would navigate through dialogues, which is usually undesirable. Of course it was only an experiment.</p>
<p>My comment form had been much neglected and it felt like the perfect opportunity to try out this modal in a real environment. Click the “<a href="#respond" class="respond">Post a comment</a>” link to see it in action.</p>
<p><iframe class="vimeo" src="http://player.vimeo.com/video/22774103" width="612" height="408" frameborder="0"></iframe></p>
<p>All references to the :target pseudo-selector have been removed, instead an “active” class is toggled using JavaScript. The CSS modal still uses an opacity transition but pointer events are gone. The default is now display:none with an intermediate state that renders the modal as display:block (remember it still begins at opacity: 0).</p>
<p>The flow is:</p>
<ul>
<li>Add an intermediate class to trigger the modal elements above everything, with opacity 0.</li>
<li>Add an active class to trigger animation and transition to full opacity.</li>
<li>On close, remove active class, add minimise class to trigger  minimise animation and transition to opacity 0.</li>
<li>Remove intermediate class.</li>
</ul>
<p>Onclick handlers are added to the “post comment” links to add classes and to the close link to remove them. When opened a handler is added to the body to listen for the ESC key, which closes the modal. The first input in the modal is focused on open.</p>
<p>I took the opportunity to play with some HTML5 features. The comment form now uses placeholder attributes, and if supported, labels are hidden. The feature detection is delightfully simple:</p>
<pre>
supportPlaceholder: function() {
	  var i = document.createElement('input');
	  return 'placeholder' in i;
}()
</pre>
<p>See <a href="http://diveintohtml5.org/detect.html#input-placeholder">Dive into HTML5</a> for more.</p>
<p>The close link text which has an :after pseudo-element (i.e. the X) is no longer hidden, instead it becomes the cancel link and is essential for browsers that can’t comprehend generated content.</p>
<p>In webkit you’ll see the modal bounce in and minimise out (smoothly in Safari and iOS). In Firefox you’ll get an opacity transition and in IE the modal will just appear or disappear. In IE8 and below the page is not greyed out due to lack of rgba support. I’m fine with this. This is still a bit of a trial to see how people actually use the modal and what problems it might throw up.</p>
<p>In conclusion, with JavaScript much of the mechanical new CSS can be dropped and with a slightly more complicated class toggle system we achieve cross browser support, without sacrificing that lovely hardware accelerated CSS animation.</p>
<p>Still want that animation cross browser? I recommend looking into <a href="http://farukat.es/journal/2011/02/514-new-creation-jquery-runloop-plugin">Faruk Ateş’s Runloop jQuery plugin</a> which gives you keyframed animations in any browser.</p>
<p>In other news, I’ve tidied up the comments layout a little and added a short <a href="/category/bookshelf/">books category</a> with a selection of books I highly recommend.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-04/css-modal-follow-up/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Creating a sphere with 3D CSS</title>
		<link>http://www.paulrhayes.com/2011-02/creating-a-sphere-with-3d-css/</link>
		<comments>http://www.paulrhayes.com/2011-02/creating-a-sphere-with-3d-css/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 23:33:33 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[sphere]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=124</guid>
		<description><![CDATA[Rotate and combine elements in 3D space to create an awesome sphere using CSS 3D transforms.]]></description>
			<content:encoded><![CDATA[<p>With CSS3’s 3D transforms I’ve illustrated how to build a <a href="http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/">cube</a> and a <a href="http://www.paulrhayes.com/2010-10/css-tetrahedron/">tetrahedron</a>. It is also possible to create a sphere-like object, albeit with many elements.</p>
<p><a href="http://www.paulrhayes.com/experiments/sphere/">3D CSS Sphere</a><br />
Works in the latest Safari and iOS (just about runs on an iPhone 4).</p>
<p><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-normal.png" alt="3D sphere using CSS transform" width="549" /></p>
<p>Recently I’ve been looking at creating applicable 3D carousels. These rely on positioning panels in a circle around a central point (ie. rotation about the Y-axis), I put these panels in an unordered list. A natural extension is to duplicate each <code>&lt;ul&gt;</code> and rotate about the X-axis. With ‘A’ rounds (or lists), and ‘B’ panels per round (<code>&lt;li&gt;</code>s), I built a script that would distribute these in a circular manner, panels about Y-axis, lists about the X-axis, creating a sphere.</p>
<p>The more elements per round and the more rounds, the smoother the sphere. But this soon stacks up and kills Safari. The optimum numbers have been about 9 rounds and 30 panels per round for a decent looking sphere, but that’s 279 3D elements and Safari starts to choke. Allowing the panels to overlap eases this somewhat and leads to a tighter sphere but it still appears blocky.</p>
<p>The biggest gains come with border radius. Using a huge radius that made each panel circular the sphere suddenly gained a lovely curvature, and the number of rounds and panels could be reduced. In the experiment I use 8 rounds and 24 panels (200 elements). This doesn’t start choking until I start aggressively animating.</p>
<p>Playing with this I’ve built a few different styles of sphere. In the experiment I’ve included the blocky “square” version, along with the smoothed out border radius one (default). Marking panels white, and a few black can create a nice eye-ball effect.</p>
<p><a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-square.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-square-150x150.png" alt="Sphere without border radius" width="150" height="150" /></a> <a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-eye.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-eye-150x150.png" alt="Eye" width="150" height="150" /></a></p>
<p>Also included in the experiment are versions showing a single round and another style named “contact”. This takes two lists and animates them like the space transportation device in the Jodie Foster movie of the same name.</p>
<p><a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-contact.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-contact-150x150.png" alt="Rotating rounds" width="150" height="150" /></a> <a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-half.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-half-150x150.png" alt="Half a sphere" width="150" height="150" /></a> <a href="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-kaleid.png"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-kaleid-150x150.png" alt="Kaleidoscope effect" width="150" height="150" /></a></p>
<p>Animating the border radius on all 192 panels (if your machine can cope), gives a neat kaleidoscope effect, also included in the experiment.</p>
<h3>Code</h3>
<p>The generated HTML is simply a couple of <code>&lt;div&gt;</code>s containing lists:</p>
<pre>&lt;div id=&quot;sphere&quot;&gt;
	&lt;div class=&quot;container&quot;&gt;
		&lt;ul&gt;
			&lt;li&gt;&lt;/li&gt;
			&lt;li&gt;&lt;/li&gt;
			…
		&lt;/ul&gt;
		…
	&lt;/div&gt;
&lt;/div&gt;</pre>
<p>To transform each set of panels into a circle the total number is divided by 360 to get the angle of rotation. Merely rotating will put all panels on top of each other, translating in the Z axis will move them out from the centre point. The correct translation distance so the panels slightly overlap (i.e. the circle radius) is worked out with some <a href="http://en.wikipedia.org/wiki/Trigonometry#Mnemonics">simple trigonometry</a>. Lists are rotated in the X axis, simply the number of lists divided by 360.</p>
<p>Looping through each panel for each list, the angles of rotation are gradually increased by the calculated increments and applied to the elements:</p>
<pre>
var panels = p || this.panels,
rounds = r || this.rounds,
rotationPerPanel = 360/panels,
rotationPerRound = 360/2/rounds,
yRotation, xRotation,
width = this.panelWidth,
zTranslate = (width/2) / Math.tan(rotationPerPanel * Math.PI/180),
$container = this.el,
$ul, $li, i, j;

this.el.html(&#39;&#39;);
for(i = 0; i &lt; rounds; i++) {
	$ul = $(&#39;&lt;ul&gt;&#39;);
	xRotation = rotationPerRound * i;
	$ul[0].style.webkitTransform = &quot;rotateX(&quot;+ xRotation + &quot;deg)&quot;;
	for(j = 0; j &lt; panels; j++) {
		$li = $(&#39;&lt;li&gt;&#39;);
		yRotation = rotationPerPanel * j;
		$li[0].style.webkitTransform = &quot;rotateY(&quot;+ yRotation +&quot;deg)
                         translateZ(&quot;+ zTranslate +&quot;px)&quot;;
		$ul.append($li);
	}
	$container.append($ul);
}
</pre>
<p>To achieve the 3D effect we give <code>#sphere</code> some perspective, which forms the containing block. A second container transitions between different transforms, letting us rotate the sphere. The complicated transform parts are applied inline via the JavaScript above, but each list element needs <code>preserve-3d</code> so its direct descendants are transformed in the same 3D space (rather than in 2D).</p>
<pre>
#sphere {
width: 100px;
height: 100px;
margin: 200px auto;
-webkit-perspective: 800;
}

.container {
width: 100px;
height: 100px;
-webkit-transition: -webkit-transform 200ms linear;
-webkit-transform-style: preserve-3d;
}

.container > ul {
-webkit-transform-style: preserve-3d;
width: 100%;
height: 100%;
position: absolute;
}

.container li {
width: 98px;
height: 98px;
position: absolute;
display: block;
background: #000;
border: 1px solid #fff;
opacity: 0.1;
border-radius: 50px;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-02/creating-a-sphere-with-3d-css/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Thoughts on Responsive Enhancement</title>
		<link>http://www.paulrhayes.com/2010-10/thoughts-on-responsive-enhancement/</link>
		<comments>http://www.paulrhayes.com/2010-10/thoughts-on-responsive-enhancement/#comments</comments>
		<pubDate>Fri, 29 Oct 2010 16:36:49 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Discussion]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[media-queries]]></category>
		<category><![CDATA[responsive-enhancement]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=116</guid>
		<description><![CDATA[An exploration into truly responsive design using media queries.]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://asyncjs.com/responsive-enhancement/">AsyncJS</a> in Brighton last night, <a href="http://adactio.com/journal/1700/">Jeremy Keith</a> gave an overview of “Responsive enhancement” — adapting a layout in response to browser or device capabilities. After considering why fixed width designs are so prevalent, via a brief history lesson, we delved into the tools and methods by which a truly responsive design can be implemented, focussing primarily on size constraints but also touching on troubles surrounding speed.</p>
<p>This article is a brain dump from last night’s event.</p>
<p>CSS3 media queries let us adapt CSS rules to different viewport properties; width, height, pixel ratio, even colour and monochrome screens (<a href="http://www.w3.org/TR/css3-mediaqueries/#contents">full list</a>). Aside: the Amazon Kindle (which uses webkit) reports itself as colour, with 8 levels, rather than monochrome.</p>
<p>The common process is to design for the desktop and use media queries to adapt downwards. On thinner devices content is linearised, navigation moves to the top or bottom, less important elements are sometimes hidden; everything is simplified down to the page’s core use case.</p>
<p>A number of tutorials have offered up the exact pixel-based media queries needed to target specific devices, a sort of restricted browser sniffing. This isn’t truly progressive, you can never cover all devices, and devices change, revisiting code for device iterations isn’t going to be fun.</p>
<p>Media queries don’t need to be pixel based either, changing a page layout based on ems will adapt content for larger text sizes. If the user’s text size is huge, our viewport is the same but we’ve got less space to play with, a linear mobile-like design might be more desirable.</p>
<p>This act of adapting downwards works for devices like the iPhone and iPad, but what about those that don’t support media queries? They’re going to get the full desktop version and it’s not going to be pretty.</p>
<p>Luke Wroblewski has suggested designing for <a href="http://www.lukew.com/ff/entry.asp?933">mobile first</a> (an excellent read). In terms of responsive enhancement that means creating your linear site as the baseline and building outwards around content, bringing in features as capabilities improve and constraints are relaxed. As the viewport widens, media queries can introduce columns, rather than remove them. It’s the same process but in the opposite direction.</p>
<p>All mobile devices and older browsers would get the simplified, linear design. This works on the assumption that desktop browsers support media queries, IE 8 and below do not, ergo they’ll be seeing the linear site design. This may be acceptable, but in the majority of cases IE will need some sort of hack to get the full featured version.</p>
<p>Using conditional IE comments an IE layout can be hacked in. The IE specific styles are likely to repeat existing code, undesirable, but unavoidable? This is still a one size fits all approach as IE will not adapt to screen or text size. For this we need a JS poly-fill, one that enables media queries in older browsers. There’s a library on Google Code that does just this, <a href="http://code.google.com/p/css3-mediaqueries-js/">CSS3 Media Queries JS</a>.</p>
<p>Building a page that can be linearised means putting the most important information first in the source code. This assumes that the context of “what is important” is similar on different devices. If the context is different, that makes a case for serving different content, usually via a standalone mobile site (which should always come with a link to the full version).</p>
<p>And on the topic of serving different content, there is also the speed problem. Hiding and showing parts of a page using CSS is great, but it doesn’t stop the slower mobile networks from downloading the unnecessary parts, including those huge background images. PPK has written an excellent article on <a href= "http://www.quirksmode.org/blog/archives/2010/08/combining_media.html">combining media queries and javascript</a> to avoid some of these caveats.</p>
<p>To round this brain dump off, I’ll recommend some other articles on the subject, which go into some of the technical aspects in a little more depth.</p>
<p>Ethan Marcotte’s “<a href="http://www.alistapart.com/articles/responsive-web-design/">Responsive Web Design</a>“<br />
Jeremy Keith’s “<a href="http://adactio.com/journal/1700/">Responsive Enhancement</a>“<br />
Yiibu’s “<a href="http://yiibu.com/articles/rethinking-the-mobile-web/">Rethinking the mobile web</a>“<br />
PPK’s “<a href="http://www.quirksmode.org/blog/archives/2010/09/state_of_mobile.html">State of Mobile Web Development</a>”</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-10/thoughts-on-responsive-enhancement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSS 3D cube with touch gestures, click and drag</title>
		<link>http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/</link>
		<comments>http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 22:20:49 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[cube]]></category>
		<category><![CDATA[perspective]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=108</guid>
		<description><![CDATA[An updated 3D cube that comes with touch gestures and click ‘n’ drag.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.paulrhayes.com/experiments/cube-3d/touch.html">Experiment: 3D cube with touch gestures and click and drag</a></p>
<p><a href="http://www.paulrhayes.com/experiments/cube-3d/touch.html"><img src="http://host.trivialbeing.org/up/small/3d-cube-ii.png" alt="3D cube"></a></p>
<p>An update on the <a href="http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/">original 3D cube</a> (from July 2009 no less), I’ve added touch gesture support (iOS) and click-and-drag behaviour. Animation is incredibly smooth on the iPhone, even the 3G model. Arrow key presses will still rotate the cube, and ESC will reset it.</p>
<p>One year on and the cube still only works in Safari. Chrome, which says it supports <code>webkit-perspective</code> and <code>webkit-transform</code>, still renders differently. Firefox doesn’t support 3D transforms <i><a href="https://developer.mozilla.org/En/CSS/Using_CSS_transforms">yet</a></i>.</p>
<p>It works relatively simply: on click the start co-ordinates are saved and on drag the difference between current drag position and starting co-ordinates are applied to the cube as a transform, which is completed after the specified transition duration. Many thanks to <a href="http://remysharp.com">Remy Sharp</a> and his rubik’s experiment, which got me started with a lot of the basics.</p>
<h3>Touch tweaks</h3>
<p>Pixel values for touch positions are found in <code>event.originalEvent.touches[0].pageX</code>, instead of <code>event.pageX</code>. Using ‘start minus current’ pixel values led the cube to rotate more than intended on the iPhone. To correct, and for intuitive behaviour, the difference is reduced by a factor of four. </p>
<p>JavaScript prevents single touch default events — e.g. scrolling and text selection, but if it detects more than one touch (<code>event.originalEvent.touches.length</code>) the cube won’t rotate, so pinch and zoom will still work. This is a compromise.</p>
<p>A 200ms transition duration suits the browser, but on touch devices it felt sluggish, so I’ve upped it to 50ms so the cube is always at your finger-tips.</p>
<h3>Better CSS</h3>
<p>The cube is created exactly as before, but I’ve simplified the markup a little — dropping the <em>face</em> and <em>number</em> class names in favour of CSS3 selectors:</p>
<pre>
#cube > div:first-child  {
-webkit-transform: rotateX(90deg) translateZ(200px);
}

#cube > div:nth-child(2) {
-webkit-transform: translateZ(200px);
}

#cube > div:nth-child(3) {
-webkit-transform: rotateY(90deg) translateZ(200px);
text-align: center;
}

#cube > div:nth-child(4) {
-webkit-transform: rotateY(180deg) translateZ(200px);
}

#cube > div:nth-child(5) {
-webkit-transform: rotateY(-90deg) translateZ(200px);
}

#cube > div:nth-child(6) {
-webkit-transform: rotateX(-90deg) rotate(180deg) translateZ(200px) ;
}
</pre>
<h3>Any questions?</h3>
<p>This is quite a speedy write-up, if anything needs explaining I’m happy to go into a bit more detail.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Useful CSS snippets</title>
		<link>http://www.paulrhayes.com/2010-08/useful-css-snippets/</link>
		<comments>http://www.paulrhayes.com/2010-08/useful-css-snippets/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 08:56:14 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[css3]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=104</guid>
		<description><![CDATA[A round up of CSS tricks I’ve recently used or discovered. Including an input type search reset.]]></description>
			<content:encoded><![CDATA[<p>A quick round-up of some CSS tricks I use on my sites.</p>
<h3>Reset input type search</h3>
<p>Safari renders search inputs with curved corners and a spy glass. If this doesn’t fit into your design, but you want to retain correct semantics, this reset is helpful. The first line removes the curved corners, but leaves a white space where the spy glass was, this is removed using the second line.</p>
<pre class="thin">
input[type=search] {
-webkit-appearance: none;
}
input[type=search]::-webkit-search-decoration {
display: none;
}
</pre>
<h3>Border radius</h3>
<p>Both Safari 5 and the latest Chrome support <code>border-radius</code>, given the fast update curves for these browsers, I have stopped using <code>-webkit-border-radius</code>, and almost always default to the useful shorthand (older versions of iOS are a known caveat).</p>
<pre>
-moz-border-radius: 10px 0 0 10px;
border-radius: 10px 0 0 10px;
</pre>
<h3>Tweaked clearfix</h3>
<p>I still see a lot of sites using the old clearfix, including IE for Mac hacks. I’ve cleaned this up a bit and moved the IE specific parts into conditional IE stylesheets. For lists, I found I often need to clear each <code>li</code>, to save littering the HTML with class names, I added <code>clearfixItems li</code>, now I only need one class on the <code>ul</code> or <code>ol</code>.</p>
<pre>
.clearfix:after,
.clearfixItems li:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
</pre>
<p>Then in IE6 and IE7:</p>
<pre>
.clearfix, .clearfixItems li {
zoom: 1;
}
</pre>
<h3>Equal height columns</h3>
<p>For when you want your containers to have the same height. If you are unfamiliar with this technique, I recommend reading <a href="http://www.ejeliot.com/blog/61">Ed Eliot’s article</a>.</p>
<pre>.col {
margin-bottom: -1000px;
padding-bottom: 1000px;
}</pre>
<h3>Ligatures and kerning pairs</h3>
<p>Where fonts support it, text rendering can be improved by enabling kerning pairs and ligature support. Add the following to your <code>body</code> to enable it on all text:</p>
<pre>text-rendering: optimizeLegibility;</pre>
<p>Firefox’s default state (text-rendering: auto) partially enables this, optimizing legibility on font sizes above 20px (surely legibility is most important on the smallest text?). Using the above code will optimize all font sizes, more details are available at <a href="https://developer.mozilla.org/en/CSS/text-rendering">MDC</a>, as pointed out in the comments by <em>rdela</em>.</p>
<h3>Gradients</h3>
<p>An invaluable tool for avoiding images and extra HTTP requests. For the most part I avoid providing fallback images, instead seeing gradients as a progressive enhancement. This usually means Opera and FF3.5 or less will see a solid colour, I’m fine with that.</p>
<pre>
background: #990000;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#cc0000), to(#990000));
background: -moz-linear-gradient(#cc0000,#990000);
</pre>
<p>And in IE conditional stylesheets:</p>
<pre>
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#cc0000, endColorstr=#990000);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-08/useful-css-snippets/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Moving markup towards HTML5</title>
		<link>http://www.paulrhayes.com/2009-06/moving-markup-towards-html5/</link>
		<comments>http://www.paulrhayes.com/2009-06/moving-markup-towards-html5/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 23:03:31 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=78</guid>
		<description><![CDATA[A foray into marking up a blog with HTML5]]></description>
			<content:encoded><![CDATA[<p>Having read John Resig’s “<a href="http://ejohn.org/blog/html5-shiv/">HTML5 Shiv</a>” article and Remy Sharp’s “<a href="http://remysharp.com/2009/01/07/html5-enabling-script/">HTML5 enabling script</a>”, it felt like the right time to begin the full fledged migration from XHTML to a cross browser compatible HTML5 blog. All in all the process of updating the templates was painless, taking about an hour or so to modify the WordPress Sandbox theme.<br />
<span id="more-78"></span></p>
<p>To enable IE6 and IE7 support for new HTML5 tags, which are not naturally styled, some JavaScript is necessary. As per the ‘shiv’ article, Remy Sharp has a small script that creates DOM elements, one for each type of new HTML5 tag, the simple act of doing so leads Internet Explorer to apply styles to said tags. I slightly modified the existing script to add the recently proposed <code>hgroup</code>.</p>
<p>Even though these tags accept style they don’t come with their default renderings. For that we need a bit of CSS to make block elements behave as they should.</p>
<pre class='prettyprint'>
(function(){
	if(!/*@cc_on!@*/0) return;
	var e = &quot;abbr,article,aside,audio,bb,canvas,datagrid,datalist,details,dialog,
		eventsource,figure,footer,hgroup,header,mark,menu,meter,nav,output,
		progress,section,time,video&quot;.split(','),i=0,length=e.length;
	while(i&lt;length){
		document.createElement(e[i++])
	}
})();
</pre>
<pre class='prettyprint'>
article, aside, dialog, footer, header, section, footer, nav, figure {
	display: block;
}
</pre>
<p>I’ve also updated the Eric Meyer reset script, removing now deprecated HTML 4 tags and applying reset to the new elements, so they do not unexpectedly inherit padding, margin, etc. in the future. These changes are not yet exhaustive.</p>
<p>Moving onto the page’s actual markup, the new DOCTYPE and character encoding settings are remarkably simple. Standards based web development is getting easier. For browsers that do not support HTML5, the new DOCTYPE still triggers standards mode. The <code>xmlns</code> HTML attribute is no longer necessary and the <code>profile</code> attribute has been dropped.</p>
<pre class='prettyprint'>
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
&lt;head&gt;
	&lt;meta charset=&quot;UTF-8&quot; /&gt;
	&lt;title&gt;FofR Online&lt;/title&gt;
</pre>
<p>The header section has been placed in the appropriate <code>&lt;header&gt;</code> tags, and similarly with the footer. I’d hoped to include the ‘About Me’ section within this, but as part of the specification you cannot include headings within a <code>&lt;footer&gt;</code> element.</p>
<p>Each of the posts comes wrapped in an <code>&lt;article&gt;</code> tag, i.e. an independent element with content that could standalone. Within are the respective <code>&lt;header&gt;</code> (containing title and date) and <code>&lt;footer&gt;</code> (containing meta links)  elements. Technically the meta links could be marked as <code>&lt;nav&gt;</code>, but the former is more fitting and still acceptable use.</p>
<p>The date makes use of HTML5’s <code>&lt;time&gt;</code> element, with a <code>datetime</code> attribute that gives the precise posting time, including timezone offset.</p>
<p>The previous and next links that follow the article can comfortably sit within a <code>&lt;nav&gt;</code> tag. Similarly, my sidebar region is predominantly navigation based with lists of archives and categories, it’s been marked as such.</p>
<pre class='prettyprint'>
&lt;article id=&quot;post-67&quot; class=&quot;&quot;&gt;
	&lt;header&gt;
		&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&quot; title=&quot;&quot; rel=&quot;bookmark&quot;&gt;POST TITLE&lt;/a&gt;&lt;/h2&gt;
		&lt;div class=&quot;entry-date&quot;&gt;
			&lt;time datetime=&quot;2009-04-30T15:54:28-07:00&quot; class=&quot;published&quot; title=&quot;2009-04-30T15:54:28-07:00&quot;&gt;April 30, 2009 &amp;#8211; 3:54 pm&lt;/time&gt;
		&lt;/div&gt;
	&lt;/header&gt;
	&lt;div class=&quot;entry-content&quot;&gt;
		POST
	&lt;/div&gt;
	&lt;footer class=&quot;entry-meta&quot;&gt;
		META LINKS
	&lt;/footer&gt;
&lt;/article&gt;

&lt;nav id=&quot;nav-below&quot; class=&quot;navigation clearfix&quot;&gt;
	&lt;div class=&quot;nav-previous&quot;&gt;&lt;/div&gt;
	&lt;div class=&quot;nav-next&quot;&gt;&lt;/div&gt;
&lt;/nav&gt;
</pre>
<p>One avenue I should explore is the inclusion of the <code>&lt;section&gt;</code> tag, which I’d like to break up individual posts, probably by splitting the content at level three headings downwards; thereby becoming the header of each new section.</p>
<p>It’ll be a while before the real benefits of HTML5 can be fully appreciated by everyone, but it feels good to make a start, however small that step may be.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-06/moving-markup-towards-html5/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Track outbound links using Google Analytics</title>
		<link>http://www.paulrhayes.com/2009-03/track-outbound-links-using-google-analytics/</link>
		<comments>http://www.paulrhayes.com/2009-03/track-outbound-links-using-google-analytics/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 00:06:20 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=14</guid>
		<description><![CDATA[Combine CSS3 selectors and analytics event tracking to report on outbound links.]]></description>
			<content:encoded><![CDATA[<p>“Track everything”, lest vital visitor trends fall through the cracks — that’s my newly endorsed web analytics doctrine. As a precursor to the quantitative ‘what’ and the qualitative ‘why’ we need that cold hard data before analysis can begin; Google Analytics is the popular harvester of choice and out of the box it grabs a lot. Visits, Pageviews, Screen resolution, et al — <acronym title="Google Analytics">GA</acronym> seemingly has all your conventional data needs covered. But one significant trend is lacking — how visitors leave your site, specifically through outbound links on a page, data that inevitably leads to a what and an avenue for investigating the why. For instance, “<em>Which partner sites are attracting the highest click throughs?</em>” or more generally “<em>Why do visitors leave my site?</em>”.<br />
<span id="more-14"></span></p>
<p>GA gives the ability to <a href="http://code.google.com/apis/analytics/docs/eventTrackerGuide.html">create your own events</a> with a category, action, label and numerical value using the syntax:</p>
<pre class="thin">_trackEvent(category, action, optional_label, optional_value)</pre>
<p>Hence, on an outbound link click, by calling this JavaScript method you can trigger a tracked event in GA. An obtrusive onclick attribute on every outbound link is both cumbersome to implement and difficult to manage, it also goes against the best practices of progressive enhancement and unobtrusiveness.</p>
<p>The solution is to attach a click event listener to each of the outbound links on the page, and the question becomes how to do that. CSS3 comes with a couple of handy <a href="http://www.w3.org/TR/css3-selectors/">new selectors</a> that we can use in combination with Prototype or jQuery to root out the correct links. The appropriate selectors:</p>
<blockquote><p>
E[foo^=“bar”]  	an E element whose “foo” attribute value begins exactly with the string “bar“<br />
E[foo*=“bar”] 	an E element whose “foo” attribute value contains the substring “bar“<br />
E:not(s)  	an E element that does not match simple selector s
</p></blockquote>
<p>The magic outbound link selector then becomes one of the following, depending on your needs:</p>
<pre class='prettyprint'>
/* Any link that does not contain yourdomain.com */
a:not(a[href*="yourdomain.com"])

/* Any link that does not start with yourdomain.com */
a:not(a[href^="yourdomain.com"])

/* Any link that does not start with yourdomain.com or www.yourdomain.com */
a:not(a[href^="yourdomain.com"]):not(a[href^="www.yourdomain.com"])

/* Any link that starts with http - e.g. any non relative links */
a[href^="http"]

/* Catch all - any link that starts with http but doesn't link to your domain */
a[href^="http"]:not(a[href*="yourdomain.com"])
</pre>
<p>With an array of all the outbound links at hand, adding a click listener is simple. But we do need to set up the category, action and label. I have opted to create an arbitrary “Outbound Link” category that uses the link’s text (with HTML tags stripped out) as the action and the url as the label:</p>
<pre class='prettyprint'>
Event.observe(outboundLink, 'click', function() {
        // category, action, label
        pageTracker._trackEvent('Outbound Link', outboundLink.innerHTML.replace(/(&lt;([^&gt;]+)&gt;)/ig,&quot;&quot;), outboundLink.href);
}
</pre>
<h3>The complete code</h3>
<p>Using Prototype version 1.6 the final code might look like this:</p>
<p><strong>Update</strong>: As pointed out in the comments, hard coding a domain into your code isn’t the best idea, <code>window.location.hostname</code> is a good alternative. This may not always work if you do not want to exclude subdomains.</p>
<pre class="prettyprint">
var domainName = &quot;domainname.com&quot;;
// Select all outbound links
$$('a[href^=&quot;http&quot;]:not(a[href*=&quot;'+domainName+'&quot;])').each(function(outboundLink) {
        // Add listener to each of the links
        Event.observe(outboundLink, 'click', function() {
        // category, action, label
        pageTracker._trackEvent('Outbound Link', outboundLink.innerHTML.replace(/(&lt;([^&gt;]+)&gt;)/ig,&quot;&quot;), outboundLink.href);
        }
});
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-03/track-outbound-links-using-google-analytics/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

