HTML5 Reset Debug

December 3, 2010 | HTML/CSS | Comments Off on HTML5 Reset Debug

I’m a huge fan of using HTML Reset, originally created by Eric Meyer and given HTML5 updates by people like Richard Clark.

The only problem is that when you try to use Firebug, WebKit inspector, IE Developer Tools, or Opera Dragonfly, you get tons of declarations. Ever seen something like this?

HTML Reset Production

Continue Reading…

HTML Table to JSON

May 5, 2010 | HTML/CSS, JavaScript | 6 Comments

I am updating a tool that allows users to customize a large data table to their needs. It’s sort of like a progressive insurance for seminaries in that it helps students compare information on about 30 US seminaries so they can make an informed decision about where to go.

My initial approach when I built it 4-5 years ago was to embed JSON data in the HTML page and then use JavaScript to convert that JSON data into a table based on the user’s choices.

But there are a few problems with this approach.

  1. The data is not accessible to screen readers.
  2. The data is not accessible to those without JavaScript
  3. Embedding a lot of JSON data in an HTML page isn’t a very good idea. It should be a separate cached .js file, but I can’t do

    that since the data often changes and it still wouldn’t address #1 and #2

So I’ve decided in the new version to start with a large <table> and then turn that table into JSON data using the <thead> region as the JSON labels. Then I can take that data and customize it based on the user’s choices. Interestingly the overall data size is a bit smaller since writing a <td> and </td> for each peice of information is actually smaller than writing the header name and quotes over and over.

Here’s the simple table to JSON code. It assumes the first row is has header names and removes spaces and lower cases it.

function tableToJson(table) { 
var data = []; // first row needs to be headers var headers = []; 
for (var i=0; i<table.rows[0].cells.length; i++) {
 headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,''); 
} 
// go through cells 
for (var i=1; i<table.rows.length; i++) { 
var tableRow = table.rows[i]; var rowData = {}; 
for (var j=0; j<tableRow.cells.length; j++) { 
rowData[ headers[j] ] = tableRow.cells[j].innerHTML; 
} data.push(rowData); 
} 
return data; 
}

Below are links to the two pages for comparison. Please note that the site where the “new” page is is still a work in progress and won’t be launched for a month or two.

HTML5 Video Player with Slides and Transcript

April 26, 2010 | HTML/CSS, JavaScript, Video | 7 Comments

A few weeks ago I created an HTML5 version of DTS’s online video player application. A few years ago, when Flash 9 enabled H.264 playback, we switched all of our video from the FLV format to MP4s encoded with the H.264 codec so that our videos could work on as many places as possible, especially Apple’s iPod and iPhone.

I didn’t initially plan to work the the HTML5 <video> tag because of all the browser support and formatting issues, but with the advent of the iPad and IE9’s support for H.264 it makes sense to start using it. I wish that Firefox would support H.264 as well or at least fall back helpfully, but until it does, we will only support Webkit and IE9.

The Player

The player begins in a landscape format with a small video frame and larger slides, but it can also switch to portrait mode and an alternate layout by clicking on the buttons in the lower right. On an iPad, it automatically sense the orientation and rotates accordingly.

Portrait Version

The Code

To code the player, I build a generic MediaPlayer JavaScript object which abstracts out several HTML5 JavaScript APi methods and events. Other than handling HTML5 Media Events, the main thing it does is store and fire Time Cue events much like Flash’s MediaPlayer API (see addASCuePoint). This allows me to add events for syncing the transcript and slides and also handling the UI for controls. On top of the core MediaPlayer object, I built a DtsController which handles choosing a class and building the visual environment for slides and transcript. The timing code looks like this:

player.addCuePoint(‘event-title’, 66); player.addEventListener(‘cuepoint’, function (e) { console.log(‘fired’, e.name, e.time); });

To keep it relatively lightweight, I didn’t use a library like jQuery, but instead used HTML5’s document.querySelector and some custom animation methods to achieve the scrolling and fading effects. I only wish it were as elegant as Thomas Fuch’s emile library.

Try it Out

If you’re interested in the player or the code head to (using a WebKit browser like Safari or Chrome)

http://my.dts.edu/player-html5

Hopefully, the next preview of IE9 will enable the HTML5 <video> tag and let me clean it up for the final version of IE9. Once that happens, we’ll abandon the Flash version of the player and go completely HTML5.

