ChocolateChip-UI 1.0

For those of you who visit my blog looking for how to put together different widgets with HTML and CSS, I’m proud to announce the launch of ChocolateChip-UI 1.0. This is a major update with many refinements, bug fixes and new features, such as titled lists, alphabetical lists, and iPad style popovers. If you like the examples in these blog post and would like to use them, you can download an entire framework with everything in this blog and more, all ready to use. And, if you’re good with CSS, it’s fairly easy to customize the look and feel of the framework.

Visit ChocolateChip-UI.com.

Here’s a list of the types of widgets, controls and layout options that ChocolateChip-UI offers:

  • Toolbars
  • Navbars
  • Buttons
  • Icons
  • Navigation Lists
  • Table Views
  • Selection Lists
  • Switch Controls
  • Popups
  • Popovers
  • Expanders
  • Progress Bars
  • Activity Indicators
  • Actionsheets
  • Tab Bars
  • Segmented Controls
  • Deletion Lists
  • Sliders
  • Carouses
  • Scroll Panels
  • Paging Controls
  • Split Layout

Here’s what some of those layouts and controls look like:

ChocolateChip-UI for jQuery

ChocolateChip-UI has been ported to jQuery. This means if your preferred JavaScript library is jQuery, you can now use this version of ChocolateChip-UI for creating mobile apps. It uses the latest version of jQuery for DOM traversing, manipulation and Ajax calls. It also includes jquery.tmpl.js to accommodate your tempting needs.

Because ChocolateChip.js was designed to work similar to jQuery, in most cases the port was trivial. However, jQuery’s wrapping of nodes in its object instead of returning an actual node introduced complications that I did run into in the regular version of ChocolateChip.

The end result of the port is that ChocolateChip-UI’s controls work the same as they always have. There are only some slight difference in how callbacks are handled in a couple of places. If you’ve already been using the regular version of ChocolateChip and want to switch to the jQuery version, open up and examine the provided examples to see if you need to change anything. In most cases you won’t.

ChocolateChip-UI for jQuery:
On Github: rbiggs/chocolatechip-ui-jq

To learn more about how to use ChocolateChip-UI, visit ChocolateChip-UI.com.

iOS 5 Style Switch Control

Recreating the iOS 5 Switch Control with HTML5, CSS3 and a Bit of ECMAScript 5

The final result of this post will run in iOS 5, Safari 5.1, as well as the latest versions of Chrome, Firefox and Opera.

Previously I had created a version of the switch control in iOS. With the launch of iOS5 Apple complete updated the look of the switch control. They went with a rounded style, which they also did with most controls in their desktop operating system, Lion.

After playing around with the early betas of iOS 5, I came up with the following reproduction of the new switch control look using just HTML5, CSS3 and some JavaScript for the interactive part. Functionally the switch control is nothing more than a fancier way of presenting a checkbox. So, for our purposes we are going to use a checkbox. Except that we need a couple of tags to wrap the checkbox so we can make it look like the switch control. Fortunately the amount of wrapper is really minimal. If you examine the picture below, you will notice that the switch control really has only two parts: the oblong base and the circular thumb. In our case we need a third part: a checkbox input.

Switch Control

We’re going to make a minor tweak to this default look. You’ll notice that the version above is in English. Actually, only the English version has labels for “On” and “Off”, everyone else uses the international symbols instead. They look like this:

International version of Switch Control

If we ignore the “On/Off” parts and just look at the colored areas we can see that we’re only really dealing with a simple vertical gradient on the thumb and some inset box shadows on the switch control base. This makes our styling really easy. For the “On/Off” parts we don’t need extra markup. You’ll notice that they exist in relation to the switch control’s thumb. We can use CSS pseudo elements on the thumb to create them.

To recreate the iOS5 switch control all we need is the following markup:

1
2
3
4
<div class="switch">
    <span class="thumb"></span>
    <input type="checkbox" />
</div>

Without styling, this gives us a very normal checkbox:

Unstyled switch control

We know what the dimensions need to be by measuring the screenshots, so we can give the switch control base some styling:

1
2
3
4
5
6
7
.switch {
    height: 28px;
    width: 77px;
    border: 1px solid #979797;
    border-radius: 20px;
    overflow: hidden;
}

This will give us the following:

Switch control with rounded border

It looks kind of funny with the checkboxes. We don’t need to see them. We will be setting their checked state with JavaScript later on anyway. So for now we can hide them:

