jQuery CDN as A Named Module In RequireJS

If you want RequireJS to fetch jQuery from a CDN, you’ll need to tell it to do so using the “paths” config:

require.config({
paths: {
"jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"
}
});

As I understand it, if you want to use the local file fallback code a la html5bp you’re out of luck. For those of you who don’t know, the local file fallback code allows you to load jQuery from your own domain if the CDN version fails to load. It looks like this:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.8.2.min.js"><\/script>')</script>

Arguably, if you’re using jQuery it is likely to be a global requirement rather than a requirement for one or two modules. The same sort of thing with BackboneJS. It might be better to place these global requirements in the HTML for your pages (before the RequireJS script) to save typing ‘jquery’ and ‘backbone’ in all your module definitions.

JSIO URLs

The clever bit about JSIO is the placeholder URLs – i.e. the “jsio.gif#…” that goes in your image src attributes and background-image CSS properties. Everything after the “#” is the filename of the image that should be displayed. It doesn’t have to be the filename at all, it could just be a single letter or number or symbol or whatever. It doesn’t matter to JSIO. To JSIO, everything after the “#” is just a key into the resources object that holds data uri encoded images. As long as the key is unique (which it will be if you use filenames, since no two files in the same directory can have the same name), JSIO is happy.

Using filenames as keys into our resources object is beneficial to humans. Much more beneficial than coordinates in a sprite, simply because (hopefully) the filenames are meaningful; they describe the image. In comparison to sprites, the JSIO resources object also makes maintaining your image data much easier as it is trivial to add or remove images without having to move other images around within the sprite (and consequently all coordinates referencing your moved image).

Another benefit of using filenames as keys into the JSIO resources object is for fallback. If JSIO detects your browser is IE7 or lower, it’ll strip out “jsio.gif#” leaving just your image key as the image src, which is hopefully a valid URL to the original image. Also, if JSIO detects you’re running IE8 and the image data is larger than 32KB it’ll do the same thing*.

* …but not yet in v1.0.0 alpha

Since the image key is after the “#” (it is the URL “fragment”), your browser won’t send multiple requests for the 1*1px jsio.gif file – it’ll just send one request, cache the response, and use it again. By the way, the jsio.gif image is just a transparent 1*1px gif (for maximum efficiency), but it could be an “spinner” image or something, which is shown temporarily whilst the JSIO resources file is downloaded.

This post is about JSIO – JSIO is a tiny library that allows you to make fewer requests to your server by packaging all your site image data in a JavaScript file in data uri format. The official site for JSIO can be found here: jsio.freestyle-developments.co.uk. You can read more about why I started this project here.

JavaScript Image Optimiser (JSIO)

So, I’ve embarked on a new mini project. It is kind of inspired by image sprites.

Image sprites are a great idea, but come with a whole bunch of issues that make them a bit of a pain to work with.

Firstly, most of the time you have to use markup to create an element in html to “hold” the image you wanted to display from your sprite. This is because if you actually set a sprite as the background image for a large html element you’re likely to see other images in the sprite as well. Because of this, you actually lose useful functionality that CSS gives you, like the ability to position, repeat and scale an image. Also, the markup you’ve created to hold the image exists for style purposes, which is bad.

Secondly, sprites can be a massive ball ache to maintain. If you’ve closely packed your images in a sprite for maximum efficiency and then one of your images needs to change size, you’re either going to have to move ALL images surrounding the image you have to update (and obviously then change all background-position properties for the images you’ve moved) or leave a space and put the updated image in a new position in your sprite.

How do you know which images in a sprite are used and which ones are dead? Since your images are referenced by coordinates, this sort of clean up becomes a nightmare and is actually a bit lot of a nightmare to create image sprites in the first place.

The goals of the project are to

  1. Reduce the number of http requests (and their associated header traffic) to the server and hence reduce the time it takes to load all images on a website and bandwidth footprint the site requires
  2. Create a solution that’ll alleviate some of the problems surrounding the creation and use of image sprites
  3. Do something cool

The JSIO project website has a pretty good explanation of how it works so I won’t bore you with the details here. However, as a brief overview, it packages all your image data in data uri format and you reference particular images by their filename rather than their coordinates.

The site actually uses the HTML5 file api to generate your resources file for you, which makes creating and maintaining your JSIO “sprite” really really easy.

I read *somewhere* that data uri encoded images can be up to 1/3 larger than corresponding image files, however with gzip encoding they can be only 0-3% larger (or less). My thesis is that for a site with many small images, JSIO could be more efficient and easier to maintain than having separate files or even an image sprite.

…I’m yet to prove or disprove this and I’ll be conducting some tests whose results I’ll post up here (even if they do prove JSIO to be useless).

Disclaimer: This is the first ever ALPHA release of JSIO – it works on the latest Firefox and Chrome but I haven’t even checked it in IE yet. It probably won’t work in IE yet. Also, the website needs some work for optimal display on mobile devices.

Why HTML5?

