Play Framework HTML5 input elements

The built in Play input elements are fairly restrictive in that you can’t specify the input type. I wrote a helper template that you can use to generate input elements which have HTML5 type attributes such as url, email, number, search etc. etc.

All you have to do is call the template method, passing the HTML input type as a parameter. For example:

@helper.html5.input(form("website"), '_label -> "Website:", 'type -> "url")

If you have a form field mapped as a play.api.data.Forms.email then the template will automatically infer it’s type so you don’t have to pass the type attribute in with your html attributes:

@helper.html5.input(form("email"), '_label -> "Email:")

If your field has the required constraint, e.g. it is a “nonEmptyText” then the template will add the HTML5 “required” attribute to the field as well.

You can get the source code here.

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.

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;