<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Paul Hayes</title>
	
	<link>http://www.paulrhayes.com</link>
	<description>The web musings and experiments of.</description>
	<lastBuildDate>Sat, 11 May 2013 07:45:49 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/prhayes" /><feedburner:info uri="prhayes" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Face detection with canvas and webcam video</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/nrVFqT764Us/</link>
		<comments>http://www.paulrhayes.com/2012-11/fun-with-face-detection-canvas-and-webcam-video/#comments</comments>
		<pubDate>Sun, 18 Nov 2012 23:43:27 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[face detection]]></category>
		<category><![CDATA[getUserMedia]]></category>
		<category><![CDATA[webcam]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=154</guid>
		<description><![CDATA[With the getUserMedia API, a video element, a canvas element and LiuLiu's excellent face detection algorithm, we can easily play around with webcam video data in the browser, plug-in free. To this end, I’ve created two experiments, one that places a mask over your face as you move and another that attempts to scale content based on your distance from the screen.]]></description>
				<content:encoded><![CDATA[<p>With the getUserMedia API, a video element, a canvas element and <a href="https://github.com/liuliu/ccv">LiuLiu’s excellent face detection algorithm</a>, we can easily play around with webcam video data in the browser, plug-in free.</p>
<p>To this end, here are two experiments which do just that, one which places a mask over your face as you move and another that attempts to scale content based on your distance from the screen. Have a play below.</p>
<h2>Mask overlay experiment</h2>
<p><a href="/experiments/webcam/mask.html">View experiment</a> | <a href="https://github.com/fofr/paulrhayes.com-experiments/tree/master/webcam">GitHub</a></p>
<p><iframe class="vimeo" src="http://player.vimeo.com/video/53803605" width="612" height="408" frameborder="0"></iframe></p>
<h2>Scaling content experiment</h2>
<p><a href="/experiments/webcam/">View experiment</a> | <a href="https://github.com/fofr/paulrhayes.com-experiments/tree/master/webcam">GitHub</a></p>
<p><iframe class="vimeo" src="http://player.vimeo.com/video/53803604" width="612" height="408" frameborder="0"></iframe></p>
<h2>Background</h2>
<p>Back in 2009, when 3D transforms first appeared on the scene, and when I first toyed with a <a href="/2009-07/animated-css3-cube-interface-using-3d-transforms/">rotating 3D cube</a>, I had the desire to make that object rotate based on the position of a viewer. As you look left, the cube might rotate left. At the time I’d seen some work with canvas processing video frames and <a href="http://ajaxian.com/archives/finally-a-useful-blink-tag-detecting-your-user-blinking">detecting eye blinks</a>. But I needed seamless access to the webcam, and that was only available through Flash.</p>
<p>In 2010, at Full Frontal, Paul Rouget reminded us of the possibilities of the webcam in the browser, but back then I didn’t make much of it. I needed a custom build of Firefox and that device API was eventually deprecated. </p>
<p>Fast forward to today and we have the <a href="http://dev.w3.org/2011/webrtc/editor/getusermedia.html">getUserMedia (gUM) API</a>, for accessing a user’s microphone(s) and webcam(s). This comes as part of the real time communications spec, and it’s supported, somewhat, in Chrome 21+ and Opera 12+, albeit in slightly different guises.</p>
<p>Face detection in canvas has also improved, and we have <a href="https://github.com/liuliu/ccv">LiuLiu’s “not-so-slow” face detection scripts</a> (for those interested, <a href="http://liuliu.me/eyes/javascript-face-detection-explained/">the technique in JavaScript is explained on LiuLiu’s blog</a>). What’s more, the venerable Wes Bos <a href="http://wesbos.com/html5-video-face-detection-canvas-javascript/">used this in video</a>, last year, to great effect. Much of my experimentation has been based on this, and I’d urge you to have a read yourself.</p>
<p>Put it all together and what have you got? A webcam stream dumped into a video element, processed into a canvas element, and processed again to search for faces, in real time, in the browser, without plugins. Huzzah.</p>
<p>Detecting the presence and relative distance of a face is much simpler than the angle a user is looking. So for now, rather than rotating, I have settled on a simple scale: as you move forwards or backwards, the content adapts, transitioning and transforming as appropriate.</p>
<p>It’s never simple though. The face detection only works some of the time. With busy backgrounds or low light conditions the detection fails more often. Sometimes the wrong area is detected, which can lead to radical and jarring shifts in the scale. Perhaps a rolling average would be a better indication, alas I haven’t built that.</p>
<h2 class="strong">How to</h2>
<p>Below I have dissected the key parts of the experiments. And as always the experiment code is available on <a href="https://github.com/fofr/paulrhayes.com-experiments/webcam/">GitHub</a>. </p>
<h3>getUserMedia</h3>
<p>Presently (Nov 2012) Chrome 21+ and Opera 12+ are the only browsers that <a href="http://caniuse.com/stream">support getUserMedia</a>. Some early versions accepted a comma separated string of media types, e.g. “video, audio”, later versions use an object instead, <code>{video: true}</code>. In Chrome getUserMedia is name-spaced, as is window.URL, which we need for interpreting the webcam stream.</p>
<p>Before we begin it’s best to normalise this stuff. <a href="https://gist.github.com/f2ac64ed7fc467ccdfe3">This gist</a> and its comments were helpful, as was <a href="http://html5doctor.com/getusermedia/">HTML5 Doctor’s guidance</a>.</p>
<pre>
//normalise window.URL
window.URL || (window.URL = window.webkitURL || window.msURL || window.oURL);

//normalise navigator.getUserMedia
navigator.getUserMedia || (navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
</pre>
<p>Now let’s call it:</p>
<pre>
// toString for the older implementation (found by https://github.com/agektmr)
var options = {video: true, toString: function(){ return "video"; }};
navigator.getUserMedia(options, successCallback, errorCallback);
</pre>
<h3>Converting a stream to a video element</h3>
<p>To show a webcam stream in a video element we need only set the video source to the stream returned by getUserMedia in the success callback. This is done either directly or using a <a href="https://developer.mozilla.org/en-US/docs/DOM/window.URL.createObjectURL">URL object</a> of that stream:</p>
<pre>
// using the normalised window.URL
function successCallback(stream) {
    video.src = (window.URL &#038;& window.URL.createObjectURL) ? window.URL.createObjectURL(stream) : stream;
}
</pre>
<h3>Transplanting to canvas</h3>
<p>For the video to render within canvas we need to take the current video frame and apply it to the canvas with drawImage. We need to do this as often as possible. A timer that calls the same function again after 50ms works well enough.</p>
<pre>
function drawFrame() {
    var canvas = document.querySelector('canvas'),
        context = canvas.getContext('2d');

    context.drawImage(video, 0, 0, canvas.width, canvas.height);
    setTimeout(drawFrame, 50);
}
</pre>
<h3>Face detection</h3>
<p>First we include the wonderful <a href="https://github.com/liuliu/ccv/tree/stable/js">CCV library</a> (ccv.js) and another file which defines a face object (face.js). To detect the faces in our canvas we simply call the detect_objects method and pass in our canvas:</p>
<pre>
ccv.detect_objects({canvas : (ccv.pre(canvas)), cascade: cascade, interval: 2, min_neighbors: 1});
</pre>
<p>This gives an array of detected objects, each with x and y co-ordinates, a width and a height. It looks a bit like:</p>
<pre>
{
    confidence: 0.16752329000000035,
    height: 48.500000000000014,
    neighbors: 1,
    width: 48.500000000000014,
    x: 80.50000000000001,
    y: 104.50000000000003
}
</pre>
<p>This operation is relatively slow. To speed up the face detection I recommend using a small canvas (200x160) and hence a scaled down video frame. This gives the algorithm much less data to assess and reduces processing time per frame from ~500ms to a more manageable ~100ms. The algorithm can also detect multiple faces, by default the scaling experiment uses the first found face, and only begins when there is only one face on screen. (The masks work for everyone).</p>
<p>To highlight the face or draw a mask over it:</p>
<pre>
// highlight
context.fillRect(face.x, face.y, face.width, face.height);

// mask
context.drawImage(mask, face.x, face.y, face.width, face.height);
</pre>
<h3>Face size</h3>
<p>When starting the webcam an initial face size is stored and used as a reference point for all future scaling. Comparing the current face’s height and the original face’s height we get a simple scale factor that we can apply directly as a transform on an element. This can be transitioned, if your computer can take that, at the same time as doing the video processing and face detection.</p>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/nrVFqT764Us" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2012-11/fun-with-face-detection-canvas-and-webcam-video/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2012-11/fun-with-face-detection-canvas-and-webcam-video/</feedburner:origLink></item>
		<item>
		<title>Use CSS transitions to link Media Queries and JavaScript</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/02745iTLsLA/</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[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.]]></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>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/02745iTLsLA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-11/use-css-transitions-to-link-media-queries-and-javascript/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2011-11/use-css-transitions-to-link-media-queries-and-javascript/</feedburner:origLink></item>
		<item>
		<title>Improving the CSS only modal</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/SHcJCeXG9m4/</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[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. This follow-up addresses those concerns and creates a more production-ready version.]]></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>
<div class="edit">
<time datetime="2013-02-10">10 Feb 2013</time> The site’s design has been updated and the comment form reverted to a simpler, non-modal one. The original can still be seen in the video below.
</div>
<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>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Firefox 10 has much improved animation performance. Experiment updated to be full featured.
</div>
<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>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/SHcJCeXG9m4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-04/css-modal-follow-up/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2011-04/css-modal-follow-up/</feedburner:origLink></item>
		<item>
		<title>Creating a modern modal with CSS</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/uR8cVvrrO30/</link>
		<comments>http://www.paulrhayes.com/2011-03/css-modal/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 20:52:29 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[:target]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[modal]]></category>
		<category><![CDATA[transitions]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=139</guid>
		<description><![CDATA[Using CSS3 techniques a modal box can be created without JavaScript or images. With a bit of animation, transition and transform, it can be made that little bit more special. In this experiment, clicking an ‘open’ link pops up a dialogue with a smooth hardware accelerated bounce (where supported). When open all other elements on the page are non-clickable. Closing the modal is also animated, with a minimise effect.]]></description>
				<content:encoded><![CDATA[<p>Using CSS3 techniques a modal box can be created without JavaScript or images. With a bit of animation, transition and transform, it can be made that little bit more special.</p>
<p><a href="/experiments/modal/">CSS Modal Experiment</a></p>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Modal experiment updated for Firefox 10 which has better transform, transition and animation performance. Also supports 3D transforms.
</div>
<p><iframe class="vimeo" src="http://player.vimeo.com/video/21170189" width="612" height="408" frameborder="0"></iframe></p>
<p>In this experiment, clicking an ‘open’ link pops up a dialogue with a smooth hardware accelerated bounce (where supported). When open all other elements on the page are non-clickable. Closing the modal is also animated, with a minimise effect. I’ve marked up the modal using <code>&lt;aside&gt;</code>, but depending on the purpose of yours, <code>&lt;nav&gt;</code> or probably <code>&lt;details&gt;</code> might be more appropriate.</p>
<p>Of course, using images and JS will only make the modal better, and something like hitting ESC to close will never be reproduced in CSS. Pure CSS is rarely the best production-ready solution.</p>
<h3>How to</h3>
<p>The :target pseudo-selector changes the style of a targeted element. Combining a link pointing to an element with :target and altering visibility/display/opacity gives a hide/show mechanism. To facilitate the animations, which were jerky when using display:none, I’ve used a combination of :target, opacity and <a href="https://developer.mozilla.org/en/css/pointer-events">pointer events</a>:</p>
<pre>.modal {
opacity: 0;
pointer-events: none;
}

.modal:target {
opacity: 1;
pointer-events: auto;
}</pre>
<p>The modal is two parts, one part container, one part content. Ideally the container would be generated using a pseudo-element, but I haven’t got that working yet. The container spreads across the whole page and dims the background with rgba. A high z-index puts the modal on top.</p>
<pre>.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
z-index: 10000;
…
}</pre>
<p>The content is positioned roughly in the middle and is prettified with a sprinkling of text shadow, border radius, box shadow and gradient.</p>
<p>There are two animations, one named “bounce” (scale to slightly larger than normal, then fall back) and another, “minimise”, which act on the content part. These combine with a separate opacity transition on the container. </p>
<p>The simple opacity transition:</p>
<pre>.modal {
…
-webkit-transition: opacity 500ms ease-in;
-moz-transition: opacity 500ms ease-in;
transition: opacity 500ms ease-in;
}</pre>
<p>The scaling animations, although only 2D, uses scale3d for hardware acceleration. To make the bounce more realistic box shadow is also animated, which comes with a performance hit. Showing only the webkit version for brevity:</p>
<pre>@-webkit-keyframes bounce {
  0% {
  	-webkit-transform: scale3d(0.1,0.1,1);
  	box-shadow: 0 3px 20px rgba(0,0,0,0.9);
  }
  55% {
  	-webkit-transform: scale3d(1.08,1.08,1);
  	box-shadow: 0 10px 20px rgba(0,0,0,0);
  }
  75% {
  	-webkit-transform: scale3d(0.95,0.95,1);
  	-box-shadow: 0 0 20px rgba(0,0,0,0.9);
  }
  100% {
  	-webkit-transform: scale3d(1,1,1);
  	box-shadow: 0 3px 20px rgba(0,0,0,0.9);
  }
}

@-webkit-keyframes minimise {
  0% {
  	-webkit-transform: scale3d(1,1,1);
  }
  100% {
  	-webkit-transform: scale3d(0.1,0.1,1);
  }
}</pre>
<p>To change the animation on open we can use the cascade and override the default animation with a more specific one, using :target again:</p>
<pre>.modal > div {
…
-webkit-animation: minimise 500ms linear;
}

.modal:target > div {
-webkit-animation-name: bounce;
}</pre>
<p>The close button is a hidden close link with a styled ::after pseudo-element that scales on hover/focus/active. As we’re hiding the original close link, there are some hoops to jump through to make the :focus state change on the pseudo-element. The traditional clip, text indent or visibility hidden methods all fail, and I’ve resorted to color:transparent and some specific focus styles to override the confused native ones.</p>
<pre>.modal a[href="#close"] {
…
color: transparent;
}

.modal a[href="#close"]:after {
content: 'X';
display: block;
…
}

.modal a[href="#close"]:focus:after,
.modal a[href="#close"]:hover:after {
-webkit-transform: scale(1.1,1.1);
-moz-transform: scale(1.1,1.1);
}

.modal a[href="#close"]:focus:after {
outline: 1px solid #000;
}</pre>
<h3>Caveats</h3>
<p>It won’t work in IE8 and below, there’s no pointer-event support and opacity is poorly implemented. IE9 supports :target but no pointer-events. Some IE specific styles could easily switch the opacity toggle to a display or visibility one.</p>
<p>Users will still be able to tab through the links in the background and activate them. This only becomes an issue if you ignore the focus state…</p>
<p>As I alluded to at the start, some JS hooks for keyboard interaction wouldn’t go amiss, ESC to close and something to pull focus to the current modal and then back again on close.</p>
<p>The close button would probably look better with an image and the markup uses an extra containing element, which is always undesirable.</p>
<p>Animations can be great, in small quantities, but something that animates too much and gets in the way of functionality is a major drawback for users. It would be quite easy to go overboard with this.</p>
<div class="edit">
<time datetime="2011-04-26">26 Apr 2011</time> I’ve added a follow up post that addresses some of the caveats and makes this a little more cross browser compatible: <a href="/2011-04/css-modal-follow-up/">CSS Modal Follow Up</a>.
</div>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/uR8cVvrrO30" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-03/css-modal/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2011-03/css-modal/</feedburner:origLink></item>
		<item>
		<title>Creating a sphere with 3D CSS</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/8GlQBgGIPGk/</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[With CSS3’s 3D transforms it is possible to create a sphere-like object, albeit with many elements. 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>&#60;ul&#62;</code> and rotate about the X-axis, creating a sphere.]]></description>
				<content:encoded><![CDATA[<p>With CSS3’s 3D transforms I’ve illustrated how to build a <a href="/2009-07/animated-css3-cube-interface-using-3d-transforms/">cube</a> and a <a href="/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>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Experiment updated to support –moz now that Firefox 10 supports 3D transforms.
</div>
<p><iframe class="vimeo" src="http://player.vimeo.com/video/19806423" width="612" height="408" frameborder="0"></iframe></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><a href="/experiments/sphere/"><img src="http://www.paulrhayes.com/wp-content/uploads/2011/02/sphere-normal.png" alt="3D sphere using CSS transform" width="549" /></a></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="/experiments/sphere/"><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="/experiments/sphere/"><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="/experiments/sphere/"><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="/experiments/sphere/"><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="/experiments/sphere/"><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="sphere"&gt;
	&lt;div class="container"&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('');
for(i = 0; i &lt; rounds; i++) {
	$ul = $('&lt;ul&gt;');
	xRotation = rotationPerRound * i;
	$ul[0].style[transformProperty] = "rotateX("+ xRotation + "deg)";
	for(j = 0; j &lt; panels; j++) {
		$li = $('&lt;li&gt;');
		yRotation = rotationPerPanel * j;
		$li[0].style[transformProperty] = "rotateY("+ yRotation +"deg)
                         translateZ("+ zTranslate +"px)";
		$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;
-moz-persective: 800;
}

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

-moz-transition: -webkit-transform 200ms linear;
-moz-transform-style: preserve-3d;
}

.container &gt; ul {
-webkit-transform-style: preserve-3d;
-moz-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>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/8GlQBgGIPGk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2011-02/creating-a-sphere-with-3d-css/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2011-02/creating-a-sphere-with-3d-css/</feedburner:origLink></item>
		<item>
		<title>Thoughts on Responsive Enhancement</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/WwPwNW7S_L4/</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[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.]]></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>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/WwPwNW7S_L4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-10/thoughts-on-responsive-enhancement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2010-10/thoughts-on-responsive-enhancement/</feedburner:origLink></item>
		<item>
		<title>Creating a tetrahedron with 3D CSS</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/QLjnIXUIZe4/</link>
		<comments>http://www.paulrhayes.com/2010-10/css-tetrahedron/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 19:59:59 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[pyramid]]></category>
		<category><![CDATA[transformations]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=112</guid>
		<description><![CDATA[A triangle can be created in CSS by manipulating the borders of an element. Combining four triangles in a 3D space using <code>-webkit-transform</code>, these can be positioned to form a tetrahedron (or pyramid if you prefer). With CSS animations this can also spin.]]></description>
				<content:encoded><![CDATA[<p>A triangle can be created in CSS by manipulating the borders of an element. Combining four triangles in a 3D space using <code>-webkit-transform</code>, these can be positioned to form a tetrahedron (or pyramid if you prefer).</p>
<p><a href="http://www.paulrhayes.com/experiments/pyramid/">CSS pyramid — proof of concept</a><br />
For now this only works in Safari 5.0.2+ and iOS, although 3D transforms will surface in Firefox 4 and the next build of Chrome. The demo doesn’t use JavaScript.</p>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Experiment updated for Firefox 10 which supports 3D transforms.
</div>
<div class="edit">
<time datetime="2012-11-24">24 Nov 2012</time> Code updated with a <a href="https://github.com/fofr/paulrhayes.com-experiments/pull/2">pull request</a> from <a href="https://github.com/jbecousse">jbecousse</a> to improve the angle of rotation and the shades of the different faces.
</div>
<p><iframe class="vimeo" src="http://player.vimeo.com/video/19500636" width="612" height="408" frameborder="0"></iframe></p>
<p>Combining squares and triangles, <a href="http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/">cubes</a> and pyramids, all sorts of 3D structures are now possible, if you are so inclined. Not necessarily useful, but possible.</p>
<p><a href="http://www.paulrhayes.com/experiments/pyramid/"><img src="http://host.trivialbeing.org/up/small/css-pyramid.png" alt="CSS pyramid"></a></p>
<p>The rotation is performed using a <code>-webkit-animation</code>, I’ve given the animation the name “spin”, which rotates the pyramid around Y from 0 to 360 degrees:</p>
<pre>
#pyramid {
-webkit-animation: spin 5s linear infinite;
-moz-animation: spin 5s linear infinite;
}

@-webkit-keyframes spin {
  from {
  	-webkit-transform: rotateY(0deg) rotateX(-20deg);
  }
  to {
  	-webkit-transform: rotateY(360deg) rotateX(-20deg);
  }
}

@-moz-keyframes spin {
  from {
  	-moz-transform: rotateY(0deg) rotateX(-20deg);
  }
  to {
  	-moz-transform: rotateY(360deg) rotateX(-20deg);
  }
}
</pre>
<p>If you haven’t seen it before, the code to create an approximate equilateral triangle is as follows:</p>
<pre>
#pyramid > div {
position: absolute;
border-color: transparent transparent transparent rgba(50, 50, 50, 0.5);
border-style: solid; 
border-radius: 3px;
border-width: 200px 0 200px 346px;
}
</pre>
<p>Tantek Çelik coined this technique in his <a href="http://tantek.com/CSS/Examples/polygons.html">study of regular polygons</a> which includes pentagons, hexagons and octagons. The methods are explained over at the <a href="http://www.filamentgroup.com/lab/image_free_css_tooltip_pointers_a_use_for_polygonal_css/">Filament Group</a>.</p>
<p>The 3D techniques I’ve used in this experiment are explained in my <a href="http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/">3D cube post</a> (July 2009). This is a proof of concept and I haven’t delved into the mathematics or geometry too much, instead opting for the slightly faster but significantly less clever and less reproducible trial-and-error approach.</p>
<pre>
#pyramid > div:first-child  {
-webkit-transform: rotateY(-19.5deg);
-moz-transform: rotateY(-19.5deg);
}

#pyramid > div:nth-child(2) {
-webkit-transform: rotateY(90deg) rotateZ(60deg);
-moz-transform: rotateY(90deg) rotateZ(60deg);
}

#pyramid > div:nth-child(3) {
-webkit-transform: rotateX(60deg) rotateY(19.5deg);
-moz-transform: rotateX(60deg) rotateY(19.5deg);
}

#pyramid > div:nth-child(4) {
-webkit-transform: rotateX(-60deg) rotateY(19.5deg) translateX(-116px) translateY(-200px);
-webkit-transform-origin: 0 0 -326px;

-moz-transform: rotateX(-60deg) rotateY(19.5deg) translateX(-116px) translateY(-200px);
-moz-transform-origin: 0 0 -326px;
}
</pre>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/QLjnIXUIZe4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-10/css-tetrahedron/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2010-10/css-tetrahedron/</feedburner:origLink></item>
		<item>
		<title>Adding touch gestures and mouse controls to a 3D CSS cube</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/8nMDMRgCysc/</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 update to the <a href="/2009-07/animated-css3-cube-interface-using-3d-transforms/">original 3D cube</a> (from July 2009), 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.]]></description>
				<content:encoded><![CDATA[<p>An update to the <a href="/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><a href="http://www.paulrhayes.com/experiments/cube-3d/touch.html">Experiment: 3D cube with touch gestures and click and drag</a><br />
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>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Experiment updated for Firefox 10 which supports 3D transforms. Although the perspective appears off, probably due to a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=726397">perspective-origin bug</a>.
</div>
<p><iframe class="vimeo" src="http://player.vimeo.com/video/19501428" width="612" height="408" frameborder="0"></iframe></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);
-moz-transform: rotateX(90deg) translateZ(200px);
}

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

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

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

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

#cube > div:nth-child(6) {
-webkit-transform: rotateX(-90deg) rotate(180deg) translateZ(200px);
-moz-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>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/8nMDMRgCysc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/</feedburner:origLink></item>
		<item>
		<title>Useful CSS snippets</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/Fw2cnxVISjs/</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 quick round up of some CSS tricks I’ve recently started using. Including an input type search reset, a tweaked clearfix, equal height columns, gradients and ligature and kerning pair support.]]></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>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> border-radius can now be used without a vendor prefix.
</div>
<pre>
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>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Webkit’s gradient syntax has been updated to match the emerging standard.
</div>
<pre>
background: #990000;
/* old: background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#cc0000), to(#990000)); */
background: -webkit-linear-gradient(#cc0000, #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>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/Fw2cnxVISjs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-08/useful-css-snippets/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2010-08/useful-css-snippets/</feedburner:origLink></item>
		<item>
		<title>A new look, and a new domain</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/2VZR66RjmvY/</link>
		<comments>http://www.paulrhayes.com/2010-08/a-new-look-and-a-new-domain/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 07:58:53 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Design]]></category>

		<guid isPermaLink="false">http://www.paulrhayes.com/?p=103</guid>
		<description><![CDATA[It's been almost a year since my last post. In that time I've moved house, changed jobs and got married, it's been a bit of a whirlwind. And the web has moved fast as well, CSS and canvas experiments have been popping up all over the place (see <a href="http://delicious.com/fofr/css3">delicious.com/fofr/css3</a> for my favourites). Inevitably coming back to "FofR Online" after such a long period I wasn't happy with the site, and I've committed the web faux pas of changing the design and the domain name at the same time.]]></description>
				<content:encoded><![CDATA[<p>It’s been almost a year since my last post. In that time I’ve moved house, changed jobs and got married, it’s been a bit of a whirlwind. And the web has moved fast as well, CSS and canvas experiments have been popping up all over the place (see <a href="http://delicious.com/fofr/css3">delicious.com/fofr/css3</a> for my favourites).</p>
<p>Inevitably coming back to “FofR Online” after such a long period I wasn’t happy with the site, and I’ve committed the web faux pas of changing the design and the domain name at the same time. I’ve dropped the rather meaningless “FofR Online” pseudonym in favour of using my name as a brand. All pages now redirect to paulrhayes.com.</p>
<p>This site is my first experiment with TypeKit and web fonts. I’ve chosen to use Museo for headers and Swing dancer for my name. I can’t say I’m entirely happy, but if I waited for that I’d never release anything. </p>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/2VZR66RjmvY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2010-08/a-new-look-and-a-new-domain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2010-08/a-new-look-and-a-new-domain/</feedburner:origLink></item>
		<item>
		<title>Creating an animated 3D CSS cube using 3D transforms</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/sSFvYkL3L0A/</link>
		<comments>http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 01:16:54 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[perspective]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=99</guid>
		<description><![CDATA[A 3D cube can be created solely in CSS, with all six faces. Using JavaScript to detect key presses and update inline styles this cube can be intuitively navigated. Last week WebKit included the much anticipated (at least on my part) 3D transforms in its latest nightly build. It is now possible to create all sorts of crazy three-dimensional and animated user interfaces; the power comes largely in <code>-webkit-perspective</code> and a number of updated transforms--adapted to incorporate the Z axis.]]></description>
				<content:encoded><![CDATA[<p>Last week WebKit included the much anticipated (at least on my part) 3D transforms in its latest nightly build, announced practically alongside the awesome <a href="http://www.satine.org/research/webkit/snowleopard/snowstack.html">Snow Stack demo</a> that provides a 3D interface for browsing Flickr images (use left, right and space-bar). Today the <a href="http://webkit.org/blog/386/3d-transforms/">Surfin Safari blog</a> has updated with some more exciting demos, including “<em>Morphin Power Cubes</em>” and “<em>Poster Circle</em>”. It is now possible to create all sorts of crazy three-dimensional and animated user interfaces; the power comes largely in <code>-webkit-perspective</code> and a number of updated transforms–adapted to incorporate the Z axis.</p>
<p><span id="more-99"></span></p>
<p>Since working on the <a href="/2009-04/3d-cube-using-css-transformations/">3D cube using 2D transforms</a> back in April I’ve experimented with perspective to create something more powerful, playing around with 3D transforms on the iPhone a few times (e.g. this <a href="/experiments/perspective/">early rotating demo</a>). Now I’ve got something worth sharing.</p>
<p>A 3D cube can be created solely in CSS, with all six faces. Using JavaScript to detect key presses and update inline styles this cube can be intuitively navigated.</p>
<h3>Result</h3>
<p><a href="/experiments/cube-3d/">A 3D cube that rotates using the Up, Down, Left and Right arrow keys.</a><br />
Supported browsers: WebKit Nightly r46042+</p>
<div class="edit">
<time datetime="2010-09-28">28 Sept 2010</time> <a href="http://www.paulrhayes.com/2010-09/3d-css-cube-ii-touch-gestures-click-and-drag/">Cube updated</a> to work with touch gestures and click and drag</a>
</div>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Experiment updated. 3D transforms are now supported in Safari, Chrome and Firefox 10. Although the perspective appears off, probably due to a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=726397">perspective-origin bug</a>.
</div>
<p class="center"><img src="http://host.trivialbeing.org/up/fofr-online-20090717-3d-cube.jpg" alt="3D cube interface using new WebKit transforms" /></p>
<h3>How To</h3>
<p>I’ll start with the markup, because it’s simple. Each of the six cube faces is given a face class and another relating to it’s number. These six faces sit within a cube container, which sits in another wrapper, each is necessary.</p>
<pre class='prettyprint'>&lt;div id=&quot;experiment&quot;&gt;
	&lt;div id=&quot;cube&quot;&gt;
		&lt;div class=&quot;face one&quot;&gt;
			One face
		&lt;/div&gt;
		&lt;div class=&quot;face two&quot;&gt;
			Up, down, left, right
		&lt;/div&gt;
		&lt;div class=&quot;face three&quot;&gt;
			Lorem ipsum.
		&lt;/div&gt;
		&lt;div class=&quot;face four&quot;&gt;
			New forms of navigation are fun.
		&lt;/div&gt;
		&lt;div class=&quot;face five&quot;&gt;
			Rotating 3D cube
		&lt;/div&gt;
		&lt;div class=&quot;face six&quot;&gt;
			More content
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;</pre>
<p>The outer wrapper serves as a camera, on which you apply some perspective — appropriate 3D transformations are then applied to descendants. <code>-webkit-perspective</code> defines the depth of the Z-plane and relative sizes of elements above and below it, <code>-webkit-perspective-origin</code> specifies the perspective’s origin. <a href="http://webkit.org/blog-files/3d-transforms/perspective-by-example.html">View a perspective example (webkit.org)</a></p>
<pre class='prettyprint'>
    #experiment {
      -webkit-perspective: 800;
      -webkit-perspective-origin: 50% 200px;
    }
</pre>
<p>The second container, the actual cube, has a specified height, margin, position, etc. as usual. The height and width are necessary to create some confines for the cube face transformations — alternatively the width defaults to 100% and the cube’s appearance would vary with window width. <code>-webkit-transition</code> (<a href="http://www.w3.org/TR/css3-transitions/">documentation</a>) defines the animated property, duration and timing-function — we’re animating the 3d transformation (via <code>-webkit-transform</code>) linearly for two seconds. <code>-webkit-transform-style</code> determines whether child elements lie flat against their parent (“flat”) or remain in 3D space (“preserve-3d”).</p>
<pre class='prettyprint'>
    #cube {
      position: relative;
      margin: 0 auto;
      height: 400px;
      width: 400px;
      -webkit-transition: -webkit-transform 2s linear;
      -webkit-transform-style: preserve-3d;
    }
</pre>
<p>Using the <code>.face</code> class common styles are applied to the six sides; coloring, size, padding, etc. Importantly they are each positioned absolutely, relative to the cube container. The background rgba property is included to make the cube look pretty and transparent.</p>
<pre class='prettyprint'>
    .face {
      position: absolute;
      height: 360px;
      width: 360px;
      padding: 20px;
      background-color: rgba(50, 50, 50, 0.7);
    }
</pre>
<p>Each of the faces, one through six, needs to be rotated in 3D space to its correct starting position. Using <code>translateZ</code> the elements are brought 200px (half their width) off the Z-plane. Each of the faces must be at 90 degrees. Rotating solely in the X plane positions the top and bottom faces (one, six), before rotating the last four faces in the Y plane, much like origami. The extra rotate on the sixth face rotates the content in 2D space to correct its orientation.</p>
<pre class='prettyprint'>
    #cube .one  {
      -webkit-transform: rotateX(90deg) translateZ(200px);
    }

    #cube .two {
      -webkit-transform: translateZ(200px);
    }

    #cube .three {
      -webkit-transform: rotateY(90deg) translateZ(200px);
    }

    #cube .four {
      -webkit-transform: rotateY(180deg) translateZ(200px);
    }

    #cube .five {
      -webkit-transform: rotateY(-90deg) translateZ(200px);
    }

    #cube .six {
      -webkit-transform: rotateX(-90deg) translateZ(200px) rotate(180deg);
    }
</pre>
<p>Our cube is now complete — but it doesn’t move! With a keydown event listener we can increment X and Y angles based on different key presses, before applying them as inline styles on the cube container. In combination with the transition effect on #cube, all six faces rotate in sync from their original position to the newly defined angle, creating a seamless 3D cube interface.</p>
<pre class='prettyprint'>
  	var xAngle = 0, yAngle = 0;
	document.addEventListener('keydown', function(e)
	{
		switch(e.keyCode)
		{

			case 37: // left
				yAngle -= 90;
				break;

			case 38: // up
				xAngle += 90;
				break;

			case 39: // right
				yAngle += 90;
				break;

			case 40: // down
				xAngle -= 90;
				break;
		};

		$('cube').style.webkitTransform = "rotateX("+xAngle+"deg) rotateY("+yAngle+"deg)";
	}, false);
</pre>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/sSFvYkL3L0A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/feed/</wfw:commentRss>
		<slash:comments>88</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-07/animated-css3-cube-interface-using-3d-transforms/</feedburner:origLink></item>
		<item>
		<title>Creating an accordion using CSS transitions</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/w12fWB6EzW0/</link>
		<comments>http://www.paulrhayes.com/2009-06/accordion-using-only-css/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 22:46:36 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=89</guid>
		<description><![CDATA[A simple accordion effect can be achieved using CSS3's <code>:target</code> pseudo-class, without requiring JavaScript. Using the proprietary <code>-webkit-transition</code> property this accordion can also be animated.]]></description>
				<content:encoded><![CDATA[<p>An accordion effect can be achieved using CSS3’s <code>:target</code> pseudo-class, without requiring JavaScript. Using the proprietary <code>-webkit-transition</code> property this accordion can also be animated.<br />
<span id="more-89"></span></p>
<h3>Result</h3>
<p><a href="/experiments/accordion/#one">CSS3 Accordion</a><br />
Works in browsers that support the <code>:target</code> pseudo-class, see the <a href="http://www.quirksmode.org/css/contents.html#t34">Quirks Mode compatibility tables</a>. Animation works in recent WebKit based browsers.</p>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Experiment updated. Transitions are now widely supported, including Opera, Firefox and IE10.
</div>
<h3>How To</h3>
<p>Each part of the accordion has an ID, heading and content region. The header includes a link that matches the section’s ID, whilst the content is wrapped in a container which will control its display.</p>
<pre class="prettyprint">
&lt;div class=&quot;accordion&quot;&gt;
	&lt;h2&gt;Accordion Demo&lt;/h2&gt;
	&lt;div id=&quot;one&quot; class=&quot;section&quot;&gt;
		&lt;h3&gt;
			&lt;a href=&quot;#one&quot;&gt;Heading 1&lt;/a&gt;
		&lt;/h3&gt;
		&lt;div&gt;
			&lt;p&gt;Content&lt;/p&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	&lt;div id=&quot;two&quot; class=&quot;section&quot;&gt;
		&lt;h3&gt;
			&lt;a href=&quot;#two&quot;&gt;Heading 2&lt;/a&gt;
		&lt;/h3&gt;
		&lt;div&gt;
			&lt;p&gt;Content&lt;/p&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>The CSS then relies on the <code>:target</code> pseudo-class to apply different styles to the chosen section — increasing the height and, in large content cases, altering the overflow behaviour to allow scrolling. To animate the opening and closing of sections the <code>-webkit-transition</code> property is needed (<a href="http://www.w3.org/TR/css3-transitions/">documentation</a>), in this case acting on the height attribute for a duration of 0.3 seconds using the ease-in timing function.</p>
<p>Stripping out the styling, the CSS boils down to:</p>
<pre class="prettyprint">
.accordion h3 + div {
	height: 0;
	overflow: hidden;
	-webkit-transition: height 0.3s ease-in;
	-moz-transition: height 0.3s ease-in;
	-o-transition: height 0.3s ease-in;
	-ms-transition: height 0.3s ease-in;
	transition: height 0.3s ease-in;
}

.accordion :target h3 + div {
	height: 100px;
}

.accordion .section.large:target h3 + div {
	overflow: auto;
}</pre>
<h3>Critique</h3>
<p>Obviously this approach has its limitations. Multiple open accordions on one page wouldn’t be possible — restricted by a URI’s one fragment identifier limit; as one accordion opens the other would lose the target and automatically close. Similarly, pages that use a fragment identifier for everyday use will notice oddities — take for instance when using <em>top</em> links to return to the top of the page, any accordion would, in this case, reset. Other uses include accessibility links and simulated page histories when using Ajax.</p>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/w12fWB6EzW0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-06/accordion-using-only-css/feed/</wfw:commentRss>
		<slash:comments>52</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-06/accordion-using-only-css/</feedburner:origLink></item>
		<item>
		<title>Moving markup towards HTML5</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/2C-YJl1PzWo/</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[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.]]></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>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/2C-YJl1PzWo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-06/moving-markup-towards-html5/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-06/moving-markup-towards-html5/</feedburner:origLink></item>
		<item>
		<title>Creating a 3D Cube using 2D CSS transformations</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/kyYwGyLlWVA/</link>
		<comments>http://www.paulrhayes.com/2009-04/3d-cube-using-css-transformations/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 23:54:28 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[cube]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=67</guid>
		<description><![CDATA[The impression of a three dimensional cube can be created using modern CSS techniques, without the need for JavaScript, imagery, canvas or SVG. Using the proprietary transform property to skew and rotate shaded rectangles, individual cube faces can combine to form a 3D object. This article outlines how, with two experiments.]]></description>
				<content:encoded><![CDATA[<p>The impression of a three dimensional cube can be created using modern CSS techniques, without the need for JavaScript, imagery, canvas or SVG. Using the proprietary transform property to skew and rotate shaded rectangles, individual cube faces can combine to form a 3D object. Currently only supported in recent WebKit and Gecko based browsers, most importantly Firefox 3.5+ <code>-moz-transform</code> (<a href="https://developer.mozilla.org/En/CSS/CSS_transform_functions">documentation</a>) and Safari 3.2+ <code>-webkit-transform</code> (<a href="http://webkit.org/specs/CSSVisualEffects/CSSTransforms.html">documentation</a>).<br />
<span id="more-67"></span></p>
<p>To demonstrate the power of this effect a second experiment with multiple cubes and proprietary WebKit transitions is also available.</p>
<h3>Results</h3>
<p><a href="/experiments/cube/">A 3D cube created with CSS</a><br />
Supported browsers: Safari 3.2+, Google Chrome, Firefox 3.5+</p>
<div class="edit">
<time datetime="2009-06-7">7 Jun 2009</time> Altered CSS slightly to use skew(x,y) rather than skewY, the latter of which is not supported in Safari 3 / Chrome.
</div>
<div class="edit">
<time datetime="2009-07-21">21 Jul 2009</time> Using newly released (currently only in Webkit Nightly releases) 3D transforms, a <a href="/2009-07/animated-css3-cube-interface-using-3d-transforms/">3D rotating cube</a> with fixed perspective is possible. The cube can also be rotated.
</div>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Exper­i­ment updated. Transforms are now widely sup­ported. Support includes Opera, Fire­fox and IE9. Transitions are coming in IE10.
</div>
<p><a href="/experiments/cube/multiCubes.html">Experiment with multiple cubes and CSS transitions, still no JavaScript</a><br />
Supported browsers: Safari 4+, Google Chrome</p>
<p class="center"><a href="http://host.trivialbeing.org/up/multiple-cubes-css.png"><img src="http://host.trivialbeing.org/up/small/multiple-cubes-css.png" alt="Multiple cubes created using CSS" /></a></p>
<h3>How To</h3>
<p>Similar to my previous experiments, the HTML markup is very simple. Each of the faces has its own DIV, class and content. The top face requires some extra markup to aid the transformation, more on that shortly.</p>
<pre class="prettyprint">
&lt;div class=&quot;cube&quot;&gt;
	&lt;div class=&quot;topFace&quot;&gt;
		&lt;div&gt;
			Content
		&lt;/div&gt;
	&lt;/div&gt;
	&lt;div class=&quot;leftFace&quot;&gt;
		Content
	&lt;/div&gt;
	&lt;div class=&quot;rightFace&quot;&gt;
		Content
	&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>A short disclaimer, the geometry in this example is ‘fudged’, in that the values have been adjusted to appear roughly correct. I know that the dimensions are slightly out of whack, this is merely to save my head from mathematics and to get the concept out there quickly for people to see. With that said, let’s crack on with the CSS.</p>
<p>Each of the three rectangles is given a slightly different shade of gray to give the impression of depth, in this example the left face is in shadow. The faces are each positioned absolutely, relative to the cube container. Each face is 200 x 200 pixels, including 10 pixels of padding.</p>
<pre class="prettyprint">
.cube {
	position: relative;
	top: 200px;
}

.rightFace,
.leftFace,
.topFace div {
	padding: 10px;
	width: 180px;
	height: 180px;
}

.rightFace,
.leftFace,
.topFace {
	position: absolute;
}
</pre>
<p>Now for the fun bit. The left and right rectangles are skewed by ±30˚ along the vertical axis, with the right face shifted left by 200px, cleanly lining up the two edges to create a corner that is center aligned.</p>
<pre class='prettyprint'>
.leftFace {
	-webkit-transform: skewY(30deg);
	-moz-transform: skewY(30deg);
	background-color: #ccc;
}

.rightFace {
	-webkit-transform: skewY(-30deg);
	-moz-transform: skewY(-30deg);
	background-color: #ddd;
	left: 200px;
}
</pre>
<p>The top face proves more problematic; it needs to be skewed, scaled, rotated and positioned. The skew is the same, –30˚ along the vertical axis, this skewed rectangle must then be rotated clockwise by 60˚. Rotating the rectangle itself leads to a change in orientation of its content, a container must be added and then rotated.</p>
<p>A simple way of creating a top face without resorting to maths is to duplicate the left and right rectangles, skew them in the opposite directions (by inverting the sign, e.g. left face is now skewed by –30˚) and position them against the existing faces to create a diamond shape between the two sets. Now use positioning and scaling to fill this diamond and form the top face, deleting the duplicates when finished. My results led to a scaling factor of 1.16 in the Y direction which I have accounted for by reducing the font-size by the same factor.</p>
<pre class='prettyprint'>
.topFace div {
	-webkit-transform: skewY(-30deg) scaleY(1.16);
	-moz-transform: skewY(-30deg) scaleY(1.16);
	background-color: #eee;
	font-size: 0.862em;
}

.topFace {
	-webkit-transform: rotate(60deg);
	-moz-transform: rotate(60deg);
	top: -158px;
	left: 100px;
}
</pre>
<p>The final CSS looks like this:</p>
<pre class='prettyprint'>
.cube {
	position: relative;
	top: 200px;
}

.rightFace,
.leftFace,
.topFace div {
	padding: 10px;
	width: 180px;
	height: 180px;
}

.rightFace,
.leftFace,
.topFace {
	position: absolute;
}

.leftFace {
	-webkit-transform: skewY(30deg);
	-moz-transform: skewY(30deg);
	background-color: #ccc;
}

.rightFace {
	-webkit-transform: skewY(-30deg);
	-moz-transform: skewY(-30deg);
	background-color: #ddd;
	left: 200px;
}

.topFace div {
	-webkit-transform: skewY(-30deg) scaleY(1.16);
	-moz-transform: skewY(-30deg) scaleY(1.16);
	background-color: #eee;
	font-size: 0.862em;
}

.topFace {
	-webkit-transform: rotate(60deg);
	-moz-transform: rotate(60deg);
	top: -158px;
	left: 100px;
}
</pre>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/kyYwGyLlWVA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-04/3d-cube-using-css-transformations/feed/</wfw:commentRss>
		<slash:comments>61</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-04/3d-cube-using-css-transformations/</feedburner:origLink></item>
		<item>
		<title>Create an auto-scrolling parallax effect without JavaScript</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/5ZDIq9w5Gc4/</link>
		<comments>http://www.paulrhayes.com/2009-04/auto-scrolling-parallax-effect-without-javascript/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 07:40:16 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[parallax]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=48</guid>
		<description><![CDATA[Here's another CSS3/WebKit transitions experiment in the (controversial) realm of CSS animation. In this article I recreate the popular parallax effect using multiple background images on a single element, and animating with the recent <code>-webkit-transition</code> property.]]></description>
				<content:encoded><![CDATA[<p>Here’s another quick CSS3/WebKit transitions project in the controversial realm of CSS animation. This time I have opted to recreate the popular parallax effect using multiple background images on a single element and the <code>-webkit-transition</code> property (<a href="http://webkit.org/specs/CSSVisualEffects/CSSTransitions.html">documentation</a>). I have based this on Chris Coyier’s <a href="http://css-tricks.com/3d-parralax-background-effect/">parallax tutorial</a>, reusing the star images with permission, the technique itself was coined by <a href="http://clearleft.com/is/paulannett/">Paul Annett</a> (explanation on <a href="http://thinkvitamin.com/features/how-to-recreate-silverbacks-parallax-effect/">Think Vitamin</a>). If you’re not quite sure what parallax is, then Chris and Paul both go into some depth to explain it and <a href="http://en.wikipedia.org/wiki/Parallax">Wikipedia</a> is always helpful.<br />
<span id="more-48"></span></p>
<h3>Result</h3>
<p><a href="/experiments/parallax/#experiment">Experiment: Auto-scrolling CSS3 Parallax Effect</a><br />
Experiment works in Safari 4 Beta and Google Chrome. No JavaScript necessary.</p>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Exper­i­ment updated. Tran­si­tions are now widely sup­ported. Support includ­es Opera, Fire­fox and IE10.
</div>
<p class="center"><img src="http://host.trivialbeing.org/up/fofrOnlineAutoScrollingParallax.jpg" alt="Correctly rendered background images for parallax effect" /></p>
<h3>How To</h3>
<p>The HTML markup is fairly simple, one DIV for the background and another for the content, the example uses CSS3’s multiple backgrounds, so no need for extra markup to accommodate all those other images:</p>
<pre class='prettyprint'>
&lt;div id=&quot;background&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;content&quot;&gt;
	Content
&lt;/div&gt;
</pre>
<p>For the CSS the background container is set to a fixed position (for convenience more than anything) and spread across the bottom of the page using the top, left, bottom and right properties. The background images are defined using the background shorthand property with multiple declarations being comma delimited, the first being the top-most. Each of the images has a different position defined in percentage, so as the size of the container changes (e.g. on window resize) the images move disproportionately to each other; creating the impressive parallax effect.</p>
<pre class='prettyprint'>
#background {
	background: url('../images/foreground.png') 5% 5%,
		url('../images/midground.png') 20% 20%,
		url('../images/background.png') 90% 110%;
}
</pre>
<p>Ordinarily this effect is only seen when the page is re-sized or JavaScript is used for animation. My first approach to animation via CSS was to apply the transition to the background-positions, with background-position being an <em>animatable</em> property as defined in the proposed specification. However this doesn’t yet work in the latest WebKit nightly build (r42142), it is a <a href="https://bugs.webkit.org/show_bug.cgi?id=23219">known</a> <a href="http://farukat.es/bugs/webkit-background-pos-trans.html">bug</a>.</p>
<p>As an alternate route, albeit a temporary one, I have opted to use transitions to animate the left-most edge of the background container (for instance from 0px to –100px). This gradually alters the overall width of the container causing the backgrounds to shift disproportionately as per their percentages, creating the parallax effect. With a large enough duration and left position the effect appears to be continuous.</p>
<pre class='prettyprint'>
#background {
	left: 0;
	-webkit-transition: left 300s linear;
}

#experiment:target #background {
	left: -5000px;
}</pre>
<p>To make things a bit more fun I’ve increased the ‘flying speed’ when the mouse hovers over the background area. The final CSS looks like this:</p>
<pre class='prettyprint'>
#background {
	background: url('../images/foreground.png') 5% 5%,
		url('../images/midground.png') 20% 20%,
		url('../images/background.png') 90% 110%;
	top: 218px;
	left: 0;
	right: 0;
	bottom: 0;
	position: fixed;
	-webkit-transition: left 300s linear;
}

#experiment:target #background {
	left: -5000px;
}

#experiment:hover #background {
	left: -9999px;
}
</pre>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/5ZDIq9w5Gc4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-04/auto-scrolling-parallax-effect-without-javascript/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-04/auto-scrolling-parallax-effect-without-javascript/</feedburner:origLink></item>
		<item>
		<title>Time for some CSS debate</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/0lDomOK-wjc/</link>
		<comments>http://www.paulrhayes.com/2009-03/time-for-some-css-debate/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 01:25:51 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[debate]]></category>
		<category><![CDATA[standards]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=41</guid>
		<description><![CDATA[That's the best pun I could think of, pretty lame to be honest. My first foray into shared experimental CSS (proprietary WebKit properties used to create a <a href="/2009-03/an-analogue-clock-using-only-css/">clock animation</a>) has fired up an interesting debate; where should the realm of cascaded style sheets end?

This clock experiment does not advocate such use of style sheets, it is instead used to demonstrate the capabilities and possibilities of WebKit's transform and transition properties. It has inadvertently highlighted the controversial and unexpected nature by which web developers may use them. Should this cross-pollination of <em>behaviour definition</em> become standard? Is it risky? What might the side effects be?]]></description>
				<content:encoded><![CDATA[<p>That’s the best pun I could think of, pretty lame to be honest. My first foray into shared experimental CSS (proprietary WebKit properties used to create a <a href="/2009-03/an-analogue-clock-using-only-css/">clock animation</a>) has fired up an interesting debate; where should the realm of cascaded style sheets end?<br />
<span id="more-41"></span></p>
<p>This clock experiment does not advocate such use of style sheets, it is instead used to demonstrate the capabilities and possibilities of WebKit’s transform and transition properties. It has inadvertently highlighted the controversial and unexpected nature by which web developers may use them. Should this cross-pollination of <em>behaviour definition</em> become standard? Is it risky? What might the side effects be?</p>
<p>Comments on the <a href="http://ajaxian.com/archives/creating-a-clock-in-css#comments">Ajaxian post</a> began the discussion, <em>Malic</em> opened the debate (this comment is particularly in reference to ‘transition’ rather than the more widely accepted ‘transform’):</p>
<blockquote><p>While this [is] interesting and maybe a little bit cool, I think it is inappropriate for Webkit to take CSS (even if only for itself) in this direction. CSS was created to define style. This seems more like a behavior to me and that belongs to the Javascript problem space. Going down the the road that Webkit is going, the question is — where do you stop? Just how much do you extend CSS to be? I think you run the risk of creating solutions for problems that have already been solved.</p></blockquote>
<p>This yielded some opposition but the majority supported the notion, <a href="http://www.travisalmand.net/">Travis Almand</a> champions the new transform property but strongly questions its counter-part:</p>
<blockquote><p>CSS should be a style guide, not a programming language.</p></blockquote>
<p>Before highlighting that the road to behaviour in CSS has already begun with the much used :hover, accompanied by :active, and :focus — <a href="http://www.w3.org/TR/css3-selectors/#useraction-pseudos">user action pseudo-classes</a>, <cite>agents sometimes change the rendering in response to user actions</cite>; response being the keyword.</p>
<p><a href="http://willpeavy.net/">Will Peavy</a> comments that these behaviours <del datetime="2009-03-30T18:54:02+00:00">wreak</del> reek of IE’s abandoned CSS expressions, and <a href="http://doggydoo.net/">edthered</a> asks:</p>
<blockquote><p>What happens when your CSS library and your javascript library start trying to do the same thing to the same element, or different things to the same element?</p></blockquote>
<p><a href="http://blogs.adobe.com/jd/2009/03/pervin_the_standards.html">John Dowdell</a> of Adobe has also weighed in with an <em>honest rant</em> that I heartily recommend reading, even if I’m slightly jealous that I cannot articulate my prose as well.</p>
<blockquote><p>The clock example shows that people will use technologies in unexpected ways. The creators of Usenet did not intend mass advertising. […] Stuffing the genie back inside the bottle is harder than looking carefully at the bottle before opening it.<br />
[…]<br />
We may not be able to persuasively articulate why this will eventually be considered a bad architectural decision. It’s like when vendors of email clients started talking about how wonderful it would be to add hidden graphics and scripting to the emails strangers send to you. Vague warnings of an unsound future are at a disadvantage to self-interested “But I wanna do it!!” evangelists.</p>
<p>It’s hard to persuasively document future risks. But encumbering HTML and CSS like this is not the way to bless your own multimedia engine.</p></blockquote>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/0lDomOK-wjc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-03/time-for-some-css-debate/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-03/time-for-some-css-debate/</feedburner:origLink></item>
		<item>
		<title>An analogue clock using only CSS</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/SjCvIW3J61w/</link>
		<comments>http://www.paulrhayes.com/2009-03/an-analogue-clock-using-only-css/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 01:16:44 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[transformations]]></category>
		<category><![CDATA[transitions]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=23</guid>
		<description><![CDATA[Having read the blurb around <a href="http://webkit.org/blog/138/css-animation/">Safari's CSS transitions</a> I opted to familiarize myself with a quick project - the aim of which was to create a functional, CSS only, analogue clock. By rotating three images at different rates about the same point a clock can be made, and with JavaScript it can tell the correct time. ]]></description>
				<content:encoded><![CDATA[<p>Having read the blurb around <a href="http://webkit.org/blog/138/css-animation/">Safari’s CSS transitions</a> I opted to familiarize myself with a quick project — the aim of which was to create a functional, CSS only, analogue clock.<br />
<span id="more-23"></span></p>
<h3>Result</h3>
<p><a href="/experiments/clock/#clock">Experiment: CSS Analogue Clock</a><br />
Experiment works in Safari 4 Beta and Google Chrome. A working clock that optionally resorts to JavaScript to grab the current time (can be achieved by other means).</p>
<div class="edit">
<time datetime="2012-02-12">12 Feb 2012</time> Exper­i­ment updated. Transforms are now widely sup­ported. Support includes Opera, Fire­fox and IE9. Transitions are coming in IE10.
</div>
<h3>How To</h3>
<p>Before getting into the nitty gritty I created four images, a clock face and three transparent PNG hands (seconds, minutes and hours), ensuring that each of these were the same size so that when overlayed their centres would align. The HTML and CSS to get us going is as follows:</p>
<pre class='prettyprint'>
&lt;div id=&quot;clock&quot;&gt;
	&lt;div id=&quot;hour&quot;&gt;&lt;img src=&quot;images/hourHand.png&quot; /&gt;&lt;/div&gt;
	&lt;div id=&quot;minute&quot;&gt;&lt;img src=&quot;images/minuteHand.png&quot; /&gt;&lt;/div&gt;
	&lt;div id=&quot;second&quot;&gt;&lt;img src=&quot;images/secondHand.png&quot; /&gt;&lt;/div&gt;
&lt;/div&gt;
</pre>
<pre class='prettyprint'>
#clock {
position: relative;
width: 378px;
height: 378px;
background-image: url('../images/clockFace.png');
left: 50%;
margin: 5em 0 0 -189px;
}

#clock div {
position: absolute;
}
</pre>
<p>The magic that rotates the clock’s hands comes via two WebKit specific CSS properties, <code>-webkit-transition</code> (<a href="http://webkit.org/specs/CSSVisualEffects/CSSTransitions.html">documentation</a>) and <code>-webkit-transform</code> (<a href="http://webkit.org/specs/CSSVisualEffects/CSSTransforms.html">documentation</a>). The transform property can alter the appearance of an element via a two dimensional transformation, for instance: scaling, rotating and skewing a DIV element. In this case it is used to rotate the clock hands to the correct angles; the CSS below puts the hour hand at 3 o’clock:</p>
<pre class='prettyprint'>
#clock img[src*='hour'] {
-webkit-transform: rotate(90deg);
}
</pre>
<p>The transition property creates an animation of a specified property between two values when triggered, for instance fading the opacity on a DIV element from 1 to 0 — triggered using the :hover pseudo class. Transition duration and the transition timing function (e.g. linear) should also be set, amongst other optional properties. In this example the transition is from one transformation angle to another with durations that match the appropriate clock hand, so the second hand takes 60 seconds to complete a 360 degree rotation. The transition is triggered using the :target pseudo element — if the URI contains the ‘clock’ fragment then the time piece shall start ticking.</p>
<pre class='prettyprint'>
#clock img[src*='second'] {
/* -webkit-transition: property duration timing-function */
-webkit-transition: -webkit-transform 60s linear;
}

#clock:target img[src*='second'] {
-webkit-transform: rotate(360deg);
}
</pre>
<p>The above transition lasts only one rotation but by altering the duration length and degree of rotation in accordance the second hand can keep on going (e.g. 600 seconds and 3600 degrees rotation gives a battery life of 10 minutes), a fairly safe assumption that users will not stay on the page for too long.</p>
<pre class='prettyprint'>
#clock img[src*='second'] {
-webkit-transition: -webkit-transform 600000s linear;
}

#clock:target img[src*='second'] {
-webkit-transform: rotate(3600000deg);
}

#clock img[src*='minute'] {
-webkit-transition: -webkit-transform 360000s linear;
}

#clock:target img[src*='minute'] {
-webkit-transform: rotate(36000deg);
}
</pre>
<h3>Grab the current time</h3>
<p>Although the animation works beautifully, CSS alone is not capable of obtaining the current time. To start the clock at the correct time a dynamic transformation needs to be applied to the clock hand containers, this is  easiest done with inline styles and can be set in any number of ways by the backend when the page loads, thereby eradicating any need for JavaScript.</p>
<p>Alternatively, if you’ve no objections to using JavaScript, I’ve created a small <code>startClock()</code> function to do the job (<em>albeit using Prototype 1.6.0.3 for my own convenience</em>):</p>
<pre class='prettyprint'>
function startClock() {
	var angle = 360/60;
	var date = new Date();
	var hour = date.getHours();
	if(hour > 12) {
		hour = hour - 12;
	}
	var minute = date.getMinutes();
	var second = date.getSeconds();
	var hourAngle = (360/12)*hour + (360/(12*60))*minute;
	$('minute').setStyle('-webkit-transform: rotate('+angle*minute+'deg)');
	$('second').setStyle('-webkit-transform: rotate('+angle*second+'deg)');
	$('hour').setStyle('-webkit-transform: rotate('+hourAngle+'deg)');
}
</pre>
<p>A word of warning — applying the inline style directly to the image will override the transition effects defined in the CSS file.</p>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/SjCvIW3J61w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-03/an-analogue-clock-using-only-css/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-03/an-analogue-clock-using-only-css/</feedburner:origLink></item>
		<item>
		<title>Track outbound links using Google Analytics</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/sBiCsgI6XjE/</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["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 - <abbr title="Google Analytics">GA</abbr> 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.]]></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 — <abbr title="Google Analytics">GA</abbr> 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>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/sBiCsgI6XjE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-03/track-outbound-links-using-google-analytics/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-03/track-outbound-links-using-google-analytics/</feedburner:origLink></item>
		<item>
		<title>Creating the first design</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/zcwj9z1MCYo/</link>
		<comments>http://www.paulrhayes.com/2009-03/creating-the-first-design/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 00:20:30 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[theme]]></category>
		<category><![CDATA[typography]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=5</guid>
		<description><![CDATA[For the default FofR Online theme, I have chosen a simple appearance that focuses on the beauty of fonts and typography. The header uses a sans-serif font, on OS X this will be Helvetica Neue, on Windows the CSS font stack allows the design to fall back to the more common Arial, plain old Helvetica isn't used because some Windows machines have a terrible low quality version installed. The content area is distinguished with a serif font, for the time being, Times New Roman.]]></description>
				<content:encoded><![CDATA[<p>For the default FofR Online theme, the first of many, I have chosen a simple appearance that focuses on the beauty of fonts and typography. The header uses a sans-serif font, on OS X this will be Helvetica Neue, on Windows the CSS font stack allows the design to fall back to the more common Arial, plain old Helvetica isn’t used because some Windows machines have a terrible low quality version installed. The content area is distinguished with a serif font, for the time being (no pun intended — where would I be if I started making typeface puns?), this is Times New Roman. I may experiment further with less common serif fonts that are installed on a good majority of machines (e.g. with MS Office or Adobe CS4), falling back to Times New Roman if necessary.<br />
<span id="more-5"></span></p>
<p><strong>Update</strong>: I have slightly altered the content’s stack to begin with Apple’s Times font rather than Times New Roman, mainly for the superior glyphs that it offers, take for instance ‘fi’ in this post’s title. I’m attempting to research the differences between Times and Times New Roman beyond a simple comparison though internet sleuthing has not proved fruitful.</p>
<p>I’ve spent a short amount of time researching leading, kerning, the measure, et al to improve the legibility of the content region (e.g. <a href="http://www.thedesigncubicle.com/2008/12/10-common-typography-mistakes/">The Design Cubicle</a>). I’ve increased the CSS line-spacing and slightly upped the word-spacing to make the content area more readable. The design’s horizontal dimensions are all defined in <em>em</em>s, so the page scales correctly with changes in font size — always maintaining an appropriate measure in the region of 78 characters, ‘<em>a couple of alphabets</em>’ — a good rule of thumb for legibility. The vertical alignment in the header uses pixels to keep the desired appearance. The header image uses the text-indent text replacement technique and a transparent PNG that uses Helvetica Neue to achieve a consistent branding style across platforms.</p>
<p><a href="http://markboulton.co.uk/journal/comments/five_simple_steps_to_better_typography/">Mark Boulton</a> states that the leading should increase proportionately with the measure. I am tempted to create a small JavaScript project for a fluid web layout that dynamically alters the CSS line-spacing of the content based on the width of the window and hence the measure; just to see how things change. I think the first problem may be deciding the scaling factor to apply to the line-spacing.</p>
<p>One of the biggest caveats of creating a design that strongly relies on the <em>beauty</em> of fonts is the difference in Windows and Apple font rendering. Take for instance the screen capture below which compares Windows XP (Left, IE7) with OSX (Right, Firefox 3). My preference is towards Apple’s stylish approach that attempts to match print, versus Microsoft’s pixel jamming but easier to read pragmatic rendering. By using fonts as the predominant styling force on the page it is clear that in this case the Apple approach is superior. <a href="http://www.joelonsoftware.com/items/2007/06/12.html">Joel on Software</a> has a very nice article that makes a good comparison between the two.</p>
<p class="center"><a href="http://host.trivialbeing.org/up/windows-mac-comparison.png"><img src="http://host.trivialbeing.org/up/small/windows-mac-comparison.png" alt="Windows and OS X font rendering comparison" /></a></p>
<p>Areas still left to develop include the right hand columns, a proper grid layout and the footer, I have put these aside until next week.</p>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/zcwj9z1MCYo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-03/creating-the-first-design/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-03/creating-the-first-design/</feedburner:origLink></item>
		<item>
		<title>Let’s get the ball rolling</title>
		<link>http://feedproxy.google.com/~r/prhayes/~3/9QVshepZwU4/</link>
		<comments>http://www.paulrhayes.com/2009-03/lets-get-the-ball-rolling/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 17:01:00 +0000</pubDate>
		<dc:creator>Paul Hayes</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[sandbox]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.fofronline.com/?p=3</guid>
		<description><![CDATA[This blog has been devised as a spring board for my ideas whilst serving as a professional outlet for my skills, thoughts and collaborations. If I were to include some buzz words in this opening blurb to describe the content I'll endeavour to put here I might include; CSS3, HTML5, Information Architecture and User Experience.]]></description>
				<content:encoded><![CDATA[<p>Good evening, day, or morning, depending on the time you read this. Welcome to my online portfolio, my sandbox for design, my playground for web development, my platform for industry opinions and my business, “FofR Online”. What does FofR stand for? It’s Czech for “move it”, it’s a common typo of for and it sits in that ballpark of quirky online branding — reminiscent of Flickr or Twitter, especially if pronounced ‘foffer’.<br />
<span id="more-62"></span></p>
<p>This blog has been devised as a spring board for my ideas whilst serving as a professional outlet for my skills, thoughts and collaborations. If I were to include some buzz words in this opening blurb to describe the content I’ll endeavour to put here I might include; CSS3, HTML5, Information Architecture, User Experience, Unobtrusive JavaScript, Prototype &amp; jQuery libraries, SEO, web analytics, OOCSS, progressive enhancement, accessibility, rapid design prototyping and internet marketing.</p>
<p>As an exciting starting point, rather than build my own WordPress theme from scratch I have opted to use the excellent Sandbox theme — ‘<em>beautiful on the inside</em>’. With its hugely powerful class-generating functions Sandbox creates clean and accessible markup with a huge array of context sensitive CSS selectors, creating an ‘<em>exceptionally extensible foundation</em>’.</p>
<p>For more information on the Sandbox WordPress theme I recommend checking out the official <a href="http://www.plaintxt.org/themes/sandbox/">Sandbox website</a> hosted at plaintxt or the project home on <a href="http://code.google.com/p/sandbox-theme/">Google Code</a>.</p>
<img src="http://feeds.feedburner.com/~r/prhayes/~4/9QVshepZwU4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.paulrhayes.com/2009-03/lets-get-the-ball-rolling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.paulrhayes.com/2009-03/lets-get-the-ball-rolling/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 2.018 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-05-25 12:14:38 -->
