As I go through the HTML5 spec, I find some use­ful new fea­ture just about every­where, and the new con­tente­d­itable attribute is cer­tainly one of those. It’s sup­ported by most ele­ments and pro­vides a sim­ple and yet effec­tive way for you to allow the users to edit user con­tents (blog posts for instance) inline as opposed to hav­ing to open up a sep­a­rate form.

It couldn’t be sim­pler to use it, just set the con­tente­d­itable attribute of your ele­ment to true:

<article id="editable" contenteditable="true">
    <p>This area is an article, its border will light up when you click anywhere inside.</p>
    …
</article>

And now when the user can edit the con­tent of the ele­ment themselves:

image image

Here is a quick demo I’ve put together which uses two but­tons to save and clear changes to/from the local stor­age, though you can just eas­ily save the changes auto­mat­i­cally when the ele­ment loses the focus.

Share

HTML5 includes two new ways to store data on the client – local stor­age and ses­sion stor­age. Local stor­age has no time limit on how long the data should be kept around, ses­sion stor­age on the other hand (as the name sug­gests) stores data for only one session.

Tra­di­tion­ally you can store data on the client using cook­ies, but they are not suited for stor­ing large amounts of data because every­thing gets sent back to the server on every request and hence slows down the roundtrip and mak­ing the user expe­ri­ence less enjoyable.

Using the new stor­age meth­ods, data is only passed on when asked for and it’s there­fore pos­si­ble to store large amounts of data with­out slow­ing down the site. The data is also sand­boxed and a web­site can only access data stored by itself, you can use javascript to set and get data from the rel­e­vant storage.

Browser Sup­port Detection

A browser that sup­ports HTML5’s local stor­age will have a local­Stor­age prop­erty on the global win­dow object, you can write your own func­tion to check for the exis­tence of and valid­ity (not null) of the local­Stor­age prop­erty, or use a third-party library like Mod­ern­izr.

Mod­ern­izr is an open source, light weight javascript library that detects sup­port for many HTML5 and CSS3 fea­tures, when it runs it cre­ates a global object called Mod­ern­izr. To check for local stor­age sup­port, all you need to do is to check the boolean flag for local storage:

if (Modernizr.localstorage) {
    // browser supports local storage
}
else {
    // browser doesn't support local storage
}

or sim­i­larly for ses­sion storage:

if (Modernizr.sessionstorage) {
    // browser supports local storage
}
else {
    // browser doesn't support local storage
}

API

The full API spec­i­fi­ca­tion for the local­Stor­age and ses­sion­Stor­age objects can be found here. At the time of writ­ing, this is how the com­mon Stor­age inter­face look:

image

Demo

I’ve put together a quick demo here to illus­trate how to detect and use the local and ses­sion stor­age to get, set, remove and clear stored items (well, basi­cally, cov­ers each of the avail­able meth­ods on the Stor­age inter­face above).

The page itself is sim­ple and crude, just a cou­ple of <div> and most impor­tantly two tables which I use to show all the key value pairs stored in the local and ses­sion storage:

image

Page Load

When the page fin­ishes load­ing, I call the Mod­ern­izr object to find out if the cur­rent browser sup­ports local and/or ses­sion stor­age, if not, hide the rel­e­vant <div> ele­ments so the tables are not even shown on the page:

$(document).ready(function () {
    // hide the storage divs if browser doesn't support local storage or session storage

    if (Modernizr.localstorage && Modernizr.sessionstorage) {
        $("#detectionSpan").html("Your browser supports both local and session storage");
    } else {
        if (!Modernizr.localstorage) {
            $("#detectionSpan").html("Your browser doesn't support local storage");
            $("#localStorageDiv").hide();
        } else {
            $("#detectionSpan").html("Your browser doesn't support session storage");
            $("#sessionStorageDiv").hide();
        }
    }
    showKeys();
});
Pop­u­late Tables

The showKeys() func­tion pop­u­lates the localTable and ses­sionTable tables with the keys in the cor­re­spond­ing stor­age if and only if the stor­age type is sup­ported by the browser:

// show the keys currently held in the local and session storage
function showKeys() {
    if (Modernizr.localstorage) {
        showStorageKeys("local", "#localTable");
    }
    if (Modernizr.sessionstorage) {
        showStorageKeys("session", "#sessionTable");
    }
}