1
2
3
.switch input[type=checkbox] {
    display: none;
}

Now let’s add some color. How to re-create that gray shadow area? We’ll use a series of inset box shadows. Like gradients, you can define multiple box shadows on an element. These stack up like layers, the last one being the bottom-most and the first being the top-most. We need to create a sizable gray choke inside the switch base, so we’ll use a box shadow with four values instead of three to create that effect:

1
box-shadow: inset 0 12px 3px 2px rgba(232, 232, 232, 0.5);

To this we’ll add a second inset box shadow to create a darker shadow along the top inside of the switch control:

1
box-shadow: inset 0 1px 3px #BABABA, inset 0 12px 3px 2px rgba(232, 232, 232, 0.5);

Switch control with gray box shadow

Here’s the complete CSS definition for the switch control:

1
2
3
4
5
6
7
8
9
10
.switch {
    height: 28px;
    width: 77px;
    border: 1px solid #979797;
    border-radius: 20px;
    margin-top: -5px;
    box-shadow: inset 0 1px 3px #BABABA, inset 0 12px 3px 2px rgba(232, 232, 232, 0.5);
    cursor: pointer;
    overflow: hidden;
}

Now for a tricky part. This gray inset box shadow is for the off state. How do we implement the bluish on state? Well, first of all we need to decide how to represent the states in markup. We’ll do this by added a class of “on” to the switch control base. That means that the base will have a class of “switch on” for when it’s flipped on and just “switch” when it’s off. We can use a pseudo element on the switch base to create the blue state and position it in view or out of view based on the presence of the “on” class. Of course we’re going to need a little JavaScript to set and remove the “on” class when the user clicks. So, here’s the CSS for the on state. We create an empty text node and give it the height we need to match the base. We don’t give it a width just yet since that will get set when the switch has the “on” class. We give it a bluish background color and inset box shadow. The absolute positioning is so that when it’s show, it doesn’t push the thumb out of the switch but instead sits independently inside the switch.

1
2
3
4
5
6
7
8
9
10
.switch::before {
    content: "";
    display: block;
    height: 28px;
    width: 0px;
    position: absolute;
    border-radius: 20px;
    box-shadow: inset 0 1px 2px #0063B7, inset 0 12px 3px 2px rgba(0, 127, 234, 0.5);
    background-color: #64B1F2;
}

To show the “on” state we just need to give the blue pseudo element the same width as the base:

1
2
3
.switch.on::before {
    width: 77px;
}

If we add the “on” class to one of our switches, we can see how the on state looks:

1
2
3
4
<div class="switch on">
    <span class="thumb"></span>
    
</div>

Switch control with 'on' state

