Archives - November, 2011



30 Nov 11

Itorian - Razor View Engine in MVC 3 "In this e-book you will learn all about Razor View Engine introduced in MVC 3. I will walk through the simple steps and even I will keep my ideas simple so that you can understand the Razor View Engine better. My aim through this e-book is to teach Razor so I am going to play a little loose with rest all.

Filed under: Reviews

Trackback Uri






29 Nov 11

We’ve been able to play video in the browser without a plugin for a couple of years now, and whilst there are still some codec annoyances, things appear to have settled down on the video front. The next step is adding resources to the video to make it more accessible and provide more options to the viewer.

We currently have no means to provide information about what’s happening or being said in the video, which means the video isn’t very accessible and the user can’t easily navigate to a particular section of the video. Thankfully, there’s a new format specification in the works called WebVTT (Web Video Text Tracks). As of now, it’s only in the WHATWG spec, but the recently established W3C Web Media Text Tracks Community Group should introduce a WebVTT spec to the W3C soon.

You may recall a similar format called WebSRT (Web Subtitle Resource Tracks) that was recently under discussion. WebSRT was renamed to, and has been replaced by, WebVTT.

A WebVTT (.vtt) file is simply plain text containing several types of information about the video:

Subtitles
The transcription or translation of the dialogue.
Captions
Similar to subtitles, but may also include sound effects and other audio information.
Descriptions
Intended to be a separate text file that describes the video through a screenreader.
Chapters
Intended to help the user navigate through the video.
Metadata
Information and content about the video, which isn’t intended to be displayed to the viewer by default, though you may wish to do so using JavaScript.

This article will mostly be talking about subtitles and captions, but it will briefly touch on chapters too.

Beyond the scope of this article but worth mentioning is the text track API, which, amongst other things, denotes how many text tracks there are and which ones have loaded and are ready for use. If you have used this API, let us know.

How to Make and Link to a WebVTT file

All you need to make a WebVTT file is a simple text editor. Type WEBVTT as the first line of the file and save it as a .vtt file. In the future, we expect existing captioning tools such as Universal Subtitles to export to WebVTT format.

WEBVTT
The simplest possible valid WebVTT file

That’s all you need to get started. Next, we have to link to the file in the HTML document. We do this via the <track> element, which is a child of the video element. The <track> element has several optional attributes:

  • the source WebVTT file (src),
  • the language of the track (srclang),
  • a user-readable label, and
  • what kind of track it is. The values of the kind attribute come from the list above (i.e., subtitles, captions, etc.).

In the following example, we’re using a <track> element for subtitles:

<video width="640" height="480" controls>
  <source src="video.mp4" type="video/mp4" />
  <source src="video.webm" type="video/webm" />
  <track src="subtitles.vtt" kind="subtitles" srclang="en" label="English" />
  <!-- fallback for rubbish browsers -->
</video>

A few notes about the attributes:

  • If no kind is specified, the default is subtitles.
  • If the kind is subtitles, then srclang is required.
  • There should not be two tracks of the same kind with the same label.

In the above example, we use a <video> element with two different <src> elements (for cross-browser loveliness). After the sources comes the <track> element. You can have several <track> elements as you might have subtitles, captions, and descriptions all in different languages.

<track> doesn’t presuppose a particular file format. Microsoft supports the TTML format, but this format will not be implemented by other browser vendors.

WebVTT Contents

We now know how to make a WebVTT file and how to reference it in an HTML document, but what goes inside it? Within the file, we list what are known as “cues”. The WebVTT file might only have one cue, but it can contain as many as you want. Each cue starts with an ID, followed by the time settings, followed by the text. Each cue is separated by a blank line. Here’s an example of captions:

WEBVTT

1
00:00:01.000 --> 00:00:10.000
This is the first line of text, displaying from 1-10 seconds

2
00:00:15.000 --> 00:00:20.000
And the second line of text
separated over two lines
WebVTT example content

The above example has two cues. Times must be written in hh:mm:ss.mmm format, so the timings in this example occur in the first twenty seconds. The second cue will split the text over two lines automatically.

