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.

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:

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

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

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

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

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.

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

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

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:

This slideshow requires JavaScript.

CSS Gradients are about to Graduate!

Finally all browser vendors are on the same page when it comes to gradients

The Webkit team introduced CSS gradients on April 14th, 2008. Shortly afterwards they presented it to the W3C for consideration as a recommendation. Sometime later, Mozilla decided to implement CSS gradients using the same notation the Webkit gradients, but with the -moz prefix. After some time, however, they decided to replace that notation with a simpler one. Ever since, to do CSS gradients on the Web you had to write gradients the Webkit way for Safari and Chrome, and the Mozilla way for Firefox. Well, now all browser vendors have agreed to implement the same spec. At this time you can write a single notation that is identical for Safari, Chrome, Firefox, Opera and IE10.

Since version 5.1, Safari has supported the newer notation. Opera beta running Presto 2.10.299 fully supports the linear and radial notation, although the developer site only mentions support for the linear notation. Firefox, of course, already supports this notation. And the latest beta of IE10 does as well. This means that at some point all browsers will support this notation. Well, sort of.

Recently somebody at the W3C has been thinking a little too much. As of January 2012 the document CSS Image Values and Replaced Content Module Level 3 now has a slightly different notation. Since this just showed up, there is no support for it in any browser. And, since it is a working draft, it could change at any time. So, at this time, I’m going to ignore what the document says and just cover what the latest browsers have agreed to support.

Because CSS gradients are still a draft proposal, all browser vendors use their respective prefixes with the notation. This is a good thing since the spec is in flux. They shouldn’t change their present implementation until the spec reaches recommendation status, in which case they can implement the final version of CSS gradients without their vendor prefixes.

  • Webkit: -webkit-
  • Mozilla: -moz-
  • Opera: -o-
  • Microsoft: -ms-

CSS gradients are rendered as a background image. That means that all of the properties of the CSS background module apply to CSS gradients. In other words, you can have multiple gradients on the same element and control their size and position as well, or use them as image masks. Also, whereas in the past you might have used a background color in conjunction with a background image, you can now use a background gradients as the backdrop for a background image, or you could have a transparent gradient layered over a background image. The ability to stack up gradients while controlling their size, position and repetition means you can create complex repeating patterns that would normally require a background image. The ability to define multiple background images results in a layered affect not unlike Adobe Photoshop’s layers. The new CSS filters module will increase the comparison with Photoshop further my providing many color filters, such as reverse, multiply, dodge, burn, darken, lighten, grayscale, etc. With JavaScript you could also manipulate the properties of your CSS gradients to produce a background pattern that morphs in real time.

Linear Gradients

The notation for linear gradients is quite simple and straightforward. First thing, you’ll be defining it as a background image on an element. CSS uses functions that create the gradient according to the arguments you provide. For linear gradients, the values you’ll need are as follows:

[<point (one value, two values or degrees)>]?, <color [stop]?>, <color [stop]?>

From the above definition we can see that all values are optional, except the start and end colors.

The first value (point) is optional. If no value is provided, it will default to drawing the gradient from top to bottom. You can use keywords for the position. These can be a single keyword or a combination of two. You can also use any valid degree values. The purpose of these point definitions is to define which direction the gradient flow towards. You also need to provide at least two colors. The first color will be where the gradient starts from, and the last color will be where the point indicates. So a gradient with yellow and blue and a point value of top will start at the bottom with yellow and end at the top with blue. Here re possible point values:

– top
– right
– bottom
– left
– top left
– top right
– bottom left
– bottom right
– 0deg
– 11deg
– 67deg
– 182deg
– -45deg
– -90deg

Colors can have optional stop values. If no stops are provided, the colors will blend equally from the first to the last.You can provide as many colors as you want to create the gradient, and you can vary their widths by providing stops. The value of the stops can use any valid CSS length identifier (px, pt, em, %, etc.). The position value is placed after the color. You can use any valid CSS colors, such as keywords (red, yellow, blue), or hex, hsl, rgb or rgba values. Regardless of what the stop position is for the last color, that color will continue filling the element the rest of the way.

background-image: linear-gradient(top, yellow 10px, red 80px);
background-image: linear-gradient(top right, orange, green 30%, yellow 70%);
background-image: linear-gradient(60deg, red, white, blue 50%);

Repeating Linear Gradients

Repeat linear gradients are easy to do. Actually, the same effect can be achieved with background size and background repeat properties, but it is nice to have it I suppose. It works the same way as regular linear gradients, except that you use repeating-linear-gradient as the function:

background-image: repeating-linear-gradient(top, yellow 10px, red 80px);
background-image: repeating-linear-gradient(top right, orange, green 30%, yellow 70%);
background-image: repeating-linear-gradient(60deg, red, white, blue 50%);

Radial Gradients

The notation for radial gradients is similar to linear gradients, except that you can specific a shape argument to control how the radial is produced. Here’s the possible values:

[<position (two separate values)>]?[[<shape (literal value or length value)>] || [<size length value>]>]? <color [stop]?> <color [stop]?> 

From the above definition we can see that all values are optional, except the start and end colors, just like linear gradients.

If no value for position is supplied, the radial gradient will be centered in the element. Position is based on the center of the radial gradient. It accepts the same values as background position. Those values include percentages, lengths and keywords. Just like background positioning, you can use negative values to move the center of the radial gradient off the screen. Percentages and lengths require two values, the first defining the x axis and the second defining the y axis.

percentage: 0% 0%, 20% 60%, 50% 50%
length: 0px 0px, 24px 45px, 3em 5em

The keywords are: top, right, bottom, left and center. You could combine these in various ways:

top left, bottom right, center center, center right, top center

Shape can be either circle or ellipse. If no shape is supplied, if the length value is single, it defaults to a circle with a radius defined by that length. Otherwise, if no shape is supplied and two lengths are passed, it uses those to draw an ellipse. The first value determines the width, the second the height:

// A vertical ellipse:
background-image: radial-gradient(center, 100px 400px, red, white);
// An horizontal ellipse:
background-image: radial-gradient(center, 400px 100px, red, white); 

If you use one of the shape keywords, you can also use size keywords to control how the radial gradient is draw in relation to its container. The size keywords are:

– closest-side
– farthest-side
– closest-corner
– farthest-corner

First of all, these keywords only work when you use a shape keyword. Defining the shape of the radial gradient with lengths and then trying to use these size keywords will not work. So, this is how these size keywords work. If the container is narrower than it is tall, the size of circle or ellipse will be restrained by the left and right of the container. With farthest-side, it would be restrained by the top and bottom of the container, probably resulting in the left and right extending beyond those sides. Be aware that these work in relation to the position of the radial gradient. That means that if it is positioned near the top left, it will be rendered differently than if it were centered. Closest-corner and farthest-corner work just like closes-side and farthest-side. The best way to get the hang of these keywords is to play around with a radial gradient to see how they affect it. Although these keywords are nice conveniences, you’ll see that they are far from exact. If you need precise placement and size, you’re better off using lengths to define the size of your radial gradient.

Color and stops work similar to linear gradients. The first color defined the color drawn from the center of the radial gradient. The last color will define the outermost color of the gradient. Stops allow you to define more precise positioning of those colors in the radial gradient.

Repeating Radial Gradients

Like repeating linear gradients, it is possible to create the same effect as a repeating radial gradient. You’d just need to define it tediously repeating the colors and providing appropriate stops. In contrast, using the repeating-radial-gradient function makes this easy.

Practical Examples

Enough with theory. Let’s look at what we can do with linear and radial gradients. By layering them and controlling their size and positioning, we can create complex patterns that we can use as Web assets. Please note that in all of the following examples I’m presenting the gradients without vendor prefixes. To have them render in a browser that currently supports CSS gradients, you would need to provide the appropriate vendor prefix for that browser. When the current spec reaches recommendation status, browser vendors will drop their prefix.

In most of these examples I’ve used a transparent gray. This was so I could just add an background color to show through the transparency. Having the color controlled by the background color makes it easy to change the feel of the pattern.

Here’s a vertical stripe with the transparent gray stripe is separated by a 1 pixel transparent stripe:

background-image: 
   linear-gradient(0deg, 
      rgba(0,0,0,0.1) 75%, 
      transparent 75%);
background-size: 5px 100%;

vertical stripes gradient

Here’s the same stripe horizontal:

background-image: 
   linear-gradient(90deg, 
      rgba(0,0,0,0.1) 75%, 
      transparent 75%);
background-size: 100% 5px;

horizontal stripes gradient

And here it is slanted to the left:

background-image: 
   linear-gradient(45deg, 
      transparent 15%,  
      rgba(0,0,0,0.1) 15%, 
      rgba(0,0,0,0.1) 50%, 
      transparent 50%, 
      transparent 65%,
      rgba(0,0,0,0.1) 69%);
background-size: 6px 6px;

gradient of stripes slanting left

And then to the right:

background-image: 
   linear-gradient(-45deg, 
      transparent 15%,  
      rgba(0,0,0,0.1) 15%, 
      rgba(0,0,0,0.1) 50%, 
      transparent 50%, 
      transparent 65%,
      rgba(0,0,0,0.1) 65%);
background-size: 6px 6px;

gradient of stripes slanting right

Now lets have some fun with repeating linear gradients. Here’s vertical repeating stripes:

background-image: 
   repeating-linear-gradient(0deg, 
      rgba(0,0,0,0.1) 0px, 
      rgba(0,0,0,0.1) 5px, 
      transparent 5px, 
      transparent 10px);

repeating vertical stripes gradient

Horizontal repeating stripes:

background-image: 
   repeating-linear-gradient(90deg, 
      rgba(0,0,0,0.1) 0px, 
      rgba(0,0,0,0.1) 5px, 
      transparent 5px, 
      transparent 10px);

repeating horizontal stripes gradient

Left slanted repeating stripes:

background-image: 
   repeating-linear-gradient(45deg,
      rgba(0,0,0,0.1) 0px, 
      rgba(0,0,0,0.1) 5px, 
      transparent 5px, 
      transparent 10px);

repeating gradient of left leaning stripes

Right slanted repeating stripes:

background-image: 
   repeating-linear-gradient(-45deg,
      transparent, 
      transparent 5px, 
      rgba(0, 0, 0, 0.1) 5px, 
      rgba(0, 0, 0, 0.1) 10px);

repeating gradient of right leaning stripes

Now lets cross them:

background-image: 
   repeating-linear-gradient(0deg, 
      transparent 0,
      transparent 5px, 
      rgba(0, 0, 0, .1) 5px, 
      rgba(0, 0, 0, .1) 10px),
   repeating-linear-gradient(90deg, 
      transparent 0,
      transparent 5px, 
      rgba(0, 0, 0, .1) 5px, 
      rgba(0, 0, 0, .1) 10px);

checkered

And now criss-cross them:

background-image: 
   repeating-linear-gradient(-45deg,
      transparent, 
      transparent 5px, 
      rgba(0, 0, 0, 0.1) 5px, 
      rgba(0, 0, 0, 0.1) 10px),
   repeating-linear-gradient(45deg,
      transparent, 
      transparent 5px, 
      rgba(0, 0, 0, 0.1) 5px, 
      rgba(0, 0, 0, 0.1) 10px);

intersect

Enough with stripes, let’s get square:

background-image: 
   linear-gradient(180deg, 
      rgba(0,0,0,0.05) 75%, 
      transparent 75%),
   linear-gradient(90deg,  
      rgba(0,0,0,0.05) 75%, 
      transparent 75%);
background-size: 5px 100%, 100% 5px;

cubes

And a nice checkerboard pattern:

background-image: 
   linear-gradient(45deg, 
      rgba(0,0,0,0.1) 4.5px, 
      transparent 5px, 
      transparent 16px, 
      rgba(0,0,0,0.1) 16px, 
      rgba(0,0,0,0.1)), 
   linear-gradient(45deg, 
      rgba(0,0,0,0.1) 4.5px, 
      transparent 5px, 
      transparent 16px, 
      rgba(0,0,0,0.1) 16px, 
      rgba(0,0,0,0.1));
background-position: 0 0, 8px 8px;

squares

And let’s make those diagonal:

background-image: 
   linear-gradient(45deg, 
      rgba(0,0,0,0.1) 25%, 
      transparent 25%),
   linear-gradient(-45deg, 
      rgba(0,0,0,0.1) 25%, 
      transparent 25%),
   linear-gradient(45deg, 
      transparent 75%, 
      rgba(0,0,0,0.1) 75%),
   linear-gradient(-45deg, 
      transparent 75%, 
      rgba(0,0,0,0.1) 75%);
background-size: 10px 10px;

chess

Now that we have them diagonal, lets spice them up and turn them into an argyle pattern:

background-image: 
   linear-gradient(right top, 
      rgba(0,0,0,0.1), 
      rgba(0,0,0,0.1) 50%, 
      transparent 50%, 
      transparent),
   linear-gradient(left top, 
      rgba(0,0,0,0.1), 
      rgba(0,0,0,0.1) 50%, 
      transparent 50%, 
      transparent);
background-size: 12px 12px;

argyle

OK, now lets take another look at stripes. But this time we want to shake things up about. We want to get out to the monotony of strictly repeating patterns, but still have a pattern. What I’m talking about is sometimes called the Cicada principle. It produces a pattern that doesn’t repeat itself exactly. It does this my layering different repeating patterns, except that these are different proportions, similar to the progression of prime numbers. Using this principle, I’ve created a series of overlapping lines that creates a textile like pattern that retains it’s randomness. Here’s the CSS:

background-image: 
   linear-gradient(left, 
      rgba(0,0,0,0.1), 
      rgba(0,0,0,0.1) 25%, 
      transparent 25%, 
      transparent),
   linear-gradient(left, 
      rgba(0,0,0,0.1), 
      rgba(0,0,0,0.1) 15%, 
      transparent 15%, 
      transparent),
   linear-gradient(left, 
      rgba(0,0,0,0.1), 
      rgba(0,0,0,0.1) 15%, 
      transparent 15%, 
      transparent),
   linear-gradient(top, 
      rgba(0,0,0,0.1), 
      rgba(0,0,0,0.1) 17%, 
      transparent 17%, 
      transparent),
   linear-gradient(top,
      rgba(0,0,0,0.1), 
      rgba(0,0,0,0.1) 15%, 
      transparent 15%, 
      transparent),
   linear-gradient(top,
      rgba(0,0,0,0.1), 
      rgba(0,0,0,0.1) 13%, 
      transparent 13%, 
      transparent);
background-size: 10px 100%, 17px 100%, 21px 100%, 100% 10px, 100% 17px, 100% 21px;
backgroud-position: 0 0, 6px 0, 14px 0, 0 0, 0 6px, 0 16px;

linen

Now lets play with radial gradients. We’ll start with basic patterns and build up to more complex combinations.

background-image:
   radial-gradient( 
      rgba(0,0,0,0.1),
      rgba(0,0,0,0.1) 45%,
      rgba(0,0,0,0) 50%,
      rgba(0,0,0,0) 95%);
background-size: 8px 8px;

speckeled

Now we’ll take the above pattern and turn the dots inside out so that the pattern looks like someone cut holes in the color.

background-image:
   radial-gradient( 
      rgba(0,0,0,0),
      rgba(0,0,0,0) 50%,
      rgba(0,0,0,0.1) 55%,
      rgba(0,0,0,0.1) 95%);
background-size: 10px 10px;

spotted

Now we’ll just play with the size of circles a bit.

background-image:
   radial-gradient( 
      rgba(0,0,0,0.1),
      rgba(0,0,0,0.1) 9px,
      rgba(0,0,0,0) 9px,
      rgba(0,0,0,0) 17px);
background-size: 18px 18px;

circles

OK, I now the above patterns are not revolutionary or anthing. Now we’re going to get creative. For the next ones we’re going to user colors, yeah! The next pattern has a gold background with orange and greenish polka dots:

background-image:
   radial-gradient( 
      rgba(255,0,0,0.2),
      rgba(255,0,0,0.2) 4px,
      rgba(255,255,255,.10) 5px,
      rgba(255,255,255,.10) 7px),
   radial-gradient( 
      rgba(0,0,0,0.2),
      rgba(0,0,0,0.2) 4px,
      rgba(255,255,255,.25) 5px,
      rgba(255,255,255,.25) 7px);
background-size: 18px 18px;
background-color: #ffd239;
background-position: 10px 10px, 0% 0%;

gold-polka-dots

The next one I call puff balls because of their look:

background-image:
   radial-gradient(
      rgba(255,255,255,0) 90%,
      rgba(255,255,255,.5) 90%,
      rgba(255,255,255,.5)
   ),
   radial-gradient( 
      rgba(255,255,255,0.01),
      rgba(255,255,255,0.01) 10%,
      rgba(255,255,255,255.1) 70%,
      rgba(0,0,0,0) 79%,
      rgba(0,0,0,0) 96%);
background-size: 20px 20px;
background-color: #ff77a1;

puff-balls

Here’s another gold pattern with four-pointed stars:

background-image:
   radial-gradient( 
      rgba(255,0,0,0.2),
      rgba(255,0,0,0.2) 8.5px,
      rgba(255,255,255,.5) 9.5px,
      rgba(255,255,255,.5) 17.5px),
   radial-gradient( 
      rgba(0,0,0,0.2),
      rgba(0,0,0,0.2) 8.5px,
      rgba(255,255,255,.15) 9.5px,
      rgba(255,255,255,.15) 17.5px);