That’s all we need for the switch control’s base. Now let’s tackle the thumb. We’ll make the span a block element with dimensions, set its positioning to relative so we can give it a higher z-index than the other elements in the switch control, specifically, the blue on state pseudo element. Next up: border, box shadow and gradient, very straightforward. And finally, because we want to have the thumb slide back and forth when the switch is clicked, we need to enable a CSS transition and give it a default translate value. Note: you will need to add an appropriate vendor prefix for the gradient, transition and transform.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.switch > .thumb {
    display: block;
    width: 26px;
    height: 26px;
    position: relative;
    top: 0;
    z-index: 3;
    border: solid 1px #919191;
    border-radius: 28px;
    box-shadow: inset 0 2px 1px white, inset 0 -2px 1px white;
    background-color: #CECECE;
    background-image: linear-gradient(top, #CECECE, #FBFBFB);
    transition: all 0.125s ease-in-out;
    transform: translate3d(0,0,0);
}

This gives us the following:

Switch control with thumb

As you can see, all thumbs are in the same place. We need to define a translate value for their “On” state:

1
2
3
4
5
.switch.on > .thumb {
    -webkit-transform: translate3d(49px,0,0);
    -o-transform: translateX(49px);
    -moz-transform: translateX(49px);
}

Which gives us:

Switch control thumb in 'on' state

Now the only thing left is to create the “on/off” indicators. We’ll start with the “on” one. It’s really quite simple. a vertical stripe with a border around it. We’ll create a pseudo element that has an empty text node, style it and position it beside the thumb. Here’s the CSS:

1
2
3
4
5
6
7
8
9
10
11
12
.switch > .thumb::before {
    content: "";
    display: block;
    height: 14px;
    width: 2px;
    background-color: white;
    box-shadow: 0px -1px 1px #666;
    border: none;
    position: absolute;
    top: 6px;
    left: -24px;
}

Switch control with 'on' state indicator

And for the “off” indicator, we create a pseudo element with an empty text node styles as a circle positioned to the right of the thumb:

1
2
3
4
5
6
7
8
9
10
11
.switch > .thumb::after {
    content: "";
    display: block;
    height: 10px;
    width: 10px;
    border-radius: 10px;
    border: solid 2px #777;
    position: absolute;
    right: -32px;
    top: 6px;
}

Switch control with 'off' state indicator

Now we have a fully styled switch control with minimal markup. We just need to add some interactivity. For that we’ll have to write some JavaScript. Since this is a self-contained example, I’m going to use the very latest version of ECMAScript 5. This gives me an easy way to get DOM elements and toggle classes on elements. If you want to reuse this you’ll need to switch those parts out for whatever methods your chosen JavaScript library provides.

So, first up I’m going to wrap everything up in an anonymous function:

1
2
3
(function() {
})();

Next I need a convenience method to get a collection of nodes and turn it into an array so I can iterate over it. I use call slice method of the Array object and pass in the results of querySelectorAll. That will convert the node collection into an array:

1
2
3
4
5
(function() {
    var $$ = function(selector) {
        return Array.prototype.slice.call(document.querySelectorAll(selector));
    }
})();

Now I want to define an event that executes when the DOM is fully loaded:

1
2
3
4
5
6
7
8
(function() {
    var $$ = function(selector) {
        return Array.prototype.slice.call(document.querySelectorAll(selector));
    }
    document.addEventListener("DOMContentLoaded", function() {
    
    }, false);
})();

After getting an array of all switch controls in the document, we iterate through them with the **forEach** method and bind a click event listener. The listener will execute a function that toggles the class “on”. ECMAScript 5 introduces a new token collection for classes called classList. This has several useful functions: add, remove, contains and toggle. To accomplish these methods with straight JavaScript you would need to use regular expressions. Instead I can just use **Element.classList.toggle(“on”)** to add and remove the class when the user clicks:

1
2
3
4
5
6
7
8
9
10
11
12
(function() {
    var $$ = function(selector) {
        return Array.prototype.slice.call(document.querySelectorAll(selector));
    }
    document.addEventListener("DOMContentLoaded", function() {
        $$(".switch").forEach(function(switchControl) {
            switchControl.addEventListener("click", function toggleSwitch() {
                switchControl.classList.toggle("on");
            }, false);
        });
    }, false);
})();

With the above JavaScript in our document, when the user clicks a switch control, the class “on” will be added to or removed from the switch, causing its thumb to slide to the left or right accordingly. This handily takes care of our visual requirements for the functionality of the switch control. However, we do need to manage the checked state of the checkbox. The first thing we’ll do is make sure any switch controls that had the class “on” during page load have their checkboxes set to chekced. Since the checkbox is the last element in the switch control div, we can reference it that way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function() {
    var $$ = function(selector) {
        return Array.prototype.slice.call(document.querySelectorAll(selector));
    }
    document.addEventListener("DOMContentLoaded", function() {
        if (switchControl.classList.contains("on")) {
            switchControl.lastElementChild.checked = true;
        }      
        $$(".switch").forEach(function(switchControl) {
            switchControl.addEventListener("click", function toggleSwitch() {
                switchControl.classList.toggle("on");
            }, false);
        });
    }, false);
})();

Next we need to update a switch controls checkbox when the switch control itself is clicked. We just need to again get a reference to the checkbox and set its clicked state to the opposite of what it was when the user clicked:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(function() {
    var $$ = function(selector) {
        return Array.prototype.slice.call(document.querySelectorAll(selector));
    }
    document.addEventListener("DOMContentLoaded", function() {
        var checkbox;
        if (switchControl.classList.contains("on")) {
            switchControl.lastElementChild.checked = true;
        }      
        $$(".switch").forEach(function(switchControl) {
            switchControl.addEventListener("click", function toggleSwitch() {
                checkbox = switchControl.lastElementChild;
                checkbox.checked = !checkbox.checked;
                switchControl.classList.toggle("on");
            }, false);
        });
    }, false);
})();

And that’s all you need to make the switch controls work. The final example has some extra JavaScript to output some text when the user flips a switch on to show them working. For Safari, Chrome and Opera, I use innerText to set the text value, but Firefox uses textContent. So the code has to deal with those differences.

