Posts tagged CSS
Using the 960 Grid System for Layout
2So I’ve been using the 960 grid system for over 6 months now and I have learned a thing or two that could be helpful to those looking at using it as well. If you don’t already know, 960.gs is a css framework to help you quickly enable layouts and help ease the pain of cross browser compatibility. I will start by laying out the pros and the cons of the 960 and then show you how to overcome possible gotchas.
The Pros
This is what you want to hear right, how is 960.gs going to make your layout easier to manage and create. Well let’s start then.
- Complex layouts relatively fast.
- Consistent layout (IE, Firefox, Chrome, …)
- Reusable and Flexible
- Easy to learn
The Cons
Ok so some of the down sides of using 960.gs, cause there are some obvious ones.
- More stylesheets ( 960.gs, reset.css, text.css and then yours)
- Respect it or it will bite back
- Divitus (lots of div tags based on your layout)
- Everything you need to do isn’t a grid
- not semantic (grid_12 is not expressive)
- multiple css classes on one element
Overview
by default the 960.gs is split into either a 12 column grid or a 16 column grid. I will focus on the 12 column grid. Each column in a 12 column grid is 60px wide with a margin of 10px on each side. You can see that below the max content area you can have is 940px, while the container expands to 960px due to the 10px margin on each side. You can also see that the margin between two columns is 20px, because each column has a 10px when two columns margins combine they make 20px. And finally, a div tag can span multiple columns and it’s length is made up of all the columns it spans and 10px of margin on each side.
ex. a column that spans 11 columns is 880px. column: 60px + 10px + 10px. 11 x 80px = 880px total : 880px with outside margins and 860px without outside margin (content area).
Ok that was a lot of math, but you only need to know how to count up to 12 or 16 to use this system. No need to do this math because it is done for you automatically. The point of the math is to show you that the box model is important to understand. Margin is outside of your div tag, while everything else is inside.
Example – The Basics
So you are curious about the above example, how what does the HTML look like? It looks like this.
<div class="container_12"> <h2> 12 Column Grid </h2> <div class="grid_12"> <p> 940 </p> </div> <!-- end .grid_12 --> <div class="clear"></div> <div class="grid_1"> <p> 60 </p> </div> <!-- end .grid_1 --> <div class="grid_11"> <p> 860 </p> </div> <!-- end .grid_11 --> </div>
Simple right, you see that we use a div with a class of container_12. This is used to help center your page and give a place to start laying out your page. The next thing you will see is grid_12. That is telling that div to span the whole way across, and it is then followed by grid_1, and grid_11. You can guess that we are specifying that the first div is a size of one column, while the next is 11 columns. The div with a class of clear forces the grids to the next line, but I have found if your rows always add up to 12 you can forgo the clearing, since floating will force elements to the next line anyways, that is up to you.
Gotchas
The first and major gotcha that people run into is they attempt to overly style their div tag that already has a grid class. This is a mistake and can lead to huge headaches. Let’s look at why you shouldn’t. I will show you what css rules are ok to use and which aren’t.
Border
The first no-no is border. You shouldn’t use border on your grid divs because it adds size to your layout.
ex. You have a grid div that spans 5 columns. 5 x 80px = 400px. So you want to add a border of 1px solid black (always bet on black). What does that do?
That changes the math 5 x 80px + 2px (border-left and border-right) = 402px. now 2px might not seem like a lot, but it can force whole divs to the next line, throwing off your layout completely.
To fix this problem you should put another div inside the grid div and then style that. What you end up with is a container –> content relationship.
Margin and Padding
So you want to move a grid just a little bit over huh? DON’T. The same problem happens that occurs with Border. You force the columns to stretch pass what they were designed to do. Think of yourself trying to wear pants that are two sizes too small, it just isn’t pretty.
The solution again is to use a container-> content relationship. Where you have another div inside that handles margin and padding.
Width
You might be seeing a theme here, width is the enemy of the grid system, especially explicit widths. If you have an element that is 200px in a column that is only 60px, then you’ll have problems.
The solution is to be mindful of your parent div. If you want to use width, look at using percentage. ex. width: 100% on the content div.
Things that are OK to Style:
background-color, color, background-image, position (absolute and relative).
Conclusion
The 960.gs is very powerful, but some CSS purist might not like it’s lack of semanticness (not sure if that’s a word). I see their point, but the up side is so great that I can overlook my HTML/CSS purism. Keep in mind the gotchas and you should be able to create consistent layouts in all major browsers.
That Pesky Active Page for ASP.NET MVC
3When working with HTML and CSS there are some visual queues that you can add to enhance the user experience. One of these tricks is to highlight the menu button in your navigation. Most web applications do it, but how do you accomplish this in your current ASP.NET MVC application? First let’s look at what we are trying to do. Below you will see the header to the Aqua Bird Consulting site. You’ll notice that one of the buttons is different than the others; the button that relates to the page we are on is different.
If we look at the source of the page we’ll see that the home button has an id of “active”. Obviously you could accomplish the same thing by putting a class on the HTML element, but that’s another discussion. So how do you get the correct button to be active as we move around the site? There are two ways, I’ll first talk about the BAD way to do it.
<ul>
<li id="active">
<a href="/"><span>Home</span></a>
</li>
<li>
<a href="/About"><span>Company</span></a>
</li>
<li>
<a href="/Services"><span>Services</span></a>
</li>
<li>
<a href="/Portfolio"><span>Portfolio</span></a>
</li>
<li>
<a href="/Products"><span>Products</span></a>
</li>
<li>
<a href="/Contact"><span>Contact</span></a>
</li>
</ul>
The Bad
You could always place a value into ViewData, TempData, or even on your view model. This is bad because, now we are pulling visual elements down into our controller. This is a big no-no, and we would be violating the will of the MVC gods. Having the “Home” button highlighted doesn’t change the state of our underlying application (by underlying, I mean business logic). So don’t do this; it will definitely work but you’ll be in a world of pain if you decide to redesign your site or refactor.
The Good
The great thing about ASP.NET MVC and .NET 3.5 is the extensibility of it all. Everything is right there for you to access. So knowing that little fact about the extensibility of the ASP.NET MVC framework, you have to figure there is a way to know what Controller, Action, or even View we are on. For the scenario pertaining to the Aqua Bird Consulting site, we needed to link buttons to Controllers and Actions. Know let’s look at how we get the Controller and Action.
// helper is and HtmlHelper var currentController = helper.ViewContext.RouteData.Values["controller"].ToString(); var currentAction = helper.ViewContext.RouteData.Values["action"].ToString();
Cool! Nothing to it. Now all we need to do is check it on the view. I created an extension method, where you pass in a controller name, or a controller name and action pair. In addition to those parameters you pass in your designated output. I also have one where you can pass the controller name only, possibly for multipurpose controllers or sections.
public static string IsActive(this HtmlHelper helper, string controllerName, string output)
{
var currentController = helper.ViewContext.RouteData.Values["controller"].ToString();
return (currentController == controllerName) ? output : string.Empty;
}
public static string IsActive(this HtmlHelper helper, string action, string controllerName, string output)
{
var currentController = helper.ViewContext.RouteData.Values["controller"].ToString();
var currentAction = helper.ViewContext.RouteData.Values["action"].ToString();
return (currentController == controllerName && action == currentAction) ? output : string.Empty;
}
And here is what the view code looks like. Notice that I declare my output as a constant string in the view. I chose to do this in case I chose to change my html. I also didn’t want html to sneak into my helpers and thought this was a good alternative to that.
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%@ Import Namespace="AquaBird.MainSite.Infrastructure.Extensions"%>
<%const string output = " id=\"active\""; %>
<ul>
<li<%=Html.IsActive("Index", "Home", output)%>>
<a href="<%=Url.Action("Index", "Home") %>"><span><Home</span></a>
</li>
<li<%=Html.IsActive("About", "Home", output) %>>
<a href="<%=Url.Action("About", "Home") %>"><span>Company</span></a>
</li>
<li<%=Html.IsActive("Services", output) %>>
<a href="<%=Url.Action("Index","Services") %>"><span>Services</span></a>
</li>
<li<%=Html.IsActive("Portfolio", output) %>>
<a href="<%=Url.Action("Index", "Portfolio") %>"><span>Portfolio</a>
</li>
<li<%=Html.IsActive("Products", output) %>>
<a href="<%=Url.Action("Index", "Products") %>"><span>Products</a>
</li>
<li<%=Html.IsActive("Contact", output) %>>
<a href="<%=Url.Action("Index", "Contact") %>"><span>Contact</a>
</li>
</ul>
There you have it. Now you can know whether you are on a certain controller and action from your view without breaking the rules of MVC.
P.S. Having multiple elements on the same page with the same id will make your page invalid when run through a HTML validator, keep that in mind.

