JavaScript Fatigue

An old developer’s take on JavaScript fatigue:

Old guy yells at young whippersnappers: Get your JavaScript fatigue off my lawn or I’ll whoop your ASCII!

Read the article.

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.

From ChocolateChip-UI to TruckJS

It all started with a simple DOM library for mobile use. I named it ChocolateChip, because I liked chocolate a lot and because if was really small.

On this blog, one post after another, I created prototypes of how to replicate iOS with markup, CSS and some JavaScript. After many posts I had the makings of a framework. These were all random, so I needed to bundle it all together. ChocolateChip was the glue, so I named the framework ChocolateChip-UI. That was six years ago.

As time passed, ChocolateChip-UI grew to accommodate new layouts, widgets and support for Android and Windows Phone, and could switch out to use jQuery. And then we made jQuery the default. So many changes…

Recently I was thinking about where to take ChocolateChip-UI. It seemed like it had everything it needed. I went and got some specialty chocolates and some good coffee and sat down to brood. I thought about the difference between Backbone and Angular. Backbone at least had models, where as Angular does not. Because of that, Angular has to run constant polls to compare the state of the raw JavaScript objects. The more you use Angular’s data binding, the more polls you have going and everything starts slowing down, especially on mobile.

In a system with models, it’s the model’s responsibility to inform the system when its data is modified. The system does not need to be running polls to observe the model. It should provide encapsulation and abstraction, protecting data from accidental modification by the system/developer. And so, I began tinkering until I had a model. I created some uses for it, fine tuned it, added some more features, etc. It was an object factory that returned a new model instance without having to use the “new” keyword.

I was pretty happy that ChocolateChip-UI would now have a model, but that got me to thinking – maybe ChocolateChip-UI could use a controller module too. So I looked at how the competition was dealing with controller behavior. And, in the end, I decided to take a completely different approach. I was creating a framework for mobile apps. These have unique challenges because they are mobile. So decided to base this work around the concept of mediators. These sit in the middle of an app’s interactions, like this image:

mediator

I used ChocolateChip-UI pubsub methods as the basis for my mediator module. But mediators have a number of unique features. You can control how many times a mediator can run or when it can run. Then I went back to my model code and updated it so that a model would automatically notify the mediator layer that it had changed. Like the model, this was also an object factory reusing the same pattern.

So now I had a model-controller for ChocolateChip-UI. I had always thought of ChocolateChip-UI as just a view. But it was a very passive and disconnected view because it had nothing built into it to enable working with other MVC frameworks. This meant that to use these required various workaround. It was not optimal, but it worked. I started thinking that maybe I could create a view module in the same way that I had create the model and controller modules. My idea was to enable a more component like pattern. I popped out the template parser from ChocolateChip-UI and put it into a new object factory. The object that this created knew about an element that it was associated with. This would be the container for any template rendering. It would automatically parse the element’s child nodes to extract a template. Or you could define a template in the view’s initializer. And you could define events in the view. And finally, you could bind a view to a model.

In the background the code would generate a mediator that would listen for any changes to the bound model. When a change would occur, it would update the rendered view.

So, I now had a model view controller framework. They had no dependency on ChocolateChip-UI. At the moment they were running on top of jQuery. While I was creating these modules, I kept comparing functions to mechanical ones. So, when I was done I realized I had something totally different from ChocolateChip-UI. It was time for a name change. I thought about vehicle names, but in the end I settled on TruckJS because trucks are powerful, they can carry heavy loads. You can count on trucks.

I then though I’d give a shot at rewriting ChocolateChip using the new patterns I used for TruckJS. But I was going to do one important thing. The new DOM library would be identical in API to jQuery so developers wouldn’t have to learn anything new to use it. In the end I had a DOM library less than half the size of jQuery with 90% of the functionality. But instead of the old Ajax syntax, I used the new Fetch API for remove server interaction. And instead of jQuery’s deferred object implementation, I went with the ECMAScript 6 Promises API. Fetch uses ES6 promises, so this was a perfect fit.

Then I though about routing, so I built a router. Then I added in data formatting and form validation. After that I began porting the widgets over. I wound up rewriting every single widget, changing their behavior to return objects and enabling the form-based widget to work with the new form validation.