background-size: 18px 18px;
background-color: gold;
background-position: 9px 9px, 0% 0%;

gold stars

And here we change the background to green:

background-image:
   radial-gradient( 
      rgba(255,210,57,0.42),
      rgba(255,210,57,0.42) 9px,
      rgba(0,0,0,0) 11px,
      rgba(0,0,0,0) 15px),
   radial-gradient( 
      rgba(0,0,0,0),
      rgba(0,0,0,0) 9px,
      rgba(255,210,57,1) 10px,
      rgba(255,210,57,1) 15px);
background-size: 17px 17px;
background-color: #1e8e04;
background-position: 8.5px 8.5px, 0% 0%;

green stars

And finally, we do some interesting overlap with the radial gradients:

background-image:
   radial-gradient( 
      rgba(255,255,255,0),
      rgba(255,255,255,0.5) 14px,
      rgba(255,255,255,0) 14px,
      rgba(255,255,255,0) 26px),
   radial-gradient( 
      rgba(0,0,255,0.31),
      rgba(0,0,255,0.31) 14px,
      rgba(255,255,255,0) 16px);
background-size: 28px 28px, 28px 28px;
background-position: 14px 18px, 0% 18px, 0% 0%;
background-color: rgba(200,250,190,0.5);

petals

You can see these gradients in action here. You can same the page to your desktop, since it is a self-contained document.

Proposed Changes to Spec

So, as I mentioned, since January 2012 the draft for CSS gradients at the W3C has some notation changes. Really their minor, but in my opinion, not necessary. Actually, I’m irritated by them. The two owners of the document: Elika J. Etemad and Tab Atkins Jr., from Mozilla and Google respectively, have decided to make the notation more English-like by requiring prepositions for the position keywords for linear and radial gradients. So if you had a yellow to red linear gradient that ended in the bottom right, you’d need to write the following:

linear-gradient(to bottom right, yellow, red);

For a radial gradient, it would be

radial-gradient(circle at closest-side, yellow, red);

OK, so if the point is to make it more English-like, shouldn’t it be:

linear-gradient(to the bottom right, yellow, red)

Or better yet:

linear-gradient(directed toward the bottom right, yellow, red);

Or:

radial-gradient(a circle positioned at closest-side, yellow, red);

And, last time I check, a big chuck of the world doesn’t know what the English word “to” means and so it adds no clarity to what the keywords are doing. I’m totally against requiring unnecessary English grammatical constructs in to CSS. We don’t do that with HTML or JavaScript. What strikes me as really odd, one of the authors is from Mozilla. They were the guys that complained that the original Webkit notation used “to” and “from” to designate the start and end colors. Now they want to make the simpler notation more complicated. Adding prepositions to keywords for gradients will not add any new functionality nor prevent any rendering errors. They just make the notation more wordy. Fail! Making CSS more English-like is a rabbit hole down which you do not want to go.

March 23, 2012

Since writing this post there has been some ongoing discussion at CSS Working Group about the reasoning behind the use of prefixes in the new syntax. The gist of it is that prepositions actually remove the ambiguity of direction when dealing with gradients. Here’s a quote from the discussions:

The “to” keyword was added to linear gradients because there was
significant confusion about whether “top” meant “start from the top
(put the 0% color on the top)” or “point toward the top (put the 100%
color on the top)”.

Radial gradients gained keywords in an attempt to make the syntax more
flexible and more readable – previously, for example, you could have a
declaration like “radial-gradient(20% 20%, 30% 30%, black, white)”.
It’s very unclear what that means – even if you know that one of them
is a position and the other is a size, how can you tell which is
which? Due to this ambiguity, the syntax also disallowed specifying
just a size without a position.

The new syntax, while not ideal in some ways, solves this problem –
you’d write the previous example as “radial-gradient(30% 30% at 20%
20%, black, white)” which gives you some clues as to which is the size
and which is the position. As well, it’s now possible to specify
either a size or a position alone, and have it parsed unambiguously –
“radial-gradient(30% 30%, black, white)” has an explicit size and
default position, while “radial-gradient(at 20% 20%, black, white)”
has an explicit position and default size.

In light of the above I’ve been won over to support prepositions in the gradient syntax. It solves the problems described above and will make creating gradients easier for everyone.

Back and Next Buttons Revisited

So, many moons ago, I wrote a post about how to make iOS style “Back” and “Next” buttons using CSS. Only problem was that technique used a span tag to create the pointer. For some reason it slipped my mind that I could use the CSS generated content property with the :before pseudo-element. Rather than being bothered with having to stick spans into buttons to turn them into pointers, I now introduce you to a more sane method of creating “Back” and “Next” buttons with just CSS.

Now you might be wondering how we would generate the node we need to style as a pointer. Using the CSS content property we can generate automatic content inside the button, removing the necessity of having a tag sitting there for no other reason. Unfortunately the content property only generates alpha-numeric content. We can’t use it to create a span or any other tag. But we don’t have to use a normal character as the content. A space will suffice to create the desired pointer. We make it display as a block element and then style it as if it were a normal pointer. Problem solved.

To accomplish our goal we need to switch out any reference to < span.pointer for :before

So, here’s the styles for a normal button, followed by the styles for the pointer.


