Over the last couple of years, I've started to develop something of an obession with web standards. Perhaps it's unhealthy for an ASP.NET developer. I'm not quite ready to call myself a "standarista", that's a little too metro for me, and I still have some bad habits lingering around. I'll often leave off title attributes for images or set the alt attribute to nothing. That's not so bad is it? However, I do see the importance of having semantic markup (can you bring yourself to call it POSH?). It is easier to maintain, better for SEO and screen readers.
One of the reasons I'm so excited about the new ASP.NET MVC Framework, is that you have total control over your markup. I can use ids on the client again! With traditional ASP.NET. You lost control over the ids as soon as you used a master page or user control, and who's going to try and build a site without those? ASP.NET does its best to protect you from having duplicate ids in your rendered markup so it adds on a bunch of prefixes to help you out (that and it's own selfish purposes like maintaining state). As it turns out, I'd rather if the framework didn't worry about it. I can handle that myself, thank you.
So, after shedding the bagagge of a stateful framework, I'm coming back to what building websites is really about. HTML, CSS, and JavaScript. Not <asp:textbox />, but <input type="test">; not <asp:button>, but <input type="submit">; etc. It really is liberating in a geeky, "the cruft of the web is dragging me down", sort-of way. It's good to know your HTML elements - all of them. Use the right one for the job, that's semantic markup. Don't just use a bunch of divs.
While we were making ASP.NET Themes and AJAX server controls, developers on other platforms were building all kinds of great JavaScript frameworks and pioneering great practices with CSS. Ideas like not putting JavaScipt in your markup:
"One of the most wicked defilers of beautiful markup is inline JavaScript. This makes the markup all but impossible to read, and provides lots of little dark corners for bugs to hide."
Ideas like CSS belongs in a different file. Then it's easier to participate in CSS Naked Day.
Yeah, beautiful markup is important. Yep, it's true.
One technique that stuck with me and has helped out quite a bit in my day-to-day CSS work is writing all the CSS attributes on one line. I used to put each little attribute on its own line. They deserve their own lines write? Nope. Suprisingly enough, these little attributes are social creatures that like to travel around in packs.
Consider the following CSS snippet:
#header {margin: 0 auto; width: 889px; position: relative;}
#header h1 {background: url(img/header.png) no-repeat; width: 889px; height: 146px; position: relative;}
#header h1 a {margin-top: -100px; display: block; height: 250px; width: 257px; position: absolute;}
#header ul#topnav {position: absolute; top: 29px; left: 274px; width: 604px; height: 30px; list-style: none;}
#header ul#topnav li {width: 33% ; float: left; text-align: center;}
That's 5 lines. That's only a portion of the CSS for a website. It's easy to scan and find what elements I have assigned style to. Then I can look for for the styles I've applied. Had I put a line-break after each attribute, selector, and curly brace, I'd be up to 36 lines. Go format it yourself and see. For a whole site, that can easily become more pages than you want to scroll through.
I'll often over-specify the element I'm selecting. It might have been okay to just use "a" rather than "#header h1 a" in the CSS above, but then if I decide to style an anchor elsewhere in the page, I'd have to go back and undo what I've already done. Either by appling more selectors, or overriding the style. It's much easier to over-specify from the start. Plus it makes it easier to find things in your CSS.
Often you'll want to have different styles in different pages on your website. Nothing too wild, but maybe on your home page you want the headers to be a little bit bigger. Perhaps you want an additional column on the home page, but on your article pages you get rid of a column and widen your main content area. There are all kinds of possibilities. In this scenario, it can be convient to add an id to your body. Why, you say? Well, you can have more than one body element... In a website. It's nice to keep all your CSS in one file (so long as it doesn't become too ridiculous). So if I wanted h2s on my homepage to be 2 ems while on an article page I wanted them to be only 1.5 ems I could do this:
#home h2 {font-size: 2em;}
#article h2 {font-size: 1.5em;}
So how can we do this in ASP.NET MVC? With CTP2, if you create a new project, you get a master page by default. Then, when you add a view, you can add an MVC Content View Page. Unfortunately, it is terribly difficult to reach back up to the master page and set the body ID within the content view page. I haven't figured out a way to do it. Maybe you can. There is another way to go about it though. You can set the body id in your controller right before you render the view. This may make more sense anyway, since you may render the same view from multiple controller actions.
The first step, is to modify the Site.Master page. Open it and change the body element like this:
<body id="<%= ViewData["BodyId"] %>">
Then in the controller, right before you render the view, set the view data:
public void Index()
{
ViewData["BodyId"] = "home";
RenderView("Index");
}
If you want to get even more fancy/automatic, you could set the body id using the controller and action names:
public void Index()
{
ViewData["BodyId"] = RouteData.Values["controller"] + "_" + RouteData.Values["action"];
RenderView("About");
}
That line could then be refactored in to a function, or into your very own view engine. Just watch out if you are going to be using typed views. In that case, you might want to look into the TempData Dictionary.
For more great reading on Semantic HTML, CSS, and JavaScript be sure to check out the following sites:
- http://www.alistapart.com/
- http://www.456bereastreet.com/
- http://snook.ca/jonathan/
- http://mezzoblue.com/