Category Archives: Tutorial

CSS3 Quick Tip: plastic buttons with gradients and box-shadows

Hi all.

Tonight I was browsing dribble.com when I stumbled on this impressive piece of design by David Lanham:

I wanted to replicate this buttons with some CSS3 styling, using all the cool new things you can get: border radius, box shadow, gradients and text shadow, to name a few.

I started with a simple standard HTML5 document.

<!DOCTYPE html>
<html>
  <head>
    <title>CSS3 Plastic Buttons</title>
  </head>
  <body>
    <div class="container">
      <a href="#" class="red button">Red</a>
      <a href="#" class="blue button">Blue</a>
    </div>
  </body>
</html>

The results so far aren’t impressive. Let’s start to add some styling.

body {
  background: #32383a;
}
.container {
  width: 450px;
  margin: 150px auto;
}
a, a:link, a:visited {
  cursor: pointer;
  font-family: Helvetica, Arial, sans-serif;
  text-decoration: none;
  color: #ddd;
  font-weight: bold;
}

Nothing complicated here: I set the background color for the page then positioned the buttons’ container roughly in the center of the viewport and gave some basic styling to the anchor tag, our button-to-be.

Now we can start to style our .button class. First I added some margin to separate the buttons apart from each other and some padding to set the button’s size and to place the text in the lower left corner.

I also set the line-height to 65 pixel in order to position the buttons well apart if you want to place them in two or more rows.

a.button {
  margin: 10px 5px;
  padding: 30px 40px 6px 10px;
  line-height: 65px;
  text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
  border: 2px solid #111;
  -webkit-border-radius: 7px;
      -mozborder-radius: 7px;
          border-radius: 7px;
  -webkit-box-shadow: 0 -1px 4px rgba(255,255,255,0.1), 0 2px 5px rgba(0,0,0,0.8);
     -moz-box-shadow: 0 -1px 4px rgba(255,255,255,0.1), 0 2px 5px rgba(0,0,0,0.8);
          box-shadow: 0 -1px 4px rgba(255,255,255,0.1), 0 2px 5px rgba(0,0,0,0.8);
}

You can notice that I’m starting to use some new CSS3 styling: I added a slight hint of shadow to the button’s text with text-shadow (reference) to give it more depth.
I also gave the button a 2 pixel rounded dark border and two different box shadows: an highlight and a button’s drop shadow to the bottom (reference).
As you can see you can concatenate several box shadows together, to achieve different kind of effects.

Right now the buttons have the shape but not the colors we want, let’s use some CSS3 gradients!

