-
24 days agoCSS3 animations demonstrated with snow
This winter we have had an unusually snowy time of things, as a matter of fact so has the whole of the UK. As a Clearleft christmas snowy surprise I wrote a CSS3 snow bookmarklet.
If you are running a WebKit based browser you can make it snow on anywhere on the internet by dragging the following bookmarklet into your toolbar, sending any site into a mini snowstorm!
I based the snow in part on the leaf example on the WebKit blog.
JavaScript is only just to add the snowflakes in their starting position (and naturally in order for it to be a bookmarklet) but all the animation and styles are done in pure CSS. So if you wanted to do this without any JavaScript at all you could just start with the snowflake elements directly in the source and it would work fine.
For the snowflakes themselves I had a lot of fun looking through the Unicode list of snowflakes, and asterisks trying to find the prettiest snowflakes ❆, ❅, ❄, ✳, they are in an array and the sizes are in another array. Every snowflake is an absolutely positioned div with a span inside, we will come to that later. When a snowflake is chosen a size and a character are chosen at random. the distribution of sizes is controlled by the proportion of the size class in the array:
var flakes = ['2746', '2745', '2744', '2733']; var sizes = ['tiny', 'tiny', 'tiny', 'small', 'small', 'small', 'small', 'medium', 'medium', 'medium', 'medium', 'medium', 'medium', 'large', 'massive'];When the snowflakes are positioned, a random side (left or right) and a percentage between 0 and 60 is chosen to set the position absolute values, this makes it work nicely when you resize the browser and means there is a higher concentration of snowflakes in the center 20% of the screen. They also needed an epic-ly large z-index because this is going to be used as a bookmarklet and you don't know what will be on the page it is used on.
Another consideration in the setup was that white snowflakes would not be seen on white pages so a text shadow was added to make it stand out, I used rgba for this to make it blend in better with any background color.
text-shadow: rgba(0, 0, 0, 0.7) 1px 1px 2px;There are two main animations for each snowflake, fading and dropping. The span inside the snowflake does the spinning. These animations are set up and given a reference-able name in the CSS file:
/* Hides a snowflake towards the very end of the animation */ @-webkit-keyframes fade { /* Show a snowflake while into or below 85 percent of the animation and hide it, otherwise */ 0% { opacity: 1; } 85% { opacity: 1; } 100% { opacity: 0; } } @-webkit-keyframes drop { /* Makes a snowflake fall from -50px to 650px pixels in the y-axis starting at -50 so as to appear to be falling from above the screen not starting at the top */ 0% { -webkit-transform: translate(0px, -50px); } 100% { -webkit-transform: translate(0px, 650px); } }The named animation group contains sub groups, rule blocks where the selector is one moment in the animation. When the animation runs it looks at the timeline of keyframes and smoothes the animation accordingly, for example in the fade animation above, the opacity stays at 1 until 85 percent through its animation (aka one drop) where it then begins a smooth fade to 0 over the last 15% of the time. If we had omitted that middle step and just had opacity set to 1 at 0% and to 0 at 100% then the fade would be a smooth fade over the duration of the whole animation.
You can also set the 'moment' of the keyframe using the keywords from and to, this is effectively the same as 0% and 100%. For simple animations this probably would suffice but I find using percentages gives you a greater degree of control over the pace of your animation.
-webkit-animation-name: 'fade, drop'Because we know we have two animations being applied to each snowflake div in JavaScript we can give the other animation properties two values and know that they apply to the two animations respectively.
-webkit-animation-iteration-count: infinite, 20;The
animation-iteration-countstates how many times an animation should run. We are not too fussed about the fade but we want to only have each snowflake fall from the sky 20 times before disappearing, just in case the bookmarklet is used and left open in a tab it shouldn't continue indefinitely.-webkit-animation-direction: normal, normal;Options for this are normal and alternate. Normal behaves exactly as you have specified in your keyframes, alternate behaves normally on odd iterations and reversed on even iterations
-webkit-animation-timing-function: linear, ease-in;There are quite a few options you can play with for this property
easelinearease-inease-outease-in-outand if you really know your animation maths you can go wild withcubic-bezier(X, X, X, X). Basically this describes the acceleration of the animation e.g.linearis all at the same speed,ease-inhas a little warm up first,ease-outwarms down andease-in-outdoes both. I wanted the snowflakes to ease gradually in before reaching a constant speed.-webkit-animation-durationWe are setting the animation-duration in Javascript because it needs to be randomised to avoid all the flakes falling at the same rate. This is being set at a random time between 5 and 11 seconds (trial and error got these magic numbers). Ideally I would have set the range based on the size of the snowflake which would have been cool, I could easily have made the larger ones fall faster than smaller ones, but I didn't think of that at the time.
-webkit-animation-delayHow long until the first snowflake starts falling? I have set this in Javascript to be instant for the first snowflake (remember it still has to fall 'into the screen' when it starts) and then a random amount of time between 4 and 8 seconds for the others. This was important with so few snowflakes because we need to spread them out so they don't all fall at the same time and look like a continuous snow storm
Naturally there is an animation shorthand property should you wish to specify everything at once.
With our snowflakes falling and fading nicely, all that remains is the spinning. in the JavaScript I set a random animation to the span inside the snowflake div that contains the snowflake character. The animation is then either clockwiseSpin or counterclockwiseSpin
@-webkit-keyframes clockwiseSpin { /* Rotates a snowflake from -50 to 50 degrees in 2D space */ 0% { -webkit-transform: rotate(-50deg); } 100% { -webkit-transform: rotate(50deg); } } @-webkit-keyframes counterclockwiseSpin { /* Rotates it from 50 to -50 degrees in 2D space */ 0% { -webkit-transform: rotate(50deg); } 100% { -webkit-transform: rotate(-50deg); } }We then set the properties explained above for the span.
-webkit-animation-iteration-count: infinite; -webkit-animation-direction: alternate; -webkit-animation-timing-function: ease-in-out; -webkit-transform-origin: 50% -100%;The spinning should be infinite and to add to randomness we need to use the 'alternate' value for direction and ease-in-out as the timing function, the offset transform origin plays with the rotation transform inside the spinning animation in order to make it seam like it is floating on a light snowy breeze.
To finish it off then the JavaScript is wrapped in a self executing function, the CSS is added to the head of the document from the main JavaScript file rather than having to bulk that into the bookmarklet. The JavaScript on is then splurted into the head of the document. The bookmarklet looks like this:
javascript:(function(){var%20s=document.createElement('script');s.src='http://j.mp/7ZZuRu';document.getElementsByTagName('head')[0].appendChild(s);})()All that remains is to just Let it Snow!
Further reading
These two articles on the WebKit blog have some good demo's on the use of animation. My 24ways article goes into a bit more detail on transforms and Tim Van Damme's great 24ways article has a supurb space animation demo which is worth looking at. The spec is available on the w3c site.
-
one month agoCSS Selector reference guide
At dConstruct last year Richard Rutter and I had the pleasure of hosting the CSS3 portion of the HTML5 and CSS3 Workshop. It sold out fast and was so popular that we're holding another CSS3 workshop on the 29th January 2010.
One of the handouts we gave to attendees was this useful little reference guide to CSS selectors. Made using CSS transitions, the pocketbook is printable in WebKit browsers and modern versions of Firefox, or you can download a PDF version. You can read more about how it works in my explanation of dinky pocketbooks.
The pocketbook includes all the available selectors in CSS2.1 & CSS3. Most of these have very good support and you can use them quite happily right now. Even some that are currently less supported can be used to provide additional visual flair to newer browsers. CSS selectors also come in handy to get elements in JavaScript when you are using a CSS-based JavaScript selector engine such as in jQuery.
If you are interested in learning more about CSS3, come along to workshop on the 29th January.
-
eight months agoStyling buttons to look like links
A common mistake that many developers make is to use a link to trigger an action on the server, for example deleting an item from a shopping basket or adding something to your favourites. Both of these examples are actions that modify state on the server and should therefore be performed using '
post'.However, sometimes even developers who know that is wrong to use a link where they should be using a form, get sucked in to doing so when the design requires a button to look like a link.
Please note that I am definitely not encouraging the redesign of button elements to look like links. I believe that we shouldn't mess too much with browser defaults for functional things like form controls, scroll bars and the like. That said, sometimes you just have to build what your designer tells you to.
It actually isn't hard to make a submit button look like a link using CSS so you should never find yourself in a position where you have to sacrifice forms for links purely for the sake of the design.
Firsly the markup: although you can use an input
type="submit"as a submit element and this example would work in the same way, the button element is, in my opinion, a much better option. It is really flexible and can have a variety of different elements nested inside if you so choose, from simple text with an image right through to headings and paragraphs. This article on buttons by Aaron Gustafson back in 2006 is still fairly relevant today and explains some of the uses the humble button element can be put to.Another useful article also from a while ago explains the techniques that Wufoo use to style links to look like buttons. The really important thing to take away from this article is that putting
overflow: visibleon a button fixes the crazy width issue that IE likes to deal us.I have posted a simple demo for you to follow along in your browser. For the purposes of this example the markup will be:
<form action="#" method="post"> <p><button type="submit" class="link"><span>Hello there I am a button</span></button></p> </form> <p><a href="#">That's nice, I am a link</a></p>The basic page in this demo has the following styles applied to the links and body:
body { font-family: "Verdana" sans-serif; } a:link, a:visited { color: blue; } a:hover, a:focus, a:active { color: black; }Next I add the magical incantation to kick the width in IE for all buttons:
button { overflow: visible; width: auto; }I have added a class of link to the button that I wish to style as a link element and the basic styles that I apply to this are the colour and font family (the button seems to inherit system font settings), as well as over-riding the button defaults with regards to border, margin, padding and background.
The default cursor for button elements is a regular arrow. I normally set
cursor: pointerfor all button elements to ensure the user knows they are clickable. This makes even more sense for buttons that are pretending to be links.button.link { font-family: "Verdana" sans-serif; font-size: 1em; text-align: left; color: blue; background: none; margin: 0; padding: 0; border: none; cursor: pointer; }Interestingly, Mozilla won't let you select the text of the button element like other browsers will, so to override this and enforce that the user can select the text of our psuedo-link, you can apply the following as well:
-moz-user-select: text;You can also choose to override all your other button styles if there are any.
Now you almost have a link. Those of you paying close attention earlier on will have noticed an as yet unexplained inner span to our button. This is because it does not appear to be possible to set text-decoration on a button directly and depending on how you have your link styles set this is something you are likely to want to do.
The text-decoration: underline rule is actually applied to the span on hover or focus of the button. This way is more flexible if you choose at some point to add or remove an underline on hover.
button.link span { text-decoration: underline; } button.link:hover span, button.link:focus span { color: black; }Naturally everybody's 'favourite' browser, Internet Explorer six will not display the hover effect on your link because it doesn't 'do' hover on arbitrary elements, only on actual links. You can fake this effect with Javascript if you really wish, adding a class on hover and removing it on mousout. Other limitations of this technique are that selection of text looks a bit dodgy in all versions of IE.
My example above is very simple. If you wath a button that appears in flow with text as a link, for example the delete link on a shopping basket item in this example, you will also need to apply '
display:inline' to both the form and any block level elements inside.So there you have it, no excuses now — go forth and use the correct HTTP method!
-
eight months agoDinky pocketbooks: the command-line reference edition
I have fulfilled my intention from to create a dinky pocket book as a reference for useful terminal commands (see below). I'll be printing a set of these out for my colleagues to find on their desks next week.
The printable pdf can be found here, but if you are running safari — or a recent gecko build as now it also uses
-moz-transform— you can print directly from the browser.The HTML for the reference booklet together with some minor updates to the original booklet css can be found on github.
I rarely use the terminal so these are commands that I will find useful as a reference and some of these I always end up having to look up. It is not designed to be an exhaustive list but if you have any suggestions I would love to hear them!

