Welcome to Cykod. We are a fully-integrated, self-funded web-development startup located in Boston, MA.

Cykod Web Development and Consulting Blog

Discover your non-testing Goat w/ Git blame and RCov

I wrote a quick n' dirty script for fun last night to see how we were doing on test coverage and who was responsible for the most untested code in the git repo. The idea behind the script is to take the output of RCov and line it up with the output of `git blame` and then track who's responsible for each line. It's ugly code, but it's was fun to pull together a couple of different pieces. Here's a sample modified coverage/ file (with the commit and person responsible for the code add on the left):

Gist below.

I unfortunately discovered I was the goat.




Posted Tuesday, Nov 29 2011 09:48 AM by Pascal Rettig | Consulting, Development

Using Node.js and your phone to control a Browser game

This past week I undertook a pretty cool project as the Intern here at Cykod. We were wondering how easily a smart phone –specifically using its gyroscopes and accelerometers– could be used as a controller for a multi-player game on a larger screen. With a bit of Node.js and HTML5 magic, it turned out to be pretty simple.

Concept

We want to use a desktop (laptop, iPad, etc. something with a bigger screen that multiple players can easily look at) connection to act as the common game space. Once that screen is initialized, each player connects to a specific URL in their phone browser that links them to that game instance. We'll follow this basic outline:

  • Register new connections to the server and decide if it is a room or mobile user:
  • Create a new room,
  • Or add the connection to an existing room
  • Constantly poll the mobile device for orientation data
  • Use said data to update the HTML5 Canvas game
  • Handle dropped connections appropriately

Result

The proof-of-concept full game is up at http://bit.ly/G4LSpaceWords  

 

The Technology

Node.js
Node.js is what makes this project possible. Built on Google's V8 Javascript Engine, Node.js is a server environment written in -wait for it- JavaScript. I started this project with zero knowledge of writing a server or what it would take, and Node made it super easy. Unfortunately, because the Node.js project is growing so quickly, up-to-date documentation with current-version examples can be lacking.

Socket.io
A Node.js module, Socket.io adds multiple levels of socket support, accommodating nearly every browser. This allows Node.js to quickly communicate with the browser similar to the way AJAX would, but with less overhead. Socket.io does not yet seem to support the updated Websocket Spec deployed in the latest Chrome and Firefox. As soon as it does, performance will be significantly smoother compared to the current default of XHR Long polling.  Now supported in the newest version of Socket.io, and controller performance is better.

Mobile Phone Orientation
Nearly all smart phones on the market have some sort of accelerometer or gyroscope in them. The phone parses this information and makes it accessible in the browser. The HTML5 DeviceOrienation and DeviceMotion events allow us to take advantage of this. You can read more about it at HTML5 Rocks. (Fun Fact: The native Android browser does not support access of this data. A third party browser like Firefox is needed)

Building the server

The actions performed by the mobile phone and desktop will be completely independent of each other, communicating only through the server (app.js). The best way to do this is through two different html files. We could embed all the code into one large file, but that would overly complicate our simple proof of concept. Create index.html (for the desktop), and mobile.html (for the phone).

Room Structure
Each game instance needs a desktop screen and at least one mobile device to communicate. We don't want any outside interference, so we'll create a new game instance for each desktop screen. We'll refer to a game instance as a room. Each room contains a desktop and an unknown number of mobile connections. For clarity's sake (and to help distinguish between different rooms), we'll also include a room id. Room Structure:

App.js

//An array to store the existing rooms
var rooms = [];
function room(roomSocket, roomId){
  this.roomSocket = roomSocket;  //Stores the socket for the desktop connection
  this.roomId = roomId;          //The room id/name. A unique string that links desktop to mobile
  this.mobileSockets = [];       //A list of all the mobile connections
};

Definition: A socket is how we refer to a single connection. So for every device connected to the server, a socket is created. Node.js and Socket.io streamline this process, automatically creating and destroying sockets as needed. This continually simplifies our room management.
 

New Connections
When a new socket is created (anytime a user visits index.html or mobile.html), we want to notify app.js so it can either:

A) Create a new room (if index.html is sending the data),

index.html

//This sends the signal 'new room' to the server, along with data containing the room name id. For live deployment, this should be a random string. See the full documentation for example socket.emit('new room', { room: “lolcats”});

 

app.js

//The receiving end of 'new room'
socket.on("new room", function(data){
  //Pushes a new room instance, storing the desktop connection as the roomSocket and data.room ("lolcats") as the roomId
  rooms.push(new room(socket, data.room));
});

Awesome! So we have a new room object being created and stored each time a new desktop connection is established. For efficiency's sake, we want to monitor any lost connections and delete those rooms, but we'll get into that shortly.

 

B) Or add a user to a room instance (if mobile.html is sending the data)

mobile.html

socket.emit('connect mobile', { room: getUrlVars()["id"]}, function(data){
  if(data.registered = true){
    registered = true;
  }else{
    $('#error').append(data.error);
  }
});

Similar to a new desktop connection, mobile.html sends an emit('connect mobile') to app.js. We also pass along the id parameter from the URL (mobile.html?id=RoomName) to specify which room this mobile user should belong to. Lastly, a callback function informs the mobile user that they have connected successfully, and can now transmit data.

app.js

socket.on("connect mobile", function(data, fn){
  var desktopRoom = null;

  //Cycle through all the rooms and find the room with the same roomId as our mobile device
  for(var i = 0; i < rooms.length; i++){
    if(rooms[i].roomId == data.room){
      desktopRoom = i;
    }
  }

  if(desktopRoom !== null){
    rooms[desktopRoom].mobileSockets.push(socket);

    //Store the position of our room that this mobile device belongs to
    socket.set('roomi', desktopRoom, function(){})

    //Return the callback as true
    fn({registered: true});

    //Access the room that this socket belongs to, and emit directly to the index.html to 'add user' with the socketId as a unique indentifier.
    rooms[socket.store.data.roomi].roomSocket.emit('add user', socket.id, data);
  }else{
    //Callback returns false with an error
    fn({registered: false, error: "No live desktop connection found"});
  }
});

The server searches through the array of rooms to locate the correct one. Once we've identified the room by its name, it is saved in desktopRoom. After double checkingagainst a null value to ensure we have located a room, the mobile socket is pushed into the room[id].mobileSocket array. The socket.set method is then used to store data directly in the socket. We save the room's position in the array. With this value, we can easily access the appropriate room without having to search the array each time. The callback is returned as true if successful, or false with an error message.

Lost connections
But what happens when we lose a connection? Socket.io has a built in 'disconnect' function that is called when a socket disconnects. We start by testing for the existence of socket.store.data.roomi. Because we only set that value for the mobile connections, we know instantly the type of connection.

node.js

socket.on("disconnect", function(){
  var destroyThis = null;
  i
f(typeof socket.store.data.roomi == 'undefined'){

    //The lost socket is a room

    //Search through all the rooms and remove the socket which matches our disconnected id
    for(var i in rooms){
      if(rooms[i].roomSocket.id == socket.id){
        destroyThis = rooms[i];
      }
    }

    if(destroyThis !== null){ rooms.splice(destroyThis, 1);}

  }else{
    //Lost socket is a mobile connections

    //Sort through the mobile sockets for that particular room, and remove accordingly
    var roomId = socket.store.data.roomi;
    for(var i in rooms[roomId].mobileSockets){
      if(rooms[roomId].mobileSockets[i] == socket){
        destroyThis = i;
      }
    }

    if(destroyThis !== null){rooms[roomId].mobileSockets.splice(destroyThis, 1);}

    //alert the room that this user was a member of
    rooms[roomId].roomSocket.emit('remove user', socket.id);
  }
});

We now have a fully functioning Node.js server that handles all connections, disconnections, and stores our data in easy to parse room structures.

Updating the Tilt Data

With the connection established, we can easily send tilt data from the mobile to desktop side. This is covered in much better detail over at HTML5 Rocks, so we'll skip to the Node stuff.

mobile.html

function deviceOrientationHandler(tiltLR, tiltFB, dir, motionUD) {
  if(registered){
    socket.emit('update movement', { tilt_LR: Math.round(tiltLR), tilt_FB: Math.round(tiltFB)});
  }
}

This function will run every time the phone gets new mobile tilt data. We're really only interested in the tiltLR (Left Right), and tilfFB (front back). Read through the HTML5 Rocks for more info. app.js receives this data and immediately forwards it along to the desktop corresponding to our mobibile device.

app.js

//Update the position socket.on("update movement", function(data){
  if(typeof socket.store.data.roomi !== 'undefined'){
    if(typeof rooms[socket.store.data.roomi] !== 'undefined'){
      rooms[socket.store.data.roomi].roomSocket.emit('update position', socket.id, data);
    }
  }
});

Because mobile.html transmits data after a connection is established, there is no error checking to make sure the index.html counterpart still exists. Our 'update movement' performs this check to ensure the desktop connection still exits. It emits data directly to the correct room in the 'update position' signal.

index.html