a.red {
  background: #b3312a; /* Old Browser */
  background: -webkit-gradient(linear, left bottom, left top, color-stop(0.4, #A02C28), color-stop(0.95, #C24B45), color-stop(0.96, #d4766e), color-stop(0.99, #C24B45)); /* Chrome, Safari4+ */
  background: -moz-linear-gradient(center bottom, #A02C28 40%, #C24B45 95%, #d4766e 96%, #C24B45 99%); /* FF3.6+ */
  background: -webkit-linear-gradient(bottom, #A02C28 40%, #C24B45 95%, #d4766e 96%, #C24B45 99%); /* Chrome10+, Safari5.1+ */
  background: -o-linear-gradient(bottom, #A02C28 40%, #C24B45 95%, #d4766e 96%, #C24B45 99%); /* Opera11.10+ */
  background: -ms-linear-gradient(bottom, #A02C28 40%, #C24B45 95%, #d4766e 96%, #C24B45 99%); /* IE10+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F5A2A2', endColorstr='#C24B45', GradientType=0 ); /* IE6-9 */
  background: linear-gradient(bottom, #A02C28 40%, #C24B45 95%, #d4766e 96%, #C24B45 99%); /* W3C */
}
a.blue {
  background: #202631; /* Old Browser */
  background: -webkit-gradient(linear, left bottom, left top, color-stop(0.1, #202631), color-stop(0.95, #3e464f), color-stop(0.96, #67717c), color-stop(0.99, #444f5e)); /* Chrome, Safari4+ */
  background: -moz-linear-gradient(center bottom, #202631 10%, #3e464f 95%, #67717c 96%, #444f5e 99%); /* FF3.6+ */
  background: -webkit-linear-gradient(bottom, #202631 10%, #3e464f 95%, #67717c 96%, #444f5e 99%); /* Chrome10+, Safari5.1+ */
  background: -o-linear-gradient(bottom, #202631 10%, #3e464f 95%, #67717c 96%, #444f5e 99%); /* Opera11.10+ */
  background: -ms-linear-gradient(bottom, #202631 10%, #3e464f 95%, #67717c 96%, #444f5e 99%); /* IE10+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#202631', endColorstr='#3e464f', GradientType=0 ); /* IE6-9 */
  background: linear-gradient(bottom, #202631 10%, #3e464f 95%, #67717c 96%, #444f5e 99%); /* W3C */
}

It seems a lot of code, but actually I wanted to use all the different browsers’ custom syntaxes. You can use this beautiful tool to test your colors and generate the code.
I tried to adhere to the original colors as mush as I could, playing with the percentages you can achieve subtle effects and reach amazing results.

Now it’s time to add some “animation” to our buttons, first by adding a glow effect to the a:hover state.

a.button:hover {
  -webkit-box-shadow: 0 -1px 4px rgba(255,255,255,0.4), 0 2px 5px rgba(0,0,0,0.8);
     -moz-box-shadow: 0 -1px 4px rgba(255,255,255,0.4), 0 2px 5px rgba(0,0,0,0.8);
          box-shadow: 0 -1px 4px rgba(255,255,255,0.4), 0 2px 5px rgba(0,0,0,0.8);
}

I enhanced the highlight around the button but you can do other things, like changing the gradient colors or whatever you like.

Finally I styled the a:active state in order to simulate the clicking of the button. I wanted to simulate the actual pressing of a plastic button, so I played with the padding and the relative positioning in order to move the text slightly 1 pixel to the top.

Then I also changed some percentages of the gradient to move the highlight to the top, just as the button is being pressed down. As a last thing I removed the glow effect of the hover state because I didn’t want to put too much stuff at the same time.

a.button:active {
  position: relative;
  top: -1px;
  padding-top: 29px;
  padding-bottom: 6px;
  border-bottom: 3px solid #111;
  -webkit-box-shadow: 0 -1px 4px rgba(255,255,255,0.1), 0 2px 5px rgba(0,0,0,0.8);
     -moz-box-shadow: 0 -1px 4px rgba(255,255,255,0.1), 0 2px 5px rgba(0,0,0,0.8);
          box-shadow: 0 -1px 4px rgba(255,255,255,0.1), 0 2px 5px rgba(0,0,0,0.8);
}
a.red:active {
  background: #b3312a; /* Old Browser */
  background: -webkit-gradient(linear, left bottom, left top, color-stop(0.4, #A02C28), color-stop(0.97, #C24B45), color-stop(0.98, #d4766e), color-stop(0.99, #C24B45)); /* Chrome, Safari4+ */
  background: -moz-linear-gradient(center bottom, #A02C28 40%, #C24B45 97%, #d4766e 98%, #C24B45 99%); /* FF3.6+ */
  background: -webkit-linear-gradient(bottom, #A02C28 40%, #C24B45 97%, #d4766e 98%, #C24B45 99%); /* Chrome10+, Safari5.1+ */
  background: -o-linear-gradient(bottom, #A02C28 40%, #C24B45 97%, #d4766e 98%, #C24B45 99%); /* Opera11.10+ */
  background: -ms-linear-gradient(bottom, #A02C28 40%, #C24B45 97%, #d4766e 98%, #C24B45 99%); /* IE10+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#C24B45', endColorstr='#F5A2A2', GradientType=0 ); /* IE6-9 */
  background: linear-gradient(bottom, #A02C28 40%, #C24B45 97%, #d4766e 98%, #C24B45 99%); /* W3C */
}
a.blue:active {
  background: #202631; /* Old Browser */
  background: -webkit-gradient(linear, left bottom, left top, color-stop(0.1, #202631), color-stop(0.97, #3e464f), color-stop(0.98, #67717c), color-stop(0.99, #444f5e)); /* Chrome, Safari4+ */
  background: -moz-linear-gradient(center bottom, #202631 10%, #3e464f 97%, #67717c 98%, #444f5e 99%); /* FF3.6+ */
  background: -webkit-linear-gradient(bottom, #202631 10%, #3e464f 97%, #67717c 98%, #444f5e 99%); /* Chrome10+, Safari5.1+ */
  background: -o-linear-gradient(bottom, #202631 10%, #3e464f 97%, #67717c 98%, #444f5e 99%); /* Opera11.10+ */
  background: -ms-linear-gradient(bottom, #202631 10%, #3e464f 97%, #67717c 98%, #444f5e 99%); /* IE10+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3e464f', endColorstr='#202631', GradientType=0 ); /* IE6-9 */
  background: linear-gradient(bottom, #202631 10%, #3e464f 97%, #67717c 98%, #444f5e 99%); /* W3C */
}

So, I think that’s all for tonight. I consider this just a little experiment and I hope you’ll find it useful.

I tested this code with Chrome 12, Safari 5 and Firefox 4. I know that it doesn’t work as intended on Internet Explorer but I don’t care.

You can find the final result and then some more on this page.

Bye,
L

An MVC implementation for Appcelerator – Part 1: Introduction

Hi all,
let me introduce this post by welcoming Andrea Mostosi as a new addition to our team here at PrimeGap. Andrea is one of the most brilliant coder and passionate geeks I’ve ever met.

Starting with this introduction, he will present several tools and frameworks to enhance your coding with Appcelerator Titanium.

Welcome Andrea and here’s your post.

LT

Since Titanium was introduced, in December 2008, no MVC implementation has been proposed from Appcelerator Inc.

People who work with common MVC frameworks (like Rails, Django, …) don’t like messy files. Many MVC implementations have been proposed, but no one has yet succeeded in becoming the standard.

On the official Wiki there is a “Javascript Frameworks” section with a link to Foundation, a MVC microframework with basic features. With a Google search you can find out a few other. I personally prefer Appcelerator on Rails.

Appcelerator on Rails tries to implement most of Rails features using similar filesystem design and limited-feature Ruby-based generator.

Model generator creates standard code for accessing data

var #{model} = Model.extend({
table_name: "#{table}",
_fields: {id: Number #{fields_sql}},

find: function(id) {
var model = new #{model}(this.db, this._find(id));
return model;
},

item_from: function(row) {
var model = new #{model}(this.db, this._item_from(row));
return model;
}
});

Controller generator writes both View and Controller code

var #{name}View = View.extend({
init: function(win, controller) {
this._super(win, controller);
this.layout();
},

layout: function() {
// do something
}
});
var #{name}Controller = Controller.extend({
init: function(win) {
this._super(win);
this.view = new #{name}View(win, this);
}
});

(function() {
var win = Titanium.UI.currentWindow;
new #{name}Controller(win);
})();

Controller gets its own View using a conventional (and static) name and View has a method layout() which draws the interface. Then there is a closure which instantiates the controller.

This is an efficient strategy, but with many big downside, we will see advantages and disadvantages in part 2.

There’s also a Migration generator who generate SQL code for table creation.

migrate("#{migration}", "CREATE TABLE IF NOT EXISTS #{model} (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT #{fields_sql})");

The migrate method executes SQL code and add a new row to the migration table.

Stay tuned for Part 2, where we will see Appcelerator on Rails in action.

UPDATED on July 22nd: added the Part 2 link. Enjoy!

Problems with Rake 0.9.0 and Ruby on Rails?

Problems Rails?

If you tried to use rake in a Ruby on Rails project in the last few days, it could happen something like this:

rake aborted!
undefined method 'task' for <Your::Application:0x00000123ddd567>;

It depends on something that happened with the 0.9.0 version of Rake and you could fix it reverting to the previous version (0.8.7).

First uninstall the 0.9.0 version (maybe you should use sudo)

$ gem uninstall rake -v=0.9.0

Then specify the forced version in your Gemfile file inside your Rails application.

# Gemfile
gem 'rake', '0.8.7'

Finally update the bundle with the new (old) version of Rake.

$ bundle update rake

As a general rule, it’s advisable to specify the version of your gems inside the Gemfile, especially in production environment.

That’s all, I hope it could be useful and save your day.

jQCloud, a jQuery plugin to build neat word clouds (that actually look like clouds)

Have you ever noticed that tag clouds and word clouds come in many shapes, but they hardly ever look like actual clouds? This fact was bugging me, so I decided to code jQCloud, an open-source jQuery plugin that draws neat cloud-shaped word clouds.

jQCloud

click the image to see a live demo

It is powered by an algorithm somehow reminiscent of Wordle, but producing pure HTML word clouds, that can be easily styled through CSS.

Using jQCloud is quite simple. First, make sure to import jQuery and the most recent version of the plugin’s JavaScript and CSS code, that you can find here.

Once you have done that, the first step is creating a container element in your HTML, explicitly specifying its dimensions and position (like relative, absolute, or really anything different from static):

<div id="wordcloud" style="width: 550px; height: 350px; position: relative;"></div>

Then, simply create an array of words, specifying for each of them a text, a weight (its relative “importance” in the cloud) and, optionally, a URL. Finally, call the jQCloud method on the container element to release the magic:

var word_list = [
   {text: "Lorem", weight: 15},
   {text: "Ipsum", weight: 9, link: "http://jquery.com/"},
   {text: "Dolor", weight: 6},
   {text: "Sit", weight: 7},
   {text: "Amet", weight: 5}
   // ...other words
];
$(document).ready(function() {
   $("#wordcloud").jQCloud(word_list);
});

You can style the cloud at will with CSS: just remember that the container element will be given a class of jqcloud, while each word will belong to one of ten classes of relative importance, from w1 to w10. Anyway, the best approach is probably to edit the default jqcloud.css file provided in the package.

Also, remember that jQCloud has a GitHub repository, where you can read the docs, find examples and fork the code.

Ruby on Rails Quick Tip: passing variables to i18n localized strings

UPDATE: this tutorial has been updated on May 6th, 2011. Thanks to equivalent.

Hi all,
today I want to share a little gotcha about Ruby on Rails.

I usually embed variables inside my erb (or haml) code in my view to do things like these:

<p>
  Welcome, <%= @user.name %> to our awesome app
</p>

In order to internazionalize my application I needed to pass the username from the view to the localized string.
To do it you have to pass to the translate method an hash with your variable as value and a key to be referenced inside the locale yml file:

<p>
  <%= t("message.welcome", :username => @user.name) %>
</p>

While in the locale yaml file you have to embed the placeholder inside double curly brackets, like this {{variable}}:

en:
  message:
    welcome: "Welcome, %{username} to our awesome app"

Bye and I hope you will find this tip useful,
L