Navigate the file tree
changing directory to
dirnamecd dirnamemove up a directory in the tree—dont forget you can drag a folder in from the finder to get a path to that directory.
cd ..go back to the last directory I was in
cd -where am I? (present working directory)
pwdlist what's in this directory
lsnow give me more information in the listing
ls -lahssh to server
ssh user@domain.comFind & open
list all files recursively in subdomains
find .find all files with '
.css' in the namefind . | grep .cssfind the string '
prose' in the contents of all the files in this directorygrep -r "prose" .open a file as if you had double clicked it in the finder (mac only)
open filenameopen the current directory in the finder
open .make a directory called
dirnamemkdir dirnamecreate a file called
filenameif it doesnt exist or update last modified date if it doestouch filenameMove, remove & copy
move or rename a file or directory
mv oldname newnameremove a file
rm filenameremove a directory and all its contents. BE VERY CAREFUL! you could easily delete everything!
rm -rf dirnamecopy a file
cp oldfilename newfilenamecopy a directory and everything in it
cp -r olddirname newdirnamesecurely copy a file to / on a remote server — you can also copy a directory using
scp -rscp file user@domain.com:Subversion
check out a repository to the current directory
svn co http://domain.com/svn/ .update local directory from repository
svn upare there new or modified files?
svn statusadd new files to the repository
svn add filenameremove a file from subversion
svn remove filenamemark a previously conflicted file as resolved
svn resolved filenamewho changed what line number of this file
svn blame filenamecommit all changes in this directory
svn commit -m "commit msg"Subversion & download
is this directory checked out from svn? and where?
svn infoshow everything that has changed
svn diffshow what has changed in one file
svn diff filenameopen text editor in order to specify which files to ignore from svn
svn propedit svn:ignore .download a file to the current directory
wget URLshow the contents of a file in the terminal
curl URLHelp & information
run any command as root
sudo your-command-hereget help for any command, eg
svnsvn --helphow long has this computer been on?
uptimewhat is the size of the current directory and all the contents
du -hcancel the command you were currently typing
ctrl + cgo to the beginning of the line in the terminal
ctrl + ago to the end of the line in the terminal
ctrl + e -
eight months agoDinky pocketbooks with WebKit transforms
I'm a big fan of stuff written on paper. My computer is covered in useful post-it notes, and I do a lot of planning on paper at the start of every client-side build.
On my desk at work is a piece of paper written in felt tip that I pass around to my co-workers on occasion. It's a reference document for how we check projects out of subversion, upload to live and some basic terminal commands for people who are unfamiliar in that environment.
This was a great opportunity to break out my favourite paper folding technique, where an A4 page becomes an 8 page booklet. I first learnt about this from a Christmas card I received a few years ago from some very inventive friends.
Brian Suda happened to be in the office that day and pointed me to a cool Flash interface for creating these, pocketmod.com. He also suggested that it would be possible to build these using just HTML and CSS with CSS3 transforms, currently supported by Safari and WebKit.
Inspired, I did exactly that.
Here's the demo.html (no transforms, so I can easily preview the pages) - the transforms are applied by the print stylesheet, so hit "print preview" to see them. Alternatively, visit demo.html?print to preview the print stylesheet directly in your browser.
Just in case you aren't running Webkit or Safari, here's what the print output looks like:

Each "page" has a set width and height (241x370 px) and is absolutely positioned, but the real magic happens with the CSS3 transforms in the print stylesheet:
/* rotated left */ #page1, #page8, #page7, #page6 { -webkit-transform: translate(64.5px, -64.5px) rotate(-90deg); } /* rotated right */ #page2, #page3, #page4, #page5 { -webkit-transform: translate(-64.5px, -64.5px) rotate(90deg); }It's not enough just to rotate 90 or -90 degrees. This works fine if you are rotating something that is square because the rotation happens around the centre point. I wanted to rotate the rectangles around the corner to ensure they fitted snugly inside their parent container. The solution was to shift the position using a
translate()transform. I could have done this with position: relative, but I opted for a transform since I was already using-webkit-transformfor the rotation. 64.5px is worked out as (height - width) / 2.You can fill each page with whatever you like, but make sure it fits or it will be clipped by the
overflow: hiddenapplied to the page. The only required markup is as follows:<div id="book"> <div id="page1" class="page"></div> <div id="page2" class="page"></div> <div id="page3" class="page"></div> <div id="page4" class="page"></div> <div id="page5" class="page"></div> <div id="page6" class="page"></div> <div id="page7" class="page"></div> <div id="page8" class="page"></div> </div>I surround textual content with a
<div class="inner">to apply sensible padding without affecting the width of the page.There are currently two special page types. An empty page with lines (suitable for hand-written notes) is achieved by applying a class of
lines:<div id="page5" class="page lines"></div>The second special page uses the Google Static Maps API. The API takes a bunch of name value pairs, which I decided to represent using a definition list. On load, pages with the class
gmapare scanned for definition lists, which are then hidden and replaced by an image constructed from the definition terms.<div id="page4" class="page gmap"> <dl> <dt>center</dt> <dd>50.8197155,-0.1365716</dd> <dt>key</dt> <dd>insert your Google Maps API key here (get one here)</dd> <dt>zoom</dt> <dd>13</dd> </dl> </div>I use Simon's www.getlatlon.com to find the correct values.
Aside from these special pages, I've included styles for the HTML usual suspects - lists, tables, headings, pre etc. To make a todo list, simply apply a class of
todoto a<ul>or an<ol>. To make a blank todo list, just use blank list items.Once you've constructed and printed your dinky booklet masterpiece, you'll need to fold it. Here's a nifty video from pocketmod.com showing how:
I've published the code on GitHub, so please feel free try it out yourself or fork it and have a play. Let me know what you think.
Yesterday
@Natbat You are in a maze of options, each one leading to the same person. You are likely to be eaten by a Grue.
@Natbat <Go North> You see a dragon... <Fight dragon> It's a very very busy dragon... It hangs up on you automatically
@Natbat I assume then you have died 5 times and had to start again, only to be eaten by the giant tone of disconnection :)
Playing the text adventure game that is O2 telephone support
I have not yet watched "Around the world by Zeppelin" but I'm counting the hours until this evening http://www.bbc.co.uk/programmes/b00qpjpr
Map Rectifier — A web-based map rectification tooly MetaCarta Labs.
5th February 2010
4th February 2010
Having my designs implemented by @andyhume and @natbat is a real pleasure. It's almost as if they're using image maps.
3rd February 2010
Ooh cool! WildlifeNearYou is a featured app on the flickr blog! http://blog.flickr.net/en/2010/02/03/wildlife-is-spotted-in-the-app-garden/
2nd February 2010
Convert any font with TransType universal font converter — Handy looking tool for converting fonts between types via @allmarkedup.