If you have a segment of text that needs to appear in a karaoke/paint-on caption style, then you can place timers inline with text:

1
00:00:01.000 --> 00:00:10.000
Never gonna give you up <00:00:01.000> Never gonna let you down <00:00:05.000> Never gonna run around and desert you
Karaoke-style captioning

Styling Options

The previous examples specify the minimum configuration you need for subtitling and captioning, but you can style your captions too. Let’s start with the cue settings, which are done on the same line as the time settings:

D:vertical / D:vertical-lr
Display the text vertically rather than horizontally. This also specifies whether the text grows to the left (vertical) or to the right (vertical-lr).
L:X / L:X%
Either a number or a percentage. If a percentage, then it is the position from the top of the frame. If a number, this represents what line number it will be.
T:X%
The position of the text horizontally on the video. T:100% would place the text on the right side of the video.
A:start / A:middle / A:end
The alignment of the text within its box – start is left-aligned, middle is centre-aligned, and end is right-aligned.
S:X%
The width of the text box as a percentage of the video width.

To make use of these settings, put them alongside the time settings, like this:

00:00:01.000 --> 00:00:10.000 A:middle T:50%
00:00:01.000 --> 00:00:10.000 A:end D:vertical
00:00:01.000 --> 00:00:10.000 A:start T:100% L:0%

which would result in something like the following:

Examples of subtitle display

Examples of subtitle display and alignment

Along with the above cue settings, you can use inline styles for text:

Bold text
<b>Lorem ipsum</b>
Italic text
<i>dolor sit amet</i>
Underlined text
<u>consectetuer adipiscing</u>
Ruby text
<ruby>見<rt>み</rt></ruby>

You can even apply a CSS class to a section of text using <c.myClass>Lorem ipsum</c>, giving us many more styling options.

Finally, you can add a declaration representing the name of the voice: <v Tom>Hello world</v>. This declaration accomplishes three things:

  1. The caption will display the voice (Tom) in addition to the caption text.
  2. The name of the voice can be read by a screenreader, possibly event using a different voice for male or female names.
  3. It offers a hook for styling so that, for example, all captions for Tom could be in blue.

Chapters

You can provide a chapter list for the video the same way you would provide subtitles or captions. Start with the same WEBVTT declaration, and then for each cue, declare the chapter number, the start and stop times, and the chapter title:

<track src="chapters.vtt" kind="chapters" srclang="en" />
HTML <track> element for providing chapters to a video
WEBVTT

Chapter 1
00:00:01.000 --> 00:00:10.000>
Introduction to HTML5
WebVTT file containing video chapter markers

Browser Support

One slight glitch with WebVTT: not a single browser currently supports it. All major browsers have started working on implementations, so we should see some results soon. Thankfully, in the meantime, there are several JavaScript polyfills available:

Demo

We’ve put together a quick demo which uses the Playr polyfill. We started using MediaElementJS, but it doesn’t sport as many features as Playr, such as separate lines of text and CSS classes. In the demo, the subtitles start at 2 seconds and 15 seconds and use bold, underline, and custom styles. Here’s the associated WebVTT file.

Conclusion

This article covers the basics of creating a WebVTT file suitable for subtitles or captions for a video. We know how to add cues and chapters and how to add styles and change how the text appears on the video. Although no browser yet supports it, there’s a lot more to come for accessible video, so stay tuned to the W3C Web Media Text Tracks Community Group.

What are your thoughts on WebVTT? Are any of you using it now? How can it be improved?

Finally, let’s thank @silviapfeiffer for taking the time to answer some questions about WebVTT and for her tremendous work in this field.

Reading

Video Subtitling and WebVTT originally appeared on HTML5 Doctor on November 29, 2011.


Filed under: Web Development

Trackback Uri






29 Nov 11

