Radial Gradients and Web SQL Databases

Feb 8, 2010
Episode 11
Nick and Jim keep the party going from last week, and continue exploring CSS3 gradients and web storage techniques.

Thanks to those who make Doctype possible!

Radial Gradients

Last week we took a look at linear gradients, but this time, we're taking things a step further and trying out radial gradients, which can be good if you want to highlight a particular area of your page or create a spotlight or vignette effect.

In Firefox, set the background-image of an element to -moz-radial-gradient and in parenthesis type CENTER, circle, your inner color, the radius for your inner color, and your outer color, and finally the radius for your outer color. This will create a radial gradient in the shape of a circle, but if you want to create an elliptical gradient, replace the word circle with ellipse. Each argument should be separated by a comma.

-moz-radial-gradient(center, circle, #ff0099 0%, #e4c700 100%);

Webkit is just a little bit more tricky. Basically, it works by creating two concentric circles and drawing a gradient between them. To create a radial gradient, set the background-image of an element to -webkit-gradient. Then, in parenthesis type RADIAL. The next argument is the coordinates of the inner circle, followed by its radius. In this example, we'll use center center for the coordinates, but you can also use integer values. We'll set the radius, to 0. Next, type the coordinates for the outer circle, followed by its radius. Last, type FROM, your-first-color, and then TO, your second color.

-webkit-gradient(radial, center center, 0, center center, 625, from(#ff0099), to(#e4c700));

Adding noise to your gradients can add some texture to elements on your site and help mitigate any problems with color banding.

In an image editor like Photoshop, create a square image with some harsh noise. 500 pixels square should probably be large enough. Then, set the opacity to a very low number, and save the image as a 24-bit png.

In both webkit and Mozilla, all you have to do is use the URL function inside of your background-image declaration, set the path of the image, and be sure to put a comma afterwards.

background-image: url('noise.png'), -moz-radial-gradient(center, circle, #ff9900 0%, #000 100%);
Browser Support

To use gradients in Internet Explorer, you have two options. You first choice is to go with the IE gradient filter which is specific to Internet Explorer. This isn't recommended however, because it's best to avoid proprietary technology when possible.

The better way to go is to create a special stylesheet that uses images instead of gradients. This is also useful for people using older browsers. Remember, Firefox just added support for gradients, and there's a lot of people that haven't upgraded to 3.6 yet.


Web SQL Databases

Last week in episode 10 we took a look at the Web Storage API, which provided a persistent key-value database in JavaSceipt. This week we take a look at the Web SQL Database API, which gives us a full SQL database in the browser.

If you are used to programing with a sql database on the server, you should be pretty familiar with how it works. However, the shape of your code will be a little different. In typical server side database code, you go from one statement to the next, and always wait for your query to be executed before going to the next line of code. In JavaScript, however, you can't do that. There is only one thread of execution, and if you wait for database calls to return data, you are stopping other things from happening like animations or drawing UI. Instead we utilize asynchronous database calls and use callbacks to handle results.

Getting Started

Let's start by opening a database connection and creating a table.

  var db = openDatabase("myDatabase", "1.0");

    var sql = 'CREATE TABLE people( \
      name TEXT NOT NULL DEFAULT "John Doe", \
      shirt TEXT NOT NULL DEFAULT "Purple" \

First we get our database using openDatabase(). Each database is identified by a name and version. The version numbers allow you to migrate the data, should you change the schema later.

Then we start a transaction. Transactions allow us to roll back data if errors occur during a sequence of statements. We call the transaction() function on the database, which takes a callback function that will be passed the transaction object (tx). Then we can call executeSql on the transaction and pass it a query string. In this example we are creating a table with an id, name, and shirt;

Handling Results

When you perform a SELECT query, you usually want to get your data back. This is done using a resultHandler callback function that is passed to executeSql(). The executeSql function takes 4 arguments: query, parameters, resultHandler, and errorHandler. When you include ? (question marks) in your query, the values in the parameters array will be placed into the string properly escaped.

resultHandler is a function that will be executed if the query runs successfully. The result handler will be passed the transaction object and a result object. The result object has a 'rows' property which contains all of the selected rows. Each row is an object with the properties that match the column names from the query.

Example result handler:

        function (tx) {
            var SQL = "SELECT * FROM people WHERE shirt=?;";
            tx.executeSql(sql,[ color ], function(tx, results){
              var names = [];

              for(var i = 0; i < results.rows.length; i++){
                var row = results.rows.item(i);
              alert('These people like ' + color + ' :' + names.join(', '))

Handling Errors

The fourth parameter for executeSql is an error handler. This is a function that will be called if something goes wrong in the query; It will be passed the transaction object, and an error object. The error object has two properties, message, which is a human readable message; and code, and integer error code;

The error handler also controls whether or not to roll back a transaction. If the error handler returns true, the entire transaction will be rolled back. Any changes made up to that point in the current transaction will not be committed to the database. If the error is bad, you probably want to return true;

If you return false, the transaction will continue on as though no error occured. If it is a minor error and the rest of the queries should still execute, you should return false.

Example Error Handler:

        function (tx) {
            tx.executeSql(sql, params, resultHandler, function(tx, error){

              var error_is_fatal = true;
                return true; // Rollback Transaction
                return false; // Continue with transaction;