You can try the working example. If you want the code, just save that page to your desktop. Everything is self-contained in the page.

Advertisements

ChocolateChip-UI 2.1 for Android

ChocolateChip-UI has been updated with a theme styled after the dark Holo theme of Android 4.2 Jelly Bean. ChocolateChip-UI 2.1 allows you to choose whether you want to target iOS or Android. If you create a standard ChocolateChip-UI app for iOS without any custom style modifications, you can turn it in an Android compatible app by just switching out the ChUI files. For iOS you use chui.ios.css, chui.ios.desktop.css and chui.ios.js, and for Android you use chui.android.css, chui.android.desktop.css and chui.android.js. That’s all there is really. ChocolateChip-UI 2.1 enables you to create a custom color branded version by simply replace a half dozen colors in the three Android theme files. Visit ChocolateChip-UI.com to learn more about how to use ChocoalteChip-UI for Android. Most of the magic conversion from iOS to Android is done though CSS.

Advertisements

Announcing ChocolateChip 3.0

So, I’ve been really, really busy this last year. And then something happened. ChocolateChip-UI, and myself, got acquired by Sourcebits http://www.sourcebits.com. With a company behind me, I started preparing a major update with support for iOS 6, Android Jelly Bean and Windows Phone 8. Then something else happened. Apple held their World Wide Developers Conference and showed of iOS 7.

This was a show stopper. It was also a challenge. I was forced to rethink everything about how ChocolateChip-UI functioned. So, I decided to create a completely new version–from scratch. The result is a smaller, lighter and faster framework than before. The markup is slimmer, and the CSS and JavaScript are also much less. As a matter of face, you can change the look and feel of your app for iOS 7, Android and Windows Phone 8 but just switching the CSS file, that’s all. Your markup and JavaScript stays the same. It’s also easier to customize the CSS. Each OS theme comes with two versions: the default, and at the end, a dark version. The only difference between the two is that the dark version overrides the colors of the default theme. Using this approach, you cold copy the dark theme and change the colors to suit your branding needs.

Since ChocolateChip-UI was acquired by Sourcebits, the repository has moved to: https://github.com/sourcebitsllc/chocolatechip-ui

This new version sports the spiffy new look of iOS 7, and offers the sheet overlay that automatically blurs the underlying contents like iOS 7. This is done purely in CSS, of course. Download load it, and dig into the examples to see how they work. Look in the chui folder for the CSS and JavaScript to see how this was put together. And please visit chocolatechip-ui.com for documentation and tutorials.

ChocolateChip-UI 3.0.3 Supports jQuery

As of version 3.0.3, ChocolateChip-UI now supports jQuery 2.0.3. We tried earlier versions of 2.x, but there where performance issues that prevented us from offering it as an option. jQuery 2.0.3 has proven to be a good option for mobile Web apps as far as size and speed. As such, going forward we will be supporting jQuery with the latest version of ChocolateChip-UI.

This means you can use other frameworks or plugins with jQuery dependencies and still take advantage of the great features in ChocolateChip-UI for creating cross-platform Web apps for iOS 7, Android Jelly Bean and Windows Phone 8.

For more information about jQuery support in ChocolateChip-UI, please visit ChocolateChip-UI.com and read the documentation for jQuery Support.

ChocolateChip-UI 4

So, after a lot of thought, we decided to push a lot of the features of TruckJS to ChocolateChip-UI. Why? Because of the brand. So many people were already using ChocolateChip-UI and it’s been out for four years.

To learn more about the new version, visit the website at ChocolateChip-UI.Github.io

At the same time, we didn’t want to make the move from 3 to 4 too drastic for people used to the earlier version of ChocolateChip-UI. So we went back and simplified some of the things we were doing in TruckJS. The result is ChocolateChip-UI 4. All the layouts and widgets you need to make a mobile app quick. But we moved the heavy lift out of the ChocolateChip-UI Github repository and instead completely redid our NPM module Chui. Chui is now at version 2. It now is the main way you create your ChocolateChip-UI apps. It also lets you output all the ChocolateChip-UI examples to your desktop, as well as four references apps that show you how to create apps with plain JavaScript or with ES6 modules and a build step. It can also turn your app into a hybrid app to iOS and Android. It’s your one tool for everything you need to build your app.

You install Chui with the following NPM command:

npm install -g chui

