Tag Archives: HTML5

Responsive is not just visual: Three useful web APIs

A mobile user using a laptop outside.Mobile users are on the go. They’re rushing to get a train or busy meeting people. They don’t have much time and they’re on a slow connection. Right?

The answer of course is not necessarily. So-called mobile browsing could include shopping online while tucked up in bed, sending messages while watching TV or giggling at silly photos while relaxing in a cafe. It could also include being out and about but not using a mobile device.

In reality we have no idea what the users of our website are doing or where they are, and it would be a huge invasion of privacy if we did! Our fancy responsive designs should therefore not only look good but also be flexible enough to handle a variety of situations.

In other words, responsive doesn’t mean responding to screen size or even device capabilities. It means responding to the user’s environment (as much as possible).

But enough chatter. How can we do this in practice?

There are three handy web technologies that take us part of the way there: the Battery Status API, the Network Information API and Ambient Light Events. Support for all of them is mostly Chrome and Firefox for now, but keep an eye on caniuse.com and mobilehtml5.org for the latest support info. And now, on to the APIs…


Battery Status API

Why use it

Knowing whether your user is plugged in or not and whether their battery has much juice left can influence how your site reacts. Battery-draining features such as repeated actions and animations can be reduced or disabled, for example. Or you could notify the user and offer to save the current state in case there’s a sudden shutdown.

How to use it

The spec had a rewrite recently and now uses shiny new promises. The advantage of this is that the API is asynchronous, meaning that when you call the getBattery() method the browser makes sure the BatteryManager object is ready before you try to read its attributes. Those attributes are:

  • charging (a boolean)
  • chargingTime (in minutes)
  • dischargingTime (in minutes)
  • level (a number between 0 and 1)

Each of these attributes has an event so you can listen for when they change. In practice, you could use the attributes and events like this:

// Prepare a function to display the battery status
function showStatus(battery) {
  battery.onchargingchange = function () {
    console.log('Charging: ' + battery.charging);
  };
  battery.onchargingtimechange = function () {
    console.log('Charging time remaining (mins): ' + battery.chargingTime);
  };
  battery.ondischargingtimechange = function () {
    console.log('Discharging time remaining (mins): ' + battery.dischargingTime);
  };
  battery.onlevelchange = function () {
    console.log('Battery level: ' + battery.level);
  };
}

// Check for browser support first
if (!!navigator.getBattery) { // The latest API is supported
  // Use the battery promise to asynchronously call showStatus()
  navigator.getBattery().then(function(battery) {
    showStatus(battery);
  });
} else if (!!navigator.battery) { // The old API is supported
  var battery = navigator.battery;
  showStatus(battery);
}

Guille Paz has made a nice battery status demo which includes code for the old and new versions of the spec.

Status

This API has the best support of the three with Opera, Chrome and Firefox having implemented it. In the case of Firefox, the implementation currently uses an old version of the spec so for the time being it’s best to allow for both versions in your code.


Network Information API

Why use it

You’re probably aware of the navigator.onLine HTML5 attribute and its wide browser support but that only tells us if the user is connected to a network or not. For more detailed information about the network we need the aptly-named Network Information API. With the data it provides you could opt to show smaller or lower-quality images to users on slow connections, or only show a video background when you know the network speed is fast. Be careful when making assumptions though — wifi doesn’t necessarily mean fast.

How to use it

When fully implemented this provides the type and speed of connection using two attributes (type and downlinkMax) on the global navigator object. Let’s jump straight into an example…

// Some browsers use prefixes so let's cope with them first
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;

// Check for browser support
if (!!connection) {
  // Get the connection type
  var type = connection.type;

  // Get the connection speed in megabits per second (Mbps)
  var speed = connection.downlinkMax || connection.bandwidth;
}

So easy! The type values are a pre-defined selection of self-explanatory strings:

  • bluetooth
  • cellular
  • ethernet
  • none
  • wifi
  • wimax
  • other
  • unknown

Network speed, when available, is exposed as downlinkMax, previously called bandwidth, although in reality this is difficult for browsers to measure so it may be a while before we’re able to use it. You can also attach a change event listener to navigator.connection to be even more responsive.

For a more thorough look at this API and its background, Aurelio De Rosa has written a good tutorial and network information demo which I recommend.

