Print Shortlink

Creating 1 euro per dag: lessons learned

After months of work we finally released the website for our charity 1 euro per dag at the beginning of this month. The idea is to have a monthly voting between two charities and the winner gets 1 euro per day of the participating people. Simple yet efficient method of making donating money to charities fun. Participation is doing quite well. Without any publicity besides posting it on Facebook/Twitter/Google+ we have managed to get 16 participators.

From the beginning on we had the focus on keeping the website as simple and lean as possible. Thinking twice about every page that we would add. We achieved this by hiding a lot of unnecessary content behind buttons (but not in an annoying way).

I was the developer and since we were starting the project from scratch it was a nice opportunity to play with jQuery and Less CSS. We had to stick to PHP to keep hosting costs to a minimum but for the rest I could go all out.

Less CSS saves time and helps in keeping things clean and lean

This is the first time I release a project built with Less and I must say that using it is a blessing. I used to have projects where the designer had his classes too loosely defined ending up in weird style errors all over the project. Nesting in Less CSS solves this problem once and for all. Will definitely use this again next project.

A good framework saves a lot of time, pick a good one

Picking a good framework that supports all your requirements will help you save a lot of time. After some testing I went for CodeIgniter 2 based XTA 2 which includes login for Facebook, Yahoo, Google and Twitter. It was only once we started testing intensively that we found out that XTA 2 had quite some shortcomings which required a lot of development to get it all fixed but I managed: a user account system that allows the user to link multiple external authentication providers to its account and saves the original target url throughout login and registration process.

Working with different account providers is the source of a lot of headaches. Example: if a user creates an account through Twitter we do not have an e-mail address or password. If we require the user to enter his password to delete his account he first has to setup an e-mail address, verify it, create a password and only then the user is able to delete his account. This means the user has to jump through a lot of hoops to delete his account and give even more information to us in the process. In the end we chose to let the user delete his account without a password when he has not setup a password. A minor security issue but we avoid a big inconvenience for the user.

jQuery rocks for adding small interactions to the site.

I have mainly worked on projects that serve whole apps written in JavaScript (GWT, Closure Tools). For adding small interactions jQuery was really a blessing as a requirement for reusability is nonexistent. The only thing that I made for reusability is the small piece of code that I wrote for tooltips:

Screenshot tooltip

The code is only a few lines of jQuery, Less CSS, a sprite for the arrows and utilizes the data-* attributes introduced by HTML5. And since sharing = caring. Here is the code, free to use for whatever you like.

Example of an element with a tooltip (adding the attribute data-tooltip-position=”below” will show the tooltip below instead of above the element)
This <span data-tooltip="I'm a tooltip!">text</span> has a tooltip!
The JavaScript:

function setupTooltips() {
  $("[data-tooltip]")
    .unbind('mouseenter')
    .unbind('mouseleave')
    .mouseenter(function(e) {
    var el = $(this);
    var offset = el.offset();

    if(typeof tooltip === "undefined") {
      $("body").append("<div id='tooltip'><div class='arrow-up'></div><div class='content'></div><div class='arrow-down'></div></div>");
      tooltip = $("#tooltip");
    }

    // show tooltip, we need this to calculate height
    tooltip.show();

    tooltip.find('.content').html(el.attr("data-tooltip"));

    if(el.attr("data-tooltip-position") == "below") {
      tooltip.find('.arrow-up').show();
      tooltip.find('.arrow-down').hide();

      // position 3 pixels between bottom element and tip arrow
      var top = offset.top + el.height() + 3;
    } else {
      tooltip.find('.arrow-up').hide();
      tooltip.find('.arrow-down').show();

      // position 3 pixels between top element and tip arrow
      var top = offset.top-tooltip.height()-3;
    }

    // center the tooltip above the center of the element
    var left = offset.left + el.width()/2 - tooltip.width()/2;

    // show tooltip and set position
    tooltip.offset({ top: top, left: left});
  }).mouseleave(function() {
    tooltip.hide();
  });  
}

The Less CSS

#tooltip {
  display: none;
  position: fixed;
  top: 0px;
  left: 0px;
  z-index: @zIndexTooltip;

  .content {
    padding: 1px 7px;
    background-color: @orange;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
    color: white;
    font-weight: bold;
    text-align: center;
    -box-shadow:        3px 3px 0 #ddd;
    -webkit-box-shadow: 3px 3px 0 #ddd;
    -moz-box-shadow:    3px 3px 0 #ddd;
  }

  .arrow-up {
    height: 7px;
    background-image: url(img/sprite-tooltip.png);
    background-position: center top;
    background-repeat: no-repeat;
  }  

  .arrow-down {
    height: 10px;
    background-image: url(img/sprite-tooltip.png);
    background-position: center bottom;
    background-repeat: no-repeat;
  }  
}

The sprite image for the tooltip: 

Using sprites to limit number of connections

To minimize the number of requests to your server to cope with the limitation of the HTTP 2-connection-per-server constraint it is advised to bundle your images in 1 image. While using Google Web Toolkit I never had to care about doing this manually, it is done automagically. Doing this manually can be a big pain if it wasn’t for this solid tutorial that includes anything you need to know to get started using sprites quick and easy. It uses a Photoshop script to make creating the images an easy process and offers a couple of Less-functions to integrate it easily in to your site.

Small note on the sprite Photoshop script: make sure you have set your default measurement units to pixels or it won’t work.

Leave a Reply