A List Apart strongly opposes United States H.R.3261 AKA the Stop Online Piracy Act (SOPA), an ill-conceived lobbyist-driven piece of legislation that is technically impossible to enforce, cripplingly burdensome to support, and would, without hyperbole, destroy the internet as we know it. SOPA approaches the problem of content piracy with a broad brush, lights that brush on fire, and soaks the whole web in gasoline. If passed, SOPA will allow corporations to block the domains of websites that are “capable of” or “seem to encourage” copyright infringement. Once a domain is blocked, nobody can access it, unless they’ve memorized the I.P. address. Under SOPA, everything from your grandma’s knitting blog to mighty Google is guilty until proven innocent. Learn why SOPA must not pass, and find out what you can do to help stop it.

Filed under: Design

Trackback Uri






29 Nov 11

CSS’ simplicity has always been one of its most welcome features. But as our sites and apps get bigger and become more complex, and target a wider range of devices and screen sizes, this simplicity—so welcome as we first started to move away from font tags and table-based layouts—has become a liability. Fortunately, a few years ago developers Hampton Catlin and Nathan Weizenbaum created a new style sheet syntax with features to help make our increasingly complex CSS easier to write and manage—and then used a preprocessor to translate the new smart syntax into the old, dumb CSS that browsers understand. Learn how Sass (“syntactically awesome style sheets”) can help simplify the creation, updating, and maintenance of powerful sites and apps.

Filed under: Design

Trackback Uri






29 Nov 11

There’s no need to explain what a tooltip is and you already know that using tooltips can help you increase usability. Therefore, in this article we’ll concentrate just on the practical side.

So, today you’ll learn how to create awesome CSS3 & jQuery tooltips.

View demo

You may already read my previous CSS3 tooltips tutorial, but this time we’ll use some jQuery and HTML5 data-* attributes for our tooltips.

The major advantages of these tooltips are:

The HTML

As you can see below, thanks to the new HTML5 custom data attributes, our tooltip structure looks as clean as possible:

<b data-tooltip="Fantasy Action Adventure">Batman: Arkham City</b>

Easy CSS3 & jQuery tooltips - preview

The CSS

Here are the styles used in order to create this 3D looking tooltip:

.tooltip {
	position: relative;
	display: inline-block;
	cursor: help;
	white-space: nowrap;
	border-bottom: 1px dotted #777;
}

.tooltip-content {
	opacity: 0;
	visibility: hidden;
	font: 12px Arial, Helvetica;
	text-align: center;
	border-color: #aaa #555 #555 #aaa;
	border-style: solid;
	border-width: 1px;
	width: 150px;
	padding: 15px;
	position: absolute;
	bottom: 40px;
	left: 50%;
	margin-left: -76px;

	background-color: #fff;
	background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,.1)), to(rgba(255,255,255,0)));
	background-image: -webkit-linear-gradient(rgba(0,0,0,.1), rgba(255,255,255,0));
	background-image: -moz-linear-gradient(rgba(0,0,0,.1), rgba(255,255,255,0));
	background-image: -ms-linear-gradient(rgba(0,0,0,.1), rgba(255,255,255,0));
	background-image: -o-linear-gradient(rgba(0,0,0,.1), rgba(255,255,255,0));
	background-image: linear-gradient(rgba(0,0,0,.1), rgba(255,255,255,0));
	-moz-box-shadow: 1px 1px 0 #555,
				2px 2px 0 #555,
				3px 3px 1px rgba(0, 0, 0, .3),
				0   1px 0   rgba(255,255,255, .5) inset;
	-webkit-box-shadow: 1px 1px 0 #555,
				2px 2px 0 #555,
				3px 3px 1px rgba(0, 0, 0, .3),
				0   1px 0   rgba(255,255,255, .5) inset;
	box-shadow: 1px 1px 0 #555,
				2px 2px 0 #555,
				3px 3px 1px rgba(0, 0, 0, .3),
				0   1px 0   rgba(255,255,255, .5) inset;
	-webkit-transition: bottom .2s ease, opacity .2s ease;
	-moz-transition: bottom .2s ease, opacity .2s ease;
	-ms-transition: bottom .2s ease, opacity .2s ease;
	-o-transition: bottom .2s ease, opacity .2s ease;
	transition: bottom .2s ease, opacity .2s ease;
	}