Optimizing CSS with Base64 Embedded Images (with Bonus Utility!)

January 26, 2010 | HTML/CSS, Utilities | 11 Comments

 

As I design a new site (current site | early demo of new site), I am working through what combination of technologies (CDN, sprites, caching, gzipping, etc.) we want to use to optimize it. One tool I’m looking at is embedding images in CSS with base64 strings. Instead of the browser needing to make several calls, one for the CSS file and then one for each image, base64 embedding means that all of the images are embedded within the CSS file itself.

It’s great for small images or images that only show up on :hover or mouseover and you don’t want there to be any delay in the image appearing. Here’s what it looks like:

Normal CSS

.myclass {
width: 45px;
background: transparent url(myimage.jpg) top left no-repeat;
}

CSS with Base64 Embedded Image

.myclass {
width: 45px;
background: transparent url(data:image/png;base64,LONG-STRING-OF-BASE64-TEXT) top left no-repeat;
}

Problems with Base64

  1. Works in all browsers except IE6 and IE7. Solution: use a conditional comments to give IE6/7 a stylesheet that still references the images.
  2. Base64 is bigger than real images: In my tests a base64 encoded string image is somewhere around 150% the size of a regular image. This means it’s unusable for large images.
  3. Hard to manage: If you change the image, you’ll need to reembed the base64 string. You also have to maitain a separate IE stylesheet.

How to manage it

To help figure out which images were worth embedded and help

manage it, I developed a small utility that analyzes a CSS file and allows you to select which images you want to embed. You can also preselect them by adding a comment somewhere within your CSS declaration that says /*embed*/

What It Does

  • Finds all image URLs in your CSS file (note: no CSS3 multiples or borders)
  • Shows the size difference between the image and the base64 string
  • Shows the final size output size and the GZipped size for comparison to the original
  • Removes comments and whitespace if you want
  • Creates a new base64 stylesheet and a IE6/7 stylesheet with references to the original image

Download

Refactoring the JavaScript Color Picker – Step 1: Clean up the HTML and CSS

November 19, 2009 | HTML/CSS, JavaScript | 10 Comments

On of the most popular posts on this blog was a color picker (demo) I created about 4 years ago and then released 2 years ago. It was based on the Prototype library which at the time was the only major mega-JavaScript library. Since then, others have ported the color picker to jQuery, MooTools, YUI, and other libraries, and it’s popularity can be seen by searching for “javascript color picker” on Google.

The Original Color Picker (mimics Photoshop)

Color Picker Example

Rebuilding Goals

If the original color picker was popular, it was because of it’s functionality, not so much pretty code. So, I’d like to rebuild the color picker with a few goals in mind:

  1. Be library independent – I’ll have to add a little bit of extra code for things like event management, but this will allow it to work for everyone.
  2. Small and fast – The original JavaScript isn’t too slow, but the color picker uses lots of separate images (27!). Originally, I hid these inside a <div> so that the browser would keep them cached, but I’d like to combine them into a few sprites to speed up the load time.
  3. Clean up the HTML/CSS – The original has a lot of inline styles and unnecessary complexity, making it ugly and unwieldy.
  4. Clean up the JavaScript – The original code separated out some functionality which makes it harder to figure out what’s going on. I plan bring these together, so that I have one class for color conversion, one class for slider functionality, and one class for the color picker. The new code will also include code to function as a plugin to the major existing libraries (jQuery, Prototype, Mootools, YUI, etc.).

The first big step is to clean up the HTML and CSS. To get a feel for the old HTML/CSS, check out the version 1 example page. Here’s what I’ve come up with so far:

Color Picker CSS

.color-picker
    { border: 0; padding: 0; margin: 0; font-family: Tahoma; font-size: 12px;}
.color-picker table, .color-picker td
    { border: 0; margin: 0; padding: 0; vertical-align: top;}   
.color-picker label
    { margin: 4px 0; display: block;}