Status

In the browsers I tested only connection.type was supported properly and that was only in Chrome for Android and Firefox Mobile/OS (you may need to ensure dom.netinfo.enabled is set to true). It’s still early days for this API but its simplicity means it could easily be incorporated into your website or app.

Note: There is a version of the spec hosted on w3.org that currently says work on it has been discontinued. This refers to an older version and current work is being done in the GitHub-hosted version, which should eventually migrate to the W3C site.


Ambient Light Events

Why use it

We’re probably all familiar with struggling to read a screen in bright sunlight. Increasing the contrast of what’s displayed on the screen or hiding distracting backgrounds can make content much easier to read in such cases. The opposite is true — reducing how vivid a design is can avoid users screaming and covering their eyes when in a dark environment.

How to use it

Tomomi Imura, AKA @girliemac, has the definitive lowdown on how to respond to differing levels of light. Eventually we’ll all be able to use CSS4 media queries so when the light-level is dim, for example, we can respond accordingly. In the meantime though, there’s the more precise JavaScript approach which gives you access to data from the device’s light sensor. You just listen for a devicelight event and use that event’s value attribute to get the brightness of the user’s surroundings measured in lux. For example:

window.addEventListener('devicelight', function(e) {
  var lux = e.value;

  if (lux < 50) {
    // ambient light is dim so show lower-contrast version
  }
});

See Tomomi's article for a more detailed example with added CSS and a link to her ambient light demo on CodePen.

Status

At the time of writing support is only available in Firefox and Chrome beta for Android but here's a short video of her code in action:


Of course, these are not the only web technologies that are part of responsive web design but if you want to show the world that you know more than just media queries, they're a good place to start.

How to convert videos to WebM with FFmpeg/AVConv

After lots of trial and error each time I convert a video to WebM, I finally got around to posting this so I don’t forget next time. In a nutshell, here’s the conversion command that works for me:

avconv -i myvideo.mp4 -acodec libvorbis -aq 5 -ac 2 -qmax 25 -threads 2 myvideo.webm

What is this doing? Let’s go through it bit by bit. Assuming we have a video called myvideo.mp4, the simplest way to convert to WebM is with this little line:

avconv -i myvideo.mp4 myvideo.webm

Easy, but the quality will likely be rubbish hence the use of a few flags. The flags can be divided into three sorts: audio, video and the transcoding itself.

Audio flags

FFmpeg/AVConv outputConcentrating on the audio first, we should specify the audio codec which for WebM is Ogg Vorbis: -acodec libvorbis

In later versions the audio codec is Ogg Vorbis by default but personally I specify it just in case.

The quality can be adjusted with the -aq flag from -1 to 10 with a higher number meaning better quality. I’ve found 4 or 5 to be more than adequate.

The number of channels, e.g. mono (1) and stereo (2), is controlled with the -ac flag.

Video flags

Moving on to the video quality and thankfully it’s nice and simple. Like the audio, we can specify a quality level. With the libvpx library used for WebM, this is actually a quantization level, set with the -qmin and -qmax flags ranging from 0 to 51. In my tests, setting qmin makes no difference so I ignore it. Setting qmax effectively controls the maximum compression that will be applied to each frame. In other words, a higher qmax means higher compression, which results in lower quality and smaller file size. Obviously you should adjust this to whatever’s best for your circumstances, but I’ve found 25 to be a good starting point.

Note that with both the audio and video, setting flags for bitrate (-ab for audio, -b for video) makes little or no difference. Instead, setting quality flags indicates the use of a variable bitrate.

Transcoding flags

Finally, I tend to also use the -threads flag. This simply sets how many CPU threads to use when transcoding. If your PC has multiple cores then a higher number means faster processing but with less spare capacity for running other programs. Incidentally it’s also possible to do 2-pass encoding with WebM using the -pass flag.

FFmpeg naming confusion

Note that due to what seem to be political reasons, using the ffmpeg command in Ubuntu results in a sad message.

Was:

*** THIS PROGRAM IS DEPRECATED ***
This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.

Now:

ffmpeg: command not found