.tooltip-content:after,
.tooltip-content:before {
	border-right: 16px solid transparent;
	border-top: 15px solid #fff;
	bottom: -15px;
	content: "";
	position: absolute;
	left: 50%;
	margin-left: -10px;
}

.tooltip-content:before {
	border-right-width: 25px;
	border-top-color: #555;
	border-top-width: 15px;
	bottom: -15px;
}

.tooltip:hover .tooltip-content{
	opacity: 1;
	visibility: visible;
	bottom: 30px;
}

The jQuery

Basically, the jQuery code does all the “dirty” job for you. Using the HTML5 data-tooltip attribute value, it appends a new HTML node: <span class="tooltip-content"> which will be animated using CSS3.

$(document).ready(function(){
	$('[data-tooltip]').addClass('tooltip');
	$('.tooltip').each(function() {
		$(this).append('<span class="tooltip-content">' + $(this).attr('data-tooltip') + '</span>');
	});

	if ($.browser.msie && $.browser.version.substr(0,1)<7)
	{
	  $('.tooltip').mouseover(function(){
			$(this).children('.tooltip-content').css('visibility','visible');
		  }).mouseout(function(){
			$(this).children('.tooltip-content').css('visibility','hidden');
		  })
	}
});

IE6 gets some extra treatment, as you can see above.

Browser support

As usual, this demo also works across all major browsers:

View demo

That's all

I hope that you enjoyed this tutorial and if you have any comments or questions feel free to add them below. Thanks for reading!


Filed under: Design,Usability

Trackback Uri






25 Nov 11

This Friday, November 25, 2011, mastering the art of JavaScript performance got cheaper! Use code TURKEY to get over 50% off my JavaScript Performance Rocks! Ebook and get it for only $19! Enjoy! P.S. We have a few more seats available for our November 28/29 JavaScript Master Class. See you there?

Filed under: Web Development

Trackback Uri






25 Nov 11

ISBN or ASIN:  0321718380 Book Author(s):  Dan Rubel Jamie Wren Eric Clayberg Publisher:  Addison-Wesley ...

Filed under: Reviews

Trackback Uri






23 Nov 11

Cue
PJ recently took another stab at making gesture icons more comprehensible and released Cue under Creative Commons. It’s a proposed system for representing gestures more clearly that makes use of thumb like icons. He explains his motivation for the project in a blog post as well. The icons come in PNG (4 sizes), SVG, Omnigraffle and InDesign formats. Awesome. It’s always great to see explorations in visual language. Thanks PJ!

Here is how he puts it:

These gesture icons act as roadsigns to an app for interaction way-finding. As expected, there has been a significant collection of gesture icon sets that have been made available to fill this need. The current crop of icons succeed in clarity, but they lack the iconic qualities necessary to act as a standard representation of gestures. My goal is to help create a foundational set of icons that are flexible, clear and distilled to a point where they could become a standard visual system to build from – ultimately to be used within apps for when explicit communication is needed.

Credits: PJ Onori


Filed under: Design,Web Development

Trackback Uri






15 Nov 11

Until recently, we developers couldn’t to do much with the state and history of the browser. We could check the number of items in the history and push users forwards and backwards, but this provides little benefit to the user. With the rise of more dynamic web pages, we need more control. Thankfully, HTML5 gives us that control by extending the JavaScript History API.

What’s the point?

It goes without saying that URLs are important. They’re the method of accessing the vast collections of information and resources on the web, and more recently, they’ve begun representing the intended state of a web application. You can copy these URLs and share them with your friends or use them to create links from any HTML document. They’re the veins of the web, and they need to be looked after.

Previously, the JavaScript History API offered some very simple functionality:

// Check the length of the history stack
console.log(history.length);

// Send the user agent forward
console.log(history.forward());

// Send the user agent back
console.log(history.back());

// Send the user agent back (negative) or forward (positive)
// by a given number of items
console.log(history.go(-3));

With dynamic Ajax web applications, where the browser updates the page in parts instead of changing location entirely, it’s difficult to give the user a URL to bookmark or share the current application state. Fragment identifiers, like those used on this article’s headings via the id attribute, provide some state information, but they’re entirely dependent on client-side scripts.

