LESS CSS clearfix

The fantastic clearfix, as a LESS CSS class:

.clearfix {
    zoom: 1;
    &:before, &:after {
        content: "";
        display: table;
    }
    &:after {
        clear: both;
    }
}

Use in your code like so:

ul#gallery {
    .clearfix;
    li {
        float: left;
    }
}

Easy.

jQuery plugin to add a CSS class to last-child DOM elements

This has been bugging me for ages. IE < 9 does not support the CSS3 last-child pseudo class. I’ve created a _very_ simple jQuery plugin to add a CSS class “last-child” to the element that is the last child of a DOM element.

It performs this recursively, so it’ll apply the class to the last child of an element as well as to the last child of all it’s children…and so on and so forth.

It’ll perform this on each of the set of matched elements in a jQuery object. So you can have it traverse the whole, of your page by providing a jQuery object with the <body> element in it, or you can pick and choose DOM elements to apply the plugin to for efficiency. For instance, you might only need the "last-child" class to be applied to the last child of an unordered or ordered list:

    $('body').lastChild(); // Applies to all elements attached to the document.body
    $('ul, ol').lastChild(); // Applies to all elements in an unordered or ordered list

By default, the plugin applies the CSS class to a restricted set of DOM element types. You can specify the types of DOM elements to apply the class to by passing an options object to the function. In this way you can also specify the name of the CSS class that will be applied:

    $('ul, ol').lastChild({
        tags:['li'], // Only elements with the tag name 'li' will have the class applied to them
        cssClass:'ie-last-child' // The CSS class name will be 'ie-last-child'
    });

For super shorthand, you can simply pass a string to the lastChild function – which it presumes to be the CSS class you want to use:

    $('ul, ol').lastChild('ie-last-child');

You can download the plugin here.

Note, while I created this plugin to get around my IE problem, it is not built specifically for IE. If you only want IE to receive these classes, you’ll probably want to do something like:

    if($.browser.msie) {
        $('body').lastChild();
    }

…but obviously preferably using Modernizr:

    if($('.ie6, .ie7, .ie8').length) {
        $('body').lastChild();
    }

Enjoy!

Modernizr progressives or exceptions?

Modernizr, what an interesting tool you are. How do I use your class names in my CSS files? You’ve given me a choice and I’m not sure what to use:

.multiplebgs div p {
  /* properties for browsers that
     support multiple backgrounds */
}
.no-multiplebgs div p {
  /* optional fallback properties
     for browsers that don't */
}

There are two ways to view this, bottom up, and top down. They both have their advantages and disadvantages, and I’m going to attempt to highlight these for you, so you can make your own decision.

Bottom up

For the “bottom up” way of doing things, we define a lowest common denominator. A set of styles that will work with all the browsers your website is designed to target. The intersection of all the features of all your browsers, if you want to put it that way. From here, we use Modernizr to progressively enhance the user’s browsing experience for browsers that support particular features. An example may help:

a.btn {
  background:transparent url(../img/btn-red.gif) no-repeat scroll 0 0;
  padding:5px;
  display:inline-block;
  width:40px;
}
.borderradius a.btn {
  background-color:red;
  background-image:none;
  border-radius:5px;
}

The advantages being:

  • A clearly defined baseline that works on all browsers we’re coding for
  • If we aren’t able to determine client features (because for example, Modernizr is not available: the CDN is down, or the client doesn’t have JavaScript enabled) we know that the baseline styles will be used and will ensure the site looks acceptable regardless

The disadvantages are:

  • We end up writing more and more CSS as we utilise new features that become available
  • It doesn’t encourage a particularly forward thinking coding practice. You’re essentially coding for the browser with the lowest feature set
  • If you want to change the baseline styles because of a redesign or perhaps your baseline is raised, you’re probably going to have to change overridden styles in the progressive enhancement style blocks as well

Top down

The “top down” approach is where we define styles for new browsers, and then use the “no-” prefix classes to define exceptions for browsers that don’t support the feature we’re exploiting. e.g.

a.btn {
  border-radius:5px;
  background-color:red;
  padding:5px;
  display:inline-block;
  width:40px;
}
.no-borderradius a.btn {
  background:transparent url(../img/btn-red.gif) no-repeat scroll 0 0;
}