.button.bordered.back:before {
	content: " ";
	display: block;
	z-index: 0;
	background-image: 
		-webkit-gradient(linear, left top, right bottom, 
			from(#92a1bf), 
			color-stop(0.3, #798aad),
			color-stop(0.51, #6276a0), 
			color-stop(0.51, #556a97), 
			color-stop(0.75, #566c98),
			to(#546993)); 
	border-left: solid 1px #484e59;
	border-bottom: solid 1px #9aa5bb;
	-webkit-border-top-left-radius: 5px;
	-webkit-border-bottom-right-radius: 5px;
	-webkit-border-bottom-left-radius: 4px;
	height: 23.5px;
	width: 23.5px;
	display: inline-block;
	-webkit-transform: rotate(45deg);
	-webkit-mask-image: 
		-webkit-gradient(linear, left bottom, right top, 
			from(#000000), 
			color-stop(0.5,#000000), 
			color-stop(0.5, transparent), 
			to(transparent));
	position: absolute;
	left: -9px;
	top: 2.5px;
	-webkit-background-clip: content;
}
.button.bordered.back:hover:before, .button.bordered.back.touched:before {
	background-image: 
		-webkit-gradient(linear, left top, right bottom, 
			from(#7d88a5), 
			color-stop(0.3, #58698c),
			color-stop(0.51, #3a4e78), 
			color-stop(0.51, #253c6a), 
			color-stop(0.75, #273f6d),
			to(#273f6d)); 
}

You can check out the finished version online or download the source code.

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.

The Holy Grail of Mobile Layout

The Holy Grail of Mobile Layout

The perfect mobile layout should allow the presence of a navbar, a content area and maybe a footer toolbar. This layout should resize with orientation changes such that the bottom toolbar is always at the bottom and the content area resizes its width and height to fit the new dimensions. This is tough because, first off, there is not fixed positioning, and secondly, there is no single finger scrolling in Webkit for CSS defined scrolling regions.

it’s taken me a while to come up with a solution to these layout requirements. Any of you trying to make a Web app feel like a native mobile app know the frustration of trying to deal with orientation change and complex layout. Not being able to make a toxic mix of viewport meta tags, CSS media queries and onorientationchange events work to give me a fluidly resizing layout when the mobile device’s orientation changed drove me to despair. I compensated early on using JavaScript to resize everything, except I had to pay a performance penalty, especially if an app was complex. After a lot of sweat and blood and endless trial and error, I finally came up with a CSS only solution to making a layout that resizes smoothly with orientation changes.

So, the first big mistake, one that everyone and their brother recommends, is not to use the meta tag viewport settings of device width and device height. Instead, just use the initial scale, maximum scale and user scalability:

<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

The reason is that no matter what you set the width and height to with CSS, Webkit insists on thinking the document should have the height and width from when the document first loaded. This happens even if you use a CSS value of “width: 100%”. Switching from portrait to landscape, you’ll see that your layout fails to fill the width of the landscape screen:

iPhone Portrait Layout

iPhone Portrait Layout

iPhone Landscape Layout

iPhone Landscape Layout

As you can see with the landscape orientation the layout fails to fill the available width of the device. This app has its root elements’ widths set to 100% and a meta tag of:

<meta name="viewport" content="width=device-width; height=device-height; initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

Removing the device width and height from the meta tag will give us the fluid layout we seek:

<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

With the above change, when switching this document loaded in portrait orientation to landscape mode orientation we get a resized document the way we would like:

iPhone Landscape Layout Correctly Resized

iPhone Landscape Layout Correctly Resized

OK, so we have a navbar on the top, but what if we want a toolbar on the bottom? No problem. We can accomplish that with a few adjustments. To fix the toolbar to the bottom we’ll use absolute positioning. One thing to remember about this layout technique, if you are going to have navbars or toolbars, you’ll need to adjust the height of the content so that it fits the space left over by the bars. I do this using a class or class on the content section. A navbar or toolbar has a default height of 45 pixels, so you’d want to position your content that distance from a navbar or toolbar. To make this work, we’re going to have to use absolute positioning on the content section and on any bottom toolbar. One thing rather frustrating about using absolute positioning on block elements is that it causes them to collapse to what their content is, even with they have a width of 100%. We can get around this by setting the appropriate side to 0 pixels. For a bottom toolbar this could be something like this:

.toolbar.bottom {
    height: 45px;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
}

With the above measurement, we have a toolbar that is 45px high fixed to the bottom and stretching from side to side. This toolbar will maintain these dimensions and placement even with an orientation change. We’ll need to do something similar for the content area. Like I said, we’ll need to use absolute positioning and account for any space taken up by a nav or toolbar. I use classes to do this, such as “withNavbar”, or “withNavbar withBottomToolbar”, or “withBottomToolbar”. The CSS for these classes would be something like this:

/* Definition for content area that fills the screen: */
#content {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
#content.withNavbar {
    top: 45px;
    right: 0;
    bottom: 0;
    left: 0;
}
#content.withBottomToolbar {
    top: 0;
    right: 0;
    bottom: 45px;
    left: 0;
}
#content.withNavbar.withBottomToolbar {
    top: 45px;
    right: 0;
    bottom: 45px;
    left: 0;
}

We also need to make sure that the document’s content doesn’t bleed down below the bottom toolbar. We do this by wrapping the entire document in a div. I give it an id of #main:

<body>
	<div id="main">
		<div class="navbar">
			<h1>The Title</h1>
		</div>
		<div id="content" class="withNavbar withBottomToolbar">
			<ul class="table-view">
				<li><span class="title">Item One</span></li>
				<li><span class="title">Item Two</span></li>
				<li><span class="title">Item Three</span></li>
				<li><span class="title">Item Four</span></li>
				<li><span class="title">Item Five</span></li>
				<li><span class="title">Item Six</span></li>
				<li><span class="title">Item Seven</span></li>
				<li><span class="title">Item Eight</span></li>
			</ul>
		</div>
		<div class="toolbar placement-bottom">
			<div class="button">Edit</div>
			<div class="button">Save</div>
		</div>
	</div>
</body>

The styles for the div#main would be:

#main {
	width: 100%;
	display: -webkit-box;
	margin: 0 0 0 0;
	padding: 0;
	height: 100%;
	-webkit-box-orient: vertical;
	-webkit-box-align: stretch;
	-webkit-box-sizing: border-box;
	-webkit-transition: all 0.25s  ease-in-out;
	overflow: hidden;
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
}

Although the above arrangement solves the layout problems for mobile interfaces with automatic adjustment with orientation changes, it presents a new problem. That’s the problem of making the data in the content area reachable by the user. You’ll need to add a way for the user to scroll just that area. Normally the whole document would scroll with the browser, with the result that the top part would scroll out of view. Since we’ve fixed the toolbar to the bottom and have the height of the content area control by absolute position affecting its top, right, bottom and left, we need to provide a way to enable scrolling. Actually we could do this very simply using the CSS overflow property: #content { overflow-y: auto; }. However, on mobile Webkit this requires a two finger gesture. Most users would not expect this. They’ll use a single finger and think that the content is not scrollable.

There’s a simple way to provide single finger scrolling with a JavaScript module called “iScroll” created by Matteo Spinelli. This is a great implementation which provides deceleration animation of the scrolling, just like iOS, Android and other mobile OSes. One thing to be aware of when using iScroll, you don’t use it directly on the content container as this would cause that contain to slide up and down over the navbar and toolbar. Instead you’ll need to add an extra div tag inside it and use iScroll on that. iScroll will then enable scrolling of the div inside the content div. There are a number of options, my favorite is for desktop simulation. Here how you would do it:

<div id="content" class="withNavbar withBottomToolbar">
    <div id="scrollwrapper">
        <!-- Content In Here -->
    </div>
</div>
.........

<script type="text/javascript">
    var scroller = new iScroll(’scrollwrapper’, { desktopCompatibility : 
        true });
</script>

This gives you a basic mobile Web interface with a top navbar, a bottom toolbar and a content area with scroll that resizes quickly with orientation change.

Since publishing this article, I’ve created a framework for creating mobile Web apps. It uses many of the techniques explored in my blog posts. You can learn more about the framework by visiting ChocolateChip-UI.com. There are demos you can try in your desktop browser or on your mobile device.

Practical Examples of the Flexible Box Model

If there’s one thing in CSS3 that really gives me warm fuzzies, it’s the flexible box model. What it does is provides a way to create many layout affects that otherwise would require workarounds with float or positioning or both. And there are many types of layouts that without out it would require JavaScript to create the same effect. Sadly, at present the flexible box model is only implemented in Firefox, Safari and Chrome. As it turns out, Microsoft’s IE team approached the W3C standards teams with a proposal for a grid-based layout module. It appears to be based on experience implementing the Silverlight grid layout system, which is a good thing. Silverlight grids are a powerful layout tool and is the most important feature for creating interfaces with Silverlight. Because this grid proposal is very solid, the W3C has dropped all further work on the flexible box model and instead are moving ahead in finalizing the draft for the grid layout module. If you read that speck, you’ll realize how much we need a CSS grid system. For now, however, we do have the flexible box model working in Firefox, Chrome and Safari, as well as on mobile Webkit, which includes iOS, Android, WebOS, and Blackberry. This means that if you’re doing mobile development you can use the flexible box model today to help you implement your layout needs. Once you start using the flexible box model, you’ll hate having to go back to situations where it’s not available.

The flexible box model got a lot of attention from a post by Alex Russell back in August 2009. The good thing is that in his post he showed some of the practical things that the flexible box model addresses and provided a stylesheet with a small subset of the flexible box model properties that people could use right away. His post has been replicated and linked to all over the Web. Unfortunately a lot of people who are not familiar with the spec for the flexible box model are under the impression that what’s in his stylesheet is it. So, with that in mind I’m loosing another stylesheet on the public that allows a greater utilization of the flexible box model. I’ll also give you a layout where a lot of these are in use so that you can see how they work.

Before I get going let me say this. The flexible box model is not perfect. It isn’t supported by IE9 or Opera. And now it looks like the W3C is bypassing it for a more robust grid system. Personally, I’d like to see something like the Silverlight grid system combined with aspects of the flexible box model. That would be the best of both approaches. If you’re targeting the mobile Web, in other words you intend on target Webkit browsers, you can expect robust support for the flexible box model. I doubt it’s going to go away just because the W3C doesn’t include it in any recommendation. I expect it to remain in Webkit for the foreseeable future because it’s already been in use for a number of years.

The flexible box model is about the way a collection of child nodes gets laid out in relation to each other and their parent node. To achieve its layout goals, the flexible box model offers properties for the parent node as well as for the child nodes that determine the layout characteristics of the child nodes.

To work with the flexible box model you need to define its display property to box:

#myDiv {
    display: -webkit-box;
    display: -moz-box;
}

Elements with display set to box can order their child nodes in two orientations: vertical or horizontal. If no orientation is provided, the box defaults to vertical:

#myDiv {
    display: -webkit-box;
   -webkit-box-orient: horizontal;
    display: -moz-box;
    -moz-box-orient: horizontal;
}

Besides defining the orientation, you can also designate what direction the child elements stack, either normal or reverse. A box direction of reverse means the elements display in the opposite order in which they physically appear in the document, so that the first would be last and the last first. By default the box direction is normal stacking order.

Then there is the packing order. This allows you to define how the child elements are packed inside the parent. By default they are packed in from the beginning of the parent. For vertical orientation this is the top and for horizontal orientation this is the left. Other packing orders are end, center and justify. If the packing order is end, for a vertical orientation the elements will stack up from the bottom. For a box with horizontal alignment, the boxes will stack from the right. A packing order of center means that for vertical orientation the child elements will be centered vertical with any left over space displayed equally at the top and bottom. For horizontal orientation a packing order of center means the elements are centered horizontally with left over space equally divided on the left and right. A packing order of justified means that any available space is spread equally between the child elements, for vertical orientation this is vertical spacing, and for horizontal orientation this is horizontal spacing.

Box-align-start

A box with alignment set to "start"

box-align-end

A box with alignment set to "end"

box-align-center

A box with alignment set to "center"

And elements can have their box alignment defined. The default is stretch. This stretches the dimensions of the child elements to fill the parent box. If the alignment is start, for horizontal orientation the elements are aligned to the top of the parent. If the orientation is vertical, they are aligned to the left of the parent. An alignment of end will align elements with horizontal alignment to the bottom of the parent. With vertical orientation they will be aligned to the right of the parent. An alignment of center will align horizontal elements along the horizontal center of the parent and for vertical orientation it will center them along the vertical center of the parent. There is also an alignment of baseline, but this is only for horizontal orientation. It aligns the elements along their horizontal baseline.

Then there is a set of properties that you can define on the child elements. These are flex and ordinal group. The flex property tells the browser how to deal with the dimensions of the child element. If you have three child elements and they don’t fill their parent, giving one of the a value of flex:1 will cause that element to take up all the left over space. If you gave one element flex: 1 and another one flex: 2, the available space would be divided up such that the element with flex: 1 would get one third of the available space and the element with flex: 2 would get two thirds of the available space. Of course the element with no flex value would default to whatever its width is. The ordinal group property allows you to designate groups of elements so that they appear in a different order than their document order. I’m not so sure about the practical use for this property. I’ve thought about it for months and have not been able to come up with a use case where I would need it. But it’s there.

I’ve created a flexible box model stylesheet with classes for all the various box properties. This means you can add the classes to an element to build out the definition you need for an element. I’ve also put together a interactive test case where you can dynamically toggle a number of the box properties and see their effect in real time. You can try it out online if you’re using Firefox, Chrome or Safari, or you can download the working example to dissect and learn.

Multiple Background Images & Animation

Multiple background images allow one to build up complex layered visual effects using one element. In the past such effects would require each background image rendered inside its own element, these being either nested or stacked on top of each other with positioning. When I was working on creating the progress bar example, I ran to a problem where I couldn’t seem to get a specific layer to animate. I could figure out what was going on. Recently, after looking at the code and fiddling with it, I found out what the problem was. Animation of background images works a little differently from other CSS properties. Because multiple backgrounds consists of multiple definitions, it works more like other properties with multiple property values: margins, borders, padding. For example, you can animate all borders on an element, otherwise you can animate a single border. Unfortunately, with multiple backgrounds there is no easy way to single out an individual background image for animation as you can with a border, margin or padding property.

Now the thing to bare in mind when dealing with multiple background images is the stacking order. The first image defined is the topmost image, and the last image defined is the bottommost. Same thing with animations for multiple background images. So, in the case of the animated progress bar, I wanted to animate the bottommost gradient image which consisted of white slanted bars. The rest of the progress bar was fine stable. Well, except that I used a single animation which would instead affect the topmost layer, making it impossible for me to get the stacking layer they way I wanted. Here is the gradient:

background-color: rgb(56,138,213);
background-image:
	-webkit-gradient(linear, 18 0, 0 10,
		color-stop(0.23, rgba(255,255,255,0)),
		color-stop(0.3, rgba(255,255,255,0.8)),
		color-stop(0.3, rgba(255,255,255,1)),
		color-stop(0.7, rgba(255,255,255,1)),
		color-stop(0.7, rgba(255,255,255,0.8)),
		color-stop(0.77, rgba(255,255,255,0))),
	-webkit-gradient(linear, 0 0, 0 100%,
		color-stop(0, rgba(255,255,255,.8)),
		color-stop(0.45, rgba(255,255,255,.05)),
		color-stop(0.55, rgba(0,0,0,.05)),
		color-stop(0.85, rgba(0,0,0,.2)),
		color-stop(0.98, rgba(0,0,0,.5))),
	-webkit-gradient(linear, 0 0, 0 100%,
		color-stop(0.20, transparent),
		color-stop(0.20, rgba(255,255,255,.5)),
		color-stop(0.32, rgba(255,255,255,.5)),
		color-stop(0.32, transparent));

To animate this, I was using a key-frame animation that moved the x axis of the background gradient across the element from 0 to 100% in a loop:

@-webkit-keyframes progressBarAnim {
	0% { background-position-x:  0%; }
	100% { background-position-x: 100%; }
}

If you ran my previous example of the progress bar, it animates as you would expect, except one problem. The topmost gradient layer is the part that should be on the bottom. Yet every time I positioned it to where I wanted it, it wouldn’t animate. In my mind I was thinking that the key frame animation defined above would be animating all the background images. Actually, it doesn’t. It only animates the topmost image background, which is why I had to have the part I wanted to animate on top. Unfortunately I didn’t figure this out until recently. After a lot of fiddling and digging into what was going on with animation of multiple background images, I finally sorted it all out. When defining animations you have to start from the top and work you way down. You don’t have to include an animation for every background image, only down to the layer you need to. But you do have to include all the layers above the animated one up to the topmost one. So here’s my new stacking order for the CSS the way I actually wanted it:

background-color: rgb(56,138,213);
background-image:
	-webkit-gradient(linear, 0 0, 0 100%,
		color-stop(0, rgba(255,255,255,.8)),
		color-stop(0.45, rgba(255,255,255,.05)),
		color-stop(0.55, rgba(0,0,0,.05)),
		color-stop(0.85, rgba(0,0,0,.2)),
		color-stop(0.98, rgba(0,0,0,.5))),
	-webkit-gradient(linear, 0 0, 0 100%,
		color-stop(0.20, transparent),
		color-stop(0.20, rgba(255,255,255,.5)),
		color-stop(0.32, rgba(255,255,255,.5)),
		color-stop(0.32, transparent)),
	-webkit-gradient(linear, 18 0, 0 10,
		color-stop(0.23, rgba(255,255,255,0)),
		color-stop(0.3, rgba(255,255,255,0.8)),
		color-stop(0.3, rgba(255,255,255,1)),
		color-stop(0.7, rgba(255,255,255,1)),
		color-stop(0.7, rgba(255,255,255,0.8)),
		color-stop(0.77, rgba(255,255,255,0)));

And here’s the key frame animation, notice the extra animations for the upper layers:

@-webkit-keyframes progressBarAnim {
	0% { background-position-x:  0%, 0%, 0%; }
	100% { background-position-x: 0%, 0%, 100%; }
}

So remember, in the above key frame animation the first value if for the topmost layer and the last value is for the bottom most layer.

To show the difference in the stacking order, I changed the white stripe that goes horizontally across the progress bar to black. In the wrong stacking order version you can see that its actually behind the white stripes. The corrected version with multiple background animations has it correctly on top:

progress bar with incorrect stacking order

progress bar with incorrect stacking order



progress bar with correct stacking order

progress bar with correct stacking order

Of course, the final product would not be a black streak, it would be white. This was just to show how the stacking order was previously wrong.

CSS Gradients for IE9

This works with Desktop IE9, Desktop Firefox, Desktop Chrome, Desktop Safari, Desktop Opera, iOS, and Android.

Attention! IE9 will not destroy the world, kill babies, or take away your home or job.

Simply put, IE9 is the best browser Microsoft has ever released. Has it caught up to Chrome, Firefox and Safari? No. But that doesn’t matter. It’s still light years ahead of any other version of IE. All of us should be praying every day for IE users to upgrade to it as soon as possible.

Shortly after the initial launch of the beta of IE9, I began testing to see what kind of support it had for all the rich and exciting features CSS3 offers for Web layout and interaction. The earlier beta’s didn’t have much, but with each release it has gotten better. If you’re already using advanced CSS3 for Web development and never bothered supporting IE before, you’ll want to know what it supports and what it doesn’t. Here’s what it supports at present right from the horse’s mouth. In particular, it supports real CSS opacity, multiple background images, box shadows, border radius, background-clip, background-size, background-position, WOFF for Web fonts, RGBA and HSLA color, box sizing, as well as the full suite of CSS3 selectors. The above post also talks about support for CSS3 2d transforms, however, even with the -ms- vender prefix I am unable to get it to work with the present beta (7).
Update: Transforms are working in Platform Preview 6, which is different from the present public beta. Microsoft is taking a two track approach to releasing this: the public beta for general users to test and a platform preview where features are introduced but not necessary finalized.

So what didn’t make it into IE9? First up, the flexible box model. Once you’ve used the flexible box model for layout, it’s as painful as eating glass to go back to using floats and positioning for layout. No text shadow, which is a strange omission considering they have box shadow. No border images. No CSS transitions. The single-threaded nature of JavaScript makes it inefficient for complex animations. Offloading style animations to the browser’s CSS rendering engine frees up JavaScript and allows the browser to use threads and hardware acceleration for better optimization. In my opinion, CSS3 transitions are more important than CSS3 transforms. Since Firefox, Opera and Webkit all support CSS3 transitions to some degree, it’s a odd omission for IE9. No 2d or 3d transforms. As I mentioned before, transforms do not appear to be implemented in the current beta. (Someone correct me if I’m wrong on this.) The thing I love about CSS3 transitions and transforms is that they allow you to create user interactions that make a Web application feel like a native one, blurring the difference between desktop and Web. No CSS3 keyframe animation. If you thought CSS3 transitions were awesome, you be blown away by CSS keyframe animations.

When I look at IE9’s support for CSS3, it appears they decided to pick the low hanging fruit: border radius, drop shadow, multiple backgrounds, etc. But the flexible box model, gradients, transitions, transforms and keyframe animation are the things in CSS3 that really turn your head.

I have no experience working with Adobe Flash. I do have extensive experience working with Microsoft’s Silverlight platform. I love how it enables you to create rich, interactive user interfaces where you can customize every aspect of a control’s look and feel. Chrome, Firefox and Safari’s support for CSS3 enables a similar high level of possibilities for the creation of Web user interfaces. IE9 is attempting to achieve feature parity with the other browsers and is making good progress. But if you want to use the CSS3 features that IE9 doesn’t support, you’ll need to find workarounds.

Presently my main area of focus is the mobile Web on Android, Blackberry 6, iOS and WebOS. That’s a world ruled by Webkit. But I usually make efforts to ensure that my solutions can also work with modern desktop browsers: Chrome, Firefox and Safari. That involves a lot of vender prefixes: -moz, -webkit. And then you need to future proof it by supplying the same property without the vendor prefix. This technique allows browsers that understand the properties, like IE9, to also render them without any extra effort.

I’m going to take one example of an HTML/CSS3 implementation of iOS’s popup dialog box which I originally created for use on iOS devices and show how I got it to render equally in Chrome, Firefox, IE9, Opera and Safari. At the end of this post you’ll find links to try it out online or download it. One thing, I’m not using any image pieces, just CSS3 properties. Here’s the initial state of the page with the popup in Safari and Firefox:

popup Initial state

Here’s the page with the popup in view in Safari and Firefox:

Here’s the same markup in IE9. Notice how it understands border radius, box shadow and RGBA background color, but cannot render the flexible box model layout nor the CSS3 gradients.

ie9 initial state no styleie9 final state no style

IE9’s lack of support for the flexible box model can be resolved by using old-school layout techniques (floats/positioning). But there is no way to fake CSS3 gradients with pngs. When you stretch them they exhibit banding. Since I make extensive use of CSS3 gradients all the time, I felt pressed to find a solution for IE9. After spending some time experimenting with SVG in IE9, I hit on an idea. Using an IE9 specific stylesheet, I would try setting SVG gradients as background images on the element’s that use CSS3 gradients. The technique works quite well. Here’s IE9 with its custom CSS:

ie9 initial state fixedie9 final state fixed

First, here’s a CSS3 gradient used by Chrome, Firefox and Safari:

header {
	width: 100%;
	display: -webkit-box;
	display: -moz-box;
	display: box;
	-webkit-box-orient: horizontal;
	-webkit-box-pack:justify;
	-webkit-box-align: center;
	-webkit-box-sizing: border-box;
	-moz-box-orient: horizontal;
	-moz-box-align: center;
	-moz-box-pack:justify;
	-moz-box-sizing: border-box;
	box-orient: horizontal;
	box-align: center;
	box-pack:justify;
	box-sizing: border-box;
	height: 45px;
	margin: 0;
	padding: 0 10px;
	background-image: 
		-webkit-gradient(linear, left top, left bottom, 
			from(#b2bbca), 
			color-stop(0.25, #a7b0c3),
			color-stop(0.5, #909cb3), 
			color-stop(0.5, #8593ac), 
			color-stop(0.75, #7c8ba5),
			to(#73839f)); 
	background-image: 
		-moz-linear-gradient(top,
			#b2bbca, 
			#a7b0c3 25%,
			#909cb3 50%, 
			#8593ac 50%, 
			#7c8ba5 75%,
			#73839f); 
	border-top: 1px solid #cdd5df;
	border-bottom: 1px solid #2d3642; 
}

As you can see in the above code, we’re defining background images as gradients with a number of color stops. That all a CSS3 background gradient is. As a matter of fact, it’s rendered by the browser as a canvas background image. Since IE9 supports SVG, including as background images, I’ve come up with a way to use SVG gradient images as background gradients. Because SVG is vector-based, the gradients scale without banding. SVG is an XML markup language for describing vector graphics. The HTML5 parsing engine allows SVG to be directly embedded in HTML. But I want background images. By defining the height of the SVG document as 100%, I have an image that will scale to whatever the element is, just like the CSS3 gradient. Here’s the markup that I used to create the gradient for the header. Notice that the SVG gradient has color-stops and offsets like the CSS gradients. They aren’t that different.

<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" version="1.0" width="100%" 
   height="100%" 
     xmlns:xlink="http://www.w3.org/1999/xlink">

  <defs>
    <linearGradient id="myLinearGradient1"
                    x1="0%" y1="0%"
                    x2="0%" y2="100%"
                    spreadMethod="pad">
      <stop offset="0%"   stop-color="#b2bbca" stop-opacity="1"/>
      <stop offset="50%"   stop-color="#909cb3" stop-opacity="1"/>
      <stop offset="50%"   stop-color="#8593ac" stop-opacity="1"/>
      <stop offset="100%" stop-color="#73839f" stop-opacity="1"/>
    </linearGradient>
  </defs>

  <rect width="100%" height="100%"
     style="fill:url(#myLinearGradient1);" />
</svg>

The document has a height and width of 100%, the gradient is set to expand to 100% and the rectangle is defined with a height and width of 100%. It is possible to turn this SVG image into a datauri and put it directly in the CSS, using use any of the many resources available for datauri conversion. However, the SVG files are just simple text files. If you convert them to datauris, you will not be able to make any changes to them. While putting this demo together I had to constantly tweak the values in the SVG gradients to get them exact. Keeping the SVG files allows you to go back and modify the gradients at any time. Here’s how you use this for IE9:

header {
  background-image: url("svg-gradient.svg");
}

That’s it. IE9 will display the above SVG graphic in a manner indistinguishable from native CSS3 gradients.

For the repeating striped background gradient on the body tag, I’m using a CSS3 gradient with background sizing and letting it repeat across the page. For IE9 I do the same thing, using background sizing on the SVG equivalent to get the same effect.

Like IE9, Opera also does not support the flexible box model nor CSS3 gradients. Notice how Opera renders the demo basically the same as IE9:

Opera initial state no styleOpera final state no style

After creating the SVG workaround for IE9 to mimic CSS3 gradients, I started thinking about Opera’s lack of support for CSS3 gradients. Opera has the best support for SVG out of all the browsers. I therefore tried giving Opera the same CSS that I gave IE9. It worked as well as it did for IE9. You can see the results below:

Opera inital state fixedOpera final state fixed

There is very minimal browser sniffing required to make this work across modern browsers. One stylesheet for Chrome, Firefox and Safari, a conditional comment for IE9 and a browser agent sniff for Opera:

<!--[if IE 9]>
	 <link rel="stylesheet" type="text/css" href="popup-svg.css">
<![endif]-->

<script type="text/javascript">
    var Opera = /opera/i.test(navigator.userAgent);
    if (Opera) {
        var link = document.createElement("link");
        link.setAttribute("rel", "stylesheet");
        link.setAttribute("href", "popup-svg.css");
        document.getElementsByTagName("head")[0].appendChild(link);
}
</script>

Please Note: If you’re going to use this technique in a production environment you should use feature detection because at some point Opera will support CSS gradients. There are a number of ways to accomplish feature detection. Perhaps the easiest is to use Modernizr.

You can try out this demo online or download the source code. Feel free to use the included SVG files as templates for your own gradients.

Oh, and one last thing. I’m using the ChocolateChip mobile JavaScript framework for this demo. Originally I created it to work on mobile devices using Webkit browsers. I therefore provided no support for the JScript quirks of IE. But since IE9 has a completely rewritten JavaScript engine and uses the standard event model and DOM interfaces like the other browsers, ChocolateChip works fine on it without modification. That definitely put a smile on my face.

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.

Subpixel Rendering

You know the problem. No matter what you do you can’t get two elements to line up properly. The connecting points are always off by one pixel.

Everyone doing Web development at some point or other comes across a layout problem where no matter what you do, you can’t get two elements to align perfectly. One or the other is always off by one pixel. I was pulling my hair out try to get the pointers on the back and next buttons to align perfectly. They just didn’t look perfect. Worse still, when I used the browser’s “Zoom In” command from the view menu, I could clearly see that the lines did not connect properly.

After hours of fiddling with element sizes and positioning, I was on the verge of giving up. It was then that I remembered similar layout problems that I dealt with when doing Silverlight development. Silverlight is Microsoft’s vector-based, Flash killer/non-killer plugin for creating RIAs. For whatever reason, versiond before 4.0 had terrible problems with exact positioning of elements, causing frequent one pixel disconnects when rendered to screen. The only way to resolve this was to use subpixel rendering. This was accomplished by positioning an element by using partial pixel values, such as 1.5 or 1.25. This would force Silverlight to output the element with subpixel rendering, eliminating the visual disconnect.

OK, so what the heck is subpixel rendering? You experience it everyday with the browser’s font smoothing. You know it as anti-aliasing. The browser looks at the bézier curves of the font and when it sees that a line passes though a pixel, it looks at how much of the pixel is intersected. Depending on the percentage, the browser outputs a percentage of the font’s color. Less means the pixel gets less of the font’s color. For the human eye this creates the illusion of smoother curves.

You can use this same technique to trigger subpixel rendering on an element by giving it percentage-based position, or percentage-based dimensions. Here are some examples:

.button {
    position: absolute;
    left: 0px;
    top: 2.5px;
    height: 23.5px;
    width: 23.5px;
}

Here’s a image of my next button with the browser zoomed in. As you can see the pointer doesn’t line up perfectly with the rest of the button. This caused a slightly noticeable disconnect at normal size as well.

next button with its pointer misaligned

Now here’s the same button with the pointer using position set to top: 2.5px;:

next button using subpixel positioning

Subpixel rendering solved the connect problem I had at all zoom levels, including at normal size. Depending on your problem, subpixel positioning may be enough, or subpixel dimensions may be enough, or you may need to do both. Using subpixel values can help resolve problems when your layouts are not coming out pixel perfect.

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

Today’s new technology terms:

subpixel:
   A pixel rendered with a shade of an adjacent element’s color to make it appear as if the element occupies part of that pixel’s space.
subpixelate:
   To force the browser to render an element with subpixel values.
subpixelation:
   The act of forcing an element to render with subpixel values or the condition of being rendered with subpixel values.

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!

Range Slider with CSS and JavaScript

Works on desktop Safari, desktop Chrome, desktop Firefox 3.5 – 4, iPhone, iPod Touch, iPad.

In this post I’m going to show how to make a range slider using HTML, CSS and JavaScript that works with both a mouse and a finger. The mouse-enabled version required a small drag-and-drop JavaScript framework. Fortunately I had already put that together several years back. After spending some time playing around with touch events on mobile Webkit, I was able to come up with a way to implement horizontal dragging for the range slider.
range slider

I’m not going to go into details about my mouse-enable drag-and-drop framework. You can popup it open and read the copious comments in the example. However, I will explain how I implemented the touch-enabled drag for the slider.

The structure for a slider is fairly straightforward. You need a track and a thumb:

<div id="redSlider" class="slider">
	<div class="thumb"></div>
</div>

Since the structure is so simple, you might be wondering how we give it the look. The thumb gets border radius to make it round, along with a box shadow and a background-gradient, including a blue background gradient for hover. The slider track is styled with two background gradients, the bottom-most gradient is the default grey which swans the width of the slider. Layered on top of the same track is a second, bluish gradient. By using CSS3’s background sizing property, we will dynamically resize it as the slider’s thumb is dragged.

Of course, just dragging a slider thumb back in forth is not suck a big deal. I therefore created three sliders implemented as RGB pickers. By dragging each thumb, you add or subtract from a red, green or blue value. Down below you’ll see the final RGB and Hex values.
RGB Slider

Here are the basic styles for the slider:

.slider {
	display: inline-block;
	-webkit-box-sizing: border-box;
	-moz-box-sizing: padding-box;
	box-sizing: padding-box;
	-webkit-box-shadow: 2px 2px 4px #666;
	-moz-box-shadow: 2px 2px 4px #666;
	box-shadow: 2px 2px 4px #666;
	height: 9px;
	width: 277px; 
	padding: 1px;
	-webkit-border-radius: 4px;
	-moz-border-radius: 4px;
	border-radius: 4px;
	background-image: 
		-webkit-gradient(linear, left top ,left bottom,
		   from(#0a3a86),
		   color-stop(.5, #4c8de7),
		   color-stop(.95, #6babf5),
		   to(#0a3a86)),
		-webkit-gradient(linear, left top ,left bottom,
			from(#919191),
			color-stop(.5, #f0f0f0),
			color-stop(.5, #fff),
			color-stop(.95, #fff),
			to(#919191));
	background-image: 
		-moz-linear-gradient(top,
		   #0a3a86,
		   #4c8de7 50%,
		   #6babf5 95%,
		   #0a3a86),
		-moz-linear-gradient(top,
			#919191,
			#f0f0f0 50%,
			#fff 50%,
			#fff 95%,
			#919191);
	background-repeat: no-repeat, repeat-x;
}
.thumb {
	position:relative;
	-webkit-box-shadow: 2px 2px 3px #666;
	-moz-box-shadow: 2px 2px 3px #666;
	box-shadow: 2px 2px 3px #666;
	height:20px;
	width:20px;
	left: 0px; 
	top: -6px;
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	border-radius: 10px;
	background-image: 
	   -webkit-gradient(linear, left top, left bottom,
		   from(#aaa),
		   color-stop(.5, #ddd),
		   to(#ccc));
	background-image: 
	   -moz-linear-gradient(top,
		   #aaa,
		   #ddd 50%,
		   #ccc);
	cursor: move;
	-webkit-tap-highlight-color: transparent;
}
.thumb:hover, .thumb.hover {
	background-image: 
	   -webkit-gradient(linear, left top, left bottom,
		   from(#6297f2),
		   color-stop(.5, #0251ae),
		   to(#6297f2));
	background-image: 
	   -moz-linear-gradient(top,
		   #6297f2,
		   #0251ae 50%,
		   #6297f2);
}

Notice the slider’s background gradient style. The first background gradient will be the top-most. The last will be the bottom-most. But the top-most is going to be the blue part of the track that appears to the left of the thumb as it is dragged away from the left start of the range slider.

We also need some styles to set the initial states of the three thumbs. Notice that I’ve used background sizing to control the two background gradients. The first is for the blue top-most gradient, the second is for the full width grey gradient.

#redSlider .thumb {
	left: 121px;
}
#redSlider {
	-webkit-background-size: 123px 9px, 100% 9px;
	-moz-background-size: 123px 9px, 100% 9px;
	background-size: 123px 9px, 100% 9px;
}
#greenSlider .thumb {
	left: 156px;
}
#greenSlider {
	-webkit-background-size: 158px 9px, 100% 9px;
	-moz-background-size: 158px 9px, 100% 9px;
	background-size: 158px 9px, 100% 9px;
}
#blueSlider .thumb {
	left: 230px;
}
#blueSlider {
	-webkit-background-size: 232px 9px, 100% 9px;
	-moz-background-size: 232px 9px, 100% 9px;
	background-size: 232px 9px, 100% 9px;
}

So, I’ve defined two gradients with different background repeats: background-repeat: no-repeat, repeat-x; and background sizing with values such as: 123px 9px, 100% 9px. 9px is the height of the slider track. The bottom-most gradient has a width of 100%, and the top-most bluish one gets a width of 123px. By using these values, with very little markup, we can create visually and functionally complex structures.

/**
* Touch enabled support:
*/
/**
*
* Method to set the colors of color swatches and width of the slider progress track when the slider thumb is dragged.
*/
Element.prototype.setupSliderTouch = function( event ) {
	event.preventDefault();
	var el = event.target;
	var touch = event.touches[0];
	curX = touch.pageX - this.parentNode.offsetLeft;
	if (curX <= 0) { 
		curX = 0;
	}
	if (curX > 255) {
		curX = 255;
	}
};
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]));
};

$("#redSlider > .thumb").bind('touchmove', function(event) {
	this.setupSliderTouch(event);
	this.updateSliderTouch("red");
});
$("#greenSlider > .thumb").bind('touchmove', function(event) {
	this.setupSliderTouch(event);
	this.updateSliderTouch("green");
});
$("#blueSlider > .thumb").bind('touchmove', function(event) {
	this.setupSliderTouch(event);
	this.updateSliderTouch("blue");
});

Basically, I attach a touchmove event to the slider thumbs. The event listener passes the event to the setupSliderTouch method. The first thing the setupSliderTouch method does is to prevent the default interaction from taking place, such as page scrolling. We want the user to be able to move the thumb without scrolling the page. From the event passed in to setupSliderTouch we get the touch event and calculate its x coordinate on the screen. To calculate the touch’s position in relation to the slider, we subtract the left offset of the slider from the pageX of the touch. This gives us the left-most edge of the slider’s thumb. We store this as curX. We check the value of curX. If it is less than zero, we set it back to zero. We do this because this value will be used to set the position of the thumb and one of the RGB values. We don’t want either the thumb being dragged off of the left edge of the slider, nor a value less than zero, since RGB values start at zero. We do the same thing when the curX value is greater than 255 for the same reasons.

The updateSliderTouch method uses the value of the slider’s thumb to calculate and update RGB and Hex values, giving the user visual feedback as the thumb is dragged. Then we use the value of curX to update the background size of the blues background gradient on the slider track:

$("#" + color + "Slider").css("-webkit-background-size:" + (curX + 1) + "px 9px, 100% 9px");
$("#" + color + "Slider").css("background-size:" + (curX + 1) + "px 9px, 100% 9px");

That’s all there is to it. You can try this out online using desktop Safari, Chrome, or Firefox for the mouse version, or on an iPhone, iPod Touch or iPad for the touch version. Or you can download the source code, which I recommend, so you can dig into the CSS and JavaScirpt.

Update: September 15, 2010
If you’re trying this out on an iPhone, I noticed that there seems to be a very slight delay before an initial touch is registered on the screen. This means that in order to slide the thumb, you need to press and hold for a very brief moment before sliding, otherwise no touch gets registered and nothing happens. This doesn’t seem to happen when performing the same action on the iPad. Touches seem more responsive.

Activity Indicator with CSS3

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

You’ve seen them. The things on the screen that mean you’ve got to wait for some activity to complete. They’re called activity indicators. They’re usually several pieces arranged in a circle. They spin around. And if things go really bad, you could be watching them spin for quite some time. Hopefully not.
activity indicator

Usually people make these with images. There are even Web sites dedicated to making this spinning baubles for you in animated gif format. Except that gif stink. Pngs look better. I’m going to show you two ways to implement an activity indicator. One starts off with an image that has been converted into 64 bit data. We’re talking about dataurls here. Dataurls eliminate the need for separate images. It’s the same image but reduced to data which you can paste directly in your document. Heck, you can paste it directly into your CSS file so you never have to worry about losing an image or rewriting the image path when you move the CSS. Cool, huh? And if you start with a large image, you can scale it down for small screens and low resolution devices, and scale it up for hi res devices, like the iPhone and iPod Touch retina display. Cooler still, you can make the activity indicator completely out of HTML and CSS, no images, no dataurl. And by using a scale transform, you never have to worry about resolution. It will always render smoothly.

So, let’s look at dataurls. The concept is simple. Instead of having a resource reside as an external file, you convert it into a 64 bit data sample which you can include in your document. In the case of an image, it’s basically embedding it in your HTML/CSS. You can encode images as dataurls in many ways, using PHP, Python, etc., or you can simply upload a file to a Web site that will conveniently do it for you. A dataurl looks something like this (Note: I trimmed off the data to fit here):

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATEAAAEwCA+

For an image, you would do something like this:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATEAAAEwCA+...">

When you create your first dataurl you’ll probably be shocked at how big the resulting code is. Don’t worry. Somehow this winds up being more efficient for download and rendering than a traditional image. Besides being the source for an inline image, you could also embed the dataurl into your CSS as a background image. As I mentioned, my original image was large to allow for scaling up or down without loss of quality. I therefore add in some resizing to the CSS for the size of the element and the size of the background image:

.activityIndicator {
	/*
	The original height is:
	height: 304px;
	width: 305px;
	*/
	height: 40px;
	width: 40px;
	-webkit-background-size: 40px 40px;
	margin: 0px auto;
	background-image: url("data:image/png;base64,iVBORw0KGgoAAAANUb...");

This is what I used to produce the image above. Now we need to animate it. That’s actually quite easy, just a couple of lines of CSS:

.activityIndicator {
	/*
	The original height is:
	height: 304px;
	width: 305px;
	*/
	height: 40px;
	width: 40px;
	-webkit-background-size: 40px 40px;
	margin: 0px auto;
	background-image: url("data:image/png;base64,iVBORw0KGgoAAAANUb...");
	-webkit-animation-duration: 1s;
	-webkit-animation-iteration-count: infinite;
	-webkit-animation-timing-function: linear;
	-webkit-animation-name: spinnerAnim;
}
@-webkit-keyframes spinnerAnim {
	0% { -webkit-transform: rotate(0deg); }
	100% { -webkit-transform: rotate(360deg); }
}

By using the keyframe animation, we can implement the continuously spinning activity indicator without using JavaScript. But, as I mentioned, dataurls tend to be verbose and are rather unsightly. I therefore came up with a reproduction of the activity indicator using only HTML and CSS3. At the end of this post are links to the working file. Download or view source of the online document to see what the dataurl looks like. It’s not pretty, but it is efficient. However, by reproducing the same image using markup and CSS, we can achieve the same result with even less code. The markup isn’t terribly complex, two parent contains and twelve blades:

<div id="activityIndicator">
	<div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
		<div class="blade"></div>
	</div>
</div>

That’s really all we need, the rest is done with CSS3 properties. You’ll notice that all the blades have the same class “blade.” We don’t need to give each one anything special because we can use CSS3 selectors to indicate each blade individually. To do this we’ll use the :nth-child selector. We first give all the blades some generic styling. Then we start from the second blade using the CSS3 nth-child selector: .blade:nth-child(2), then .blade:nth-child(3), etc. Since there are twelve blades, we need to rotate each one 30 degrees more than the previous. We also need to change the color by approximately 21.25% to go from and rgb value of 0 to 255. Since rgb values expect positive integers between 0 and 255, we need to round the float off to the nearest whole number. As you can see, CSS3 selectors allow us to create complex structures with minimal markup and CSS.

#activityIndicator {
	position: relative;
	width: 130px;
	height: 130px;
	margin: 0 auto;
	-webkit-perspective: 500;
	-webkit-animation-duration: 1s;
	-webkit-animation-iteration-count: infinite;
	-webkit-animation-timing-function: linear;
	-webkit-animation-name: spinnerAnim2;
}
@-webkit-keyframes spinnerAnim2 {
	0% { -webkit-transform: rotate(0deg) scale(.29); }
	100% { -webkit-transform: rotate(360deg) scale(.29); }
}
#activityIndicator > div:first-of-type {
	margin-left: 58px;
	margin-top 0;
	width: 50%;
	height: 50%;
}
#activityIndicator .blade {
	position: absolute;
	height: 40px;
	width: 14px;
	background-color: rgba(234,234,234, .30);
	-webkit-border-radius: 10px;
	-webkit-transform-origin-x: 50%;
	-webkit-transform-origin-y: 165%;
}

#activityIndicator .blade:nth-child(2) {
	-webkit-transform: rotate(30deg);
	background-color: rgba(212,212,212, .70);
}
#activityIndicator .blade:nth-child(3) {
	-webkit-transform: rotate(60deg);
	background-color: rgba(191,191,191, .70);
}
#activityIndicator .blade:nth-child(4) {
	-webkit-transform: rotate(90deg);
	background-color: rgba(170,170,170, .70);
}
#activityIndicator .blade:nth-child(5) {
	-webkit-transform: rotate(120deg);
	background-color: rgba(149,149,149, .70);
}
#activityIndicator .blade:nth-child(6) {
	-webkit-transform: rotate(150deg);
	background-color: rgba(128,128,128, .70);
}
#activityIndicator .blade:nth-child(7) {
	-webkit-transform: rotate(180deg);
	background-color: rgba(106,106,106, .70);
}
#activityIndicator .blade:nth-child(8) {
	-webkit-transform: rotate(210deg);
	background-color: rgba(85,85,85, .70);
}
#activityIndicator .blade:nth-child(9) {
	-webkit-transform: rotate(240deg);
	background-color: rgba(64,64,64, .70);
}
#activityIndicator .blade:nth-child(10) {
	-webkit-transform: rotate(270deg);
	background-color: rgba(42,42,42, .70);
}
#activityIndicator .blade:nth-child(11) {
	-webkit-transform: rotate(300deg);
	background-color: rgba(21,21,21, .70);
}
#activityIndicator .blade:nth-child(12) {
	-webkit-transform: rotate(330deg);
	background-color: rgba(0,0,0, .70);
}

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

Update: September 14th, 2010
I forgot to mention one thing. If you look at the styles on #activityIndicator .blade you’ll notice the last two property definitions:

	-webkit-transform-origin-x: 50%;
	-webkit-transform-origin-y: 165%;

By setting the transform origin x value to 50% we fix the horizontal rotation to the blade’s center. By setting the transform origin vertical value to 165% we define the turning point at that distance from the start of the blade. Together these values cause the blades to rotate around leaving and empty circular space in the center, thus reproducing the appearance of the png image.

iPhone Modal Popup with HTML5, CSS3 & JavaScript

Works on Desktop Safari, Desktop Google Chrome, iPhone, iPod Touch, iPad. Note that I’ve included some styling for Firefox, even though it has no presence to speak of in the mobile space. In particular, Firefox 4 beta still lacks support for CSS3 keyframe animation, although that will make it into a later update.

If you’ve used an iPhone, iPod Touch or iPad, then you’re familiar with the modal popup dialog boxes that the native system uses. Here’s a typical iPhone popup:
Native iPhone modal popup

Notice the white radial gradient behind the popup. I was able to replicate this, but when the user was on a long document and scrolled down to do something that would trigger a popup, I could find no way to center that radial gradient based on the vertical page scroll. I therefore went with a whitesh blur around the popup itself using a CSS3 box shadow. Here’s what my HTML5/CSS3 version looks like:

Originally I thought I would use just one popup per app, re-assigning values to the popup’s part each time the popup was invoked. However I ran into the problem of events from different and I failed to find an elegant way to resolve this. I therefore came up with a scheme where you initialize a popup at the view level, allowing each view to have a custom popup. The initializing script creates the popup and injects it as the last child of the view. The setup script creates the markup for the popup and populates it with values passed as an argument to the initializing script. The setup script also adds basic functionality to the buttons so that clicking either of them will close the popup. The setup script also creates a screen cover which traps events to prevent user interaction with what is behind the popup until it is closed.

The setup script accepts a single argument—an object literal containing key/values pairs to populate the popup. In order for the setup script to create a popup, you must at least pass a value for a valid view in your Web app. This would be like selector: "#Popup". If no other values are passed, the script will produce a basic popup that looks like this:
Basic popup

I used the ChocolateChip mobile JavaScript library to add the interactive functionality to the popup. Here’s the JavaScript that creates the markup and functionality for the popup:

/** 
* 
* A method to initialize a modal popup. By passing a valid selector for a view, this method creates a view based popup with the properties supplied by the options argument. It automatically binds events to both popup buttons to close the popup when the user clicks either. If a callback is passed as part of the opts argument, it gets bound to the "Continue" button automatically.
*
* @method
* 
* ### setupPopup
*
* syntax:
*
*  $.setupPopup({selector: "#News", title: "Subscribe", cancel: });
*
* arguments:
* 
*  - string: string A valid selector for the parent of the tab control. By default the an object literal.
*  - string: string An object literal which can have the following properties:
	title: a string defining the title in the popup.
	message: a string defining the popup message.
	cancelButton: a string defining an alternate name for the cancel button.
	continueButton: a string defining an alternate name for the confirm button.
	callback: a function to run when the user touches the confirm button.
	If no title is supplied, it defaults to "Alert!".
	If no cancelButton value is supplied, it defaults to "Cancel".
	If no continueButton value is supplied, it defaults to "Continue".
* example:
*
*  $.setupPopup({selector: "#buyerOptions"});
*  $.setupPopup({
		selector: "#Popup",
		title: 'Attention Viewers!', 
		message: 'This is a message from the sponsors. Please be seated while we are getting ready. Thank you for your patience.', 
		cancelButton: 'Skip', 
		continueButton: 'Stay for it', 
		callback: function() {
			$('#popupMessageTarget').fill('Thanks for staying with us a bit longer.');
			$('#popupMessageTarget').removeClass("animatePopupMessage");
			$('#popupMessageTarget').addClass("animatePopupMessage");
		}
	});
*
*/
$.setupPopup = function( opts ) {
	if (opts.selector) {
		var selector = opts.selector;
	} else {
		return false;
	}
	var title = "Alert!";
	if (opts.title) {
		var title = opts.title;
	}
	var message = "";
	if (opts.message) {
		var message = opts.message;
	}
	var cancelButton = "Cancel";
	if (opts.cancelButton) {
		cancelButton = opts.cancelButton;
	}
	var continueButton = "Continue";
	if (opts.continueButton) {
		continueButton = opts.continueButton;
	}
	var popup = '<div class="screenCover hidden"></div>';
	popup += '<section class="popup hidden"><div>';
	popup += '<header><h1>' + title + '</h1></header>';
	popup += '<p>' + message +'</p><footer>';
	popup += '<div class="button cancel">' + cancelButton + '</div>';
	popup += '<div class="button continue">' + continueButton + '</div></footer></div></section>';
	$(selector).insertAdjacentHTML("beforeEnd", popup);
	// Bind event to close popup when either button is clicked.
	$$(selector + " .button").forEach(function(button) {
		button.bind("click", function() {
			$(selector + " .screenCover").addClass("hidden");
			$(selector + " .popup").addClass("hidden");
		});
	});
	
	if (opts.callback) {
		var callbackSelector = selector + " .popup .continue";
		$(callbackSelector).bind("click", function() {
			opts.callback();
		});
	}
	
};

And here is an initialization of a popup:

$.setupPopup(
	{
		selector: "#Popup",
		title: 'Attention Viewers!', 
		message: 'This is a message from the sponsors. Please be seated while we are getting ready. Thank you for your patience.', 
		cancelButton: 'Skip', 
		continueButton: 'Stay for it', 
		callback: function() {
			$('#popupMessageTarget').fill('Thanks for staying with us a bit longer.');
                        // Remove this class in case the popup was opened previously.
			$('#popupMessageTarget').removeClass("animatePopupMessage");
                        // Then add the class to trigger an animation of the message being displayed.
			$('#popupMessageTarget').addClass("animatePopupMessage");
		}
	}
);

Now that a popup has been created and populated with the desired values, we need a way to show it. Before actually showing the popup, the $.showPopup method display a screen cover which captures user interaction and thereby prevents the interface behind the popup from being accessed until the popup is dispelled. The showPopup method accepts one argument, a selector indicating a uniquely identifiable node that contains the popup as a descendant.

$.showPopup = function( selector ) {
	var screenCover = $(selector + " .screenCover");
        // Make the screen cover extend the entire width of the document, even if it extends beyond the viewport.
	screenCover.css("height:" + (window.innerHeight + window.pageYOffset) + "px");
	var popup = $(selector + " .popup");
	$(selector + " .popup").style.top = ((window.innerHeight /2) + window.pageYOffset) - (popup.clientHeight /2) + "px";
	$(selector + " .popup").style.left = (window.innerWidth / 2) - (popup.clientWidth / 2) + "px";
	$(selector + " .screenCover").removeClass("hidden");
	$(selector + " .popup").removeClass("hidden");
};

With this method defined we can now show the popup as need. Here’s a script that attaches an event handler to a button with a class of “openPopup” for a popup somewhere among the descendant nodes of a node with an id of “Tabs”:

$("#Tabs .openPopup").bind("click", function() {
	$.showPopup("#Tabs");
});

OK, so we have the markup and functionality for the popup, but we don’t have the look. We’ll take care of that next. In order to create the unique look of the iPhone popup, I use several layers for encasing borders and composited transparent background gradients. Originally I had two gradients, the dark blue linear gradient and the whitish radial gradient, layered on top of each other as multiple backgrounds. But Google Chrome had a problem rendering the underlying linear gradient, ignoring its transparent alpha values and rending the colors as opaque. I was therefore forced to break them out into separate elements. The end result is the same. When the popup is created by the setup script, it is given a class of “hidden.” This defines its scale as 0% and its opacity as 0%. When we execute the showPopup method, it removes that “hidden” class. Because the popup has basic transitions properties defined on it, its scale and opacity transition from zero to full, making it appear to popup out of no where. The scripts also always make sure that the popup is centered in the viewport, regardless of where it was displayed when scrolling down a long document.

For their modal popups, Apple always indicates the default button, what would be equivalent to a submit or OK button, with slightly lighter colors so that it stands out from the other button, which is the equivalent of a cancel/close button. I have the buttons located in a footer and I use CSS3’s flexible box model styles to make the buttons position and size them selves according to available space.

/* Modal Popup Styles */
section.popup {
	width: 75%;
	max-width: 300px;
	border: solid 1px #72767b;
	-webkit-box-shadow: 0px 4px 6px #666, 0 0 50px rgba(255,255,255,1);
	-moz-box-shadow: 0px 0px 1px #72767b,  0px 4px 6px #666;
	box-shadow: 0px 0px 1px #72767b, 0px 4px 6px #666;
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	border-radius: 10px;
	padding: 0px;
	opacity: 1;
	-webkit-transform: scale(1);
	-webkit-transition: all 0.25s  ease-in-out;
	position: absolute;
	z-index: 1001;
	margin-left: auto;
	margin-right: auto;
	background-image: 
		-webkit-gradient(linear, left top, left bottom,
			from(rgba(0,15,70,0.5)),
			to(rgba(0,0,70,0.5)));
}
section.popup.hidden {
	opacity: 0;
	-webkit-transform: scale(0);
	top: 50%;
	left: 50%;
	margin: 0px auto;
}
section.popup > div {
	border: solid 2px #e6e7ed;
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	border-radius: 10px;
	padding: 10px;
	background-image: 
	   -webkit-gradient(radial, 50% -1180, 150, 50% -280, 1400,
		   color-stop(0, rgba(143,150,171, 1)),
		   color-stop(0.48, rgba(143,150,171, 1)),
		   color-stop(0.499, rgba(75,88,120, .9)),
		   color-stop(0.5, rgba(75,88,120,0)));
	color: #fff;
	text-shadow: 0px -1px 1px #000;
}
section.popup header {
	background: none;
	-webkit-border-top-left-radius: 10px;
	-webkit-border-top-right-radius: 10px;
	-moz-border-radius-topleft: 10px;
	-moz-border-radius-topright: 10px;
	border-top-left-radius: 10px;
	border-top-right-radius: 10px;
	border: none;
	color: #fff;
	text-shadow: 0px -2px 1px #000;
}
section.popup header > h1 {
	letter-spacing: 1px;
}
section.popup footer
{
	display: -webkit-box;
	-webkit-box-orient: horizontal;
	-webkit-box-pack:justify;
	-webkit-box-sizing: border-box;
	display: -moz-box;
	-moz-box-orient: horizontal;
	-moz-box-pack:justify;
	-moz-box-sizing: border-box;
}
section.popup footer > .button {
	-webkit-box-flex: 2;
	-moz-box-flex: 1;
	display: block;
	text-align: center;
	-webkit-box-shadow: none;
	-moz-box-shadow: none;
	box-shadow: none;
	margin: 10px 5px;
	height: 32px;
	font-size: 18px;
	line-height: 32px;
	-webkit-border-radius: 8px;
}
section.popup footer > .button.cancel {
	background-image: 
		-webkit-gradient(linear, left top, left bottom, 
			from(#828ba3), 
			color-stop(0.5, #4c5a7c), 
			color-stop(0.5, #27375f), 
			to(#2e3d64));
}
section.popup footer > .button.continue {
	background-image: 
		-webkit-gradient(linear, left top, left bottom, 
			from(#b0b6c4), 
			color-stop(0.5, #7a839b), 
			color-stop(0.5, #515d7c), 
			to(#636e8a));
}
section.popup footer > .button:hover, .popup footer > .button.hover {
	background-image: 
		-webkit-gradient(linear, left top, left bottom, 
			from(#70747f), 
			color-stop(0.5, #424857), 
			color-stop(0.5, #171e30), 
			to(#222839));
}
.screenCover {
	width: 100%;
	height: 100%;
	display: block;
	background-color: rgba(0,0,0,0.5);
	position: absolute;
	z-index: 1000;
	top: 0px;
	left: 0px;
}
.screenCover.hidden {
	display: none;
}

You can try this out online or download the source code to play around with it.

iPhone Style Radios Buttons with HTML, CSS & JavaScript


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

Have you ever surfed to a Web page on the iPhone or iPod Touch’s Safari browser and come across a form with standard radio buttons? It’s a pretty miserable experience trying to hit them with your finger. You have to zoom in to do so, maybe zoom in a lot. When Apple was designing the interface for the iPhone, they put a lot of thought into how to make conventional interface elements easier to use in a touch environment. If you think about it, what is a group of radio buttons but a list of items to select from. And only one item can be selected at a time. To cover this requirement Apple came up with the radio table control. A radio table is just a list of items, same as a radio button group. Only one list item can be chosen, and this is indicated by a checkmark on that particular list item which correlates to the single radio button being selected out of a group.

The radio button list looks like this:
Radio Button List

One of the things that I really can’t understand is why people think a mobile touch interface needs radio buttons like on the desktop browser. All the other mobile frameworks are providing ways to implement the standard tiny, round radio buttons. They don’t work for touch interfaces. Get over it. The radio list works better for touch. Embrace it and love it and it will love you. Wait, I didn’t really mean that, but you get the picture. I have a hard enough time hitting normal sized controls designed for the iPhone. Heck, sometimes I can’t even find my iPhone, but that’s another issue.

To make this more like the Web equivalent of radio buttons I added real radio buttons to my solution. Here’s the markup to implement them (note that you still need to great the grouping of the radio buttons by giving each radio button in the list the same name):

<ul id="activityChoices" class="radioList">	
	<li>
		<span>Go eat something</span> 
		<span class="check">&#x2713</span>
		<input type="radio" name="activity" value="Go eat something" />
	</li>
	<li>
		<span>Take a nap</span> 
		<span class="check">&#x2713</span>
		<input type="radio" name="activity" value="Take a nap" />
	</li>
	<li>
		<span>Get some work done</span> 
		<span class="check">&#x2713</span>
		<input type="radio" name="activity" value="Get some work done" />
	</li>
	<li>
		<span>Play a game</span> 
		<span class="check">&#x2713</span>
		<input type="radio" name="activity" value="Play a game" />
	</li>
</ul>

Notice that the last item in each list item is the radio input. Please leave this as such, since it makes it easy for us to target the actual radio button as the last child of the list items child nodes. If you have a need to add other things into the list, insert them elsewhere in the list items collection of child nodes.

We’ll use CSS to hide the radio buttons and when a user touches a list item, we’ll use JavaScript to set the checked state of that list item’s radio button to true. After that, what you do with the user interaction is up to you. In many cases that initial choice can immediately trigger a corresponding action, or you may wait until the user takes a decisive final action that triggers a submit or post of all the selected inputs. Notice the span with the class “check.” It contains a hex value of “&#x2713” which is an HTML entity for a standard check mark. We’ll use CSS to position and hide or show it depending on the user’s interaction.

Here’s the CSS needed to make our list look like the iPhone one. Since the radio button group is based on the list control type, it shares some styles with standard lists:

.list, .radioList {
	-webkit-box-shadow: 2px 2px 4px #666;
	-webkit-border-radius: 12px;
	-moz-box-shadow: 2px 2px 4px #666;
	-moz-border-radius: 12px;
	box-shadow: 2px 2px 4px #666;
	border-radius: 12px;
}
.list li, .radioList li {
	cursor: pointer;
	padding: 8px;
	border-left:  1px solid #acacac;
	border-right: 1px solid #acacac;
	border-bottom: 1px solid #acacac;
	background-color: #fff;
	font-weight: bold;
	-webkit-tap-highlight-color: transparent;
}
.list li:hover, .radioList li:hover {
	background-image: 
		-webkit-gradient(linear, left top, left bottom, 
			from(#4286f5), 
			to(#194fdb));
	background-image: 
		-moz-linear-gradient(top, 
			#4286f5, 
			#194fdb);
	color: #fff;
}
.list li:hover:after, .radioList li:hover:after {
	color: #fff;
}
.list li:first-of-type, .radioList li:first-of-type {
	border-top: 1px solid #acacac;
	-webkit-border-top-right-radius: 10px;
	-webkit-border-top-left-radius: 10px;
	-moz-border-radius-topright: 10px;
	-moz-border-radius-topleft: 10px;
	border-top-right-radius: 10px;
	border-top-left-radius: 10px;
}
/** 
	Styles for single choice lists.
	These are the same in functionality as a 
	radio button group.
*/
.radioList li > .check {
	float: right;
	-webkit-transition: all 0.125s  ease-in-out;
	-moz-transition: all 0.125s  ease-in-out;
	transition: all 0.125s  ease-in-out;
	opacity: 0;
}
.radioList li.selected > .check {
	opacity: 1;
	color: #496691;
}
.radioList li > .check, .radioList li.selected:hover > .check {
	color: #fff;
}
.radioList li > input[type="radio"] {
	display: none;
}

The selector radioList li > .check defines the check mark. We set it’s initial opacity to 0 so that it is completely transparent. When the user selects a list item by clicking/touching, we add a “selected” class to the list item. The selector .radioList li.selected > .check then sets the check mark’s opacity to 100%.

To make all the behavior work, we need to write some JavaScript for a reusable control. We’ll use the light, mobile JavaScript framework ChococlateChip.

/** 
* 
* A method to initialize a list of radios buttons to present the user with a group of single choice options. It takes as the main argument, a unique selector identifying the view or section where the radio list resides.
*
* @method
* 
* ### RadioButtons
*
* syntax:
*
*  $.RadioButtons(selector);
*
* arguments:
* 
*  - string: string A valid selector for the parent of the tab control. By default the selector will target a class, id or tag of the radio list itself, so if you want to pass in a selector for a parent tag, such as an article, section or div tag, you'll need to make sure to put a trailing space on the end of the selector string.
*  - function: function A valid function as a callback. This is optional. The callback gets passed a reference to the clicked item, so you can access it in your callback function.
* 
* example:
*
*  $.RadioButtons("#buyerOptions");
*  $.RadioButtons("#buyerOptions", function(choice) {
	   // Output the value of the radio button that was selected.
	   // Since the actual radio button is the last item in a radio
	   // button list, we can use the last() method to get its value.
	   console.log(choice.last().value);
   };
*
*/
$.RadioButtons = function( viewSelector, callback ) {
	var items = viewSelector + ".radioList li";
	var radioButtons = $$(items);
	radioButtons.forEach(function(item) {
		item.bind("click", function() {
			radioButtons.forEach(function(check) {
				check.removeClass("selected");
			});
			this.addClass("selected");
			this.last().checked = true; 
			if (callback) {
				callback(item);
			}
		});
	});
};	

Because the radio input is the last child of the list’s node collection, we can set its checked value to true when the user clicks or touches a list item. We do this with the line: this.last().checked = true; We also manage toggling of the selected state of a list item by adding and removing a “selected” class. This hides or shows the check mark. We also have a conditional block to check for a callback. If one was passed as an argument, we invoke it. We pass in a reference to the list item that was clicked using the term “item.” This allows us to reference the clicked item in our callback. We can initialize a radio button list as follows:

// Radio button initialization:
$.RadioButtons("#activityChoices", function(item){
	$("#RadioButtons .response").fill(item.last().value);
});

In the above code we’re passing in a reference to the clicked list item in an anonymous function which fills a span with a class of “response” with the value of the list item’s radio button.

The radio button list has an id of “#activityChoices,” so I just pass that in. If “#activityChoices” were a parent node, I would have had to written the selector thus (notice the trailing space at the end before the closing parenthesis): $.RadioButtons(“#activityChoices “); This differentiation is necessary because the selector passed in gets concatenated with “.radioList li” to set up the radio button list’s functionality. There is no way for the control to know when you are targeting the list itself or a parent node. If the selector is the list itself, “.radioList li” gets appended to that, but if the selector is a parent node, you need to indicate that with a trailing space so that the “.radioList li” gets appended with the space separating. Otherwise the resulting complete selector will not identity the radio button list properly and nothing will get initialized. I hope this is clear. Yeah, I could have written the control to check to see if the selector was the list or a parent node, but that would have resulted in a performance hit as the code would have had to do quite a bit of evaluation to determine what the selector relation was.

Remember that the callback is optional. That means if you are construction a form with a submit process, then all you need to do for the radio button list is pass in a correct selector to initialize its behavior. You’ll then get the user’s choice during the submit process.

You can try out an example online or download the source code.

iPhone Style Tab Control with HTML, CSS and JavaScript


Works with Desktop Safari, Desktop Google Chrome, Desktop Firefox 4, Android, iPhone, iPod Touch and iPad.
Please not that this was originally designed for Android/iPhone/iPad use. It can be used on modern desktop browsers. Just note that the attached example will only work with Firefox 4 or later because it uses CSS3 transitions for navigation.

If you’ve used an iPhone or iPad, you’ve seen them. Actually, Apple uses them on the operating system. They even use them on their Website and online assets. As is usual for Apple, they take a very different approach to implementing tabs. They use segmented buttons to indicate tabs. This works especially well in the mobile space where you want the tab to stand out and be an easy target for a fat finger. It also eliminates all the futzing around to try to get all the border of tabs and tab panels to fit together properly. The panels have no borders, just their content. The segmented buttons capture your attentions as the device that toggles the content.

The interaction is simple and immediate. As soon as a user clicks or touches a segmented button, it reveals the new content below. On the iPhone, there are not even any special effects, not even a fade. It just directly switches out the data.

Let’s go over the markup for the tab control. Note that the class names it uses are important. By using standardized markup and classes, we can reuse the tab wherever we need it in our app, and initialize it with one line of JavaScript. The tab controls has two parts. The first is a div with the class “Tabs segmentedControlBase.” This is where the segmented buttons that hide and show the tab panels reside. Following this there is another div with the class “TabPanels,” with obviously holds the tab panels. Here’s the markup:

<div class="Tabs segmentedControlBase">
	<div class="button segmentedControl leftEnd tab"><span>Search</span></div>
	<div class="button segmentedControl tab"><span>Directions</span></div>
	<div class="button segmentedControl rightEnd tab"><span>Options</span></div>
</div>
<div class="TabPanels">
	<div class="tabPanel">
		<p class="rounded">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
	</div>
	<div class="tabPanel">
		<p class="rounded">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
	</div>
	<div class="tabPanel">
		<p class="rounded">Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?</p>
	</div>
</div>

As you can see, the markup is very straightforward and we can easily reuse the pattern through an application as necessary. Of course, this needs some styling so that it looks like something. The most visual part of the tab control is the set of segmented buttons which constitute the tabs. If you’re going to use these on a mobile phone, be aware the you can probably at maximum fit in four tabs. Two or three is optimal. If your tabs are cramped, hard to read or even hard to touch because there so many, you should probably rethink how you’re present your data. Maybe a drilldown menu would serve your purposes better. Realistically, the tab control is for a small number of data sets which you wish to present to the user.

Here’s the markup. Remember, the left and right ends of a segmented button set are normally rounded. They don’t have to be, but they definitely look more elegant that way. The button or buttons between the two ends are squared off.

.segmentedControlBase {
	display: -webkit-box;
	-webkit-box-orient: horizontal;
	-webkit-box-pack:justify;
	-webkit-box-sizing: border-box;
	display: -moz-box;
	-moz-box-orient: horizontal;
	-moz-box-pack:justify;
	-moz-box-sizing: border-box;
}
.button.segmentedControl {
	display: block;
	-webkit-box-flex: 1;
	-moz-box-flex: 1;
	border: solid 1px #9a9a99;
	border-left: none;
	-webkit-border-radius: 0px;
	-moz-border-radius: 0px;
	border-radius: 0px;
	text-align: center;
	background-image: 
		-webkit-gradient(linear, left top, left bottom, 
			from(#fbfbfb), 
			to(#bdbdbd));
	background-image: 
		-moz-linear-gradient(top, 
			#fbfbfb, 
			#bdbdbd);
	color: #6b6b6b;
	font-size: 16px;
	padding: 10px;
}
.button.segmentedControl:hover, .button.segmentedControl.hover, .button.segmentedControl.selected {
	background-image: 
		-webkit-gradient(linear, left top, left bottom, 
			from(#2a55b1), 
			to(#6297f2));
	background-image: 
		-moz-linear-gradient(top, 
			#2a55b1, 
			#6297f2);
	color: #fff;
	border-color: #193a7f;
}
.button.segmentedControl.leftEnd {
	-webkit-border-top-left-radius: 10px;
	-webkit-border-bottom-left-radius: 10px;
	-moz-border-radius-topleft: 10px;
	-moz-border-radius-bottomleft: 10px;
	border-top-left-radius: 10px;
	border-bottom-left-radius: 10px;
	border-left: solid 1px #9a9a99;
}
.button.segmentedControl.rightEnd {
	-webkit-border-top-right-radius: 10px;
	-webkit-border-bottom-right-radius: 10px;
	-webkit-border-top-right-radius: 10px;
	-webkit-border-bottom-right-radius: 10px;
	border-top-right-radius: 10px;
	border-bottom-right-radius: 10px;
}
/* Styles for Tab states */
.TabPanels .tabPanel {
	display: none;
}
.TabPanels .tabPanel.selected {
	display: block;
}
/* End Styles for Tab states */

This will give us a tab control that looks like this:

tabs

Now we’re going to create the JavaScript to make the tabs function. I’m going to use the ChocolateChip JavaScript framework because it’s tiny, just 12k, and does everything I need it to do in the mobile space. For those of you who would rather use jQuery, you should be able to replicate my control’s functionality fairly easily. If you don’t know jQuery good enough to do that, then maybe you want to give ChocolateChip a look. If you compare the two, you’ll see that ChocolateChip and jQuery code look very similar. The difference is that with ChocolateChip you’re always dealing with real JavaScript. ChocolateChip gives you some simple helpers to make it easier for you to write clean, maintainable and legible code. Yet everything ChocolateChip returns is normal JavaScript. With jQuery, you’re always dealing with an object wrapper and therefore have to do things the jQuery way. You cannot use normal JavaScript with what the jQuery returns.

Anyway, here’s the code that creates the tab:

/** 
* 
* A method to initialize a set of tabs using lozenge or segmented buttons to toggle data sets in a view. It takes one argument, a unique selector identifying the view or section where the tabs reside.
*
* @method
* 
* ### setupTabs
*
* syntax:
*
*  $.setupTabs(tabsSelector);
*
* arguments:
* 
*  - string: string A valid selector for the parent of the tab control.
* 
* example:
*
*  $.setupTabs("#buyerOptions");
*
*/
$.setupTabs = function( viewSelector ) {
	var tabsSelector = viewSelector + " .Tabs .tab";
	var panelsSelector = viewSelector + " .TabPanels .tabPanel";
	var tabs = $$(tabsSelector);
	var panels = $$(panelsSelector);
	
	tabs.forEach(function(tab) {
// Set the first tab and tab panel to the selected state automatically.
		tabs[0].addClass("selected");
		panels[0].addClass("selected");
		tab.bind("click", function() {
			var i = 0, len = tabs.length;
			var panelToHide = null;
			while(i < len) {
				tabs[i].removeClass("selected");
				panels[i].removeClass("selected");
				if (this == tabs[i]) {
					panelToHide = i;
				}
				i++
			}
			this.addClass("selected");
			panels[panelToHide].addClass("selected");
		});
		
		tab.bind("touchstart", function() {
			var i = 0, len = tabs.length;
			var panelToHide = null;
			while(i < len) {
				tabs[i].removeClass("selected");
				panels[i].removeClass("selected");
				if (this == tabs[i]) {
					panelToHide = i;
				}
				i++
			}
			this.addClass("selected");
			panels[panelToHide].addClass("selected");
		});
	});
};

If you look at the argument passed in, setupTabs expects a selector indicating the parent element that the tab control abides in. This can be the article tag, the section tag, or whatever you choose. I wouldn’t expect there to be more than one set of tabs in a particular view. If no selector is supplied, the script searches the entire document for the first occurrence of the tab control’s classes and initializes it. So, if you do have more than one tab control in your mobile app, you’ll need to pass in a selector indicating where it resides.

Since by default the tab control’s CSS sets the segmented buttons to unselected and the tab panels to hidden, the script does some initialization to select the first tab and show it’s tab panel. You don’t have to tell the script how many tabs there are or how many tab panels there are. It searches the markup and figures that out itself.

Now, its time to discuss the data in the tabs. How do you intend to get it in them? The simplest way is to do it on page load. If you have many tab controls, and your app is large, you might want to avoid that. In that case you code do something creative, such as binding an event listener to the transition effect of the view the first time the user navigates to it. You could use the webkitAnimationStart event to load your data with an Ajax call. You’d only want to do this the first time the user comes to the view, so you might want to use either a custom object or a value registered in the sessionStorage object to indicate that the user has visited the section already so you don’t need to reload the data.

You can see this tab control live, or download the code to pick it apart.

Update 9/1/10
What was I thinking? My bad. The two classes “leftEnd” and “rightEnd” are totally unnecessary. Using CSS3 selectors we can always target the first and last tabs using :first-of-type and :last-of-type. That way, you never have to worry about naming the first and last. Just put the tabs and the CSS will create the first and last. So the line:

.button.segmentedControl.leftEnd

should be:

.button.segmentedControl:first-of-type

and the line:

.button.segmentedControl.rightEnd

should be:

.button.segmentedControl:last-of-type

The online sample and downloadable code has been updated for this.

CSS3 Gradient Image Masks


Works on Desktop Safari, iPhone, iPod Touch, iPad.

Besides using CSS3 gradients as background images, you can also use them as image masks. An image mask will reveal whatever is behind the element whose background it is applied to while simultaneously masking whatever is in its parent element. This affects both any background properties, colors, images or gradients, as well as the foreground content, whatever it may be. This allows for some interesting layered effects, but you do need to take care that your content gets masked by the mask. I’ll say that again, don’t let your content get masked by the mask. It can happen, so use masks sparingly and with care.

The notation for an image mask is fairly straightforward. First off, you can use an image, either a png or and svg graphics as a mask. The notation is like this:

-webkit-mask-box-image: url(image-mask.png) 75 stretch;

In this post we’re going to look at how to use CSS3 gradients to mask. So my little trick is to nest the element with the mask inside another element which has a background color, background image or background CSS3 gradient which the mask will reveal. In my first example I’m going to give the parent element a background color of #000 (black). The mask will therefore reveal that black to varying degrees added a patterned image burn effect to an otherwise flat foreground. So, here’s the styles for the parent:

article {
	width: 600px;
	height: 500px;
	margin: 40px auto;
	border: solid 6px gold;
	background: #000;
	border-radius: 60px;
	-moz-border-radius: 60px;
	-webkit-border-radius: 60px;
	-webkit-box-sizing: border-box;
	overflow: hidden;
	-webkit-background-clip: padding;
	box-shadow: 
		-2px -2px 2px rgba(255,255,255,.75), 
		2px 2px 10px #000;
	-webkit-box-shadow: 
		-2px -2px 2px rgba(255,255,255,.75), 
		2px 2px 10px #000;
	-moz-box-shadow: 
		-2px -2px 2px rgba(255,255,255,.75), 
		2px 2px 10px #000;
}

And its child element will get this style:

section { 
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	-o-box-sizing: border-box;
	-webkit-background-clip: padding;
	height: 100%;
	padding: 20px;
	border-radius: 54px;
	-moz-border-radius: 54px;
	-webkit-border-radius: 54px;
	background-color: #800023;
	background-image: 
		-webkit-gradient(linear, 100% 0%, 0% 100%, 
			color-stop(0.15, #8a3726),  
			color-stop(0.15, #800023), 
			color-stop(0.50, #800023), 
			color-stop(0.50, #8a3726), 
			color-stop(0.65, #8a3726),
			color-stop(0.65, #800023));
	-webkit-background-size: 6px 6px, 100% 20px;
	background-image: 
		-moz-linear-gradient(right top, 
			#8a3726,
			#8a3726 15%, 
			#800023 15%, 
			#800023 50%, 
			#8a3726 50%, 
			#8a3726 65%, 
			#800023 65%, 
			#800023);
	background-size: 6px 6px;
	-webkit-mask-image:
		-webkit-gradient(linear, left top, left bottom,
			color-stop(0.123, rgba(0,0,0,1)),
			color-stop(0.18, rgba(0,0,0,0.6)),
			color-stop(0.18, rgba(0,0,0,1)),
			color-stop(0.8, rgba(0,0,0,.5)),
			color-stop(0.8, rgba(0,0,0,0.8)),
			color-stop(0.85, rgba(0,0,0,.9)),
			color-stop(1, rgba(0,0,0,.5))); 
}

Notice in the code above the line beginning with “-webkit-mask-image.” What follows that property is a normal looking CSS3 gradient. Except that we’re using it as an image mask. Because we gave it no size or position, it will automatically stretch over the entire surface of the element. This is what the styles will produce:
CSS3 gradient image mask

As you can see, the image mask reveals the black background color in the shape of the gradient image mask. Now if we want to get creative, we can put something more interesting in the parent element’s background, and image or a CSS gradient pattern. Here’s an example of a CSS3 background gradient pattern being revealed by a mask:
CSS3 gradient image mask

You can see the document live or download the file as you wish.

Extruded 3D Text Using CSS3 Text-Shadows


Works on desktop Safari, desktop Chrome, desktop Firefox, desktop Opera, Android, iPhone, iPad.

Remember the days when every home video had lousy 3D titles? Well, now you can have similar titles on your Website using CSS3. Excited? OK, here’s what I’m talking about (displayed in Safari):

3D Text Create with CSS3 Text Shadows

Note: the last two titles have 3D perspective added using CSS3 3D transforms. At the moment that is only available on desktop Safari, iPhone and iPad. Also, at the moment only Webkit supports the text-stroke property.

And here is how it looks in Firefox, Chrome and Opera:

3D Text Using CSS3 Text Shadows on Firefox

So, the way way to make any text look extruded or 3D is to give the text a series of text shadows. We often use one or two text shadows combined to make text look embossed or beveled. But technically there is no limit to the number of text shadows you can add. The trick to to use a color with slightly more black in it than the font color. This will create the illusion of the side surface having a shadow and will make the face of the font more pronounced. Also, for those who get to enjoy Webkit browsers, you can add a text stroke using a slightly more saturated version of the font color. I usually use an RGBA value with an alpha opacity of 0.25 – 0.50.

So, you start with the first text shadow, say 1px 1px 1px. We done’ want to blur the shadow because we want to build up the depth of the font. The next value would be 2px 2px 1px and the third one 3px 3px 1px. You can extrude the font as much as you like, but don’t make it illegible. How much you extrude the text should depend on your font size. Here’s the style for the first title in the images above:

header > h1:first-of-type {
	text-align: center;
	color: #ffdc48;
	-webkit-text-stroke: 1px rgba(255,50,35,.25);
	text-shadow: 
		1px 1px 1px #ceb23c, 
		2px 2px 1px #ceb23c, 
		3px 3px 1px #ceb23c, 
		4px 4px 6px #000;
}

This creates a rather pronounced extrusion. If you want something more subtle, you can build out the extrusion more gradually as in the following example:

header > h1:nth-child(2) {
	text-align: center;
	color: #ffdc48;
	-webkit-text-stroke: 1px rgba(255,50,35,.25);
	text-shadow: 
		1px 1px 1px #ceb23c, 
		2px 1px 1px #ceb23c, 
		3px 1px 1px #ceb23c, 
		4px 2px 1px #ceb23c, 
		4px 4px 6px #000;
}

Notice that the last value of each of the above text shadow definitions is to create a normal, blackish drop shadow. This adds some further depth to the text, making it appear more realistic.

You can try these out online or download the code to begin playing with your own 3d fonts.

CSS3 Progress Bar


Works in Desktop Safari, Desktop Chrome, Android, iPhone, iPad. Displays properly but does not animate in Firefox 3.5-4 because it lacks CSS3 keyframe animation.

Since CSS3 provides a way to create gradients, including striped repeating patterns, it is possible to create the barbershop striped progress bars used on Mac OS X. Using the technique described in a previous post about CSS3 striped gradient patterns, we can easily create a self-animated progress bar. To start with, the HTML5 markup is dead simple, just a div with a class:

<div class="progressBar"></div>

We’ll start off by giving the div some basic styling as the container for the gradient:

.progressBar {
	width: 300px;
	height: 15px;
	border: 1px solid #bfbfbf;
	margin: 40px auto;
	position: relative;
	-webkit-box-shadow: 0 2px 2px rgba(0,0,0,0.5);
	background-color: rgb(56,138,213);
}

This will result in:
progress bar base

This is the base upon which we will now proceed to lay various gradient patterns to create a progress bar. Luckily CSS3 provides a way to implement multiple backgrounds, so it is just a matter of creating and layering them correctly. We start with the first layer, consists of a repeating pattern of diagonal white stripes with transparent stripes between it. This will allow the background color to show through:

background-image:
	-webkit-gradient(linear, 18 0, 0 10,
		color-stop(0.23, rgba(255,255,255,0)),
		color-stop(0.3, rgba(255,255,255,0.8)),
		color-stop(0.3, rgba(255,255,255,1)),
		color-stop(0.7, rgba(255,255,255,1)),
		color-stop(0.7, rgba(255,255,255,0.8)),
		color-stop(0.77, rgba(255,255,255,0)));

This will give us:

progressbar with stripes

This is getting close to what we want, except that it’s very flat looking. We’ll add some more layers of gradients to add some depth. We’ll start with some shadows. To do this we’ll create a gradient with translucent black and the start and end with translucent white in the middle. This will make the progress bar appear to be cylindrical. Note that we set the background to repeat on the x axis and that we define a size for the repeating stripes using the background-size property:


.progressBar {
	width: 300px;
	height: 15px;
	border: 1px solid #ddd;
	border-bottom-color: #666;
	margin: 40px auto;
	position: relative;
	-webkit-box-shadow: 1px 1px 2px rgba(0,0,0,0.5);
	-moz-box-shadow: 1px 1px 2px rgba(0,0,0,0.5);
	box-shadow: 1px 1px 2px rgba(0,0,0,0.5);
	background-color: rgb(56,138,213);
	background-image:
		-webkit-gradient(linear, 18 0, 0 10,
			color-stop(0.23, rgba(255,255,255,0)),
			color-stop(0.3, rgba(255,255,255,0.8)),
			color-stop(0.3, rgba(255,255,255,1)),
			color-stop(0.7, rgba(255,255,255,1)),
			color-stop(0.7, rgba(255,255,255,0.8)),
			color-stop(0.77, rgba(255,255,255,0)))/,
		-webkit-gradient(linear, 0 0, 0 100%,
			color-stop(0.05, rgba(0,0,0,.3)),
			color-stop(0.06, rgba(255,255,255,.8)),
			color-stop(0.45, rgba(255,255,255,.05)),
			color-stop(0.55, rgba(0,0,0,.05)),
			color-stop(0.85, rgba(0,0,0,.2)),
			color-stop(0.98, rgba(0,0,0,.5)));
		background-repeat: repeat-x;
                -webkit-background-size: 20px 15px;

This gives us:

progress bar with shadow

We are going to give the progress bar one more gradient layer to add a highlight gloss to it. To do so we’ll create a white band across the top half with opacity set to 50%. So here’s the complete background image:


background-image:
	-webkit-gradient(linear, 18 0, 0 10,
		color-stop(0.23, rgba(255,255,255,0)),
		color-stop(0.3, rgba(255,255,255,0.8)),
		color-stop(0.3, rgba(255,255,255,1)),
		color-stop(0.7, rgba(255,255,255,1)),
		color-stop(0.7, rgba(255,255,255,0.8)),
		color-stop(0.77, rgba(255,255,255,0))),
	-webkit-gradient(linear, 0 0, 0 100%,
		color-stop(0.05, rgba(0,0,0,.3)),
		color-stop(0.06, rgba(255,255,255,.8)),
		color-stop(0.45, rgba(255,255,255,.05)),
		color-stop(0.55, rgba(0,0,0,.05)),
		color-stop(0.85, rgba(0,0,0,.2)),
		color-stop(0.98, rgba(0,0,0,.5))),
	-webkit-gradient(linear, 0 0, 0 100%,
		color-stop(0.25, transparent),
		color-stop(0.25, rgba(255,255,255,.5)),
		color-stop(0.47, rgba(255,255,255,.5)),
		color-stop(0.47, transparent));
        background-repeat: repeat-x;
	-webkit-background-size: 20px 15px;

And our final progress bar looks like this:

progress bar complete

Because it’s a progress bar, we want it to animate continuously while it’s displayed. This requires some initialization code in the CSS and two lines of CSS for the animation. Because we’ll animate the stripes on the progress bar across the length of it, we need to set the initial position of the background image, which will be 0. We define the animation to last ten seconds, to loop continuously, to use linear easing and to use an animation named “progressBarAnim.” We define the progressBarAnim using keyframes next:

-webkit-background-position-x: 0%;
-webkit-animation-duration: 10s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-name: progressBarAnim;

CSS3 keyframe animations have a start and end value. Unlike transitions, you can define whatever properties you with to at any point in the animation sequence. Because we are animate the progress bar’s stripes from one end to the other, the keyframe animation is very simple, we just need to animate the x position of the gradient from 0% to 100%. Because we set the iteration count to infinite, it will automatically loop back:


@-webkit-keyframes progressBarAnim {
	0% { background-position-x:  0%; }
	100% { background-position-x: 100%; }
}

You can see this in action on Safari, Chrome, Android, iPhone or iPad, or download the source files.

CSS3 Gradients and Patterns


Works in Desktop Safari, Google Chrome, Firefox, iPhone, Android, iPad
The ability to create CSS3 background gradients on any HTML element offers a lot of potential to create visually satisfying and engage experiences in the browser. But gradients are just about creating a 60s acid inspired rainbow of color. Because an HTML element can have multiple background images, you can do tricky things such as layering different gradients. If you use a background color and use rgba colors in your gradient stops, you can create some truly interesting effects. Oh, and there are also image masks. Using a gradient as an image mask allows you to add texture to an otherwise flat surface. You can think of CSS3 gradients and image masks like Photoshop layers in your browser. Right now the following browsers support CSS3 gradients: Firefox, Chrome, Safari, Android, iPhone, iPad.

Having one giant gradient across an element is that exciting. But when you use the -webkit-background-size and -moz-background-size properties, you can creating interesting tiling patterns with your gradients. We start with a red, white and blue stripe gradient. This is a fairly straightforward pattern to create. It needs six color stops to create the stripes:

background-image:
	-webkit-gradient(linear, left top, left bottom,
		color-stop(.34, red),
		color-stop(.34, white),
		color-stop(.67, white),
		color-stop(.67, blue),
		color-stop(1, blue));

This will create a national flag filling the element.

Basic Red, White and Blue Pattern

Nice start, but to get a pattern we need to define the background size. If you use a value of -webkit-background-size: 20px 20px;, we get the following pattern:
Horizontal Pattern

And by changing the orientation (-webkit-gradient(linear, left top, right top)), we get a vertical pattern:
Vertical Pattern

Now if we change the orientation to a diagonal(-webkit-gradient(linear, left top, right bottom), we get an interesting pattern:
Diagonal Pattern

If we reduce the background size down further (-webkit-background-size: 6px 6px), we get an subtler pattern:

OK, this was all nice and good, but what about creating a diagonal pattern that fits together, like diagonal stripes? This takes a little planning. It isn’t an intuitive process to calculate the color stops to create diagonal repeating stripes that fit together seamlessly. Here’s the code. You can change the colors, or change the orientation, or use a background color and give the gradient colors transparency for some interesting effects:

background-color: #blue;
background-image: 
	-webkit-gradient(linear, 100% 0%, 0% 100%, 
	from(transparent), 
	color-stop(0.15, transparent),  
	color-stop(0.15, rgba(255,0,0,0.75)), 
	color-stop(0.50, rgba(255,0,0,0.75)), 
	color-stop(0.50, transparent), 
	color-stop(0.65, transparent),
	color-stop(0.65, rgba(255,0,0,0.75)),  
	to(rgba(255,0,0,0.75)));
	ffbackground-color: blue;
-webkit-background-size: 50px 50px;

This will give us:
Stripes

If we take this pattern and reduce its size to -webkit-background-size: 5px 5px, we get the following:

By changing the proportions of the background size (-webkit-background-size: 5px 10px), you can also create some interesting effects:
Pattern 10

So, take my patterns, play with the colors and background sizing and create your own patterns. You can try them out online, or download the source.

Update
I’ve updated code in the sample files to include the Mozilla gradient notation. This includes and update to work with the notation supported in the early betas of Firefox 4 (They’ve drop the -moz prefix off of the background-size property. CSS3 color gradients were first introduced by the Webkit team. After some time the Mozilla team began implement CSS gradients in Firefox as well. Then they came up with a simpler notation. Although the Webkit notation had already been submitted for standardization by the W3C, the Mozilla team pushed really hard to get their simpler notation accepted instead. They succeeded. The code below shows a Webkit gradient with its Mozilla equivalent.

.pattern-7 {
	background-image: 
		-webkit-gradient(linear, 100% 0%, 0% 100%, 
			color-stop(0.15, transparent),  
			color-stop(0.15, rgba(255,0,0,.5)), 
			color-stop(0.50, rgba(255,0,0,.5)), 
			color-stop(0.50, transparent), 
			color-stop(0.65, transparent),
			color-stop(0.65, rgba(255,0,0,.5)));
	background-image: 
		-moz-linear-gradient(left bottom, 
			transparent 15%, 
			rgba(255,0,0,.5) 15%, 
			rgba(255,0,0,.5) 50%, 
			transparent 50%, 
			transparent 65%, 
			rgba(255,0,0,.5) 65%);
	-webkit-background-size: 20px 10px;
	-moz-background-size: 20px 10px;
	background-size: 20px 10px;
}

These are similar, but the patterns could not be reproduced identically with the two notation differences:
gradient-6-Webkitgradient-6-firefox

If you’ve already been using the Webkit notation to create gradients for desktop Safari, Chrome, iPhone, Android or iPad, you’ll notice how much easier it is to put together a basic gradient. That said, as you start to create more complicated repeating patterns, things start to get, well, more complicated. If you create a complex pattern first in Webkit and try to reproduce it Firefox, you may find that it is impossible, or the other way around. For simple gradients or the repeating stripe patterns, it’s fairly easy to create Fireox/Webkit versions. Both notations can do things that the other cannot. Hmmm… Remains me of the bad ole days of Netscape Navigator 4 and IE5: two completely different ways of doing DHTML.

If you’re target audience is Safari/Chrome, iPhone/iPad/Android, then you need to get comfortable with the Webkit notation. Although the W3C has ratified the Mozilla notation, which it’s huge installed base of users and developers already using the Webkit notation, it’s going to be around, well, until there isn’t a Webkit anymore. At some point I would expect the Webkit team to adopt the W3C recommended standard as well. When they do, I get a million dollars they’ll keep their own -webkit prefixed version of gradients around as well for backwards compatibility.

In conclusion, CSS3 gradients offer you a way to create rich graphical backgrounds that can be tweaked and update through a few CSS3 properties. Have a client that want to change the colors of some interface elements? Easy, open the CSS file. With CSS3 gradients you can create gradients that stretch across an entire page without having a gigantic image to download, just a few lines of CSS. Photoshop may have to go see a therapist due to not feeling needed as much anymore.

Introducing ChocolateChip – A Mobile JavaScript Framework

Desktop Safari, Desktop Chrome, Desktop Firefox, Desktop Opera, Desktop IE9, iPhone, iPad, Android.

After using practically every mobile Web framework out there, I finally threw in the towel and decided to create a JavaScript library for mobile that was light weight and fast and easy to use. To this end I would like to introduce you to ChocolateChip. It’s small, a little chip, and tasty like chocolate. Minified, it weights in at 8k. It’s syntax is similar to jQuery. Unlike jQuery and other libraries, nodes are not obfuscated by object wrappers. Everything is always normal JavaScript. No need to relearn how to write JavaScript according to a library. Write it the way it’s supposed to be written.

Because I’m not dealing with old or non-standard browsers and their quirks, I could concentrate on implementing only what was necessary and doing so optimally. ChocolateChip has a $ function, like jQuery, which returns the first instance of a node identified by a valid CSS3 selector. It also has a $$ function which returns an array of nodes matching the CSS3 selector. Most methods are attached directly to the base Element object. That means those methods are available to all nodes in a document, making it unnecessary to wrap the returned nodes in an object to provide extended functionality. This means that you can use normal JavaScript functions directly on the nodes. And the keyword “this” really is this. You don’t have to do $(this). The library allows you to chain load functions when the document finishes loading, or fire blocks of code when the document’s markup is ready for parsing.

Here is what ChococlateChip looks like in action:

$.ready(function() {
	$("#aboutDownButton").onclick = function() {
		$("#About").addClass("down");
	};
	$("#aboutUpButton").onclick = function() {
		$("#About").removeClass("down");
	};
	$$(".menuList li").forEach(function(item) {
		item.onclick = function() {
			$(navigation[navigation.length-1]).removeClass("current");
			$(navigation[navigation.length-1]).addClass("reverse");
			if (!$("#Home").hasClass("reverse")) {
				$("#Home").addClass("reverse");
			}
			$(this.getAttribute("rel")).addClass("current");
			navigation.push(this.getAttribute("rel"));
			hideURLbar(); 
		};
	}); 
	$$(".menuList li").forEach(function(item) {
                item.ontouchstart = function() {
		    this.addClass("hover");
                };
	});
	$$(".menuList li").forEach(function(item) {
                item.ontouchend = function() {
		    this.removeClass("hover");
                };
	});
	$$(".button.back").forEach(function(button) {
		button.onclick = function() {
			var parent = navigation[navigation.length-1];
			navigation.pop();
			$(navigation[navigation.length-1]).addClass("current");
			$(parent).removeClass("current");
			$(navigation[navigation.length-1]).removeClass("reverse");
			hideURLbar();
		};
	});
	$$(".button").forEach(function(button) {
		button.ontouchstart = function() {
			this.addClass("hover");
		};
	});
	$$(".button").forEach(function(button) {
		button.ontouchend = function() {
			this.removeClass("hover");
		}
	});
}); 

Update October 15, 2010
You can now learn about and download ChocolateChip from it’s own site: ChocolateChip-Mobile.net. The following paragraph refers to an early, developmental version.

Without further ado, here is ChocolateChip. Download the library with some samples. Remember, this is for mobile development on advanced devices like iPhone, iPad and Android, so on your desktop use a modern browser like Safari or Chrome, or test directly on an iPhone, iPad, or Android device.

Because the minified version is only 8k, you can include it in your document instead of as an external dependency. This means one less server hit to reduce latency and avoids the possibility of the library not being found and loaded.

One last thing, I’m sure some of you are scratching your heads wondering why I didn’t provide any namespacing to prevent collisions with the use of $ and $$ by other libraries. Well, that’s the point. Mobile is all about file size and memory constraints. You really shouldn’t be using ChocolateChip with any other library. They were not designed for mobile use, ChocolateChip was. You don’t need jQuery and its plugins, Prototype/Scriptaculous/ Dojo, YUI or any of the other big boys. Take a bite out of ChocolateChip and realize how good a developer’s life can be.

UPDATE: ChocolateChip 1.01 August 30, 2010
OK, I added in support for event binding using the methods “bind” and “unbind” and some basic initialization functions built in for forward and backward navigation. If you build out your Web app using my coding conventions, this will give you automatic forward and backward navigation without writing any code yourself. Here’s the uncompressed version with comments, and a minified version, which now weighs in at 12k. And here’s a sample document showing the new bind event in action.

UPDATE Oct 15, 2010: ChocolateChip now has it’s own blog
That’s right. ChocolateChip has it’s own blog with posts about how to use it. Learn how the little guy and help you get big stuff done. ChocolateChip will also soon have it’s own site dedicated to downloads of source code, controls, layouts and other goodies.
Visit ChocolateChip-Mobile.net and check out how 8k of JavaScript can help you create light weight mobile Web apps.

iPhone Buttons without Border Images

Works in Safari, Chrome, iPhone, iPad, Android

There are five frameworks for mobile Webkit Web app development: iUI, UiUIKit, iWebKit, jqTouch and Sencha. All of these frameworks provide a simple way to implement a common interface feature of the iPhone, the slightly translucent buttons used for implementing actions. By using the CSS3 border image property it becomes trivial to use a highly compact graphic as a border image to create the visual effect of a glossy, translucent button. It’s also economical because the images are single pieces. Here are the three main ones:

White Translucent ButtonBlack Translucent ButtonBlue Translucent Button

Using the CSS3 border image property, we can create fancy buttons that are dynamic. Here’s the necessary CSS:

.plasticButton {
	cursor: pointer;
	margin: 5px;	
	text-align: center;
	color: #ffffff;
	font: bold 16px/20px Helvetica, sans-serif;
	text-decoration: none;
	text-shadow: 1px 1px 1px #000;
	text-transform: capitalize;
	display: inline-block;
	font-size: 16px;
	border-width: 0 14px;
	padding: 12px 0px;
	min-width: 110px;
}
.plasticButton.white {
	color: #000;
	text-shadow: #fff 0px 1px 1px;
	-webkit-border-image: url(whiteButton.png) 0 14 0 14;
}
.plasticButton.gray {
	color: #fff;			
	text-shadow: #333 0px 1px 1px;
	-webkit-border-image: url(grayButton.png) 0 14 0 14;
}
.plasticButton:hover, .plasticButton.hover {
	color: #fff;
	text-shadow: #333 0px 1px 1px;
	-webkit-border-image: url(blueButton.png) 0 14 0 14;
}

This would give us buttons like these:
Example of translucent buttons using the border image property

Not too bad. Well, except for the images. What if we need to change the color of the buttons for a custom theme? These images are not easily modified in Photoshop. Without Apple releasing the original artwork for use by the general public, there is no way to fine tune them for different color schemes. Also, if you intend on using them in a Web app, you’ve got to include them in a cache.manifest, etc. After thinking about all the niggling aspects of buttons using border images, I started thinking about how I could reproduce their look using just the CSS3 features we have now. Here is what I came up with. All you need is a border-radius, a border, a gradient, a box-shadow and a text shadow:

.button.black {
	display: inline-block;
	-webkit-border-radius: 12px;
	-webkit-box-shadow: 2px 2px 3px #999; 
	border: solid 3px rgb(110,110,110);
	background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(74,74,74,0.85)), color-stop(0.5, rgba(20,20,20,0.75)), color-stop(0.5, rgba(2,2,2,0.75)), to(rgba(14,14,14,0.75))); 
	color: #fff;
	text-shadow: #000 0 1px 0;
	font: bold 16px/20px Helvetica, Sans-serif;
	padding: 9px 11px;
}
.button.black:hover, .button.black.hover {
	background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(135,148,203,0.85)), color-stop(0.5, rgba(34,56,159,0.75)), color-stop(0.5, rgba(0,27,145,0.75)), to(rgba(2,59,152,0.65)));  
	color: #fff;
	text-shadow: #000 0 1px 0;
	-webkit-box-shadow: inset rgba(207,207,255,0.75) 0px 1px 1px;
}

Because the gradients values use rbga colors with alpha values, they are slightly translucent. By changing the values of the gradient, you can easily create different colored buttons. I’ve upload a working example, and you can also download the code. Do so and play around with the values. I’ve included a number of different default colors: black, white, red, green, gold and blue. You can make other yourself.

CSS3 Page Flips

Works with Safari, iPhone, iPad.

In previous examples of page navigation we used various types of sliding effects to indicate to the use the transition from one section of a Web app to another. Now we’re going to look at how to indicate section transitions with various types of page flips. In order for these types of flips to work properly, we will need to enclose the items being rotated in a parent element that has the CSS3 property for transform style with a value of preserve-3d. We also need to define the perspective value. The higher the value, the further back from the element the viewer will be, reducing the perspective distortion. Similarly, the smaller the perspective value, the more pronounced the 3D effect will be. For something a little less pronounced I use a value of 1000, and for more pronounced: 500.

First we’re going to look at implementing a typical “card flip” effect. We’re going to implement this with the same basic layout that I created in earlier posts with backward and forwards navigation with a slide effect, except that the links will lead to pages with the various flips and rotations. So, the target of the menu items will contain a parent element, a div tag, which we’ll give a class of “card.” This will have the perspective values that will determine how the rotation looks with perspective distortion. Here’s the markup for the first section. The other section have the same markup, but a different identifier to allow for unique transforms on each section. One thing to bear in mind when implenting these types of transforms, the background of the body tag will show as the elements transition. So, you should make transforms elements’ backgrounds visually different from the background of your body tag so that you can see the elements as they are rotated easier.

<article id="Flip">
	<section class="card">
		<div class="face front">
			 <header>
				 <span class="button back"><span></span>Back</span>
				 <h1>Flip Page Over</h1>
				 <span  id="flipOverButton" class="button">Flip Over</span>
			 </header>
			 <div class="paddingWrapper">
				 <h2>This is the front</h2>
				 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
		 </div>
		</div>
		<div class="face back">
			<header>
				<h1>Flip Page Over</h1>
				<span  id="flipBackButton" class="button">Flip Back</span>
			</header>
			<div class="paddingWrapper">
				<h2>This is the back</h2>
				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
			</div>
		</div>
	</section>
</article>

Here’s the CSS we need to get the rotation flip to work:

#Flip {
	-webkit-perspective: 1000;
	position: absolute;
}
article .card {
	min-height: 100%;
	width: 100%;
	position: absolute;
}
.face {
	position: absolute;
	width: 100%;
	height: 100%;
	text-align: center;
	-webkit-backface-visibility: hidden;
	-webkit-transform-style: preserve-3d;
	-webkit-transition: all .5s ease-in-out;
}
#Flip .face.front {
	-webkit-transform: rotateY(0deg);
	background-color: #fffccf;
}
#Flip .face.back {
	-webkit-transform: rotateY(180deg);
	-webkit-box-sizing: border-box;
	background-color: rgba(0,0,0,0.125);
}
#Flip .face.front.flip  {
	-webkit-transform: rotateY(-180deg);	
}
#Flip .face.back.flip {
	-webkit-transform: rotateY(0deg);	
}

We define the perspective property -webkit-perspective: 1000 on the article tag with an id of #Flip. Then we set the initial rotation status of the two divs. For the frontmost div we give it a rotation of 0 degrees, and for the back one, a rotation of 180. We also give the div with the “face” class a CSS3 property to hide its rear side so that it doesn’t show when we rotate it: -webkit-backface-visibility: hidden;. Now, to initiate the flip effect all we have to do is use a little JavaScript to add and remove the “flip” class to the two elements.

Now let’s look at how to implement another flip effect that resembles a left page turn. This is basically the same as the card flip described above, except that we’re going to define the start position of the transform. By default the start position is at the center of the element’s y axis. We’re going to use -webkit-transform-origin: 0% 0%; If we used a value of -webkit-transform-origin: 100% 0%; the result would resemble doors swinging open and closed. Here’s the complete list of styles for the left page turn effect. Notice that we’ve decreased the perspective on the “card” class to 500:

#TurnLeft .card {
	height: 100%;
	-webkit-perspective: 500;
}
#TurnLeft {
	height: 100%;
	background: #cbd2d8;background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.75, #c5ccd4), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 6px 100%;
}
#TurnLeft .face {
	position: absolute;
	width: 100%;
	height: 100%;
	-webkit-backface-visibility: hidden;
	-webkit-transform-style: preserve-3d;
	-webkit-transition: all .5s ease-in;
	-webkit-box-sizing: border-box
	text-align: center;
}
#TurnLeft .face.front {
	background-color: #fffccf;
	background-image: -webkit-gradient(linear, left top, right top, from(rgba(197, 204, 212, 0.5)), color-stop(0.75, rgba(197, 204, 212, 0.5)), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 5px 100%;
	-moz-background-size: 7px 100%;
	-webkit-transform-origin: 0% 0%;
	-webkit-transform: rotateY(0deg);
}
#TurnLeft .face.back {
	-webkit-transform: rotateY(180deg);
	-webkit-box-sizing: border-box;
	background-color: rgba(122,137,212,0.25);
	-webkit-transform-origin: 0% 0%;
}
#TurnLeft .face.front.turnLeft  {
	-webkit-transform: rotateY(-180deg);	
}
#TurnLeft .face.back.turnLeft {
	-webkit-transform: rotateY(0deg);	
}

So, once again we can trigger the turn page left effect by adding and removing the “turnLeft” class to the necessary elements.

Lastly, we’ll look at how to do a swing back and down effect. Notice that we’re not rotating on the y-axis but on the x-axis. This causes the elements to rotate on their x-axis:


#SwingBack .card {
	min-height: 100%;
	-webkit-perspective: 500;
}
#SwingBack {
	height: 100%;
	background: #cbd2d8;background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.75, #c5ccd4), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 6px 100%;
}
#SwingBack .face {
	position: absolute;
	width: 100%;
	height: 100%;
	-webkit-backface-visibility: hidden;
	text-align: center;
	-webkit-transform-style: preserve-3d;
	-webkit-transition: all .5s ease-in-out;
	-webkit-box-sizing: border-box
}
#SwingBack .face.front {
	background-color: #fffccf;
	background-image: -webkit-gradient(linear, left top, right top, from(rgba(197, 204, 212, 0.5)), color-stop(0.75, rgba(197, 204, 212, 0.5)), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 5px 100%;
	-moz-background-size: 7px 100%;
	-webkit-transform-origin: 0% 0%;
	-webkit-transform: rotateX(0deg);
}

#SwingBack .face.back {
	background-color: #fffccf;
	background-image: -webkit-gradient(linear, left top, right top, from(rgba(197, 204, 212, 0.5)), color-stop(0.75, rgba(197, 204, 212, 0.5)), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 5px 100%;
	-moz-background-size: 7px 100%;
	-webkit-transform: rotateX(180deg);
	-webkit-box-sizing: border-box;
	-webkit-transform-origin: 0% 100%;
}
#SwingBack .face.front.swingBack  {
	-webkit-transform: rotateX(-180deg);	
}
#SwingBack .face.back.swingBack {
	-webkit-transform: rotateX(0deg);	
}

And here’s a working example online, or you can download the source. Enjoy.

iPad Style Split Layout with Flexible Box Model

Works in Safari, Firefox, Chrome, iPhone, iPad, Android

In a previous post we looked at how CSS3’s flexible box model allowed us to create horizontal alignment of elements. There are several other features in the flexible box model that allow us to create layouts that would require complicated CSS hacks or JavaScript: equal height columns. You know the kind of layout I’m talking about. A header with several columns of material and a footer. You want the columns to always be the same height. You can use a table, but that can introduce a certain nasty kudginess to what you’re trying to achieve. Or you could use background images with nested divs, which is another type of kludginess. Or you could use some JavaScript, which introduces another type of kludginess.

With the flexible box model you can accomplish the equal height columns with a few CSS3 properties. What we’re going to do is show how to put together a typical split-level iPad layout with equal height sections. Here’s what we’re shooting for:
Example Layout with Equal Height Columns using CSS3 Flexible Box Model

To create the layout in this image, we’ll use the following markup:

<!DOCTYPE HTML>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width; height=device-height; initial-scale=1.0, maximum-scale=1.0, user-scalable=0;">
	<meta name="apple-mobile-web-app-capable" content="yes">
	<title>Flexible Box Model Layouts</title>
	<style type="text/css">
	</style>
</head>
<body>
<article>
	<header>
		<h1>Home Base</h1>
	</header>
	<section>
		<aside>
			<nav>
				<ul>
					<li><a href="#">Item 1</a></li>
					<li><a href="#">Item 2</a></li>
					<li><a href="#">Item 3</a></li>
					<li><a href="#">Item 4</a></li>
					<li><a href="#">Item 5</a></li>
					<li><a href="#">Item 6</a></li>
					<li><a href="#">Item 7</a></li>
					<li><a href="#">Item 8</a></li>
					<li><a href="#">Item 9</a></li>
				</ul>
			</nav>
		</aside>
		<section>
			<h2>Subtitle Here</h2>
			<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. </p>

			<p><b>Lorem ipsum dolor sit amet, consectetur adipiscing elit</b>. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. <i>Lorem ipsum dolor sit amet, consectetur adipiscing elit</i>. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
			
			<p>Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. <b>Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh</b>. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. </p>
		</<span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre="">section>
	</section</span></span>>
	<footer>
		<p>Footer stuff here</p>
	</footer>
</article>
</body>
</html>

If you load this markup in a browser, it’ll be pretty plain. Let’s add some basic styling for the header, footer, list menu, etc. First we’ll get rid of the defaults for the body and list elements.

html, body {
	margin: 0px;
	padding: 0px;
	font: normal 14px/16px Helvetica, Sans-serif;
}
ul, li {
	list-style: none;
	padding: 0px;
	margin: 0px;
}

Next, for Firefox, we need to indicate that the HTML5 tags are block elements. The latest versions of Webkit in Safari, iPhone and iPad already recognize these tags and display them properly.

/* for Firefox */
article, header, section, nav, aside, footer {
	display: block;
}
/* end Firefox */

Now we need to add the styles to give are markup a more polished look. We’re going to add CSS3 background gradients, rgba color and border radius:

section > section {
	padding: 10px 20px;
	background-color: #cbd2d8;
	background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.75, #c5ccd4), color-stop(0.75, transparent), to(transparent)); 
	background-image: -moz-linear-gradient(left, #c5ccd4, #c5ccd4 75%, transparent 75%, transparent);
	-webkit-background-size: 5px 100%;
	-moz-background-size: 5px 100%;
}
header {
	background-color: #b0bccd;
	background-image: -webkit-gradient(linear, left top, left bottom, 
		from(#b0bccd), 
		color-stop(0.5, #889bb3), 
		color-stop(0.5, #8195af), 
		to(#6d84a2));
	background-image: -moz-linear-gradient(top, #b0bccd, #889bb3 50%, #8195af 50%, #6d84a2); 
	padding: 10px 10px;
}
header h1 {
	text-align: center;
	font: bold 21px/21px Helvetica, Arial, Sans-serif;
	letter-spacing: -1px;
	text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.5);
	color: #fff;
	margin: 0px;
}
footer {
	background-color: #b0bccd;
	background-image: -webkit-gradient(linear, left top, left bottom, 
		from(#b0bccd), 
		color-stop(0.5, #889bb3), 
		color-stop(0.5, #8195af), 
		to(#6d84a2));
	background-image: -moz-linear-gradient(top, #b0bccd, #889bb3 50%, #8195af 50%, #6d84a2); 
	padding: 1px 0px;
	text-align: center;
	color: #fff;
}
nav li > a {
	text-decoration: none;
	display: block;
	padding: 8px 10px;
}
nav li > a {
	cursor: pointer;
	padding: 8px;
	border-bottom: 1px solid #acacac;
	background-color: #fff;
	font-weight: bold;
	color: rgba(0,0,0,.75);
}
nav li > a:after {
	content: "›";
	font: normal 28px/28px Verdana;
	color: rgba(0,0,0,.5);
	display: block;
	float: right;
	margin-top: -6px;
}
nav li > a:hover {
	background-image: -moz-linear-gradient(top, #4286f5, #194fdb);
	background-image: -webkit-gradient(linear, left top, left bottom, from(#4286f5), to(#194fdb));
	color: #fff;
}
nav li > a:hover:after {
	color: #fff;
}
h2 {
	color: #666;
	text-shadow: 0px -1px 1px #fff;
}
section > p {
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	background-color: rgba(255,255,255,0.85);
	border: solid 1px rgba(0,0,0,0.5);
	padding: 10px;
}

This gives us a layout that looks like this:
Style Layout Without Flexible Box Model Applied

This doesn’t look too bad, except that we want to the list to be on the left, and the content to be on the right. Normally, to achieve that we would need to put the content section before the list and float it right and then float the list left. Then we’d need to clear that float on the footer. That would work visually, except that neither the list nor the content would know about the other’s height. Or we could use relative and absolute position, and basically have the same problem. Or we could use CSS3’s flexible box model and have no problems at all, well, unless you really, really need to support IE, any version. You could use this for the god browsers and use conditional comments to give IE some crappy float arrangement. Honestly, I would to that to IE without thinking about it.

So, if you look at the document markup, we have an article tag with a header tag, section tag and footer tag as its children. The section tag has and aside tag and another section tag as its children. To make those work they way we want we need to give the parent section tag some flex power:

article > section {
	display: -webkit-box;
	-webikit-box-orient: horizontal;
	-webkit-box-align: stretch;
	display: -moz-box;
	-moz-box-orient: horizontal;
	-moz-box-align: stretch;
	-moz-box-lines: multiple;
}

This will give us cause the aside and section tags to align horizontally in their parent and each will have the same height. However in both Webkit and Firefox they both have some other issues with understanding how to deal with the long, wrapping content in the section tag.

Equal Height Columns in Firefox with Width Adjustment ProblemsEqual Height Columns in Safari with Width Adjustment Problems

To fix the problem with the browsers not knowing how to handle the wrapping content we just need to add a flexible box value to the section tag with the content:

section > section {
	-webkit-box-flex: 1;
	-moz-box-flex: 1;
}

What this does is tell the browser that the child section tag’s width should be whatever space is left over from that occupied by the aside tag, it’s sibling in the same container. Since the aside has a defined width of 200 pixels, the browser will give the rest to the section tag. Suddenly our layout is looking and acting the way you’d expect. It will even expanding dynamically as you resize the browser window.

You can try it out live or download the source.

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 2.0

ChocolateChip Version 2.0
After many months of work, I’ve just launched ChocolateChip-UI 2.0. This was a major undertaking. Everything has been re-factored. Lots of bug fixes for widgets.

The most important thing is that now there is only one version of ChocolateChip-UI for ChocolateChip.js, jQuery and Zepto. Previously I had created a separate version for each library because of their differences. This mean that, in the case of jQuery and Zepto, they didn’t have the same feature set as the original ChocolateChip.js version. And bug fixing was driving me up the walls.

To reduce the complexity and simplify things, I created an abstraction layer so that ChocolateChip-UI works exactly the same with ChocolateChip.js, jQuery and Zepto.

I’ve also done some initial work for accessibility support for screen readers, although more needs to be done.

Check out the latest version of ChocolateChip-UI. Having a unified version mean I can now dedicate some time to creating and Android theme. And after that I intend on create a right to left version for languages using Arabic and Hebrew alphabets.