It turns out that FFmpeg is very much alive, as is Libav (avconv), both with similar goals but with slightly different ways of doing it. I don’t follow the details and arguments but for practical purposes, using either the ffmpeg or avconv command is fine for converting videos to WebM with the above flags (at the time of writing). Of course, this may change eventually but for the sake of regular users, I hope not.

Unfortunately whatever FFmpeg/Libav disagreement there was has resulted in ffmpeg being removed from Ubuntu and possibly other Linux distros. For the transcoding commands in this post at least, the parameters are the same so if you have problems using avconv try with ffmpeg and vice versa.

Free HTML5 template

Official HTML5 logoAfter being asked for a bit of advice by a colleague, I decided to make a very simple starter template for creating an HTML5 page. You can download it here:

Download HTML5 template

Notes

The tricky part is making sure it works in older browsers, for which I used the following two steps:

1. Normalize.css
(Click on “normalize.css” -> “Raw” to get the main CSS file.)

This makes all browsers behave the same way, including making relevant HTML5 elements into block elements. I recommend minifying the CSS to save bandwidth and time.

2. HTML5 Shim

This makes HTML5 elements styleable in old versions of Internet Explorer. Put it after all styles in <head>.

I’ve also added a viewport meta tag as follows which, in most cases, should improve the readability of the page on small screen devices.

<meta name="viewport" content="width=device-width, user-scalable=yes">

Going further

You might want to include Modernizr in your page, to enable you to detect support for newer CSS3 and JavaScript features.

For a much more full-featured template, there’s the popular HTML5 Boilerplate with a host of built-in goodies.

I’d love to hear if this is useful for you or if you have ideas for improvement – let me know in the comments below.

Mailing list of fire

With apologies to Johnny Cash, the sorry tale of a mailing list that takes no prisoners. On a totally unrelated note, how’s HTML5 coming on?

Mailing list of fire on YouTube (with captions): www.youtube.com/watch?v=HCwgKtiu1II

Downloads

For your downloading pleasure, here are the video and audio–only files.

License is Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported. If you need a media player, I recommend VLC.

Lyrics

The web is a wondrous thing.
Flickr, Facebook and Bing.
One thing you must resist.
The pull of the mailing list.

I fell in to a mailing list of fire.
I scrolled down, down, down
and the flames went higher.
And it burns, burns, burns
this list of fire,
mailing list of fire.

And it burns, burns, burns
this list of fire,
mailing list of fire.

A geek, he never forgets.
When someone’s wrong on the internetz.
I tried not to act like a child.
Oh… but the trolls went wild.

I fell in to a mailing list of fire.
I scrolled down, down, down
and the flames went higher.
And it burns, burns, burns
this list of fire,
mailing list of fire.

And it burns, burns, burns
this list of fire,
mailing list of fire.


The HTML5 <ruby> element in words of one syllable or less

Opera colleague Bruce Lawson thought it might be spiffing if the description of the <ruby> element that appears in the HTML5 spec was clarified a bit, so here’s my attempt. I’m using Japanese as an example although it applies to Chinese and possibly other languages as well. Please note my definition of one syllable may differ from yours.

Step 1: The Japanese Writing System

In Japanese there are three alphabets—one semantic (thousands of characters) and two phonetic (roughly 50 each).

The semantic alphabet is called kanji, based on traditional Chinese characters, and each character has a meaning (although sometimes quite abstract). When you read words written with kanji you may understand their meaning but there are no clues as to their pronunciation.

日 = sun
本 = origin
日本 = land of the rising sun = Japan

The first phonetic alphabet is hiragana. This comes from highly stylised Chinese characters developed around the 5th century when only men were educated enough (or deemed intelligent enough) to use Chinese characters (kanji). Literate ladies of the ruling class used the easy-to-write hiragana, each representing one syllable and having no meaning, to write letters, poetry and novels (the original chick lit). When you read words written with hiragana you can pronounce them but you may not know their meaning.

に = ni
ほ = ho
ん = n
にほん = nihon = Japan

The second phonetic alphabet is katakana. This apparently was developed by monks also using Chinese characters as a basis for a highly simplified alphabet. Whereas hiragana characters are more rounded, katakana characters are more sharp and angular. They are used primarily for foreign words that don’t have a Japanese translation (e.g. “browser”) or for making a word stand out or appear modern. Like hiragana, when you read words written with katakana you can pronounce them but you may not know their meaning.