To learn more about Chui, visit the NPM page or read the install instructions at ChocolateChip-UI.Github.io.

Advertisements

CSS Flexbox Grids for Your Apps

ChocolateChip-UI provides a convenient grid system based on CSS flexbox. This means your grid columns use flex to determine their widths. This gives you responsive layouts. Because the grids use flexbox, there are no floats involved, and no need to clear floats, etc. Also all columns are automatically equal height in the same grid.

To make a grid, just put the class grid on a div:

1
2
// Define a grid:
<div class='grid'></div>

This gives you a grid row. Inside this you can create grid columns with the class col.

1
2
3
4
5
6
// Define a grid with 3 columns:
<div class='grid'>
   <div class='col'>1</div>
   <div class='col'>2</div>
   <div class='col'>3</div>
</div>

By default all columns have a flex value of 1, so they will all have the same width. You can give columns a specific flex value using specific classes that ChocolateChip-UI uses. These are as follows:

1
2
3
4
5
6
7
8
9
10
<div class='flex-1'></div>
<div class='flex-2'></div>
<div class='flex-3'></div>
<div class='flex-4'></div>
<div class='flex-5'></div>
<div class='flex-6'></div>
<div class='flex-7'></div>
<div class='flex-8'></div>
<div class='flex-9'></div>
<div class='flex-10'></div>

 

Live Example using “flex-1”

By giving columns various flex values you can create complex layouts for you app

 

Columns Based on Total Flex Value of 10

 

Equal Height Columns

As we mentioned, columns in the same grid row are always equal height.

 

Column Gutters

You can give your grid, both rows and columns, some preset gutters. To do so you can put one of two classes on the grid row: gutter-5 or gutter-10.

 

If you want some other gutter value, you can create your own class. Below is a possible class you could use:

.gutter-15 {
   margin: 15px;
}

Then you can use your class on your grids like with our own gutter classes.

Centered Grids

You can center the columns to the grid row, creating space around them, using the center class:

 

Fixed Width Columns

By their nature, flex columns are dynamic. They flex to fill whatever space is available on screen. This is great for mobile devices, such as when the user changes the orientation of a mobile device from portrait to landscape. You can rest assure that you layout will work equally well in all situations. However, sometimes you may need to give a particular column a fixed width. You can do this by giving it a special class. On this class you will define the width you want, and you will also set its flex value to 0:

.fixedWidth {
  -webkit-flex: none;
  flex: none;
  width: 250px;
}

Putting the above class on a column will force it to always have a width of 250 pixels. Any other columns in its grid row will use whatever space is left after that column is rendered. Below is an example of fixed columns:

 

Learning About Layout in ChocolateChip-UI

To learn more about layouts in ChocolateChip-UI, visit the following links:

ChocolateChip-UI

Mobile App Development with JavaScript

JavaScript Fatigue

I’m the author of ChocolateChip-UI, a framework for building hybrid mobile web apps. Over the years I’ve written libraries for DOM manipulation and animation. I write code every day, for hours. I’m chained to my NPM/Node build tools. Heck, I write my own build scripts. I’ve done Grunt, Gulp, NPM and straight up Node scripts. I bundle with whatever – Browserify, Webpack, JSPM. Sometimes I fall asleep at night with my laptop in my arms. And when I wake up in the morning I push the previous night’s code to Github. Sometimes I have trouble sleeping because I spend the whole night dreaming of coding while trying to figure out a weird bug I discovered the day before. And sometimes I even wake up with the solution.

I’m 67 years old, pushing 68. I have cataracts and glaucoma, so I sometimes have problems reading other people’s code, or even my own. Sometimes I have dizzy spells. I have numbness in my feet that can make it hard for me to walk. Yeah, I’m getting old. But you know what? I’m not suffering from JavaScript fatigue. Every time I hear someone complain about JavaScript fatigue I feel like screaming. For me, JavaScript and its ecosystem are not moving fast enough. Don’t tell me I’m going to have to wait until I’m 72 before all the browsers that don’t support ECMAScript 2015 are gone. I want them gone like last month already. Sheesh! I want to see my beautiful ES6 code working with all its goodness in browsers now, not transpiled by Babel into ES5 mush for old fogie browsers. When I have to go back to ES5, I feel like I’m looking at the cave scrawls of Neanderthals. Don’t even get me started on async and await. Why has this taken this long???