// show the keys currently held in the specified type of storage in the specified table
function showStorageKeys(type, table) {
    // get the specified type of storage, i.e. local or session
    var storage = window[type + 'Storage'];

    // remove the rows in the specified table before we start
    $(table + " > tbody > tr").remove();

    // loop through the existing keys in the storage and add them to the TBODY element as rows
    for (var i = 0; i < storage.length; i++) {
        var key = storage.key(i);
        var value = storage.getItem(key);
        $(table + " > tbody:last")
            .append("<tr><td>" + key + "</td>" +
                    "<td>" + value + "</td>" +
                    "<td><input type='submit' value='Remove' onclick='removeItem(\"" + type + "\", \"" + key + "\")'/></td></tr>");
    }
}
Intro­duc­ing the new place­holder attribute

You might have noticed that the two text boxes had place­holder text sim­i­lar to that famil­iar search box in Firefox:

text boxes with place holder text Firefox search box

This is done using HTML5’s place­holder attribute for the <input> tag:

<input id="keyText" placeholder="Enter key"/>
<input id="valueText" placeholder="Enter value"/>

Nice and easy, eh? ;-)

Set­ting an item

To add a new key value pair or update the value asso­ci­ated with an exist­ing key, you just have to call the setItem method on the intended stor­age object:

// adds a new key to both local and session storage
function setKey() {
    var key = $("#keyText").val();
    var value = $("#valueText").val();

    if (Modernizr.localstorage) {
        localStorage.setItem(key, value);
    }
    if (Modernizr.sessionstorage) {
        sessionStorage.setItem(key, value);
    }
    showKeys();
}
Remov­ing an item

Ear­lier in the showStorageKeys(type, table) func­tion, I added a row to the rel­e­vant table for each key value pair in the stor­age includ­ing a but­ton with a han­dler for the onclick event. The han­dlers are cre­ated with the cor­rect stor­age type (“local” or “ses­sion”) and key for the cur­rent row baked in already so that they will call the removeItem(type, key) func­tion with the cor­rect parameters:

// removes an item with the specified key from the specified type of storage
function removeItem(type, key) {
    // get the specified type of storage, i.e. local or session
    var storage = window[type + 'Storage'];
    storage.removeItem(key);
    showKeys();
}
Clear­ing all items

Finally, the ’”Clear” but­tons under­neath the tables call the clear­LocalKeys() and clearS­es­sion­Keys() func­tion to remove all the key value pairs in the cor­re­spond­ing storage:

function clearLocalKeys() {
    clearKeys("local");
}

function clearSessionKeys() {
    clearKeys("session");
}

// clear all the held keys in the specified type of storage
function clearKeys(type) {
    // get the specified type of storage, i.e. local or session
    var storage = window[type + 'Storage'];

    // clear the keys
    storage.clear();

    showKeys();
}

So that cov­ers all the inter­est­ing bits about the demo and all and all pretty straight for­ward and easy to imple­ment, admit­tedly I’m a javascript novice so if you feel any of this could be done bet­ter please feel free to point out to me!

Share

CSS3 intro­duces a use­ful lit­tle prop­erty called box-shadow, which as the name sug­gests adds a shadow to an element.

Sim­ple box shadow

You can cre­ate a basic box shadow like this:

div {
    -webkit-box-shadow: 10px 20px #000;  /* for Chrome */
    -moz-box-shadow: 10px 20px #000;  /* for Firefox */
}

This casts a shadow with an X-offset of 10 pix­els and a Y-offset of 20 pixels:

image image

You can equally use neg­a­tive val­ues for the off­sets, which will sim­ply cast the shadow onto the other side of the element:

div {
    -webkit-box-shadow: –10px -20px #000;  /* for Chrome */
    -moz-box-shadow: -10px -20px #000;  /* for Firefox */
}

image

You might have noticed the use of ven­dor pre­fixes (-webkit for Chrome and –moz for Fire­fox), the rea­son for this is described in my post about the bor­der radius here.

Adding a blur distance

To make the shadow look more real­is­tic, you can blur the shadow by sup­ply­ing an addi­tional parameter:

div {
    -webkit-box-shadow: 10px 20px 10px #000;  /* for Chrome */
    -moz-box-shadow: 10px 20px 10px #000;  /* for Firefox */
}

image

The higher the num­ber of pix­els the more pro­nounced the effect of the blur is.

Adding opac­ity