.cp-container
    { position: relative; float: left; border: solid 1px #000; padding: 0px; }
.cp-layer1, .cp-layer2, .cp-layer3, .cp-layer4
    { display: block; position: absolute; top: 0px; left: 0px; }   
.cp-map
    { width: 256px; height: 256px; margin: 0px; }
.cp-map div
    { width: 256px; height: 256px; position: absolute; top: 0; left: 0; background: transparent url(maps.png) 0px 0px no-repeat;}
.cp-bar
    { width: 20px; height: 256px; margin: 0px 9px;}
.cp-bar div
    { width: 20px; height: 256px; position: absolute; top: 0; left: 0; background: transparent url(bars.png) 0px 0px no-repeat;}
.cp-preview
    { width: 60px; height: 60px; padding: 0px; margin: 0px; border: solid 1px #000; }
.cp-hsv, .cp-rgb
    { width: 40px; }
.cp-hex
    { width: 55px; }
.cp-map-arrow
    { background: transparent url(map-arrow.gif) 0px 0px no-repeat; width: 40px; height: 9px; position: absolute;}
.cp-bar-arrow
    { background: transparent url(bar-arrow.gif) 0px 0px no-repeat; width: 15px; height: 15px; position: absolute;}

Color Picker HTML

<div id=”cp1″ class=”color-picker”>
    <table cellpadding=”0″>
    <tbody><tr>
        <td>
            <div class=”cp-container cp-map”>
                <div class=”cp-layer1″></div>
                <div class=”cp-layer2″></div>       
            </div>
        </td>
        <td>
            <div class=”cp-container cp-bar”>
                <div class=”cp-layer1″></div>
                <div class=”cp-layer2″></div>
                <div class=”cp-layer3″></div>
                <div class=”cp-layer4″></div>                   
            </div>
        </td>
        <td valign=”top”>
            <table><tbody>
            <tr>
                <td colspan=”3″>
                    <div class=”cp-preview”></div>
                </td>
            </tr>
            <tr>
                <td><input type=”radio” /></td>
                <td><label>H:</label></td>
                <td><input class=”cp-hsv” type=”text” /> &#176;</td>
            </tr>
            <tr>
                <td><input type=”radio” /></td>
                <td><label>S:</label></td>
                <td><input class=”cp-hsv” type=”text” /> %</td>
            </tr>
            <tr>
                <td><input type=”radio” /></td>
                <td><label>B:</label></td>
                <td><input class=”cp-hsv” type=”text” /> %</td>
            </tr>
            <tr>
                <td><input type=”radio” /></td>
                <td><label>R:</label></td>
                <td><input class=”cp-rgb” type=”text” /></td>
            </tr>
            <tr>
                <td><input type=”radio” /></td>
                <td><label>G:</label></td>
                <td><input class=”cp-rgb” type=”text” /></td>
            </tr>
            <tr>
                <td><input type=”radio” /></td>
                <td><label>B:</label></td>
                <td><input class=”cp-rgb” type=”text” /></td>
            </tr>
            <tr>
                <td>#</td>
                <td colspan=”2″>
                    <input class=”cp-hex” type=”text” />
                </td>
            </tr>
        </tbody></table>
        </td>
    </tr></tbody>
    <div class=”cp-map-arrow”></div>
    <div class=”cp-slider-arrow”></div>
</div>

Cleanup Comments

To make it more readable, I’ve removed all the id attributes except for the single id on the containing div, taken out all inline styles, and moved the CSS to a separate file. I also changed the layers to <div> tags with background images instead of <img> tags. This may present some problems with IE6 opacity down the road, so I might need to change it back. I’ve also removed z-index values from the CSS to prevent problems with other JavaScript controls on the page. I was not careful with DOCTYPE in the past, but the new HTML and CSS should work in any DOCTYPE (I’ll be using the HTML5 DOCTYPE in all the examples). Finally, the arrows are created using <div> that are inside the main block, which will make it easer to show and hide the entire color picker.

Bar Sprite

As a preview, I’m including the sprite for the value bar of the color picker. This combines 14 different bars into one 1.77KB file. Next time, we’ll talk about memory consumption and sprites and see if the sprite usage is actually helpful.

new color bars sprite

Hi, I'm John Dyer. In my day job, I build websites and create online seminary software for a seminary in Dallas. I also like to release open source tools including a pretty popular HTML5 video player and build tools that help people find best bible commentaries and do bible study. And just for fun, I also wrote a book on the theology of technology and media.

Fork me on GitHub

Social Widgets powered by AB-WebLog.com.