For you new guys just starting out in life as Web developers and complaining about the JavaScript ecosystem, let me tell you something. I started on the Web back in ‘93. I had the ViolaWWW browser. Yup, that mouthful was it’s real name. There was HTML 1, and no image tags. The web was text only, nicely formatted with semantic markup because that’s all there was. And links. I still remember when the image tag was introduced by Marc Andreesen in 1994. It was shocking. Some digerati said it would be a disaster. We would be buried alive in an avalanche of cat pictures. Sadly, they were right. Oh yeah, and the font tag. This dinosaur still lives and functions in browsers today. Before HTML 4 we used it for all text. It had attributes that let you set a font’s family, size and color. In those days all text on the web was enveloped in a tangled mesh of font tags. It wasn’t untile CSS came into wide use in this milenium that use of the font tag fell by the way. It was formally deprecated from the HTML standard in 1998, but lives on in old content to this day.

Back in those days, before JavaScript, the Web was simpler, you could build a Website with static markup. Except that many businesses needed dynamic content. So they installed Apache on their servers with Perl, PHP, ASP and JSP. If you wanted to be a Web developer, you had to learn one of these. Perl was always the first choice for speed. Developers loved Perl because there were so many ways you something. This meant it was always a challenge to read and understand other developers’ Perl scripts.

In 1994 I started using a new browser, Mosaic. It later became Netscape Navigator. In 1995 JavaScript shipped in Netscape Navigator, except that it was called LiveScript. That same year Microsoft shipped their own browser, Internet Explorer. A year later Microsoft added a scripting language called JScript to Internet Explorer. It was backward engineered from JavaScript, but it was not JavaScript. They shared things like variables, loops and conditionals, the standard stuff. After that, everything was different. I’m talking about the DOM. You could not implement a button click, a callback, or a DOM manipulation in the same way. Internet Explorer and Netscape Navigator had incompatible interfaces for their browser DOMs. In fact, they had different ideas about what constituted the DOM. To do anything cross-browser, you had to test the browser before branching off to browser-specific code. You could never duplicate the same experience in both browsers, their DOMs were that different.

Into this mess of incompatibilities was born the revolution of DHTML. That stands for Dynamic HTML, just so you know. It was like a dam burst. Everybody and their brother started writing DHTML libraries. There were thousands. Some were alright, but most were crap. Some were very focused on a single widget that tried to replicate the same interface and behavior across browsers, but this never turned out very good. Some libraries tried to be generic for things like animation. Thus tasteless and unnecessary animation thingies began to proliferate on the web, because why not? These were the 90s, when no one browser ruled the roost. So you had to support them all. During these wild times I also wrote DHTML libraries (blush). At the time, they seemed like the solution to the anarchy of Web development caused by incompatible DOM implementations.

To be honest, the failure of DHTML libraries was not their fault. They were working with such a nasty situation. You know, after you put enough lipstick on a pig, it stops looking like a pig with lipstick and more like a messy pile of lipstick. During these dark times, the W3C worked out the first recommendation for HTML4 and JavaScript 3 for browser vendors to implement. This included a proposal for a standarized DOM interface for browser vendors to follow. Netscape, who by 1999 had begun losing considerable marketshare to IE, was hard at work on a new version of Netscape Navigator that would support those proposed standards. Even Microsoft half heartedly embraced them while creating IE6. But since Microsoft had so much marketshare, they didn’t think they had to implement everything the standards body recommended. After all, it was only called a recommendation. They adopted some parts, and winged it with the rest. That’s how the unholy IE6 was conceived. Microsoft kept in support for a lot of the whacky things they had done in previous versions of IE. As a result, IE was incredibly buggy.

The choice to not fully accept standards would come back to haunt Microsoft, but much later. Meanwhile, in 2000 Netscape finally shipped Netscape Navigator 6. It had the real DOM. It made sense, it was easy to wire up events on elements, it was easy to style, and it was easy to change styles dynamically. It was what we had always wanted in a browser. What a breath of fresh air. But the developers who embraced Netscape Navigator 6 were a tiny group. Most developers were already developing websites that only worked with IE6. If it didn’t work with IE, nobody would bother with it. IE6 was job security. It was backed by Microsoft. The first round of browser wars were over. Microsoft won.