What’s more? You can add opac­ity to the shadow to make the shadow semi-transparent, to do this in CSS3 is sim­ple as it intro­duces a new rgba func­tion which you can use to spec­ify the colour of the shadow. Most of you should be famil­iar with how RGBa works (a stands for alpha which is a value between 0 and 1 with 0 being fully trans­par­ent and 1 being fully opaque) already and to use it on a shadow here’s what you can do:

div {
    -webkit-box-shadow: 10px 20px 10px rgba(0, 0, 0, 0.4);  /* for Chrome */
    -moz-box-shadow: 10px 20px 10px rgba(0, 0, 0, 0.4);  /* for Chrome */
}

Com­pare the two images below, using solid colour on the left and using RGBa func­tion with alpha value of 0.4 on the right:

image image

As you can see, the shadow on the right look a lot more believable!

Mul­ti­ple shadows

With the box-shadow prop­erty in CSS3, you’re not lim­ited to only one shadow, to spec­ify addi­tional shad­ows sim­ply turn the box-shadow prop­erty into a comma sep­a­rated list of shadow specifications:

div {
    -webkit-box-shadow: 10px 20px 10px rgba(0, 0, 0, 0.4),
                        -10px 20px 10px rgba(100, 0, 0, 0.4);
    -moz-box-shadow: 10px 20px 10px rgba(0, 0, 0, 0.4),
                     -10px 20px 10px rgba(100, 0, 0, 0.4);
}

image

Cre­at­ing an inner shadow

You can cre­ate an inner shadow by adding the inset keyword:

div {
    -webkit-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4);  /* for Chrome */
    -moz-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4);  /* for Firefox */
}

image

You could cre­ate mul­ti­ple inner shad­ows, though the effect tend to be a lit­tle strange if you ask me..:

div {
    -webkit-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4),
                        inset -10px -20px 10px rgba(0, 0, 150, 0.6);
    -moz-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4),
                     inset -10px -20px 10px rgba(0, 0, 150, 0.6);
}

image

Or com­bine inner shadow with nor­mal shadows:

div {
    -webkit-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4),
                        10px 20px 10px rgba(0, 0, 150, 0.6);
    -moz-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4),
                     10px 20px 10px rgba(0, 0, 150, 0.6);
}

image

again, doesn’t feel quite right…

Adding a spread distance

Finally, you can add a ‘spread’ to the shadow, which basi­cally adds some padding to the edges of the shadow:

div {
    -webkit-box-shadow: 10px 20px 0px 10px #000;  /* for Chrome */
    -moz-box-shadow: 10px 20px 0px 10px #000;  /* for Firefox */
}

Com­pare these two images, one with spread of 10 pix­els (left) and one without:

image image

Demo

Finally, here’s a quick demo page I’ve put together to let you play around with the box-shadow prop­erty and see its effects as you change the rel­e­vant para­me­ters, note it only works with webkit browsers (Safari and Chrome) for now as I’m using the new range type input in HTML5 which is not yet sup­ported in Fire­fox and iE.

Ref­er­ences:

CSS3info.com on box shadows

Share

Besides the much talked about video tag, HTML5 also intro­duced a cou­ple of new input types, one of which is a rather inter­est­ing range input type which basi­cally trans­lates to a slider bar control:

image

The range input type is cur­rently sup­ported by the lat­est ver­sions of Safari, Chrome and Opera while other browsers such as Fire­fox sim­ply treat the field as a textbox.

There are four avail­able attrib­utes – min, max, step and value. min and max should be self explana­tory, step deter­mines the size of each increment/decrement and value is the cur­rent value of the slider and also deter­mines the place­ment of the slider when the ele­ment is loaded (if not spec­i­fied, the slider will appear at the cen­tre of the con­trol when it’s first loaded):

<input type="range" min="0" max="200" step="5"></input>

image

<input type="range" min="0" max="200" value="0" step="5"></input>

image

I talked about the new bor­der radius prop­erty being intro­duced in CSS3 in my pre­vi­ous blog post, and with a lit­tle JQuery I’ve put together a quick demo here of how a 400px by 400px square looks as the bor­der radius changes.

If you look at the source of the page you will see that I added a change­Bor­der javascript func­tion to han­dle the onchange event fired by the slider, which dynam­i­cally updates the HTML con­tent of an inter­nal CSS class called myS­lid­er­BarStyles using the cur­rent value of the slider control:

<input id="mySliderBar" type="range" min="0" max="200" value="0" step="5"
       onchange="changeBorder(this.value)"></input>