We’re forward thinking, assuming everyone viewing our site is using these great new features and coding in fallbacks for the exceptions to the rule. Our view is that one day, all browsers will support the styles we’re using…and we’re adding in exceptions for in the mean time. The advantages are:

  • We end up writing less CSS, as we don’t have to override properties we’ve previously declared that the browser doesn’t understand
  • Our mindset is altered slightly, encouraging us to make use of and exploit new browser features that allow us to code and prototype faster
  • As our browser baseline increases, it’s really easy to remove exceptions that are no longer used

The disadvantages are:

  • We’re totally relying on Modernizr and the browser having JavaScript enabled. Without JavaScript the “no-” prefixed classes are not added to the <html> element and the browser is left trying to style things that aren’t supported or use style declarations that don’t exist (as far as the browser knows).

Well, sort of. You could always use the “no-js” class on the <html> element which Modernizr normally removes and replaces with “js” (to indicate JavaScript is available). You’d define your styles as above, but then define a lowest common denominator style set, for when you don’t know what features a browser does or doesn’t support. That’s kind of overkill though.

So, that’s basically it. When I first thought about it my gut reaction was to sit in the bottom up camp, but after thinking about it, and considering the audience for the project I’m working on it makes more sense to use the top down approach. Especially now that I’ve written it down like this. I’m hoping it’ll help others to make the right decision.

Website design refresh

It has been nearly 3 years since I first launched the freestyle developments website and it was long overdue for a design and code refresh. Today I finally relaunched the site.

For me, the biggest change has been to move to a HTML5 doctype. The site now utilises many of the new HTML5 tags, such as header, footer, nav, section, article, aside and time as well as some of the new HTML5 forms attributes. Many thanks goes to @rem and @brucel for their fantastic HTML5 book, which I gleaned a lot of useful information from.

I’ve also given it a bit of a visual refresh, to use some CSS3 properties that I’m now regularly using on sites I build: drop shadows, rounded corners – that sort of eye candy. It means that my CSS no longer validates with no errors, but I’m hoping people in the know will be able to see past the vendor specific CSS property prefix errors e.g. “-moz-”, “-webkit-”.

I’ve gone for a Jello Mold layout to give me the flexibility of a fluid layout within parameters I control. I love fluid layouts, but their biggest enemy is widescreen displays, which makes reading text difficult due to the long line lengths, which is minus points for accessibility.

Assuming your default font size is 16px, my site is fluid between 700px and 1280px. Outside of these browser widths the site is rigid. It means that the site never gets so small that the content is unreadable, and never become so wide that the line width is a hindrance to legibility. Another nice thing about the Jello Mold is that between the max and min, the site re-sizes itself in an organic way, which really has to be experienced to be appreciated (give it a go now, go on).

I’ve also updated my CSS to use the YUI reset sylesheet. I don’t agree with absolutely everything that YUI are doing with their CSS stylesheets, but they have some really interesting ideas and valid points. Either way, it is nice to have part of my styles coming off a CDN and is a bit more up to date than the reset I used to use.

In accordance with my post on the EM unit and browser zoom, I’ve updated my stylesheets and removed all references to pixels in favor of EM’s like I have been doing with all my new website builds for a while now. I don’t set a font size for any of my pages html or body elements, allowing the user to choose the size of my website by setting their default font size for their browser, which is 16px for most browsers.

Anyway, I think that is all I have to say for now. Enjoy the new site and all the interesting tech that comes with it. If this all sounds good to you, and you’re looking for a freelancer like me. Get in touch.

Update: Hardware accelerated alternative to jQuery animate() top, left, width, height and opacity CSS properties for iPhone/iPad

Update to my post here – I’ve tweaked the script to use CSS3 transitions on Firefox 4+ and Opera 10.50+ as well as modern webkit based browsers such as Chrome and Safari.

The CSS3 transforms and transitions enhanced carousel can be found here:
freestyle-developments.co.uk/demo/public/portsurf/?css3

…and the normal carousel:
freestyle-developments.co.uk/demo/public/portsurf/

Source code for CSS3 transforms and transitions enhanced carousel

N.B. The normal carousel works in IE7 and IE9 beta, but not in IE8 (it seems IE8 can’t figure out the dimensions of DOM elements properly).

em, and the two zooms