The changes to the History API are intended to give developers ways to push history items to the browser so the native back and forward actions can cycle through those items. These history items can also hold data that you can later extract to restore the page state.

Pages can add state objects between their entry in the session history and the next (“forward”) entry. These are then returned to the script when the user (or script) goes back in the history, thus enabling authors to use the “navigation” metaphor even in one-page applications.

If the user copies or bookmarks a stateful URL and visits it later, your back-end can be configured to interpret such a URL and jump the user right to the correct page and/or state.

In this article, I’ll cover the client-side use of the History API, so make sure you set up your server to work with the new URLs. If you’ve already built an accessible website that provide these entry points, you’re laughing!

Those f#!king hashbangs…

You may have already seen articles fussing over the adoption of the “hashbang” (#!) pattern on sites like Twitter. This technique updates the address bar with a fragment identifier that can then be used by JavaScript to determine which page and state should be displayed.

This works as a method of creating a bookmarkable, shareable URL for a page’s state in the absense of a standard API. While the Twitter implementation accepts both http://twitter.com/#!/akamike and http://twitter.com/akamike, it has some disadvantages:

  • The fragment identifier is only accessible on the client side. This means that only JavaScript can utilise it, so browsers without JavaScript enabled are out of luck.
  • As the server does not receive the path following the hashbang, removing that JavaScript drops support for all those URLs. That’s a lot of broken links, so you’re stuck with that JavaScript forever.
  • It’s ugly. It’s a hack and it looks like one.

The hashbang was never intended to be a long-term solution, so don’t rely on it. If you do use hashbangs, be prepared to deal with the consequences (and possible backlash from web purists).

Making History

These examples will build on top of each other. We’ll start with a basic HTML document with some inline styles and scripts for your convenience.

Save this file and open it in your favourite editor. It must be accessed via HTTP, so that means you need either a local server (e.g. http://localhost/) or an online web server you can upload to. Viewing the file directly using your browser’s Open File function will not work, since it uses the file:// protocol and not HTTP. Also be sure to update the href attributes on each of the navigation links to ensure the correct directory structure is used. Personally, I’m viewing the demo locally at http://localhost/history.

We’ll be working exclusively within the <script> element at the end of the <body>. The code includes some simple styles and dynamically changes the content as you click the links. In reality, this could be loaded from your server via XMLHttpRequest, but for the purposes of this demonstration I’ve bundled it up into a self-contained file. The important part is that we have a quick-and-dirty dynamic page to work with, so let the fun begin!

At the moment there, is no bookmarkable URL for the different states of this page. If you click around the navigation items, then click Back in your browser, you won’t be taken back to the previous state and may even be taken away from the page to whatever you viewed before (depending on your browser). It would be nice if you could share “Socks” with your friends, right? We can do that via history.pushState().

The history.pushState() method takes three parameters:

data
Some structured data, such as settings or content, assigned to the history item.
title
The name of the item in the history drop-down shown by the browser’s back and forward buttons. (Note: this is not currently supported by any major browsers.)
url (optional)
The URL to this state that should be displayed in the address bar.

With these parameters, you can define the state of the page, give that state a name, and even provide a bookmarkable address, as if the page had reloaded entirely. Let’s dive right in and add this to the clickHandler function, right above the return statement:

function clickHandler(e) {
  /* Snip... */

  // Add an item to the history log
  history.pushState(data, event.target.textContent, event.target.href);

  return event.preventDefault();
}

The single line of code we added informs the history object that:

  • we want to add an item to the log,
  • it should remember the data that we’ve already loaded,
  • it should assign a name to this state based on the text of the link we clicked (even though this isn’t used — it’s good to get into the habit of recording a name for the state), and
  • it should update the address bar with the href attribute of that link.

Reload the page in your browser and click a few of the links, keeping an eye on the address bar. Notice how it changes on each click, despite the fact that you aren’t actually navigating away from this page. If you also have a look at your history log, you’ll see a long list of page titles (in this case ”Kittens!” over and over). Provided your server is set up to serve the correct page upon access, the user could copy that URL and paste it into a new browser window to jump straight to that kitten.

At the moment, clicking the back button will pop you through the history items, but the page won’t react to these changes. That’s because so far, we’ve only created the history records. How can we allow active users to return to a previous state? We listen to the popstate event.

Historical Events in Navigation

The user agent fires a popstate event when the user navigates through their history, whether backwards or forwards, provided it isn’t taking the user away from the current page. That is, all those pushStates we called will keep the user on the current page, so the popstate event will fire for each history item they pop through.

Before the closing </script> tag, add a new listener for the popstate event:

// Revert to a previously saved state
window.addEventListener('popstate', function(event) {
  console.log('popstate fired!');

  updateContent(event.state);
});

We attach the event listener to the window, which is responsible for firing the event, and pass this event into our handler. We log a message (so we can see when this event is firing), and then we update the content using the state we saved previously. The state is attached to the event object via the state property.

Open up the page fresh in your browser, click around like before, and then click back. As before, the URL in the address bar changes as you cycle through states, but now the content is also restored back to what it should be. Click forward, and the content is likewise correctly restored.

If you look at the developer console in Chrome when you load the page for the first time, you’ll see the popstate event fired immediately, before you’ve even clicked a link. This is because Chrome considers the initial page load to be a change in state, and so it fires the event. In this instance, the state property is null, but thankfully the updateContent function deals with this. Keep this in mind when developing as it could catch you out, especially if other browsers assume this behavior.

Rewriting history

Unfortunately, as fantastic as HTML5 is, it doesn’t allow us actual time travel. If it did, I would be going back to my childhood and telling a younger me, “Yes, you should have a slice of cake”. Take that as you will.

The History API does, however, allow us to make amends to our history log items. For example, we could update the current state in response to fresh user input in a form. We can do this with history.replaceState.

replaceState works just as pushState does, with the exact same parameters, except that it updates the current entry instead of adding a new one. I can think of one situation in our demo where this could be used: the initial page load. If you click back for long enough, you’ll find that going back to the original URL doesn’t provide you the original content. Let’s fix that by adding the following to the bottom of our script:

// Store the initial content so we can revisit it later
history.replaceState({
  content: contentEl.textContent,
  photo: photoEl.src
}, document.title, document.location.href);

As this runs when the page loads, it saves the initial page state. We can later load this state when the user browses back to this point via the event listener we set up previously. You can try it out by loading up the page, clicking a few links, and then hitting back until you return to the original URL. The initial content has returned!

Demo

I’ve set up a demo of our completed code. I’ve also added a little back-end magic to make our history.pushState URLs work like a real site. Remember that the URLs you push should be live URLs that the user can bookmark and share as real entry points to your site.

View the History API demo

Browser support

Up-to-date copies of Chrome (5+), Safari (5.0+), Firefox (4.0+), and Opera (11.50+) have support for the new History API. Even some mobile browsers work just fine, like Mobile Safari on iOS 4+. Unfortunately, IE 9 and below lack support, but it should work in IE 10 when it arrives.

Safari 5.0 sometimes exhibits one oddity: navigating between states causes the loading spinner to appear and stay even when the state has been loaded. This stops when you navigate away using a link or action that does not involve a state saved by the History API.

Polyfill

A polyfill does exist for the History API. The aptly named History.js uses HTML4’s hashchange event with document fragment identifiers to mimic the history API in older browsers. If one of the hash URLs is used by a modern browser, it uses replaceState to quietly correct the URL.

It sounds like magic, but make sure you’re aware of the consequences of using fragment identifiers, as mentioned previously in this article. As such, the author of History.js has put together a guide titled Intelligent State Handling.

Closing thoughts

URLs go beyond just the browsing session of a user. They’re historically important markers for resources that could very well remain in use for many years to come. Before you embark on developing your site’s JavaScript, you should give thought to the design of your URLs. Make them meaningful and organised. Make sure you can directly access them without JavaScript. Only then should you add your JavaScript to enhance the browsing experience.

Pushing and Popping with the History API originally appeared on HTML5 Doctor on November 15, 2011.


Filed under: Web Development

Trackback Uri