TruckJS is a standalone framework without any dependency on other libraries or frameworks. You do not need jQuery, etc. It provides everything you need to build mobile web apps. But, if you really want to use jQuery with Truck, you can. You just have to load jQuery first. When Truck detects jQuery, it switches to using it instead of its own DOM library. I’m not sure why anyone would want to use jQuery. Its bulky and slow on mobile devices. But there’s always those special guys who think something can’t be perfect unless jQuery is loaded.

I’ve put up a site, TruckJS.io, with lots of documentation. And it’s available on Github. If you like ChocolateChip-UI, I think you’re really going to like TruckJS. It gives you the same tradition of great layouts and widgets for creating cross platform mobile web apps.

 

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.

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:

	<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:

	.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:

	.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:

	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:

	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:

	.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.

	.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:

	.switch.on::before {
		width: 77px;
	}

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

	<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.

	.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:

	.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:

	.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:

	.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:

	(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:

	(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:

	(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:

	(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:

	(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:

	(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.

ChocolateChip-UI for Zepto

I’ve ported ChocolateChip-UI to the JavaScript micro framework Zepto. Created by Thomas Fuchs of Scriptaculous fame, Zepto is a small JavaScript library for mobile devices that replicates the functions of jQuery. If you use jQuery but want to do mobile development and are disappointed with jQuery mobile’s size and performance, Zepto may be your solution. Zepto has a very small footprint and performs well on mobile devices. But Zepto provides only the equivalent of jQuery itself. If you need something to help you get your interface and widgets together, ChocolateChip-UI with Zepto provides a complete solution.

Although Zepto’s methods are the same as jQuery’s, it is not a clone of jQuery. The way it works internally is quite different. Yet it literally only took me a few hours to port the jQuery version of ChocolateChip-UI to Zepto. One major difference is that Zepto’s data method stores strings on a node using HTML5’s data attribute, whereas jQuery’s data method uses a sophisticated caching system to store any kind of data. However, on mobile browsers, HTML5 offers local storage and client side database for data persistence so this isn’t that big of a limitation. It does require more work (coding) on your part to accomplish the same thing that jQuery’s data method provides.

Check out .

Performance and size-wise, ChocolateChip-UI with Zepto is equivalent to ChocolateChip-UI with ChocolateChip. So, it’s really just up to a matter of personal preferences. If you like the coding conventions that jQuery demands, then go with Zepto. If you’d prefer more freedom to use normal JavaScript and want to break out of the jQuery mold, go with ChocolateChip.

ChocolateChip-UI

Learn more about ChocolateChip-UI

ChocolateChip.js is now ChUI (pronounced “chewy”)

In the course of time I’ve created a lot of POCs (proof of concepts) on this blog. Some where fairly good, some where flaky one-offs. In the process I also created a small JavaScript library — ChocolateChip.js — that I used for actualizing most of these demos. Seeing how many people come to this humble blog in search of solutions to their development projects, I though about taking all the good ideas in these demos and putting them together as a one stop solution for mobile Web app development. I’m therefore today announcing ChocolateChip-UI. At present it’s a beta, but I intend to keep developing it to add more useful features over time. I

ChocolateChip-UI consists of ChocolateChip.js plus two other files: ChUI.js and ChUI.css. ChUI.js is a collection of JavaScript methods built on top of ChocolateChip.js. ChUI.js provides controls and widgets enlivened with behaviors needed for Web app development. ChUI.css is the magical CSS that makes simple markup look and act in a amazing way.

ChocolateChip-UI also introduces a new concept: WAML (Web App Markup Language). This is a specialized set of tags and attributes that get around the limits of HTML. HTML tags are really about creating documents, like books and other text publications. In contrast, WAML is a collection of tags and attributes that make sense for Web app development. ChUI.js and ChUI.css are built around the implementation of WAML as the key to how ChocolateChip-UI works.

WAML takes the paradigms of mobile application development and transfers those over to the development of mobile Web apps. There’s no need to smother and bury HTML tags with tons of classes trying to make markup meant for publishing documents work for creating applications. At the same time, WAML is really just a superset of HTML5 markup. You can therefore use any HTML5 tags and attributes along with WAML and ChocolateChip-UI to implement your solution.

ChocolateChip-UI is about making Web app development more straightforward. It provides common controls which have built in functionalities. Instead of having to figure out how to build these yourself, you can spend that time providing the data you want through ChocolateChip-UI’s controls easy to use controls.

The interfaces and controls which ChocolateChip-UI provides are all created using only markup and CSS. No images are required, no gifs or pngs. This means that everything you build with ChocolateChip-UI will be resolution independent. It will look good on a handheld mobile device and on a big HDMI screen. ChocolateChip-UI also provides a set of 52 SVG icons for use with buttons. Because these are vector based, they too are resolution independent. ChocolateChip-UI is therefore the first resolution independent mobile Web app framework.

ChocolateChip Has Its Own Blog

ChocolateChip, the little guy that does big things

So, ChocolateChip, the tiny JavaScript mobile Web framework that is only 8k when minified, now has its own blog: ChocolateChip-Mobile.net. I put this blog together to show how ChocolateChip works and how you can use it to accomplish your coding needs. I also talk about best coding practices with ChocolateChip.

ChocolateChip can be so small because it doesn’t have to support ancient browsers or compensate for cross-browser nightmares. Instead it takes advantage of modern browsers’ implementation of the features in ECMAScript 5 and DOM level 3. The idea was to keep ChocolateChip simple, avoiding object wrappers and object obfuscation, and making everything interchangeable with regular JavaScript. That means you can adjust ChocolateChip to your coding style, not the other way around. You can substitute any ChocolateChip for your own code at any time. As a matter of fact, if you don’t like the default $, $$ aliases that ChocolateChip uses, open up the files and change them to whatever you want. ChocolateChip is open source with a BSD license, so if you want to add some feature, feel free to. And if you feel like sharing your feature with the rest of us, feel free to contact me.

Have a great day and enjoy your ChocolateChip.

Making an iPhone Switch Control without Images

Works on desktop Safari, Chrome and Firefox, iPhone, iPod Touch and iPad.

On the iPhone and iPad, Apple uses a control called switch. It’s actually a different take on the checkbox. Like radio buttons, checkboxes do not lend themselves to touch interfaces, especially guys with fat fingers, cough! Instead of making us suffer with those dinky checkboxes, Apple uses a more visual cue to what the user is actually doing, switching something on or off. As a matter of fact, that’s exactly how the control is labeled: “on” or “off”. They’re really easy to use, just swipe your finger to throw the switch, done. In case you’re not sure what I’m talking about, here they are:

switch control

OK, so all the mobile Web frameworks have a switch control. And I hate them all. They either do an instant switch between the on and off state, using an image sprite, or they do this really lame thing where they animate the horizontal background position of the image on a checkbox with its default styles removed. None of those implementations feels the same as when you swipe the switch control in a native iOS app.

So what am I going to do? I tell you, I’m going to throw the friggin’ image out and build the whole control from scratch using just HTML, CSS3 and some JavaScript to make it work. Bada-bing! To start with, here’s the basic markup for a checkbox:

<div class="checkbox unchecked" id="sleepSwitch">
	<div class="on">ON</div>
	<div class="thumb"><span></span></div>
	<div class="off">OFF</div>
	<input type="checkbox" value="ZZZZZZZZ!" offvalue="But, I need more sleep!">
</div>

As we did when we created iPhone style radios buttons, we’re using real checkboxes in our iPhone switch controls. And like in the radio button example, we’ll set the checkbox input’s display value to “none”. We’ll use CSS3 properties to style the markup to look like a real iOS switch control and we’ll attach event listeners to set the input checkbox’s check state to true or false, depending on whether we want it to be selected or not.

To create this switch control we’ll need to style the frame named “checkbox” with rounded corners. Notice that the markup above contains three parts: the on state, the thumb and the off state. The rounded frame will only be wide enough to show one state plus the thumb. Using CSS3 transitions and transforms, a click or touch will cause the three elements to side back and forth within the rounded frame. For positioning the switch’s elements and sliding them back and forth we’re going to use CSS3 3d transforms on the x axis. Here is the CSS to make this happen:

/* Checkbox */
.checkbox {
	display: -webkit-box;
	-webkit-box-orient: horizontal;
	-webkit-box-pack:justify;
	-webkit-box-sizing: border-box;
	-webkit-tap-highlight-color: transparent;
	width: 94px;
	overflow: hidden;
	-webkit-border-radius: 6px;
	text-align: center;
	line-height: 28px;
	cursor: pointer;
	-webkit-user-select: none;
	position: absolute;
	right: 10px;
	top: 7px;
}
.checkbox > input[type="checkbox"] {
	display: none;
}
.checkbox .thumb {
	-webkit-border-radius: 7px;
	position: relative;
	z-index: 3;
	border: solid 1px #919191;
	-webkit-transition: all 0.125s  ease-in-out;
	-webkit-transform: translate3d(0px,0%,0%);
}
.checkbox .thumb span {
	display: block;
	-webkit-box-sizing: border-box;
	height: 25px;
	width: 38px;
	border-top: solid 1px #efefef;
	-webkit-border-radius: 6px;
	background-image: -webkit-gradient(linear, left top, left bottom, from(#cecece), to(#fbfbfb));
	border-top: solid 1px #efefef;
	position:relative;
}
.checkbox .on {
	color: #fff;
	background-image: 
		-webkit-gradient(linear, left top, left bottom, 
			from(#295ab2), 
			to(#76adfc));
	width: 54px;
	padding-right: 4px;
	border: solid 1px #093889;
	-webkit-border-top-left-radius: 6px;
	-webkit-border-bottom-left-radius: 6px;
	margin-right: -6px;
	height: 25px;
	-webkit-transition: all 0.125s  ease-in-out;
	position: relative;
	-webkit-transform: translate3d(0px,0%,0%);
}
.checkbox .off {
	color: #666;
	background-image: -webkit-gradient(linear, left top, left bottom, from(#b5b5b5), color-stop(0.50, #fff));
	width: 54px;
	padding-left: 4px;
	border: solid 1px #a1a1a1;
	-webkit-border-top-right-radius: 6px;
	-webkit-border-bottom-right-radius: 6px;
	margin-left: -6px;
	height: 25px;
	-webkit-transition: all 0.125s  ease-in-out;
	position: relative;
	-webkit-transform: translate3d(-54px,0%,0%);
}
.checkbox.unchecked .thumb {
	-webkit-transform: translate3d(-54px,0%,0%);
}
.checkbox.checked .thumb {
	-webkit-transform: translate3d(0px,0%,0%);
}
.checkbox.unchecked .on {
	-webkit-transform: translate3d(-60px,0%,0%);
}
.checkbox.checked .on {
	-webkit-transform: translate3d(0px,0%,0%);
}
.checkbox.unchecked .off {
	-webkit-transform: translate3d(-54px,0%,0%);
}
.checkbox.checked .off {
	-webkit-transform: translate3d(6px,0%,0%);
}
/* For Very Important changes, use the orange checkbox */
.checkboxBase.important .on {
	border: solid 1px #d87100;
	background-image: -webkit-gradient(linear, left top, left bottom, from(#e75f00), color-stop(.5, #ff9c12));
}
/* End Checkbox */

To make the switch more realistic, I’m transforming all three pieces of the switch at the same time. This gives the switch a more realistic feeling. Notice the comment in at the end of the above CSS about the important class. You can use this to indicate a switch that makes a very important change. This class changes the default switch’s blue color to bright orange. This is the color Apple uses to show that a switch’s action is very important.

Having the CSS defined for the look and animation brings us close to the finished control, but we need to write some JavaScript to make the switch interactive. The JavaScript needs to do two things: toggle the classes “checked” and “unchecked” on the switch, and toggle the checked value of the checkbox between true and false. I’m using the ChocolateChip JavaScript framework to do this. You can switch my code to whatever library you want. If you know basic JavaScript, it shouldn’t be hard. Here’s the JavaScript to make it happen:

Element.prototype.toggleSwitch = function() {
	if (this.hasClass("switch")) {
		if (this.last().checked === true) {
			this.last().checked = false;
			this.toggleClass("checked", "unchecked");
		} else {
			this.last().checked = true;
			this.toggleClass("checked", "unchecked");
		}
	} else {
		return false;
	}
};

The last() used in the code above is a ChocolateChip method to return the last child of the control, which happens to be the checkbox input. That way we can set its checked state to true or false.

Now that we have the code to setup up the switch control, we can make it work as follows:

$(".switch").forEach(function(checkbox) {
	checkbox.bind("click", function() {
		this.toggleSwitch();
	});
	
	checkbox.bind("touchstart", function(e) {
		e.preventDefault();
		this.toggleSwitch();
	});
}); 

That’s it to make the switch switchable. But to make it do something you’d need a bit more as well. In my example, I’m getting some values from the switch and outputting it to a response field like this:

$(".switch").forEach(function(checkbox) {
	checkbox.bind("click", function() {
		if (this.last().checked === true) {
			$("#switchResponse").fill(
				this.last().getAttribute("value"));
		} else {
			$("#switchResponse").fill(
				this.last().getAttribute("offvalue"));
		} 
	});
	
	checkbox.bind("touchstart", function(e) {
		if (this.last().checked === true) {
			$("#switchResponse").fill(
				this.last().getAttribute("value"));
		} else {
			$("#switchResponse").fill(
				this.last().getAttribute("offvalue"));
		}
	});
}); 

You can try this out online or download the source code.

User Controled Color Theme

Works on Desktop Safari, desktop Google Chrome, desktop Firefox 3.6-4, iPhone, iPod Touch, iPad.

So, in the last blog post I showed how to make RGB slides with HTML, CSS and some JavaScript. I thought about it and, while interesting, it doesn’t have a whole lot of practical application. Sure you could take that and hook up any other type of value to get whatever result you might need for your interface. Well that got me to thinking, so I threw together an implementation of the RGB sliders that allow a user to change the color scheme of a Web app. No need to spend time creating different color themes. Let the user do it.

OK, before you think I’m crazy, especially you folks from the design community, let me explain. I came up with a basic theme technique. I call it chromaeleon &mdash because the app’s chrome can change colors like a chamaeleon. The way this works is, instead of solid color gradients, you create gradients with transparent values of black and white. Behind this you have a background color which shows through the transparent gradients. This way, when the user drags the sliders, the background colors update and the look of the interface changes. Now in the real world you’d want to provide a way for the user to save their color choice. You could save the choice to localStorage. Then when the app loads, it checks to see it the user saved a color choice, if not, it goes to the default. Sorry, I didn’t do all of that. Just the part to update the background colors. Here’s what it will look like:

iPhone Chromaeleon Interface

The structure we’re going to use is pretty must standard as we’ve used elsewhere, a header, a section, some buttons.

<body>
	<header>
		<a href="http://css3wizardry.com" class="button back"><span class="pointer"></span><span>Back</span></a>
		<h1>Chromaeleon Theme</h1>
		<span class="button">Click Here</span>
	</header>
	<section>
		<h2>Use the sliders to adjust the colors of the theme.</h2>
		<div class="colorRow">
			<div id="redSlider" class="slider">
				<div class="thumb"></div>
			</div>
			<div id="redColor" class="colorOutput"></div>
			<span> Red</span>
		</div>
		<div class="colorRow">
			<div id="greenSlider" class="slider">
				<div class="thumb"></div>
			</div>
			<div id="greenColor" class="colorOutput"></div>
			<span> Green</span>
		</div>
		<div class="colorRow">
			<div id="blueSlider" class="slider">
				<div class="thumb"></div>
			</div>
			<div id="blueColor" class="colorOutput"></div>
			<span> Blue</span>
		</div>
		<div class="colorRow finalResult">
			<span>Final Color: </span>
			<div id="rgbColor" class="colorOutput"></div>
			<br />
			<span>RGB: </span><span id="rgbResult">0, 0, 0</span>
			<br />
			<span>HEX: </span><span id="hexResult">#000000</span>
		</div>
	</section>
</body>

So, for the header and the buttons, we need to change their default gradients, as I mentioned above, to have RGBA transparency values. This is my basic gradient:

background-image: 
	-moz-linear-gradient(top, 
		rgba(255,255,255,.5), 
		rgba(30,30,30,.65) 50%, 
		rgba(0,0,0,.7) 50%, 
		rgba(0,0,0,.8)); 
background-image: 
	-webkit-gradient(linear, left top, left bottom, 
		from(rgba(255,255,255,.5)), 
		color-stop(0.5,rgba(30,30,30,.65)), 
		color-stop(0.5, rgba(0,0,0,.7)), 
		to(rgba(0,0,0,.8)));

And for the hover state of the button, we use this gradient:

background-image: 
	-webkit-gradient(linear, left top, left bottom, 
		from(rgba(0,0,0,.1)), 
		color-stop(0.5,rgba(0,0,0,.5)), 
		color-stop(0.5, rgba(0,0,0,.6)), 
		to(rgba(255,255,255,.2)));
background-image: 
	-moz-linear-gradient(top,
		rgba(0,0,0,.1), 
		rgba(0,0,0,.5) 50%, 
		rgba(0,0,0,.6) 50%, 
		rgba(255,255,255,.2));

Now to change the color, all we need to do is introduce a new method to our existing code:

/**
*
* Method to update chrome colors according to the RGB value of the sliders.
*
*/
$.updateInterfaceColors = function() {
	$("header").css("background-color: rgb(" + $.rgbColor[0] + "," + $.rgbColor[1] + "," + $.rgbColor[2] + ")");
	$$(".button").forEach(function(button) {
		button.css("background-color: rgb(" + $.rgbColor[0] + "," + $.rgbColor[1] + "," + $.rgbColor[2] + ")");
	});
	$("section").css("background-color: rgb(" + $.rgbColor[0] + "," + $.rgbColor[1] + "," + $.rgbColor[2] + ")");
	$(".pointer").css("background-color: rgb(" + $.rgbColor[0] + "," + $.rgbColor[1] + "," + $.rgbColor[2] + ")");
};

To execute this method, we invoke it in the slide mouse event handlers for each slider, and for touch-based mobile devices we invoke it in the updateSliderTouch method:

/**
*
* This is for the red slider's mouse interaction, you'd do the same for the green and blue sliders' setup scripts as well.
*/
// Set up three sliders for Red, Green and Blue:
$.slider("#redSlider", { 
	onDrag : function() {
		$("#redSlider").setColorFromSlider("red");
		$.updateInterfaceColors();
	},
	// onDragEnd function necessary to remove hover state off of slider thumb when drag ends.
	onDragEnd : function() {},
	top : -6
});
/**
*
* This is for touch-enabled devices. You invoke the $.updateInterfaceColors() method just once inside the updateSliderTouch method's definition, at the very end.
*/
Element.prototype.updateSliderTouch = function( color ) {
	this.style.left =  curX + 'px'; 
	if (color === "red") {
		$("#" + color + "Color").css("background-color: rgb(" + curX +",0,0)");
		$.rgbColor[0] = curX;
	}
	if (color === "green") {
		$("#" + color + "Color").css("background-color: rgb(0," + curX +",0)");
		$.rgbColor[1] = curX;
	}
	if (color === "blue") {
		$("#" + color + "Color").css("background-color: rgb(0,0," + curX +")");
		$.rgbColor[2] = curX;
	}
	$("#" + color + "Slider").css("-webkit-background-size:" + (curX + 1) + "px 9px, 100% 9px");
	$("#" + color + "Slider").css("background-size:" + (curX + 1) + "px 9px, 100% 9px");
	$("#rgbColor").css("background-color: rgb(" + $.rgbColor[0] + "," + $.rgbColor[1] + "," + $.rgbColor[2] + ")");
	$("#rgbResult").fill($.rgbColor[0] + ", " + $.rgbColor[1] + ", " + $.rgbColor[2]);
	$("#hexResult").fill("#" + $.rgb2hex($.rgbColor[0]) + $.rgb2hex($.rgbColor[1]) + $.rgb2hex($.rgbColor[2]));
	$.updateInterfaceColors();
};

This works great on desktop Safari, Chrome and even Firefox (Yay!), and fine on the iPad. For iPod Touch or iPhone you need to load it in portrait mode. it’s a bit cramped due to the size of the sliders. I needed them to be at least 255px long for the RGB values, and then borders, box shadows and the extra space for the thumbs made them barely fit in the iPhone’s and iPod Touch’s default width. Try hitting the plus icon at the bottom of the browser and save it to you device’s desktop. Then run it from there, you’ll have more vertical space. You can try this out online or download the source code. Enjoy!