Back in the days before browser “zoom”*, making text bigger on the page was done by incrementing all the font sizes in the document. All fonts set at 16px became, for example 18px, and all fonts at 20px became 22px.

The problem with this was that often text would outgrow the element it appeared in, because the element was also given a width and height in pixels and this didn’t get scaled as the text size increased or decreased.

Sometimes even if you built a site that allowed text to grow and wrap, it would get to a stage where a single long word was wider than its container, and the overflow would have to either be hidden, or just left visible to run into whatever element was placed on the immediate right. Not only that, but there are just some situations where you don’t want elements to wrap – whether they’re text nodes, floated elements with text in them, or inline-bock elements that you often find in navigation lists.

We didn’t want text zoom, we wanted magnification zoom i.e. the zoom that we have nowadays…but it didn’t exist.

Em to the rescue! Luckily, the em unit is intrinsically linked to text size. It is a relative unit, meaning that the actual size of an em depends on the font-size of its container. Clever people figured out that you could simulate magnification zoom if you measured all your widths and heights using relative units.

How does that work?

Well, if your font sizes are all increased, and everything else is measured in em’s (the width of the letter ‘M’), then everything else gets bigger as well, in proportion. Hooray!

Sure, but why would we use them nowadays?

Firstly, if someone is using an old browser that doesn’t support magnification zoom, or is using the (still existing) older text size zoom, you don’t get the problems I’ve just described above that are inherent to text zoom.

Secondly, if you never define an absolute text size for your document, your viewers are free to set their own default text size (On Firefox you can do this by visiting preferences > content > fonts & colours), and your layout will change size to accommodate. Almost all browsers set their text size at 16px by default, so if you use this as your base – i.e. 16px = 1em, then your site will be the size your designer is probably expecting it to be.

I use em’s for almost all units that could also be expressed in pixels, or percentages or whatever. Percentages almost certainly have a very important place as well, but unless you’re working with a fluid design they’re not a necessity.

* Which, for your reference, works by changing the definition of how big a pixel is on your screen. It means you’re really working with points, not pixels, but that’s by the by.

Hardware accelerated alternative to jQuery animate() top, left, width, height and opacity CSS properties for iPhone/iPad

I was recently asked to quote for a proof of concept HTML5 alternative to a flash carousel, specifically to run on iPad. I said I’d do it, but the agency later decided that others had tried to create a HTML5 version and had not been able to create a version that performed well enough for the client. From my point of view they were under the impression I couldn’t do any better. So naturally, I spent a few hours of my spare time proving this wrong, just for the fun of it.

Step 1 was to build a version of the carousel in HTML5. I chose to use the jQuery framework because…well, I felt like it. The fruits of my labour are here:

http://freestyle-developments.co.uk/demo/public/portsurf/

Now, you can view this on any browser. All that is happening is that there are a set of list items absolutely positioned in a container, when you click/touch an item on the left/right jQuery animates the top, left, width, height and opacity CSS values for each item.

Fantastic, but, it feels really sluggish on iPad and iPhone 4. Go on, try it out.

Fair enough, they are resource constrained devices. What to do though? I’ve already used all the tricks I could think of fast loops, select operation caching etc. etc. So what now?

Luckily, in iOS, transitions and animations of the -webkit-transform and opacity properties are performance-enhanced. Sweet! These correspond exactly to the two CSS properties I’m trying to manipulate for each item in my carousel. Implementation was a simple case of swapping out the jQuery animate function, for the css function. Passing in the webkit transition, webkit transform and opacity values in its place.

For example:

items[itemIndex - 3].css({
	opacity:1,
	'-webkit-transform':'translate3d(' + carousel.itemPosition.medium.left.x 
            + 'px, ' + carousel.itemPosition.medium.left.y + 'px, 0) scale(0.5)',
	'-webkit-transition':'opacity 0.4s linear, -webkit-transform 0.4s linear'
});

The webkit transition property is saying “transition these CSS properties from what they were previously to their new values, using these transition parameters (0.4s linear)”. The webkit transform property is saying “move this element to the following coordinates, and scale it by a factor of 0.5″.

Check out the hardware accelerated version on your iPad/iPhone and compare it with the other:

http://freestyle-developments.co.uk/demo/public/portsurf/?ha=1 (Note: webkit only)

Here is a video demonstrating the performance differences those of you without iPads.