I was recently asked to qualify why I had “upgraded” a website to utilise HTML5. All I had actually done was throw in a few semantic tags where it seemed appropriate and remove some unnecessary attributes. The client was concerned that the spec wasn’t complete and even suggested using HTML5 tags with an XHTML strict doctype. This was my response:

The HTML5 specification is different to your typical software specification. The W3C is no innovator: it does not lay down rules for browser vendors to follow. Vendors lead the way and their technology ideas are ultimately accepted, rejected, or tweaked to become part of the W3C specification. It’s highly unlikely the HTML5 specification will ever be fully complete. The only point when it could happen is when vendors and the W3C draw a line in the sand and move onto HTML6 (or whatever they name the next standard). If you wait for the final HTML5 specification, you’ll miss out.

http://blogs.sitepoint.com/2010/07/20/5-reasons-why-you-can-use-html5-today/

To say it’ll never be complete is a little pessimistic. Some experts in the industry believe it could be complete as soon as 2012. You get the idea though.

In terms of what the site is doing with HTML5 we’re not actually leveraging much of what HTML5 has to offer. Firstly we’re saving bandwidth by omitting attributes that all browsers already assume default values for, like the script type=”text/javascript” and stylesheet type=”text/css” attributes. Not to mention the new doctype, which is completely backwards compatible with existing doctypes in that it invokes standards mode in all browsers. Actually, in terms of your website it would be better to use a HTML5 doctype than an XHTML strict doctype, since the page is being served as text/html content-type by Apache, which is incorrect – the correct content-type for XHTML documents being application/xhtml+xml.

The second, and only other feature of HTML5 we’re actually using is semantic tags (http://bit.ly/1CzNqy). These allow us to create a document that is more accessible, in terms of search engine optimisation and for use of assistive technologies like screen readers. By using semantic tags instead of generic containers such as the div tag, our document is easier to understand when viewed by tools that don’t “see” page styles i.e. the design and layout of the page. For example, if your business name is within a paragraph tag it is likely to get lost in other content and not be returned in search engine results. But if you put it within a heading 1 tag, search robots know to give it more importance. Obviously this example doesn’t involve any HTML5 tags, but you should easily be able to see how the same principle can be applied to the new HTML5 elements, and how this principle will gain more and more importance as HTML5 becomes more widely adopted.

…and that is really the idea behind HTML5, everything that is being proposed, is being done so in a) a backwards compatible way and b) to cement features that already exist in one form or another. Pragmatically, that is what makes it viable to use features of HTML5 right now. Most existing browsers treat unknown tags as a generic HTML inline element and they can be styled to suit purpose.

Your one and only concern should be that there is a bug in IE 6, 7 and 8 that means they don’t recognise HTML5 tags. Fortunately there is a workaround, although it requires JavaScript to be enabled. If your visitor is using IE, without JavaScript enabled, your site will look differently to how it would normally look. It won’t make the site inaccessible, but some stylistic properties won’t be applied to page elements, so the page will appear a bit more like a text document than a website. Globally, I’ve seen stats showing that between 0.4% and 7% of browsers have JavaScript turned OFF. Potentially a very small percentage of your web traffic – which will probably be even less considering it only effects IE users, but it depends on your audience. Check your webstats and make a judgement call. For the majority of the time, the benefits outweigh the cost of supporting the fringe cases and I would recommend using HTML5 on your website now, as I have done for a number of clients I have worked with recently.

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.

Highlight text using jQuery and the HTML5 mark tag

Here’s a jQuery plugin I wrote that’ll add HTML5 <mark> tags around keywords or phrases in an element’s body text.

What is mark?

a run of text in one document marked or highlighted for reference purposes, due to its relevance in another context

http://www.whatwg.org/specs/web-apps/

Usage

Add the script to your page, and then when the DOM is ready, do something like:

    $('body').mark('Lorem ipsum');

The plugin can actually be used to wrap any tag around keywords. Simply pass the tag name you want to use as an option:

    $('body').mark({
      text: 'Lorem ipsum',
      tag:  'span',
      cssClass:  'mark'
    });

The above example will wrap span elements around the words lorem and ipsum. Each span element will have the class ‘mark’. View an example implementation.

TODO

  1. Input sanitation on the text to be marked. Currently the text is dumped straight into a regular expression. It needs to be escaped so that any regular expression meta-characters are interpreted as literals.
  2. Similarly, HTML special characters in the input need to be expanded into their HTML entities.
  3. From what I can see, IE doesn’t like <mark> tags, and seems to automatically self close the opening and closing tags inserted into the DOM. WTF? Can anyone shed any light on this problem? For now, you’re going to have to use a <span> with a CSS class

If you’re interested in contributing, get in touch

Using HTML5 canvas.toDataURL to generate placeholder images

A while ago lewis had a great idea – an online tool to figure out the proportional height, when given a width and a particular proportion.

I’ve actually needed to use it 3 or 4 times since it was created around a month ago, so I was keen to get involved and implement some of the suggestions he received to make it better. One of the suggestions was that the tool should generate placeholder graphics, which developers can use whilst creating websites.

