1. four months agoLeaving Clearleft, going freelance, travelling the world

    There is just under a week to go before I bid farewell to Clearleft on the 10th March. I have had a very happy and productive two and a half years working here, though it doesn't feel like it has been that long since I started.

    Team photo from a while back

    Naturally I am sad to go, it has been great fun working and being part of a team of talented people. I've learned a lot and been very lucky to have had the opportunity to work on some pretty cool projects over the years, including WWF's panda.org, the Mozilla Addon's site and so many more.

    I feel I have done some very good work during my time here, both for individual project builds, giving talks and workshops on CSS and CSS3, generally helping out with events such as dConstruct and Uxlondon. Also in introducing a systematic approach to web development—writing componentised maintainable CSS and HTML—which we now use for all of our projects.

    It is always sad to leave: I really will miss my fellow Clearlefties. We have had lots of fun memories, many team outings, conferences, fridays at the pub, epic adventures at SXSW, in depth debates & discussions, general office banter, dressing up daft for Halloween etc. They have become more than just colleagues, they are good friends.

    Me with little horns

    Andy orders us Tequila at SXSW at the Great British Booze up

    Me and Jeremy at Halloween

    There are some exciting times for me on the horizon though, in addition to running the Brighton Marathon, working on some personal projects and getting married on June 5th to the lovely Simon Willison, I am also making myself available for freelance work. If you have any HTML / CSS / Javascript projects or need emergency cross browser CSS help—I'm your girl, feel free to drop me a line.

    …and if that wasn't enough announcements for you: Simon and I will also be leaving England's green and pleasant land in mid June for an elongated honeymoon travelling the world in search of adventure, interesting food and funny animals. We will also be working as we go round. We don't have any fixed route or return date, but you can be sure there will follow a site that lets you track what we are up to as we journey through foreign lands :)

    Hugging a llama

  2. six months 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!

    Let it Snow!

    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-count states 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 ease linear ease-in ease-out ease-in-out and if you really know your animation maths you can go wild with cubic-bezier(X, X, X, X). Basically this describes the acceleration of the animation e.g. linear is all at the same speed, ease-in has a little warm up first, ease-out warms down and ease-in-out does both. I wanted the snowflakes to ease gradually in before reaching a constant speed.

    -webkit-animation-duration

    We 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-delay

    How 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.

  3. six months 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.

  4. one year 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: visible on 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: pointer for 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!

  5. one year 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!

    screenshot of dinky pocket book for terminal commands reference

    Navigate the file tree

    changing directory to dirname

    cd dirname

    move 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)

    pwd

    list what's in this directory

    ls

    now give me more information in the listing

    ls -lah

    ssh to server

    ssh user@domain.com

    Find & open

    list all files recursively in subdomains

    find .

    find all files with '.css' in the name

    find . | grep .css

    find the string 'prose' in the contents of all the files in this directory

    grep -r "prose" .

    open a file as if you had double clicked it in the finder (mac only)

    open filename

    open the current directory in the finder

    open .

    make a directory called dirname

    mkdir dirname

    create a file called filename if it doesnt exist or update last modified date if it does

    touch filename

    Move, remove & copy

    move or rename a file or directory

    mv oldname newname

    remove a file

    rm filename

    remove a directory and all its contents. BE VERY CAREFUL! you could easily delete everything!

    rm -rf dirname

    copy a file

    cp oldfilename newfilename

    copy a directory and everything in it

    cp -r olddirname newdirname

    securely copy a file to / on a remote server — you can also copy a directory using scp -r

    scp 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 up

    are there new or modified files?

    svn status

    add new files to the repository

    svn add filename

    remove a file from subversion

    svn remove filename

    mark a previously conflicted file as resolved

    svn resolved filename

    who changed what line number of this file

    svn blame filename

    commit all changes in this directory

    svn commit -m "commit msg"

    Subversion & download

    is this directory checked out from svn? and where?

    svn info

    show everything that has changed

    svn diff

    show what has changed in one file

    svn diff filename

    open text editor in order to specify which files to ignore from svn

    svn propedit svn:ignore .

    download a file to the current directory

    wget URL

    show the contents of a file in the terminal

    curl URL

    Help & information

    run any command as root

    sudo your-command-here

    get help for any command, eg svn

    svn --help

    how long has this computer been on?

    uptime

    what is the size of the current directory and all the contents

    du -h

    cancel the command you were currently typing

    ctrl + c

    go to the beginning of the line in the terminal

    ctrl + a

    go to the end of the line in the terminal

    ctrl + e

26th July 2010

24th July 2010

the Small Person has just come in to tell me that Someone On The Internet is WRONG.

Rachel Andrew 0 comments

15th July 2010

Laughing out loud at a comment by @natbat in some HTML I'm looking through.

Jeremy Keith 0 comments

11th July 2010

Emmenthal = Valley of the River Emme = Emmerdale. Not such a fancy cheese now, are we, my rubber friend?

J-P Stacey 0 comments

4th July 2010

There's a line in Back To The Future where Christopher Lloyd sets the DeLorean for "25 yrs in the future" THAT'S TODAY!

Gav McCaughey 0 comments