socket.on('update position', function(socketId, data){}

The server will then signal index.html and call the socket.on("update position") . This passes all our tilt data to the desktop client, leaving the world wide open for awesome canvas implementations.

I won't be going into the canvas game aspects, but the example code and a basic version of canvas game play is available on Github. You can also see our language learning game implementation, Super Space Words .

Posted Wednesday, Aug 24 2011 09:15 PM by James Burke | Development, HTML5 | Node.js, Socket.io

How To: Social Plugins

 

[ This is a Guest Post from Cykod Intern James Burke ]


This is a follow up post to the talk I gave recently on Social Plugins and Widgets at the Boston Front End Developers Meetup.

Social Plugins are still a fairly new concept. While widgets that track visitors or display RSS feeds have been done to death, Facebook breathed new life into social sharing with their Facebook Platform and Social Graph. Since debut, Facebook has been storing user information and building a huge network of data. With the debut of Social Plugins, any site can take advantage of the social giant Facebook has become.

 

Facebook’s Open Graph Protocol:

Access to Facebook’s Social Graph is accessible through their aptly named, Graph API. Nearly all Facebook public data is available through this graph. People, pages, events, photo galleries, etc. The ability to see this information is a very cool and powerful way to do analytics research.

We’re going to use this platform to socialize our websites. In order to properly integrate our web pages, we need to turn our content into a form that Facebook can recognize. We declare this information as meta data in the page header. There are a bunch of properties to use, but Facebook requires these four specifically:

  • og:title - What your content is about.
  • og:type - What object type your content is.
  • og:url - The URL for this object, usually dynamically generated.
  • og:image - An image that Facebook with utilize in their graph and other social actions.

 

So in my example for Cykod.com, the Open Graph tags would look like this,

<meta property="og:title" content="Cykod"/>
<meta property="og:type" content="website"/>
<meta property="og:url" content="http://cykod.com/"/>
<meta property="og:image" content="http://cykod.com/system/storage/3/11/logo.png"/>
<meta property="og:description" content="A forward thinking, Rails-based web start-up looking to change the way you interact and play with the web."/>

You can take a shortcut for your Open Graph tags by skipping to step two on the Like plugin page.

 

Like/Share Button:

This is a really simple one to implement. Just follow along on the Facebook documentation.

There’s a form to help you out. Enter in the content you like, and compare to the live preview.

Like/Share button options:

  • URL to Like - Leaving this blank will default it to the current page (for XFBML only, but we’ll get more into that in a second).
  • Send Button - Once again, XFBML only. It allows the user to specifically target who they want this page to be ‘sent’ to. Clever name right?
  • Layout Style - Each is a little different. Play with different settings and the live preview to decide what fits best.
  • Width - Based on your site layout.
  • Show Faces - The option to display small thumbnail images of the user’s friends when they see the like button.
  • Verb to display - “Like” or “Recommend”
  • Color Scheme and Font - Again, based on your layout.

XFBML or IFrame?

 eXtended Facebook Markup Language is Facebook’s very own specialized XML markup to quickly add these plugins.

IFrames are HTML tags that allow other pages to be embedded as a frame within another page. These are quick and easy to implement, but carry accessibility and SEO concerns.

In my opinion, XFBML is a cleaner approach with more options. It gives you —the developer— more control over the code.

 

Comments:

The comments plugin is pretty cool. In just a few minutes, your entire site can be up and running with a fully-fledged comment and moderation system without worrying about login/registering users.

Similar to the Like button we just covered, Facebook offers a nice form that generates the code for us.

After entering your site URL, your code will look like this:

<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script>
<fb:comments href="example.com" num_posts="2" width="500"></fb:comments>

  • We specify a div with the id “fb-root”. This is necessary for the running the JavaScript SDK (ie. any XFBML we use). If you’re using more than one plugin, it would be wise to consolidate the location of this tag.
  • The necessary JavaScript is pulled directly from Facebook.
  • A custom XML based tag is where our comment box will be inserted. Check out the additional parameters in the documentation for more customization.

Special Note: If you want each page on your site to have a different comment box (versus a side wide comment thread), then you’ll want to replace the url found in the href attribute. Using your favorite server side language, print out the url of the current page. For example, in Code Igniter (a PHP framework), I have a global function current_url(); that will return the —wait for it— current url. so, <fb:comments href=”<?php echo current_url(); ?> ...  creates a different comment thread for each page. Try Googling "{language of choice} print current url" if you need more help with the back end.

   You should see the comment box being displayed. Make sure you’re logged into Facebook and enjoy your quick commenting system!

 

Posting a message on the user’s wall:

The JavaScript SDKoffers us a bunch of additional tools to play with user data. First though, we need to take a short detour and setup a Facebook application page (so Facebook knows who is asking to publish content).

  • Visit the create application form.
  • Fill out the name of your app appropriately (I usually just use whatever the title of my site is), and agree to Facebook’s terms.
  • Skip ahead by clicking save.
  • Copy the App ID for your application. Hold onto this.

We’re going to focus on the first example from the Social Channels page. We want to prompt a logged in user to share a link on their wall. Facebook gives us the following base code.

<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({ appId:'YOUR_APP_ID', cookie:true, status:true, xfbml:true });
FB.ui({ method: 'feed', message: 'Facebook for Websites is super-cool'});
</script>

The first two lines should seem pretty familiar. We have the #fb-root again, as well as the JavaScript sdk.

Additionally, the FB.init and FB.ui methods are called right away;

  • FB.init is Facebook’s initialize method. This connects to our app and sets a few other basic parameters.
  • FB.ui is another SDK method. There’s a lot more to it, but we’re calling the feed method to display a popup to post on the users wall.

FB.ui will execute as soon as the page is done loading, which is not the best scenario. We would really like it only occur after clicking a link. Let’s wrap FB.ui in a method we can then easily call.

<script>
function postToFacebookWall(content){
FB.ui({ method: 'feed', message: content});
}
</script>

<a href=”javascript:postToFacebookWall('This is our content!');”>Click here to share this page on your Facebook wall</a>

When a user clicks on our link, we call the FB.ui to prompt a post. We pass the content parameter to populate the message value within FB.ui. This should give a bit more control when creating new links.

 

Other Sharing:

Besides Facebook plugins, there’s a whole world of different sharing plugins. Thankfully, they’re all very similar in code and usage. Nearly every instance you come across will have a form to generate customized code for you.

  • Twitter - Tweet Button
    • Select your shape, the default tweet text, what URL to focus on, and you’re done! Copy, paste, and tweet!
  • Twitter - Follow Button
    • Enter your user name. Copy, paste, follow!
  • Google Plus - Plus 1
    • The newest kid on the block, the asynchronous code looks worse than it is.
  • LinkedIn - Share Button
    • You may want keep this one away from your cute kitten Tumblr.
  • Delicious - Save Buttons
    • Although it may not be around for much longer, Delicious was the original social bookmarking website.
  • Digg - Digg Button
    • One of the earliest implementations of the social sharing.
  • Reddit - Reddit Buttons
    • Arguably where all the former Digg users now live.

Group Sharing Widgets

Easily embed dozens of Social Widgets at once. These take the guess work out of your code and make it very easy to share. There are a bunch more, but these are generally the top three options.

 

Building social functions is a tricky task, but these social plugins help the hurt. Optimized by some of the best engineers in the industry, these code snippets will help your site grow and make sharing content easy.

Make sure you dig through the Facebook documentation and let us know how you integrate social into your sites!

 

 


 

James Burke is the summer intern at Cykod. He is a front end designer and developer from Pennslvania, going into his senior year for Computer Science.

Posted Friday, Jul 29 2011 12:41 PM by James | Development | Facebook, Social

Boston Front End Web Developers Meetup, Round #1

 

The first Boston Front End Web Developers Meetup went off this past Wednesday (May 25th) according to plan with around 30 people showing up for the inaugural meeting - I gave a couple of talks, the first was a "State of Front End Development 2011" covering the current state of the craft and talked a bit about the aims of the group. The second one covered the basics of a Semantic HTML5 Chop with some extra details on Meta-data and the Semantic Web (I believe only a couple people nodded off during that one) Both presentations are embedded at the end of this post.

I asked people to fill out a survey with a few questions - the most important of which was what topics of interest for upcoming presentation might be - here's the responses:

 

Actual Data:

Writing Semantic HTML, HTML5 101 20 69%
HTML5 & Progressive Enhancement, Shiv & Fallback Options 21 72%
Using Grids, Fixed and Fluid 17 59%
SaSS, Haml, Less 11 38%
Coding for the Mobile Web - Media queries, jQuery Touch, Mobile CSS support, etc 21 72%
Javascript, Basic (language overview) 15 52%
Javascript, Advanced (closures, namespacing, ... ) 14 48%
jQuery, Basic (jQuery 101 - Selectors, Animation, Ajax) 17 59%
jQuery, Advanced (Promises, Templating, Data elements, new features 18 62%
Client side performance optimization (CDNs, minification, async loading, spriting, ... ) 17 59%
A/B Testing 14 48%
Analytics Options 12 41%
Facebook integration, OAuth, OpenGraph, Social Widgets 18 62%
Semantic Web, RDFa, Microdata 11 38%


What I thought was interesting was: one, the number of topics that had significant interest (no topic got under 38%) and two, the level of interest in learning more about mobile. It's pretty clear that there's a lot of interest in everything HTML5 related, and additionally both a serious need for mobile development and a lack of confidence in the best practices.  

If you're in the Boston area, join us for the next Boston Front End Web Developers meetup, and if you're interested in presenting on a topic shoot me an email at pascal at this domain. 




Posted Saturday, May 28 2011 06:03 PM by Pascal Rettig | Development, HTML5, Presentation

3D in the Browser: WebGL Presentation

With all the new releasing coming out - I thought it was a good time for a presentation on WebGL - below are the slides I presented to the Boston HTML5 Game Development Meetup on March 16. I also wrote a post on the state of 3D in Browsers on BostInnovation: 3D in the Browser: It's Go Time.




Posted Thursday, Mar 17 2011 01:20 PM by Pascal Rettig | Development, HTML5

PCI Compliance on Amazon's AWS

UPDATE: As  Spencer noted in the comment below, you can now configure ELB to generate PCI-compliant SSL proxying.
 
PCI Compliance, despite it's very important goals of safeguarding customer data, unfortunately right now exists primarily as a way for the processing companies to cover their butts. This weakness comes due to the fact that the bulk of the requirements can be fulfilled for small merchants by filling out the appropriate Self-Assessment Questionnaire (SAQ).

This is a little bit like asking high-school students to grade themselves on a test without giving them the answer key. There's the obvious problem of the students lying, but there's a further problem of them not knowing what the correct answer is. The terminology on the SAQ is not necessarily transparent.

To add insult to injury, most acquiring banks (the people who should receive the SAQ) aren't asking for it, simply because the number of vendors in the country processing payments far outstrips the capability of the card companies to check-up on them. Again, at the lowest levels PCI Compliance seems to exist primarily as a way to card companies to have their rumps properly protected in the event of a data breech. They get to levy fines and say "But they told use they were compliant," without springing for (the admittedly large cost of) an actual verification process.

There is, however, one part of level 4 compliance that has some value - and that's the need to pass a quarterly security scan from a Approved PCI compliance Scanning Vendor. This scan, even while it's not perfect at least provides a minimum baseline of safeguards a company needs to fulfill before it can reach compliance. Make sure you've applied the latest security patches and aren't running ancient software. That sort of thing.

Amazon recently reached level 1 compliance as a service vendor, meaning it's possible to run any size cardholder data environment on Amazon's cloud without being in violation. Unfortunately most Rails hosting companies, even those built on Amazon's AWS (like Engineyard and Heroku) don't seem to offer compliance or offer it at a significant premium.

What this means is that if you want to be compliant on the AWS cloud you either need to not take in any credit card information anywhere in your site (offsite pages, such as those provided by Braintree or Chargify are a great option) or you need to deploy your infrastructure directly onto EC2 yourself.

The good news is that the baseline infrastructure needed to pass the Automated security scan, provided you App doesn't have any holes is pretty straightforward.

There were only two notable things we had to do to pass the ASV:

1. Deploy the (as of this writing) latest version of Ubuntu - 10.10 Maverick. We deploy from the excellent alestic images. You need Apache version 2.2.16 or later to be compliant. 2.2.17 is preferred as 2.2.16 will still show up with a couple of notices (primarily related to expat vulnerabilities) but those won't affect your compliance. You could also probably find a backport of apache2 to the 10.04 LTS or compile your own. I don't know have any details on other distributions.

2A. Set up your SSL certificate directly on your instances Apache. You'll also need to disable weak ciphers and turn off SSLv2 by adding the following to your host configuration:

   SSLCipherSuite HIGH:MEDIUM:!ADH
   SSLProtocol all -SSLv2

As nice as Elastic Load Balancers support for SSL is - it unfortunately (as of right now) can't be configured in this way. Support in the API may show up at some point, see this topic on aws forums for more details. If your using ELB, you'll have to forward port 443 to your instances via TCP - which means you can't use any of the session stickiness options normally offers for HTTP connections.
A blog article on Zen One has some more details on the SSL issue as well as ways to test your configuration.
2B. (Or a Better solution) Ask amazon to configure a ELB with weak ciphers turned off. An Amazon rep we contacted has stated that they can modify anexisting load balancer to make it compliant - the advantage of this is that using Option 2A provides some problems with tracking the IP Addresses of incoming requests - something that is very important for fraud monitoring. We had to sign up for a support contract to open up a ticket to make this happen. This option also makes it possible to turn on session stickiness if that's something your app needs.
Next you need to actually run the scan - we used HackerGuardian from Comodo which gives you the first scans free. It's $250/year after that for 4 quarterly scans. They also have a SAQ Wizard to help you go through the steps necessary for compliance. The SAQ is a timesink and pain in the butt but it's not unmanageable.

And with that, you'll be good to go. You'll just need to find some people who actually want to pay you (but that's the easy part, right?)

Posted Saturday, Mar 12 2011 10:33 AM by Pascal Rettig | Business, Cloud, Development

Javascript Everyone: Online, Offline and on the Server

Presentation I gave to the MIT IAP HTML5 Game Development class on Debugging and Optimizing Javascript, Local Storage, Offline Storage and a little bit of Node.js with Web sockets




Posted Thursday, Jan 27 2011 01:35 PM by Pascal Rettig | Development, HTML5, Presentation

Archive or Trash: there is no delete

Webiva is a piece of software that lived for a long time as an internal tool whose users (us) at least sort of knew what we were doing.

As we both opened up the tool to other developers and began getting users with more experience who wanted to be able to do more with the system, we began to notice that certain things the system allowed you to do were a little too destructive.

One issue in particular has crept up again and again: deleting blogs.

Since Webiva allows you to create as many blogs as you like in the system (sites often use multiple blogs for Press Releases, News, etc), it also let's you delete those blogs. While most users don't have permissions to delete blogs, the permission is together with the permission to create blogs which users will often either ask for or add to their own account if they have the "permissions" permission.

At first we put this little needed feature in the top right of the blog detail page and just protected it with a confirmation popup that would post to the destroy page if confirmed:

About one week later we got a frantic call:

Client: I just tried to delete a post and I deleted my whole blog
Us: Didn't you read the popup saying, "WARNING: you are deleting an entire blog?"
Client: No

Oh well, to the Backup Batman!

Ok, we thought, we already know that people don't read every warning, so all we need to do is put a little more protection in.

Our 5 minute fix was to create a separate "destroy" page that had some ugly bold text that explained that they were deleting a whole blog, not a blog post. We even put the warning popup on that page:

Deleting a blog now required 4 clicks confirming that yes, you actually wanted to delete a whole blog.

Cut to a month later or so (different website):

Client: Someone hacked my site, my blog's gone
Us: How did that happen?
Client: I don't know
...Searching through the logs...
Us: Looks like you actually deleted it this morning
Client: Oh, I remember it saying something when I tried to delete a post but I just clicked "ok" until it worked.

Backup here we come..

Sure, we thought - the problem is that the top right of the page is actually pretty noticeable, the 5 minute fix in the new design we can hide the feature so that it's only visible when a user clicks on "More" - the actual delete post functionality would be visible in the table like all the other actions.

 

 

However this week the same thing happened again on yet another site, which confirmed what I already knew but hadn't taken the time to fix properly: It's not their fault. It's ours.

We could have followed this to it's natural conclusion: adding a big warning icon, moving the blog delete to a different subpage, and so on, but I'd guess that there is no amount of protection we can put in to 100% prevent a harried small business owner from deleting a blog. We could probably incrementally decrease the proportion that do it, but since our goal is to create a foolproof self-service tool, any chance is too high.

While it seems odd that warning screen after warning screen doesn't act as a deterrent, when a user is trying to figure something out, they will follow the first scent trail they see to it's natural conclusion. If they find the "Delete Blog" button before they notice the "Delete Post" button - well they will go on down that path up until something happens.

No warning, flashing text, or videos of kittens fighting will dissuade them from their path.

The solution is not to keep putting up bigger an bigger walls, as at each step the user just gets more frustrated to the point where they are just clicking and not reading a single thing.

The solution is quite simple: you can never let the user take a single action that can't be easily reversed, either by the user or by an Admin.

In complicated systems users never really know what they are doing and just satisfice their way through. What this means is that unfortunately, as a developer you can't automatically remove deleted data from the database or the file system.  It makes systems more complicated - you need to make sure you only show "undeleted" data by default, but it's really not that hard. It just takes more than 5 minutes.

The two most common ways to solve this are to use a "Trash can" where deleted content goes to die until emptied, or to add a "Archive" flag to pieces of content that doesn't remove them, simply removes them from the main Admin screen. These features are fairly easy to add in provided you account for them early in your application design.

Don't make the mistake that we did - assuming that we could kludge our way out of the problem by putting up warning screen after warning screen. It needs a real fix and the only solution is that there is no (permanent) delete option. And no, we haven't actually implemented the fix yet, but it should be available in Webiva 1.1 as we're working in adding in a system-wide trash can.

Posted Monday, Nov 29 2010 04:18 PM by Pascal Rettig | Design, Development

Getting my Hack Back

 

Stagnant.

 

There's nothing quite as scary as feeling your skillset stagnate. In the tech world, especially in consulting, failing to keep up with the times can feel like the kiss of death.

This is one of the reasons Developers, and Web Developers especially, jump at the chance to use whatever the shiny new toy is whenever they can. It's not that we really believe it's going to change our lives dramatically for the better, but rather it's making sure that we keep ourselves abreast of the trends and movements in the technology sector and don't fade quickly into obsolescence.

In the fall 2009 I was becoming more and more worried that my skillset, if not obsolescing was at least growing some mold.

We'd moved to Ruby from PHP and C++ in 2006 and had been doing website projects fairly exclusively on our magnum opus Rails CMS Webiva for the previous two years. We were gearing up for the Open-source release and were putting in long hours trying to get our ducks in a row, turning down PHP, Flash and .NET consulting projects to focus on the startup side of our business.

Being a small consulting shop and me the only developer, there wasn't a lot of cross-pollination of new techniques and ideas, and working in one language and one platform didn't help. Worse yet, we were even falling behind the times in our primary development platform Rails, which evolves at a lightning clip, and failing to stay up with the latest best-practices and trends because we were operating in our own tiny bubble.

I worried that being a small company without a daily exchange of ideas there was no easy way to separate the wheat from the chaff of development trends keep up with everything that was going on. I feared in the next couple years we were going to face a crisis of obsolescence.

It turned out I was just being lazy.

While it's true we were floating around in our own bubble, the bubble had plenty of windows to let me get back in touch with what was going on outside. A few nights a month and a few weekend's here and there was all it took to get that mental excitement at learning new things back.

Over the past year I've gotten back up to speed and felt happily plugged in to what's going on in the development community, and I wanted to share the events that have helped immensely:

1. Boston.rb - the Boston Ruby Group - but you can substitute your primary language and your city and the results should be the same. The type of people who show up to these events tend to be the people most interested in the evolution of your favorite platform, and make it dead simple to get a pulse of what's new and interesting via osmosis just by showing up regularly.

2. Rails Camp - not sure if these exist in all languages/platforms, but they should. Simply going away for a weekend to hack on something non-work related got me back to learning for learning's sake. Again the type of people who show up to this are those most interested in learning, so just sucking up the discussion and atmosphere for a weekend is invaluable.

3. Startup Weekend - if you haven't been to one yet, you're doing yourself a disservice. The energy that pervades this event is amazing, and the focus on actually getting something done and out the door makes it necessary to pack an immense amount of knowledge into your brain into a short period of time.  We launched Vidicul.us over the Boston weekend this past June.

4. Music Hack Day (or RailsRumble etc) Anything that gets you out of the house and interacting with other developers leads to learning and growth. Putting a deadline on it just makes it more likely you'll concentrate on the important things. You don't have to give up all your weekends, but the collaborative, timed-pressured, immersive environments that these events generate can't be substituted for anything else.

5. Meetup.com - The rise of Meetups and how easy they are to find and start on Meetup.com is the greatest boon to normally isolated professions to come about in the past decade. No longer are niche groups of developers invite-only and tough to find - just search for the technologies you are interested in and join up. (and if you're in Boston you should join the HTML5 Game Development meetup I just started - lot's of excellent brain-stuffing I promise)

These things, all of which encourage getting out of the building and actual face-to-face interaction with fellow developers has made this year a learning renaissance of sorts for me (hiring another developer at Cykod helped a lot too) and they all encouraged me to restart something else I'd gotten away from:

6. Learn new frameworks and languages early and often. When some new language or framework comes out, spend an evening hacking a small project together on it, just some simple itch you want to scratch. Don't worry about learning everything about it and don't make your company switch or do a production product on every new sparkly thing, but learning how to learn new languages and frameworks is the most important skill you can have. (Start with Seven Languages in Seven Weeks if you need a jump start)

The result, at least from a coding perspective has been my creating a number of pet projects in different frameworks and languages. Yes most of the time they are half-baked, half-executed hacks that don't get properly finished or tested, but serve as simple proofs of concepts for ideas.

I stopped doing this for a long time as I grew sad at at a wasteland of too many uncompleted projects, but I failed to realize that value was not in the end result, but rather in the proof-of-concept execution of some idea bubbling around in my brain. I'd put off starting a project if I didn't think I'd be able to put in the resources to complete it, not understanding that I was missing the whole point of the endeavor. I'm now happily in the middle of about 10 projects, most of which will never see the light of day but all of which have been fantastic learning experiences.

So that's the story of how, over the past year, I feel like I got my hack back -- I'd love to hear any stories about other developers going through the same trials and tribulations.

Posted Wednesday, Nov 03 2010 01:39 PM by Pascal Rettig | Development

The Perfect HTML Chop: An Opinionated Guide to slicing excellent HTML/CSS

Beta Post: This is a post that's going to form the first of three lengthy tutorials for how become a guru using our Open Source Ruby on Rails CMS Webiva, but since it doesn't actually contain anything that's Webiva-specific and could be useful to the world at large, I figured I'd put the initial drafts on the Cykod blog and see what the hive mind has to say.

Target Audience: This (lengthy) guide came out of my not having a good answer for how people should get started chopping up sites and generating "decent" markup. I would point people at this or that site and make suggestions about what was out of date and what I didn't agree with. I didn't have a good path for someone to be able to go from A to B to C and be able to actually chop up a site with markup that wouldn't make you turn pale. The goal of this tutorial is to combine the current practices (as far as I know), with some basic knowledge to give people a running start and have enough of a base to be able to use Google to fill in the gaps. Please point out any missing information, incorrect information, or recommendations for expanding the guide.

This is a relatively one-sided guide because I'm going to show you the way I do this and essentially ignore the myriad other ways to accomplish the same thing. If you're new to this stuff, know that this tutorial just one person's opinion and there are other ways to get the job done that might be a better fit for you. I'm content using a text editor and a separate browser and chopping with the GIMP. If you're a hardcore Dreamweaver-ite, this might not be for you.

Being an opinionated guide targeted at beginners I'm also going to occasionally omit details when giving a full explanation would complicate matters. Essentially, I'm asking you to take some of the suggestions on faith, you'll have plenty of time to learn all the other available techniques once you have a solid base. I'll try to point out the edge or historical cases where something I'm saying isn't true, but no promises. What you don't know can't confuse you!

While the later tutorials will be Webiva-specific, this one is pretty much applicable to Web Development in general and doesn't contain any actual Webiva specific details. We're also not going to discuss design at all in this post; we're going with the assumption that you have a AI, PSD or the necessary PNGs that you made yourself or have gotten from a designer.

The techniques in this tutorial should be useful for chops in general (there's a number of tricks for specific situations we won't be covering, but that's what Google is for) We're going to work off of the png below (full size version) - if you're relatively new to this I'd recommend you follow along by chopping up our "Evil Genius Robot Supply" site, but it might be more interesting if you try your hand at chopping a design of your own.



The first two sections are fairly  basic - skip down to section 3 if you already are comfortable with HTML, CSS and the Box Model.

1. HTML/CSS 101

We're going to assume that, even if you don't know your ul's from your ol's you at least know HTML (aka weird <thingys>) when you see it. Same thing with CSS (fonts, styles, colors, etc)

HTML is a markup language, which means you're annotating (marking up) plain text to give it structure and meaning, similar to the way you would underline or make notes in a book. While it may just look like tag soup in your editor, loading the file into a browser will show you how users will see it.

Tags 101

Tags are simply words inside of less than and greater then signs.

There are two types of tags. Tags that have an open and a close tag:

<div>Something inside a tag..</div>

and single tags: <br/>

The most important thing to remember is that each opening-tag (<div>) should have a closing tag (</div>), which is just the name for a tag containing  a forward slash ( / )before the actual tag name. All tags names should be written in lower case. Single tags need to have a `/` before the greater than sign so browsers know not to look for a closing tag.

There's generally two types of tags, those that 'mean something' and those that are generic content containers.

Meaning comes in two forms, a tag like <p> means "paragraph" - this adds some semantic meaning to the tag when you are viewing the source code, but doesn't actually mean much visually or stylistically (you can style <p> tags pretty much however your want)

A second form of meaning comes from tags like <img> and <a> - image and link tags respectively. These actually have an effect on the way a page is rendered or how it interacts with users. The former is used to put images on the page and the latter is used to create hyperlinks (technically the "a" stands for "anchor")

Of the generic content container tags there's two: <div> and <span>. These are used to break up your document into pieces so that you can group pieces of your page together and style those pieces. The only difference between a <div> and a <span> is that by default the <div> displays in a entire block and a <span> displays inline with your page.

w3schools has a good HTML5 tag reference you can use if you want more details on available tags.

The primary tags we'll be using are:

  1. the new (HTML5) semantic tags: <header>,<nav>,<section>,<article>,<footer>,<aside>
  2. the generic containers: <div> and <span>
  3. images (<img>) and hyperlinks (<a>)
  4. the old semantic tags, including paragraph (<p>), headers (<h1>,<h2>,<h3>,<h4>)
  5. lists, primarily unordered (<ul>). Unordered lists are often used for lists of menu items, form items, bulleted items, pretty much anything where there's a list of items that need to be styled consistently.


The markup for a menu often looks like:

<ul> <--- The list container
   <li> <-- the list item, a single list element
        <a href='/>Home</a> <-- the link for the navigation item
   </li>
   <li>
        <a href='/about'>About</a>
   </li>  
   .. more items ..
</ul>

Lists work nicely for menus as we can nest another <ul> inside of the first if we want to make a multi-level menu. They also provide just the right number of tags (3) to make it easy to style elements exactly as we need to.

A quick diversion into the history of HTML, Semantics, and HTML5

Now that you know what a tag is, and before we go any further, let's go over a bit of history to understand why HTML has tags and which ones we're going to use.

When HTML was first created back in the old, old days of 1992, it was primarily concerned with markup using elements that conveyed some sort of meaning - much like the outline of a book. How that markup would be displayed was left up to the browser. The original drafts included only 20 tags, with a focus on things like headers (<h1> - <h6>) and ordered, unordered, and definition lists.

As the web became more commercialized and authors wanted more control over presentation, additional tags were added to allow control over how the displayed elements looked. Tags like <font>, <b> (bold), <u> (underline), <center> and the infamous <blink> tag became commonplace.

There arose a need to separate the semantics of the document (what the pieces of the document mean) from the way those elements should be displayed (font sizes, colors, backgrounds, etc). To do that, CSS 1 was created and adopted, and despite some inconsistencies in implementation, people were generally able to write cleaner HTML while still styling elements as they wanted.

Sites eventually grew more complex, with headers and multiple columns and loads of intricately positioned images. The initial CSS spec didn't provide any way to define the structural layout of these sites, so people began to use <table> elements for site layouts, resulting in an ugly tag jumble of nested <tr><td><table><tr><td>... tags that were hard to understand and maintain, and clouded the overall meaning of the HTML document.

The solution to this was CSS2, which added in the structural capabilities developers know and love, like relative and absolute positioning and the z-index for layering elements. While support was a little patchy for a while (understatement of the year), eventually the web community came around and begin building their sites using primarily generic <div> tags and controlling the layout and styling via CSS, resulting in an easily maintainable separation of content from presentation.

The HTML community, myself included, took a little while to realize that an HTML document marked-up with dozens of div's is just as semantically empty as one filled with <font> and <td> tags. While the semantic meaning of tags is no longer really used by browsers to decide how to render tags, it is used to pick out the meaning of document. Although the backend structure of the document isn't important to most web visitors, it has become important to two consumers of web pages: search engines and the disabled. By removing all meaning from the structure of document, we're losing the opportunity to give extra meta-meaning to pieces of our site and make our sites both more accessible to disabled visitors and more easily searchable (SEO!)

HTML5 has brought all this full-circle, by adding a number of semantic tags that give meaning to the structure of various pieces of your page. The meaning of tags like <header>, <nav>, <article>, <footer>, <section> can pretty much be divined from the tags themselves.

We're going to use HTML5 tags to build our documents - because of a quirk in Internet Explorer, however, we'll need to include a piece of javascript called the html5 shiv to make it style elements correctly. If requiring javascript for IE is not a workable solution for your site, you'll need to replace the new semantic elements with <div class='..'> markup instead and adjust the CSS selectors appropriately.

Why bother to use HTML5 tags at all? The primary reason (besides being easier on the eyes) is that we are able to give hints to search engines about what the meaning of the different parts of our site are. By giving Google (et al) more information about our site we're hoping they'll be able to index it better and show our site more attractively in search results. Using the aforementioned semantic tags is a start, and we'll look at some additional ways we can provide more information to search engines and hopefully get a higher click through rate on the search results pages.

The W3C recently (October 2010) has stated the you should hold off deploying HTML5 websites for the time being.  They are most likely right that much of HTML5 isn't ready for prime time, and their primary consideration is interoperability issues. We're not going to be talking about most of the cool new HTML5 features: Video, Audio, and Canvas tags, local storage or geolocation, so this really doesn't apply to us. You can feel safe using the new semantic HTML5 tags without worrying about cross-browser comparability issues (provided you are ok with using the javascript html5 shiv for IE - and if you don't know if you're ok with it or not, you're ok with it)

Validation Primer

What does it mean to use HTML5? Well, it means more or less that we're going to be following a set of specifications that tell us, in very general terms, what tags and attributes we're allowed to use and in what order and position we need to put them in. It doesn't say: "Use a <header>, then a <section>, then a <div>...", but it states generally what tags make sense and what their general meaning should be. For the post part HTML5 allows a lot of flexibility in how you layout your tags, but there are some rules, for example you shouldn't be putting <div> tags into the <head> of your HTML.

Until they are finalized, specifications can be somewhat liquid things, with web browsers oftentimes implementing features before they are fully documented in a specification. It's also in Web Browsers best interested to try to render whatever junk a web developer has put on a page, even if it's not technically correct according to whatever version of HTML and CSS they are using. Web Browsers that don't handle errors in HTML well end up getting a bad rap.

Even though web browsers will probably render something no matter what soup of tags you throw up on the page, your best bet for a website that looks the way it's supposed to in each of the different browsers is to write code that is technically correct. Code that is correct according to the specification (HTML5 in this case) is said to "validate". The easiest way to figure out if your page validates is to run it through a validator, such as the one provided by the w3c (the World Wide Web Consortium, the people who  define the standards that are used on the internet)

The validator will point out some things that won't break your document if they aren't correct (like missing alt tags in some images), but it's in your best interest to correct these as it won't necessarily hurt and can help you with search engines and accessibility. I'd recommend using the validator frequently as you are learning HTML and CSS as you'll end up with better, more browser-independent code. Once you've gotten the hang of it, your site won't necessarily blow up anyone's computer if it doesn't validate (most sites don't actually validate) but it's good to know what you're doing that isn't correct and at least foobar it knowingly.

Sometimes you won't be able to write code that validates and still works the way we want to - that's a compromise we sometimes have to make (an example from further on is the `zoom:1` hack to make IE play nicely with relative divs) - but you should aim to have your code as technically correct as possible, and make sacrifices to that correctness only when necessary to make your page render correctly. 

Search engines like Google for example, seem to like to know you care. I've found that you'll tend to do better in search right away if your site is built "correctly" - in the long run this matters less then great inbound links, but building a well laid out site that uses tags as they were intended (like <h1>'s for your top-level titles) will most likely throw some extra Google juice your way, at least initially.

Tag Attributes

Opening and single tags can also have attributes. Attributes define additional characteristics about a tag. Here's an example:

<input type='text' name='green'/>

This is a single input tag that has two attributes: type and name. Just like tag names, attribute names should be lower case. Some attributes should be used with limited number of possible values - such as the type attribute, while some can be assigned whatever value you feel like - like the name attributes.

What attribute can be used on which tags is well defined, but there are three particularly important attributes that can be used on (almost) all tags. Those are:

  • class - this defines one or more CSS class names to assign to the tag. Multiple class names should be separated by spaces. Class names can (and should) be repeated, i.e. multiple tags can share class names. Classes are used to group styles together in CSS.
  • id - this defines a unique identifier that uniquely refers to this one tag. id's should not be repeated. IDs can be used to uniquely identify tags and style them with CSS. (They are also used to manipulate tags with Javascript)
  • style - this defines the CSS styles to use for this particular element, overriding any other CSS defined elsewhere You could, for example, add a attribute such as `style="color:red;"` to make a particular tag red.  (we try to avoid doing this however as munges our style with our HTML code - it's preferable to use a separate CSS file to style your content), but sometimes it's useful to temporarily play with styles on elements directly to try things out.


CSS

Moving on from tags, the next big concept to cover is CSS, which stands for Cascading Style Sheets. The style part is pretty obvious, as you use CSS to style your site, but the Cascading part is less so. What "Cascading" means is that both styles and selectors cascade from least specific to most specific (more on that in a minute). CSS can be defined either inside of a <style>..</style> tag in your HTML file or it can be defined in a separate file and linked to from your HTML most often with a <link.../. tag in the <head>..</head> section of your document.

CSS rules are created by specifying one or more CSS selectors (separated by commas), followed by an opening  curly-bracket ("{"), followed by one or more rules of the form:

rule: value;

i.e - a rule name, followed by a colon (":") followed by the rule's value, followed by a semi-colon. You can have as many rules inside of each CSS style as you like.

Finally the style is ended with a closing curly-bracket ("}")

The primary CSS selectors are tag name, tag class and tag id, and work as follows:

To apply a class to a tag name, just use the name of the tag (the below will apply to all input elements and make their text black.)

input { color:black; }

To affect all tags that match a specific class, use a period (.) in front of the class name:

.blue { color:blue; }

(this would affect all tags that had an attribute class='blue')
To affect a tag with a certain id="something" attribute, preceed it with a pound sign (#)

#menu { color:white; }

(The above would affect all text inside of a tag that had the attribute id='menu')

Cascading Down

There's two things about CSS that make it a little complicated. The first is that you can use multiple selectors to affect nested tags, such as:

div#menu p.blue { .. }

This would affect all the <p class='blue'>..</p> tags inside of a <div id='menu'>..</div> tag.

Secondly you might have a bunch of tags that could apply to a single tag, for instance:

p { color:red;}
.blue { color:blue; }
#menu p { color:black; }

 

Now if you had the following HTML, what color would your text be?

<div id='menu'><p class='blue'>Text..</p></div>

The answer is that it would be black, and the reason is that CSS selectors use the following criteria for determining which rules take precedence:

  1. Inline style (those defined directly with a style='...' attribute in the tag)
  2. Number of ID selectors
  3. Number of Class selectors
  4. Number of tag selectors
  5. Order of appearance last to first


Since the '#menu p' selector is the only one with a ID selector it takes precedence. If there had been two rules with a ID selector, CSS would have gone down the list to determine how to apply the style (all other things being equal) deferring to the last rule defined.

There's also a special exception that can mark property as particularly important, but I'd avoid using that unless you have no other options (or are doing a browser-specific hack) search for "!important css" for more details.

Available CSS Properties

CSS defines a fairly large number of available properties you can set to style your tags, some of the important ones are:

  • color - defines the foreground (usually text) color
  • background - defines the background, including background color and images
  • position - used by the box model to override the location of a tag (see the box model section)
  • float - lets you float elements left or right so that multiple blocks of elements can appear next to each other or other non floated elements
  • clear - gets rid of floats
  • font - defines the font used as well as the size, style and variation
  • top, bottom, left, right - used for positioned elements to define their location
  • padding & margin - sets the amount of spacing surrounding a tag
  • border - defines a border
  • width & height - well, the width and height of the element.
  • display - sets the method in which the browser displays the tag (or tells it not to)


Some of these tags (background,font,padding,margin,border) have multiple parts that can be set separately or all at once. For example you could say:

padding: 10px 0 10px 0;
padding: 10px 0px;

Both of which are the same as saying:

padding-top:10px;
padding-right:0;
padding-bottom:10px;
padding-left:0;

(padding and margin both work clockwise from 12 o'clock when you set them all at once, otherwise they set top/bottom and left/right at the same time)
The former is more succinct, but the latter lets you pick and choose which elements to override (you can also use a value called 'inherit' but let's ignore that for the time being)

You can also just use a single value:

padding: 10px;

To unformly set the padding on all sides.

While you will eventually get a hang of all the available styles, as you get going on CSS but a bookmark to a good reference (again w3schools CSS reference is pretty good)

CSS Units

There are number of different "units" you can use to define width and size properties. Two of the most common are to use a percentage or a specific pixel size. You need to make sure you specity a unit when you set a value (just like in elementary school math), otherwise your values are essentially invalid.

padding: 10px;
padding: 10;

The former will work as expected, the latter won't do anything, and is one of the most common bugs I've seen beginners run into when trying to debug your CSS.

2. The Box Model & Positioning

HTML uses what's called the box model, which boils down to two things:

1. Elements are drawn outside-in from:
  Margin -> Border -> Padding -> Width & Height

2. Your actual width and height are equal to:
   Margin + Border + Padding + content Width (or Height)

#2 usually throws people for a loop, so it's something to be aware of.

[Source]

Secondly, your HTML tags are primarily displayed in one of two modes: `block` or `inline` (there are a couple others: quirksmode has a great breakdown  )
Some tags, such as paragraph (<p>..</p>) tags default to block mode, while others such as links (<a>..</a>) default to inline mode.

You can control this with the CSS `display` property. You can also set the display to `none` to hide the element completely.

The primary difference between inline and block modes are that the former is displayed inline with your text (and can't have top & bottom margin or padding) while the latter stack on top of each other.

What if you want boxes that sit nicely next to each other? You can use the `float` property to float them up next to each other.

There's also a slightly less used display mode called 'inline-block' that does exactly what you would expect - puts your element inside it's own contained block but puts that block inline with your text. IE7 only supports this partially (the element must have inline mode by default) so shy away from this if you can.

The box model is important, if you don't already have it memorized print out a copy and paste it on your wall where you can easily view and bang your head against it when something doesn't go right.

3. The Setup

Every good craftsmen needs their tools, and make no mistake - creating a perfect chop is a craft. You need to take to take an image and turn it into a HTML representation that is minimal, understandable and easily modified, but most importantly will look good with any content you can throw at it. If you are going to be using a blog engine or CMS, you want to make sure you've thought about how your chop will handle content filled with text and images of different sizes that changes constantly. Every time someone uses a crappy tool to slice your site up into a bunch of rigid table cells or divs, a standards-based web developer somewhere dies a little inside.

Before CSS2 came along, web developers used to code most of their sites using tables. Most now use CSS to control layout, and so should you:

  1. Tables are rigid and link your HTML directly to your layout, making it difficult to tweak and modify down the road without re-writing all your HTML.
  2. HTML is moving very much in a direction where the tags you use add semantic meaning to their content in some way. HTML5, which we will be using, has tags like "header", "nav" and "article", which, when used correctly, can enhance your sites searchability by search engines and readability by screen readers.
  3. Browser support of CSS long ago got to the point where tables are unnecessary for non-tabular data.

 

The tools of the trade

To do the chop you're going to need:

1. A Text editor, preferably one that can display multiple files at the same time. I'm a big fan of MacVim & gVim, which customized all to hell are nothing like the vi your parents grew up with, but there is a (semi-epic) learning curve. Here are some good ones (not all of these support viewing multiple files, but you can't get everything you want:

        TextMate or MacVim (Mac), TextPad (Windows), gVim or Emacs (Linux)

Vim and Emacs are industrial strength code editors but both have a pretty substantial learning curve, so if you aren't in it to win it - any editor that can open and save text files should work. Editors like DreamWeaver that do more than just let you edit code can help you get started with, but since they can remove you from a full understanding of the the code you are writing, I prefer to just write in a text editor and preview in a browser.  

2. A Browser with a good DOM inspector and debugger. Firefox w/ Firebug installed or Chrome should both do the trick. I use the former, so adjust as necessary if you're a Chromite.

3. A Image Editor. What we're going to be doing only requires an image editor in the barest sense of the word. You'll most likely need to cut out a couple of pieces of our mockups into images and create a few repeating backgrounds, but what we're doing in a chop isn't going to require any real creative skills in your image editor. I use GIMP (which is open-source an multi-platform) It gets the job done and the price is right. If you already use Photoshop, it'll work just fine as well.

Fire-debugging

I'm going to assume you're working with Firebug as you're in-browser debugging/development tool.  To get started there's a couple tricks you should know:

When some element doesn't look correct, the easiest way to figure out what's going on is to inspect it - click on the little firebug in the corner to open firebug:

Then click on the inspect element icon:

Then finally click on any element in the page that you want to inspect.

You'll get a view of the HTML surrounding the element you selected in the left pane, and a overview of the CSS styles assigned to that element in the right pane. You can also click on the layout tab in the right pane to see an overview of the box model for the selected element, including height, width, padding, margin, and border. If you want to temporarily play around with some styles on that element, you can add, edit and remove styles by clicking on the styles you want to change or right clicking and selecting "new property" to add a new style in.

You can also click on the net tab when firebox is opened to see all files the system is loading - this is useful if you have images that aren't appearing as you'll see a '404' returned for the file if it doesn't exist or you put in a typo for the name.

Your choice: Multi-monitor or multi-desktop

Doing a chop you'll have three main applications open at all times: Your Image Editor with the mock-up and any images, your editor with your HTML and CSS, and your Browser.

Your best option is to have a three monitor setup that lets you have each of these maximized on a different monitor. Unfortunately, most video cards don't support three monitors yet, but many computers do support two monitors and given how cheap LCD's are now you should spring for the second monitor if you can. Multiple monitors helps because it means you don't need to keep as much information in your head at once and spend your time flipping back and forth to remember (e.g. what was that image name again?) It's the same reason you want multiple buffers in your editor so you can edit your HTML and CSS at the same time.

If you are constrained to just a single monitor, I would get yourself three virtual desktops (or workspaces, whatever they are called in your operating system) that  you can flip between easily with a keyboard shortcut and always put each app on a separate desktop. This will allow you to easily flip between your different windows without having to think twice about it. Most Linux's support multiple desktops right out of the box, OS X supports Workspaces and you can install something like if you are on Windows.

The goal is to be able to flip between apps easily, and unfortunately alt-tab doesn't work because the order constantly changes to the least-recently-used application, forcing you to stop for a moment, find the right app, and completely lose your train of thought in the process. Virtual desktops let you program a single keystroke into your muscle memory and switch between applications without any cognitive impact.

Get your mind right: we're talking layers here.

This step is important. If you're new to chopping up sites you might have an image in your head that looks something like this:

This is wrong. 1000 times wrong. You aren't taking a design and breaking it into little pieces. Instead, you should be focused on this:



Your goal is to create a nested structure of blocks, each of which fit neatly inside of each other and combine in perfect harmony. You should imagine
that you are layering pieces of your design on top of each other, each piece inheriting some portion of it's parent container.

Designing by cutting pieces up into blocks will result in a brittle design that resists change at all costs. Layering containers on top of each other makes it easy to modify portions of you site without breaking everything else. The Web is not print - you are actually allowed to (and should!) modify your website once it's published. You aren't creating a static piece of paper that's getting taped together, you're creating a wrapper for dynamic, fungible content that should be updated frequently.

So don't think of yourself as puzzle master, breaking apart your design into little pieces but rather a collage maker - layering pieces of the design on top of each other to create the finished product.

4. Beginnings

To get started with the actual chop, let's set up a file structure, it's going to look like this:

     index.html
     style.css
     images/

We're going to put our index.html and style.css files in the same directory and then create a subdirectory called `images` where we're going to put all our sliced-up images. One reason we're doing it this way so that we can easily do a bulk replace on an string that matches `images/` if we need to change the relationship between the stylesheet and the images directory, but mostly because this is the way our Webiva CMS does it to make it easy to import and create a theme.

Initial HTML

Now time for the nitty gritty - we have to crack open the text editor and start writing some code. The good news is we don't need to think yet, we just need to drop in the basic necessary HTML wrapper code.

Create a file named index.html and insert this basic HTML code:

<!DOCTYPE html>
<html>
<head>
  <title>Webpage Title</title>
  <!--[if lt IE 9]>
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
  <link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
   Content Goes Here
</body>
</html>

That first part - the doctype - lets the browser know that it should render the document in standards mode, and keeps IE from doing anything funky. It's actually the HTML5 doctype - the XHTML4 ones were much nastier, but even if we weren't doing anything HTML5 specific we can take advantage of it's brevity and still count on everything being rendered correctly.

Next we have couple of the standard tags. There are two main parts to any HTML document: the <head>..</head> and the <body>..</body>.

The head contains a lot of the housekeeping stuff - like title tags, meta tags, links that let us import javascript and CSS, hints about our favicon, pointers to related RSS feeds, etc.  Right now we're just including three tags: a title (you can set the title to whatever you want), a link to pull in our CSS style from the style.css file we created and a javascript file called the html5shiv that makes IE play nicely with the new html5 elements. We use a conditional comment around that .js file so only internet explorer versions 8 and below will pull that file in.

The body tag contains the actual content we want to render on the screen.

Go ahead and paste that code into your text editor and save it and then load the file into your browser. You should see page that's completely white except for a page title and a little piece of ugly text that says "Content Goes Here":

Initial CSS

Just like you need a doctype HTML to make browsers render your page correctly and consistently, you need the same thing for your CSS. Using a CSS reset ensures that all browsers start off renderering tags the same way. The Eric Meyer reset is the most popular and accomplishs just that. Create a new file in your text editor, and name it "style.css". Add the following to the top of your style.css file:

/* v1.0 | 20080212 */
 
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body { line-height: 1;  }
ol, ul { list-style: none; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after,
q:before, q:after { content: ''; content: none; }
 
:focus { outline: 0;  }
 
ins { text-decoration: none; }
del { text-decoration: line-through; }
 
/* tables still need 'cellspacing="0"' in the markup */
table { border-collapse: collapse; border-spacing: 0; }

/* This is an extra (non-eric meyer) reset for HTML5 elements */
header, aside, nav, footer, section, article { display:block; }

What this does is clear out the padding, orders, font-sizes, etc on all elements, leaving you a blank canvas to style as you like.

The last line also forces some of our new semantic elements to render in block mode (which they might not do by default depending on your browser)

There's also one more piece of stock CSS that we'll need that's called the 'clearfix'. As the lines below onto the end of your css file. Don't worry about what it does or how it does it, we'll go over what this does later in the document.

.clearfix:after {
    content: ".";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}
 
.clearfix { display: inline-block; }
html[xmlns] .clearfix { display: block; }
* html .clearfix { height: 1%; }

Save your style.css file and reload the browser window to see the effect this had - pretty much just squeezing your HTML up into the left corner.

5. A Chop Game plan

Now open up the mockup file and take a deep, hard look at it.

If you've got a printer handy - print out a fullpage version of the mockup. If you are working off your own and have multiple pages, print out a copy of each.

What we need to do now is break down the mockup into discrete chunks in our heads. One way to do this is to draw (either on the page or in your brain) the smallest possible rectangles you can around each piece of actual "content" in your mockup, whether it's an image, a piece of text or a blog post. You've got to draw a rectangle, though, not some other shape.

Now for each set of related rectangles, draw a larger rectangle that contains either a vertical, horizontal, or fixed height block containing those original rectangles. Vertical rectangles represent blocks stacked on top of each other, horizontal rectangles are floated blocks, and mismatched sets are a place where we're going to absolutely position inside of an area of fixed height.

Since we're working with rectangles, you'll usually end up with like pieces of content together. So, for example, all the widgets in your sidebar would be stacked together, while your sidebar itself and your main content area would be floated next to each other.

Before you go onto the next step, really stop and make sure you understand either on paper or in your head you understand how the page is going to be broken down into blocks and layers. If you need to grab a scotch, sit on the sofa and ruminate with your printout until it all becomes clear, it's ok, we'll be here when you get back..

6. A Relative Positioned header

One of the easiest ways to make a chop look absolutely perfect is to absolutely position all of your elements to the exact down-to-the-pixel position they appear in your mockup. This is also a terrible idea. Absolute positioned elements (generally) don't adjust in response to changes in content, so something that might look good with some lorem-ipsum will fall apart quicker than a Yugo as soon as real content gets in there.

That being said, for pieces of our site that aren't going to need to adjust much (like our header) absolutely positioning some elements is absolutely the way to go.

In order to absolutely position an element, that element needs a frame of reference. The way to give it a frame of reference is to nest it inside of a relative positioned tag. To make sure IE knows we REALLY want that element to be relative, was also need to make sure it 'hasLayout'. Please don't worry about the details of this (if you really care, you can read more on hasLayout)

Here's the bottom line, if you set a width or a height to a relatively positioned element, you'll be covered in IE. If you can't set a width or a height, you can use a kludge by adding `zoom:1;` to your style - which is IE5.5+ and doesn't require a conditional stylesheet (but also doesn't validate). As a number of other browser specific properties, such as `alpha` don't validate, I usually don't care, but if you do care -  you can use one of the other fixes mentioned.

In our case, we're going to set the header to a specific height, make it relatively positioned, and then absolutely position the elements inside the header. This allows us to position the pieces of our header in a way that would be complicated to do just with stacking and floating elements, and makes it easy to move pieces of our header around (like changing the position or size of the menu) without affecting any other parts.

A Brief Diversion into browser-wide banding

One of the common trends in design these days it to keep a fixed width site (in other words the content of the site will be the same width, no matter how wide the browser is) but have individual pieces of the background of the site stretch all the way across the browser. This is actually an easy effect to do and can make the empty parts of the browser on a large monitor looks less empty.

To achieve a browser-wide band, you usually only need to make sure that your HTML backs out to a level where you haven't centered your content, and an extra tag for the background wrapper, so for example, we could do this:

<body>
  <div id='header-wrapper'> <!-- #header-wrapper has our background -->
    <header id='top-header'> <!-- #header is set to a fixed size and centered -->
        ...
    </header>
  </div>
  ...
</body>

 

I'm bringing this up because we're going to use a browser-wide band on the header, menu and footer.

Initial Markup

So let's actually get to writing some HTML. We know we're going to be creating a header with a logo, and two nav elements - a set of top links and a main menu. Create an images folder within the folder where you saved your index.html and your style.css files; all of your images will go into this folder.

I like to block out the HTML first, and then add in the CSS to make it look like it's supposed to, so lets start with some html for our header.

HTML5 contains a tag called <section> that at first glance looks a lot like a <div> tag - basically a block level tag that acts as container. Deciding where to use a <div> tag and where to use a <section> tag is a little tricky - but a good rule of thumb is that when you are grouping one or more similar content pieces of your page together - use a <section> - whereas when you just need a tag to apply some styles (such as in our banding example) - use a <div>. <section>'s are for content - <div>'s are for developers.

Take second to block out some HTML either in a editor or in your header (or copy/paste what I've written below). We need a fixed-width header with a horizontal background band, space for a clicking logo link (to take us to the homepage - always a good idea), a set of top links, and the main menu.

Here's what I would use between the <body></body> tags:

<div id='header-wrapper'>
  <header id='site'>
     <a href='/'><img src ="/images/site/missing_thumb.gif" alt='Evil Genius Robot Supply '/></a>
     <nav id='top-links'>
          <ul>
            <li><a href='#'>Login</a></li>
            <li class='last'><a href='#'>Contact Us</a></li>
          </ul>
     </nav> <!-- end nav#top-links -->        
  </header>
</div><!-- end #header-wrapper -->
<div id='menu-wrapper'>
     <nav id='main-menu'>
          <ul>
            <li><a href='#'>Home</a></li>
            <li><a href='#'>About</a></li>
            <li><a href='#'>Stuff</a></li>
            <li><a href='#'>More Stuff</a></li>
          </ul>
     </nav>
</div> <!-- end #menu-wrapper -->

One of the things that I like to do is comment the end </div> tags in my HTML code. This makes it easier to understand at a glance which closing tags are associated with which opening tags. You'll notice one of the nice things about using the html5 semantic tags, is that commenting the end tags of the new elements is unnecessary, whereas with a stack of </div>'s closing comments are very helpful.

A couple notes: some people like to use <h1> tags for the logo and use a background image with the text indent trick - I think this a bad idea - you'll end up pointing a whole bunch of random link text pointing to your home page - which would be sort of useless. You'd be better pointing a consistent title at your homepage if want to use the text-indent trick. Use your h1 text in your content for your primary page titles, where they can do a lot of good SEO-wise. Second, while it'd be nice to be able to use a <header> without a id - headers can introduce individual pieces of content inside of <article> tags, so you might have more than one on your page. Same with <nav> (we already have two) - you might end up with additional navigational elements in your sidebar or other locations.

Now, normally I'll write the markup for the entire page before starting in on the CSS, but for the purposes of this tutorial, we're going to break the header, content and footer into discrete chunks.

Images: gifs and pngs and jpgs - which, where and why

Generally you are going to end up using some images on your site somewhere, but before we get to chopping up our png it's a good idea to know which types of images to use where. There are 3 primary types of images used in web pages:

  • JPGs - this format is great for photographs and images where there aren't a lot of solid colors. JPG's can get great compression ratios on complicated images, but since it is a lossy format (i.e. some data is lost during compression),  jpg's are usually bad choices for any images with sharp edges - like logos, buttons and website design elements.
  • GIFs - This is a non-lossy file format that uses run-length-encoding to achieve decent compression on images that have large numbers of solid color areas. It also supports limited transparency. Saying that GIFs are non-lossy is a little misleading as since they only support upto 256 colors in a single image, converting a complicated image to a GIF *will* end up making it look worse. This is a good file format to use for images that need simple 1-bit transparency - either the pixel is transparent or it isn't.
  • PNGs - This is a file format that has more or less replaced GIFs as the file format of choice for a non-lossy images. It comes in two primary flavors - 24bit and 8bit. The 8bit flavor is more or less interchangeable with a GIF - the only reason you would use a GIF instead is that ie6 doesn't support PNG transparency out of the box. The 24bit version is a lot bigger, but doesn't limit you to 256 colors and adds support for a "feathered" transparency, which makes it easy to layer a bunch of transparent images on top of each other. GIF or 8bit PNG transparency can look harsh around the borders if your background color is different from the original background color of the image. If you are going to be using a lot of transparent images, you can use a special CSS hacks (iepngfix) add transparent png support to ie6.


24bit PNGs sound great in theory - but be careful as one of your goals should be to minimize the amount of data that needs to be downloaded to view your page - so don't use a 24bit png when a 8bit or a GIF will do. Similarily, if you use a PNG or GIF where a JPG is a better fit (like photographs) you'll end up with huge file sizes.

Chopping out our images

The demo template doesn't have a lot of images in it that we'll need to chop out, but it does have a few, and so let's talk about our plan of attack on this template. We've got three vertical bands that go all the way across the template - the top one is a vertical gradient that stretches all the way across the page. Since it's a vertical gradient we can get away with just a 1 pixel wide image that we'll repeat all the way across the header. All the images should be saved in the "images/" directory we created. With more complicated mock-ups, the same techniques apply, however you'll often need to go back to the source file and export different layers as separate PNGs.

How exactly you slice up an image depends on the program you are using. With the GIMP, just open up the mockup, press "R" to select the rectangular marquee, and drag a square around the image you want to cut out. Press "ctrl-c" to copy "shift-ctrl-v" to paste into a new image. Save that new image as the desired file format. If you are saving a 8bit PNG you'll need to select from the menu:  Image -> Mode -> Indexed and press  "Convert" in the popup window.

Slice out that top gradient image and call it 'header_bg.gif'

Next we need to get our logo - slice out a box around the logo and called it 'logo.gif'

Next, lets pull the image from the footer gradient - slice out a 1 pixel wide vertical image same as we did in the header and call it "footer_bg.gif"

We also need our social icons, slice out the three images in the footer (facebook,rss and twitter) and use the wand to select the background in each case, and press ctrl-x to remove it. Save these as "footer_facebook.gif", "footer_rss.gif", and "footer_twitter.gif"

This is a situation where it's ok to us a GIF as we're slicing out of the correct colored background. The downside is that these footer images can't really be used anywhere else - try dropping one into the page where there's a white background an you'll see what I mean. We do want to use transparency however, and not just keep the brown background on each as we will need to be less exact lining up those images vertically, and can move them around the footer if we decide to change around the design a bit. If we wanted to use more flexible images that could be used in other parts of the site we could use a 24bit PNG generated from the original image that was created on a transparent background.

We can ignore the robots in the sidebar for now as that's "content" - but feel free to slice those out yourself if you like.

In this case, our careful slicing paid off: the total "weight" of all the images in our template is 15k, which should load screamingly fast.

Measure Twice, Style Once...

As we start to chop up the design, we're going to want to be able to find the exact pixel position of the various elements of our mockup. The easiest way to do this is to setup some guides and measure off those guides. In the GIMP, you can create guides by clicking and dragging your mouse from the horizontal and vertical ruler edges. Once you've got your guides in place, you can measure by selecting the compass icon (or pressing Shift-m) and control-dragging to find the distance between elements.

Header CSS

Jumping right into the CSS, let's start with the wrapper and the header, throw the following four lines at the bottom of your style.css file:

#header-wrapper { background:url(images/header_bg.gif) top left repeat-x; }
header#site { position:relative; height: 123px; margin:0 auto; width:900px; }

#menu-wrapper { background-color:#744918; }
nav#main-menu { position:relative;  height:35px; margin:0 auto; width:900px; }


The first #header-wrapper is pretty simple it just sets the background, but the background syntax is worth paying attention to. We're saying we want to have the background of this <div> show the image '/images/site/missing_thumb.gif', align that image to the top and left, and then repeat it as many times as necessary in the x (horizontal) direction.

header#site is a little more complicated. First of all we could just identify it with #site - but using header#site make's it a little more clear what the tag is when we're viewing the CSS. Second, as mentioned we make it relative positioned so we can absolute position our header elements inside of it. Next we set the horizontal margin to 'auto' and add a width, which will center our header on the center of the page. We've set the width of this page to 900 pixels. Most sites these days run the range from 900-1000 pixels wide, with 960 being the most common (it's a number that works well with grid layout systems).

#menu-wrapper and nav#main-menu are pretty much duplicates of the header elements - just using a solid background color instead of an image.

Next less position our logo where we want it:

header#site > a { position:absolute; left:0px; top:0px; }

Notice we use a descendant tag (indicated by the ">") which means only apply this to a <a> tag directly inside of our <header> tag. This is something that is only supported in IE7 on - so if you're targeting users with IE6, you'll have to add a class onto your <a> (like <a class='logo'>) and to your css ( header#site a.logo ) to keep your styles from descending down to your nav link elements. We didn't really need to absolutely position our logo as in this case it would have ended up in the right spot regardless, but in other designs you may want to shift your logo around.

Now let's position our couple of nav elements:

nav ul, nav li { padding:0px; margin:0px; list-style-type:none; background:none; }

nav#top-links { position:absolute; right:0px; top:14px;  }
nav#top-links li { float:left; }
nav#top-links li a { display:block; float:left; color:#744918; padding:0px 9px; text-decoration:none; border-right:1px solid #744918; }
nav#top-links li.last a { border-right:0px; }

nav#main-menu ul { float:left; }
nav#main-menu li { float:left;  }
nav#main-menu li a { color:white; font-size:20px; display:block; float:left; padding:7px 40px 4px 0px; text-decoration:none; text-transform:uppercase; font-weight:bold; }

nav#main-menu li a:hover,
nav#main-menu li.selected a { color:#b7c850; }


The first thing we want to do is reset the margin, padding, list-style and display on our <ul>  unordered list and <li> list tags inside of <nav> elements - while we reset these with our initial, oftentimes we'll want to use a <ul>'s in our page content which need to be styled with some padding and margin to look good.

Next we are going to style the top links - "Login" and "Contact Us" links at the top of the page. First we absolutely position the nav#top-links container into the top right of our page, then we float the list items (<li>'s) to the left. Finally we do most of the work for styling the menu on the individual link tag inside of the list item ("nav#top-links li a") We set the display mode to block (so we can float them as well - this is a requirement for IE6), and then float them left so that they appear in line next to each other. Next we set a color, add some horizontal padding, add add in a border to get the "|" line to the right of the link. Lastly we add another style for the last element to get rid of the extra border. There's a special selector called ":last-child" that we could use if IE didn't suck, to prevent us from needing to modify our HTML, but unfortunately that's the way it goes.

Next we need to style the actual links themselves. The color, float, and padding should be straightfoward. We set the display to block so that we can pad out the navigation elements and make them chunky. Chunky links are good and make it easier for users to navigate your site as they don't have to be quite as accurate with their mouse.

We do pretty much the same same thing for the nav#main-menu - except we don't need to absolutely position the container.

There's one more little thing that we want to do - which is the last two lines. We add special selectors for when we are hovering over a menu item, or when we have a menu item selected (marking the selected item is something we need to do in our HTML by adding a class="selected" attribute to the current item.)

7. Menu Options

The first menu option that we showed was a bottom, right aligned menu. If all we wanted to do is move the main menu to a different location, all we need to do is modify the nav#main-menu tag to adjust it's position. To float it to the right side, just change it to:

nav#main-menu { float:right;  }

Some other options are centering the menu, which is a little bit of a CSS hack, change the following two selectors to:

nav#main-menu ul { float:left; position:relative; left:50%; }
nav#main-menu li { float:left; position:relative; left:-50%; }


Lastly if we wanted to distribute the menu across all the way across the page - I've got some bad news for you - you can't do it. At least, you can't do it and still make the menu flexible enough to easily add and remove menu items without a whole bunch of extra tags and complicated CSS. If we know the number of items, we can set up the CSS to divide up the items correctly across the space, but if you really need to do this flexibly, using a table or some simple javascript is your best bet.

8. Dropdowns

Cross-browser compatible dropdown menus can be created use just CSS - which means you don't need to use a bunch of Javascript to get them to work. Here's an example, replace your nav#main-menu with:

  <nav id='main-menu'>
     <ul>
       <li><a href='#'>Home</a></li>
       <li><a href='#'>About</a>
           <ul class='submenu'>
                <li><a href='#'>Sub item 1</a></li>
                 <li><a href='#'>Sub item 2</a></li>
            </ul>
       </li>
       <li><a href='#'>Stuff</a></li>
       <li><a href='#'>More Stuff</a></li>
     </ul>
</nav>

And replace your nav#main-menu css with:

nav#main-menu ul { float:left;}
nav#main-menu li { float:left; position:relative; zoom:1; }
nav#main-menu li a { color:white; font-size:20px; display:block; float:left; padding:7px 40px 8px 0px; text-decoration:none; text-transform:uppercase; font-weight:bold; }

nav#main-menu li a:hover,
nav#main-menu li.selected a { color:#b7c850; }

nav#main-menu li ul  { display:none; position:absolute; top:34px; left:0px; width:300px; float:none; background-color:black;  }
nav#main-menu li ul li { color:white; display:block; float:none; padding:0px; }
nav#main-menu li ul li a { color:white; display:block; float:none; padding:5px 10px; }
nav#main-menu li:hover ul  { display:block; }

Reload in your browser and you should have a dropdown menu in everywhere except IE6. For IE6 we'd need to add in some javascript to make the "nav#main-menu li:hover ul" menu work. Take a look at a list apart article for some more details.

9. Floating your body

For the main body of our content, we're not going to be able to get away with absolutely positioning each of the elements - as we don't know the vertical size of the content that we're going to end up with.

What we're going to do instead is just float the body and the sidebar next to each other. Our life is made a little bit easier by the fact that we're using a fixed width design, as we can set both elements to a fixed width. Let's write the html for the body first. Add the following to the bottom of your html file right before the </body> tag.

Note: In an earlier version of this post I used an <aside> for the sidebar, this is wrong. An aside tag should be used inside of a section for tangential content - such as a pull quote or a in-section navbar. For a standard website sidebar you'll want to use a section. Thus sayeth the W3C. 

<div id='content-wrapper'>
  <div id='content-container' class='clearfix'>
    <section id='content'>
      <h1>Article Title</h1>
      <h2>Lorem Ipsum</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id ante non quam pulvinar mollis nec ut est. Cras sapien libero, interdum non tristique a, dapibus vel neque.</p>
      <h2>Lorem Ipsum</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id ante non quam pulvinar mollis nec ut est. Cras sapien libero, interdum non tristique a, dapibus vel neque.</p>
    </section>
    <section id='sidebar' class='clearfix'>
      <h2>Sidebar Header</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id ante non quam pulvinar mollis nec ut est. Cras sapien libero, interdum non tristique a, dapibus vel neque.</p>
    </section>
  </div> <!-- end #content-container -->
</div> <!-- end #content-wrapper-->

Now we can add in some css for our main content:

#content-wrapper { margin:0 auto; width:940px; }
#content-container { width:940px; padding-top:74px; }
  section#content { float:left; width:510px; padding-left:24px; }
  section#sidebar { float:right; width:275px; padding-right:27px; padding-top:70px; }

Now - quick quiz to see if you remember your box model: how much space is there between the main column and the sidebar?

Let's add it up:
#content-wrapper width: 940
#content's width: 510 + 24: 534
#sidebar's width: 275 + 27: 302

total space between left and right: 940 - 510 - 275: 104 pixels

We're floating left and right - you could also float left and left - and just add padding to the left of the sidebar. It's really up to you and what math you prefer doing.

There's one downside to floating your main content areas - you're counting on the width of your content not being larger than 510 pixels. If it does go over 510 pixels, internet explorer, the bastard stepchild of the internet, will assume you were kidding about the width of your section and will make it larger to fit the content (can we really blame it?) What that means is that your sidebar will suddenly appear below your content - not good. If you aren't going to be in control of all the content on your site, you might want to consider adding one additional style to your #content and #sidebar:   overflow:hidden;

What this will do is hide any content the overflows from the two blocks and keep your site looking nice for the IE crowd.

There's one more piece of code that we need discuss - the class='clearfix'. This is the ugly piece of css that we added back at the beginning. Don't worry about exactly how it works - but reason for it is that firefox and webkit have an behavior for tag that contains one or more floated blocks. What happens is that unless you use the clearfix your containing div's height won't wrap around your floated divs. Try adding the following to your css:  

#content-wrapper { background-color:black; }

Reload your file in the browser,  remove the class='clearfix', reload again and you'll see what I mean. Without the clearfix, our #content-container div won't actually wrap itself around the floated divs correctly.

10. Liquid Layouts

We've mostly been talking about fixed width layouts. Most consumer sites these days are fixed width, and for blogs, company websites, e-commerce - I think fixed width is generally the way to go as people have trouble reading really long lines of text and a fixed width gives you complete control over the layout of your pages.

For some situations where you want to fix as much information as humanely possible in a single window (complicated data-displaying tables and forums come to mind) You might want to consider using what is known as a liquid layout - where one or more of the columns adjusts to the width of the visitors browser. We're not going to cover those here, but there's a great page on maxdesign.com.au that lays out the different options and the minimal CSS needed to get the job done.

11. Design Styles

One of the things we haven't talked about yet is what I like to call the "Design Styles" of the site which define the look of some basic tags that you end up using in your content. This is contrasted with the "structural styles" - i.e. the styles that define the layout and structure of your document. As of right now, our site's actual content looks a little fuggly, and the design styles are what we're going to use to fix this.

One of the aims of a good chop is to make things as simple as possible - and separating out your structural and design styles is a good way to do this. A good set of design styles will make it easy to mark-up the actual content of your site simply and consistently site-wide.

In our case, let's define as baseline styling of headers, links and paragraphs (add the following right below the clearfix code your stylesheet):

h1 { font-size:40px; color:#744918; padding-bottom:8px; }
h2 { font-size:18px; color:#744918; padding-bottom:8px; padding-top:4px; text-transform:uppercase; }
h3 { font-size:14px; color:#744918; padding-bottom:8px; text-transform:uppercase; }
p { font-size:14px; padding-bottom:10px; line-height:1.4em; color:#6b6c6e; }
a { color:#744918; text-decoration:underline; }

If we want to override an of these elements in a specific container, we can just use a little bit of styling. For example, we have a couple of h2 headers in our footer that are a different color. We can just define a simple style such as:

footer#site-footer h2 { color:new-color; }

And leave the rest of <h2>'s styling the same.

Reload the page and your content should look a little nicer.

12. Adding in a custom font

One of the cool things that's popped up relatively recently is great sets of tools for embedding fonts in to your site. The Google font directory in particular makes adding a font in 2 lines of code. We're going to use  "Lobster" for our H1's. Add the following into the <head>..</head> section of your HTML directly above your 'style.css' link:

<link href='http://fonts.googleapis.com/css?family=Lobster&subset=latin' rel='stylesheet' type='text/css'>

And then modify your <h1> to read:

h1 { font-family: "Lobster", Arial; font-size:40px; color:#744918; padding-bottom:8px; }

Now reload your page and your header font should have a little more pizazz.

The downsides to custom fonts is that they take additional bandwidth to load and you may also experience a FOUT (flash of unstyled text) in Firefox that is a little unseemly, but usually not that big of a deal. There are ways around it using some javascript, but that's out of the scope of this tutorial (I love passing the buck)

Another font resource to check out are font-squirrel - which has a bunch of @font-face kits you can download and integrate into our HTML easily, as well as a @font-face generator to make it easy to package fonts for display on the web (Most fonts have embedding restrictions, so make sure any fonts you include on your webpage are there legally) If you're ok shelling out a little bit of $, check out typekit - which has a bunch of fonts that you wouldn't be able to use online otherwise available for use for a monthly fee.

13. Footer homework

Believe it or not - we're almost done with the perfect chop. All that's left is to do the footer. Working off of everything we've gone over for creating the positioned header, you should be able to write the code for the footer. Here's a few hints:

 use a: <footer id='page-footer'>..</footer> tag to wrap your footer
        make the footer relatively positioned and set a height and width
        a couple of absolutely positioned divs inside of your <footer> tag that contain your content.
        use <img src="/images/site/missing_thumb.gif"/> to add the social networking images and wrap each of those in a <a href='#'>..</a> tag

14. HTML5/CSS3 Coolness

There's some very cool new CSS3 that's slowly becomming available as browsers implement more and more of the HTML5 standard, some of these are slightly cross-browser while some of these are just things we can drool over until they are fully supported:


My personal feeling is that multi-column, rounded corners and gradients can be used now provided the fallback for browsers that don't support the features looks decent enough, as these are just extra CSS styles they are pretty easily changed (check out css3pie, mentioned below for a way to get IE up to speed) Table layouts are going to have to wait for a bit till they are well supported.

15. Some stuff we didn't cover

While this tutorial covered a lot - there's a more than a few salient pieces of web page building we skipped. Here's some of the more important ones:

Favicon's - these are the little icons that show up in the address bar and next to your bookmarks. You can add a favicon into your site in one of two ways:
  1. Add a file called favicon.ico to the root directory of your site
  2. Add the appropriate link tag to your <head>..</head> region, such as:
      <link rel="icon" href="/images/site/missing_thumb.gif" type="image/x-icon">

Making IE play nice
- The cool CSS3 feature we mentioned above are unfortunately unavailable in the world most popular browser. What to do? Use a hack to bring IE up to date. A few of the nice CSS3 features: rounded corners, drop shadows, and gradients to name a few can be added to ie without a whole lot of fuss by including css3pie in your site.

Spriting - the speed with which your website loads actually has a more to deal with how users react than people think - so when you're looking to optimize your user experience, one thing you can do is limit the number of image files that need to be downloaded. Each separate request that a browser has to make takes time - so if you could pack all your images into just a few files, your site will load quicker. One way to do this is to use background images (via CSS) - we're not going to go over the details, but take a look at the a list apart spriting article if you're going to be creating sites that use a lot of structural images.

Javascript - Once you've got yourself an handle on HTML and CSS - you'll start to wish you could add a little more dynamism to your site. That's where javascript comes in. Javascript had a bad rap for a long time as a fake and poorly supported language - but that's no longer true. Javascript lets you manipulate the pieces of your site (often called the DOM) to created an animated or more interactive experience for users. People often recommend using javascript for what is known as "progressive enhancement" i.e.  making your site operate better rather than make javascript a baseline requirement.

JQuery - Once you've got a little javascript under your belt, it's time to jump headfirst into JQuery - the most popular javascript library. JQuery let's you ignore cross browser incompatibilities and write short, clean javascript that can add interactivity and animation to your site quickly and easily. It takes  little bit of time to wrap your head around, but the power that jquery brings to the table is well worth the learning curve.

16. (Finally) Wrapping up...

There's a lot more to HTML and CSS that this tutorial didn't cover. I've also glossed over some of the sordid history of browser incompatabilities that occassionaly make web development a royal pain. You'll find out about those soon enough and when you come across something that doesn't seem to work correctly Google is your friend. The web development world is large enough that any problem you run into, chances are someone has run into it before and figured out a solution. Sometimes it's even an elegant solution. Sites like "A List Apart" stay stay on the forefront of best practices for web development, if you're interested in the web at all - subscribe to their RSS and read through some of their back catalog, there's still lots and lots to learn.

The good news is that you have a base of html and css that should be mostly cross browser compatible and don't have years of bad coding habits to hold you back. As far as you know, everyone has always been using these great <header>, <section>, <nav>, etc tags, nice CSS resets and simple CSS. If everyone started coding that way right now, the web would be a simpler, prettier place.

17. Shameless plug

Once you've gotten home HTML and CSS proficiency under your belt, take a look at our CMS platform Webiva (or, as we like to call the hosted version, a Performance Inbound Marketing Platform). Webiva is designed to make it easy to import pretty much any HTML and CSS into the system quickly and easily, and lets you create tag- and pixel-perfect CMS powered websites. It supports e-commerce, integrated targeted e-mailing, and a host of inbound marketing targeted features like easy lead tracking, grading and segmenting, A/B testing and integrated analytics. Rails folk should check out the open-source version and everyone else should sign up for our hosted beta

 

 



Posted Sunday, Oct 24 2010 04:28 PM by Pascal Rettig | Development, HTML5 | Css, Css3, Html5, Web development
1 2 3 4   > >