I was thinking PHP GD library, which could have quite easily have done the job. However, there are a few disadvantages with this:

  1. The user has to wait while the browser makes a request to the server and gets the response
  2. The server has to have the GD image library installed!
  3. The server has to do work to generate images – eating up your valuable CPU cycles
  4. The server has to temporarily store the generated image – using up disk space
  5. The request and response both use up bandwidth
  6. The tool wouldn’t work offline

All of which could be argued to be relatively inconsequential…but I wanted to do something fun. I decided to use the HTML5 canvas element to draw the placeholder graphic because, well, that sounded fun.

Canvas has a method called "toDataURL" which (as you can probably guess) encodes the content of the canvas as a data url. I spent a couple of hours in the evening knocking up a prototype utilising this functionality.

You may be thinking (when looking at the source for the prototype): "where’s the canvas"? What actually happens is that when you change the width or height using the input boxes, the page dynamically creates a canvas element, draws the placeholder graphic inside, calls toDataURL and then creates an <img> tag, whose "src" attribute is set the data url we got from the canvas. The page then removes the canvas element and the old placeholder graphic, and appends the new graphic to the DOM. The process is so fast you don’t ever see the canvas element on the page.

The reason we don’t just leave the canvas on the page is because we want users to be able to save these graphics. You can’t right click on a canvas and select "Save image as…".

The only disadvantage I can think of by using this method is that it won’t work on older browsers…or browsers without javascript enabled. Ok that is two. Other than that, it’s great:

  1. The user doesn’t have to wait for a round trip to the server to complete
  2. The server does no further work other than to serve the script file
  3. No bandwidth is consumed transferring the image
  4. The tool even works offline!

To me, that sounds like WIN.

iframe automatic height adjustment using HTML5 cross domain web messaging

Yesterday I was working on a site that needed an iframe embedded in the page whose content came from a completely different domain. I try to steer clear of iframes at all costs normally so forgive me if what I’m about to say is pretty obvious.

I didn’t want the content in the iframe to appear as though it was in an iframe, so obviously I stripped off all the default browser styles…well, the border. I wanted the iframe to be as high as the content it was containing so that no scroll bars would appear.

So what I did was just give the iframe a height, however when the user navigated to a different page within the iframe, the height I had previously set was too big or too small.

I instantly thought “right, JavaScript will sort this out for me!” and proceeded to quickly code up a function that would inspect the scrollHeight of the content in the iframe and adjust the iframe height accordingly.

No! Said cross domain policy. I had momentarily forgotten all about that. Since the iframe content came from a different domain, I wasn’t allowed to access the document object of the iframe (or vice versa).

Here is how not to do it

Firefox says “Error: Permission denied to access property ‘document’” and other browsers similar.

I started searching for some kind of workaround.  Of course there isn’t really one…except I did find an interesting hack for Firefox. Which is – an iframe document can alter the url fragment of the parent window’s location object! ha madness.

The idea is that the document in the iframe alters the url fragment to read:

http://freestyle-developments.co.uk/blog/?p=150#138

Where 138 is the height of the iframe document (obviously you could be a bit more fancy and send other parameters and name them e.g #height:138 but for simplicity I’ve just set the value). The parent then reads this value and sets the iframe height accordingly:

var iFrameHeight = parseInt(location.hash.replace('#', ''));

So…yeah, that’s pretty interesting, but not really a solution. Check out the example implementation here.

Anyway, what to do? HTML5 web messaging to the rescue! Sweet! HTML5 web messaging is cross domain messaging done right. Not only does the messenger choose who should receive messages, but the recipient also chooses who to receive messages from.

The idea is that after the iframe document has loaded, it sends a message to the parent window telling it what it’s scrollHeight is. The parent listens for messages, and sets the height of the iframe when it receives a message.

A couple of things to note:

  1. There has to be communication between the two documents. i.e. the document on the external domain needs to actively send this message. Which can be a complete show stopper if you have no control over the document on the external domain
  2. This isn’t going to work on IE < 9. I tested the implementation linked below is working on FireFox 4 (Beta 7), Safari 5.0.2, Chrome 8, Opera 10.63 and Internet Explorer 9 Platform Preview 7. Which is a pretty good spread to be honest

Check out the example HTML5 web messaging implementation here.

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.

HTML5 <article> for WordPress comments

WordPress natively allows us to wrap comments in <div>’s or <li>’s but not HTML5 <article> elements. If you want to do this, add an ‘end-callback’ param to the wp_list_comments function call and set ‘article’ as the style (in comments.php):

    wp_list_comments(array('callback' => 'twentyten_comment',
                           'style' => 'article',
                           'end-callback' => 'twentyten_comment_end'));

…then in functions.php, add the callback function:

    if(!function_exists('twentyten_comment_end')) :
    /**
     * Allow HTML5 <article> (or anything else) for comment container.
     */
    function twentyten_comment_end($comment, $args, $depth) {

        switch($args['style']) {
            case 'ol':
            case 'ul':
            case '':
                echo "</li>\n";
            break;
            default:
                echo '</' . $args['style'] . ">\n";
        }
    }
    endif;