After the launch of Netscape Navigator 6, people started publishing tutorials about how to do things with the new DOM standard, things that you couldn’t do easily or at all in IE. But businesses only cared about what worked on IE6. You could never get a client to let you build a site that also supported Netscape 6: “But our customers prefer IE”. This was partly Netscape’s fault. The Netscape browser, while supporting standards, was a horrible user experience. The browser was an interface to the world of Netscape, which included AOL. This meant constant nagging to view channels and ads, ads, ads. Sound familiar? Netscape Navigator was so bloated by the AOL parts that it took forever to load, and it was sluggish to use. In contrast, IE loaded quickly. And all the websites looked proper on it because developers made sure of that. There was no money to be made supporting Netscape Navigator.

During this time of darkness when the Internet stagnated under the dictatorship of IE6, Netscape decided to spin off an open source project called Mozilla. Some developers there took the Netscape browser, striped away all the AOL and Netscape branding and created a streamlined browser that supported the new standards. It shipped in 2002 and was called Phoenix. Later they changed the name to Firebird before finally settling on Firefox in 2004. Slowly Firefox clawed its way up from the depths of obscurity and irrelevance, changing the way people thought about the web as a platform. This would later lead to the birth of Safari and Chrome.

Firefox turned the browser market upside down, and even Microsoft was forced to support standards they didn’t create. But Microsoft wasn’t going to concede quietly. They took one more stab at trying to dominate the Web. Only this time they wanted to completely replace HTML and JavaScript with their own technology. HTML was a joke for presentation and JavaScript was the worst language in the world. So they created Silverlight. It ran on their .NET platform. For markup it used XAML, a variant XML, and their C# language for interaction. All those guys who only knew how to support IE took up Silverlight. I even did some work with it.

For a while it looked like Silverlight would replace HTML and JavaScript and Microsoft would determine what the Web platform was. But a funny thing happened. In 2007 Steve Jobs introduced the iPhone. It was touch-friendly. It had a desktop-quality browser. But there was no public SDK for making apps. Steve told everyone to user Web standards to write Web apps for the iPhone. The most significant thing about the iPhone browser was that it did not support plugins, so no Flash or Silverlight. That earthquake knocked the foundation out from underneath Flash and Silverlight. They would never recover.

With the rise of Firefox, Safari and Chrome, Web developers no longer had to be on Windows. They could work on the Mac or Linux. This resulted in a tectonic shift of Web developers from Windows to other platforms. Minds were opened and developers explored their options and tried new ways of doing things. It was like that quote from Mao: “Letting a hundred flowers blossom and a hundred schools of thought contend…”

And here we are today. Deelopers are complaining about JavaScript fatigue. You don’t realize how lucky you are. Browsers follow standards. And most standards originate from developers who are looking to make our craft better. From my perspective, we are in a Golden Era of Web development. Yeah, there’s a lot going on. That’s not new. JavaScript is not static, it’s a moving target. Every new feature will nudge developers to think how to do things differently. Then they will come up with new patterns and libraries and frameworks. Do you need to learn everything that comes along? Well do you have to listen to all music that gets produced?

Here’s a strategy. Do exactly what you need to be doing right now. But on the side, when you have some spare time, check out other libraries and frameworks. That means just read about them. Pick one that you find interesting. Download it. Look at some examples. Does it make sense to you? Do you find the approach interesting? Look for some tutorials. Keep it simple. No need to rush in. After a couple of weeks you’ll realize if it’s not for you. At least you will have learned something. Go read blogs, explore Github. Wonder off the beaten track. You won’t get mugged. You can always go back to what you were doing before. One thing though, you can’t be complacent. If you’re unwilling to learn new things, you’ll wind up like the IE only guys – out of work.

JavaScript fatigue is not the fault of JavaScript or the Web. These are only getting better. Your fatigue means there’s something wrong with you. What are you doing that’s causing you such fatigue? Are you just bored? Have you lost interest in Web development? What has changed? Maybe you could use a career change. People change careers all the time. There’s nothing wrong with that. In fact there’s plenty good about it. But please, don’t blame us for your fatigue. It’s like runners in a marathon blaming the other runners for their fatigue.

Stephen Hawkings has severe physical limitations. I’m sure he has frustrations. Yet he doesn’t let that stop him from exploring and communicating the most profound things about the universe we live in. For me, I’ll stop coding when I can no longer stitch together two coherent thoughts. Let your imaginations run free. Try something you’ve never tried before. Maybe go do something totally different from what you’re doing now. You don’t have to do big things. Many little somethings combined become something big. That’s all programming is, really – 0s and 1s. Let a million frameworks flower and millions of developers code.