…
<script type="text/javascript">
    function changeBorder(newValue) {
        var newRadius = newValue + "px";
        // set the html content of the label showing the current radius value
        $("#rangeValue").html(newRadius);
        // set the style with the new radius value
        $("#mySliderBarStyles").html(
            "#myDiv { -webkit-border-radius: " + newRadius + "; }"
        );
    }
</script>
…
<style type="text/css" id="mySliderBarStyles"></style>

Ref­er­ences:

Dive Into HTML5

Share

As you may know already, CSS3 has intro­duced a new set of prop­er­ties which allows you to eas­ily add curved cor­ners to a box.

Sim­ple round corners

You can cre­ate a div with round cor­ners with this sim­ple css:

div {
    border-radius: 50px;
}

image

How­ever, given the stage of devel­op­ment CSS3 is at as of now this is only sup­ported by Google Chrome… Instead, you are encour­aged to add ven­dor prefixes :

div {
    -webkit-border-radius: 50px; /* for Chrome */
    -moz-border-radius: 50px; /* for Firefox */
}

How much of a curve the cor­ners get is worked out by plac­ing an imag­i­nary cir­cle of a radius of the given num­ber of pix­els at each of the cor­ners (see image below):

image

Nat­u­rally this intro­duces an inter­est­ing edge con­di­tion – what if the radius of the imag­i­nary cir­cles is set to be equal to or greater than half of the width of a square-shaped ele­ment? Do we just get a cir­cle back?

Yes.

image

Spec­ify dif­fer­ent radius for each corner

You can spec­ify a dif­fer­ent radius for each of the top-left, top-right, bottom-right and bottom-left cor­ners either like this:

div {
    /* for Chrome */
    -webkit-border-top-left-radius: 40px;
    -webkit-border-top-right-radius: 10px;
    -webkit-border-bottom-right-radius: 80px;
    -webkit-border-bottom-left-radius: 20px;

    /* for Firefox */
    -moz-border-radius-topleft: 40px;
    -moz-border-radius-topright: 10px;
    -moz-border-radius-bottomright: 80px;
    -moz-border-radius-bottomleft: 20px;
}

Note: the prop­erty names are different!

Or using the short-hand syn­tax by list­ing 4 con­sec­u­tive val­ues for each of the four cor­ners in the above men­tioned order:

div {
    -webkit-border-radius: 40px 10px 80px 20px;  /* for Chrome */
    -moz-border-radius: 40px 10px 80px 20px;  /* for Firefox */
}

both will pro­duce the same result:

image

Oval-shaped cor­ners

You don’t have to be con­tent with circular-shaped cor­ners either, to spec­ify an oval-shaped cor­ner, just use this syntax:

div {
    -webkit-border-radius: 80px / 40px;  /* for Chrome */
    -moz-border-radius: 80px / 40px;  /* for Firefox */
}

image

The only thing we’re doing dif­fer­ently now is that we’re putting an oval as opposed to a per­fect cir­cle into the cor­ners. The oval is defined by a width and height:

image

And once more, you can spec­ify these for each cor­ner by set­ting sep­a­rate properties:

div {
    /* for Chrome */
    -webkit-border-top-left-radius: 80px 40px;
    -webkit-border-top-right-radius: 10px 50px;
    -webkit-border-bottom-right-radius: 40px 80px;
    -webkit-border-bottom-left-radius: 60px 20px;

    /* for Firefox */
    -moz-border-radius-topleft: 80px 40px;
    -moz-border-radius-topright: 10px 50px;
    -moz-border-radius-bottomright: 40px 80px;
    -moz-border-radius-bottomleft: 60px 20px;
}

image

though unfor­tu­nately there’s no short-hand syn­tax to save you from all these typ­ing this time around.

And finally, you don’t HAVE to use pix­els as unit either, most other stan­dard CSS units work too. It’s also worth not­ing that using the ven­dor pre­fix (e.g. –webkit, –moz) allows for a more grace­ful degrad­ing behav­ior IF the final spec for CSS3 uses a dif­fer­ent nam­ing scheme for the bor­der radius properties.

Demo

Check out this quick demo page I’ve put together for you to see the effect of chang­ing the bor­der radius, note this only works if your browser sup­ports the new ‘range’ input type defined in HTML5 (Chrome works fine, but Fire­fox doesn’t sup­port it yet).

Share