二 = ni
ホ = ho
ン = n
二ホン = nihon = Japan

Any piece of Japanese text (banner ad, article, legal doc, etc.) uses a combination of kanji, hiragana and katakana. It is sometimes the case that people reading the text can’t read the kanji, especially because kanji characters can have more than one pronunciation. People and place names are one example of kanji having numerous or irregular pronunciations.

日 = can be pronounced "nichi", "hi" or "ka"
本 = can be pronounced "hon" or "moto"
日本 = can be pronounced "nihon" or "nippon" = Japan

Step 2: What does this have to do with a pink gemstone?

To help the reader, sometimes the pronunciation is written above the kanji using the hiragana alphabet. This is called furigana in Japanese and ruby in English (from the name of small type with a height of 5.5 points). It is often used in newspapers and books but not so much on websites, due to the difficulty of squeezing miniature text above larger text on a single line. The <ruby> element aims to solve this.

Step 3: Tell us how it works

According to the current HTML5 spec, the <ruby> element is an inline element and is placed around the word or character you’d like to clarify, like so:

<ruby>日本</ruby>

By itself this does nothing, so we add the pronunciation either for each character or, as in this case and my personal preference, for the word as a whole. For this, we use the <rt> tag, meaning ruby text.

<ruby>日本<rt>にほん</rt></ruby>

We could leave it like that and supporting browsers would show the hiragana pronunciation above the kanji text, but non-supporting browsers would ignore the tags and show both the text and its pronunciation side-by-side. To solve this, the masters of the HTML5 universe have given us another tag, <rp> meaning ruby parentheses, which cleverly hides characters (namely parentheses) in supporting browsers. This means we can write the pronunciation in parentheses which non-supporting browsers will show, and supporting browsers will continue to show the pronunciation without parentheses above the main text.

<ruby>日本<rp>(</rp><rt>にほん</rt><rp>)</rp></ruby>

Step 4: Say what?

  • Supporting browsers → ruby text is shown above main text
  • Non-supporting browsers → ruby text is shown next to main text but in parentheses.

Text using the HTML5 ruby element.

Overall, the <ruby> element is a great help not just for learners of Japanese (or Chinese, etc.) but also for when uncommon characters are used in a piece of text. It could also be used in any language simply for clarifying a term or unfamiliar concept in an unobtrusive and accessible manner.

For reference:

HTML5 Doctor Oli Studholme has written a much more thorough <ruby> explanation with examples of usage in other languages.

Also, see this page for an example of how hiragana.jp uses the <ruby> element (and CSS for non-supporting browsers) to provide ruby text above all kanji words. Perfect for people learning to read Japanese. Note that they also use the <rb> tag to markup the kanji words but at the time of writing this is not officially part of HTML5.

How to create Ogg videos in Linux (with GUI)

Following up on my previous post about converting videos to Ogg Theora, there’s also an easy way for those who like a GUI.

Screenshot of the OggConvert programAlthough it’s possible to use VLC for Ogg encoding, I had problems with the audio and video being out of sync. Fortunately I found another way – enter OggConvert.

Written in Python by Tristan Brindle, there are packages for the major Linux distributions as well as a version for Windows. Not only that, it’s open source (GNU LGPL), preserves metadata when converting and is extremely easy to use:

  1. Fire up OggConvert
  2. Select the source video (or audio) file
  3. Click convert
  4. Voila! Enjoy your Ogg video

By default, the target file is saved in the same directory and with the same name as the source file but with an .ogg or .ogv extension. The default quality settings seem a bit low but should be adequate for most purposes.

When done, your Ogg video is now ready to use in your HTML5 pages:

<video src="video.ogg" width="320" autobuffer controls>
  <p>Sorry, your browser can't play this video but you can
  <a href="video.ogg">download it here</a>.</p>
</video>

How to create Ogg videos in Linux

Ogg Theora is the codec most supported by modern HTML5-capable browsers, so how can you convert your videos to it? Pretty easily, it seems.

There’s a cross-platform command-line application called ffmpeg2theora which does a good job of converting videos to Ogg Theora. Usage couldn’t be simpler:

ffmpeg2theora input.mpeg

If the audio is out of sync with the video, either try adding the –sync option or convert it to MPEG format using ffmpeg first, and then use ffmpeg2theora.

For those all-important tags (except ‘comment’) you can use parameters like so:

ffmpeg2theora input.mpeg --title "My spiffing video" --artist "Daniel" --license "http://creativecommons.org/licenses/by-nc-sa/3.0" --date "2010" --organization "Opera Software" --location "Tokyo, Japan" 

Or alternatively there’s oggz, available in the oggz-tools package in Ubuntu:

oggz-comment input.ogv TITLE="My spiffing video" ARTIST="Daniel" LICENSE="http://creativecommons.org/licenses/by-nc-sa/3.0" DATE="2010" ORGANIZATION="Opera Software" LOCATION="Tokyo, Japan" COMMENT="Best viewed on a screen" -o output.ogv

To embed your converted video in an HTML5 page, use something like this:

<video src="video.ogv" autobuffer controls>
    <p>Your browser can't display the open Ogg Theora codec but you can download it from here: <a href="video.ogv">Video</a></p>
</video>

N.B. For Mac, there’s Exom which has ‘HTML5′ as one of its output options (thanks Bruce).

UPDATE: If you’d prefer to not use the command line, there’s a GUI alternative for easy Ogg conversion.

HTML5 it is a-changin’

Off sick with a cold, what better way to recover than by singing a song?

A performance, requested by Futomi Hatano, of the tune by Bob Dylan with lyrics by Jeff Allen, suggested by Molly Holzschlag and inspired by Shelley Powers.
Details and lyrics: http://www.molly.com/2010/01/05/bob-dylan-meets-html5

Video URL (with captions): www.youtube.com/watch?v=V2s8AU8PkBU

Downloads

For your downloading pleasure, here are the video and audio–only files:

License is Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported. If you need a media player, I recommend VLC.

Update

Customers who viewed this item also viewed:

Artist: Bruce Lawson
Video URL: www.youtube.com/watch?v=7gNmFabAOGc

Opera’s (potential) HTML5 compliance

With HTML5 on its way I thought I’d take inspiration from http://www.w3.org/QA/2008/09/top-500-html5-validity.html who in turn took inspiration from Opera’s QA team and test the front page of a few of Opera’s websites for HTML5 conformity.

Firstly, an important caveat. The HTML5 validator is beta so may have erroneously missed or mis-detected issues. In addition, at the time of writing HTML5 is still a working draft only and public websites should not be expected to support it yet. Not being valid HTML5 means nothing unless the document’s doctype indicates that it’s HTML5, which none of them do at this stage. This is just intended to be a (hopefully educational) “what if” exercise. Having said that, several sites didn’t even validate against current standards – I’m looking at you list.opera.com, widgets.opera.com, bugs.opera.com, portal.opera.com, labs.opera.com and irc.opera.com!

So onto the HTML5 validation results, in no particular order:

HTML5 validator result

This is all academic until we see what errors were found and how to correct them, in other words, what are some of the common changes from HTML 4 to 5 that we may encounter in our own websites?

Not surprisingly, the majority are a result of presentation and markup being strictly separated at last. The following were encountered in this exercise:

  • Attribute size not allowed on element input.
  • Attributes bgcolor, link, alink, vlink not allowed on element body.
  • Attribute width not allowed on element table or td.
  • Attribute border not allowed on element table or img.
  • Attribute bgcolor not allowed on element table, tr or td.
  • Attributes cellspacing and cellpadding not allowed on element table.
  • Attribute align not allowed on element td or div.
  • The center, font and big elements are obsolete.

CSS is the place for presentational items such as these.

Other HTML5-specific errors were mostly as follows:

  • Attribute accesskey not allowed on element a.
  • Attribute name not allowed on element a. (Use id)
  • No whitespace allowed in paths/URIs. (Use %20)
  • The acronym element is obsolete. (Use abbr)
  • Bad values content-type and cache-control for attribute http-equiv on element meta.

Admittedly this only uses Opera’s websites as an example and they are more compliant than most, but I was still surprised at how little work would be needed to make any of these valid HTML5. I wonder if the folks at snapshot.opera.com know they’re already ahead of the game?