October 09, 2008

Print Stylesheet in ASP.NET Themes

Last post I talked about ASP.NET Themes -- all CSS files in the theme folder will be loaded, no matter what. This makes having a matching print stylesheet a little difficult since you can't specify media types for you theme stylesheets.

Enter the @media tag. In your print.css stylesheet, you can use this tag to specify your media type in the stylsheet instead of in the <link> tag as you normally would.


@media Print 
{
	body,a {color:#000;}
}

And as an added bonus: this even works in IE 6. Who would have thought?

Stylesheet order in ASP.NET Themes

I've started using ASP.NET Themes in my latest projects. They're interesting, but just goofy enough to make me hate them. The latest quirk I've discovered is that all CSS files in a theme are loaded, regardless if you want them or not.

Cascading Style Sheets is built on the idea of inheritance, in which order or styles is very important. So, when you can't control what styles are loaded at what time, it's hard to overwrite things when needed.

Problem

My theme is called cojui. Inside the App_Themes/cojui/ folder I have cojui.css. In that stylesheet, I import my other stylesheets: reset-min.css & masterpages.css.


@import "stylesheets/reset-min.css";
@import "stylesheets/masterpages.css";

/* My main styles follow below */

Visual Studio reads cojui.css first since it's in the root of the theme directory. Then, VS loads the rest of the stylesheets, in alphabetical order. This causes reset-min.css to reset all my styles since cojui.css has already been processed -- not the intended effect.

Solution

I put all my CSS files in App_Themes/cojui/stylesheets/ folder and add an underscore ( _ ) to the stylesheets I want to load first. This only gives me levels of granularity in load order, but for now it's working. I also renamed cojui.css to main.css to let other people know it's the 'main' stylesheet since it's no longer in the root directory.

Update: I've since decided this is NOT a good way of doing things.

I re-evaluated what should be a .NET theme, and what shouldn't. Themes should be limited to theme-specific style only. _masterpages.css and _reset.css are utility stylesheets, but not 'style specific' stylesheets. So, I've moved them into a 'stylesheet' folder ouside of the App_Themes folder.

Reference JS file when using MasterPages

Problem

I need to reference a JS file in the <head> in a Master Page in Visual Studio 2008. In Visual Studio 2005, I did:


<script type="text/javascript" src="<%= Page.ResolveClientURL("~/javascript/jquery/jquery-1.2.6.min.js")%>"></script>

but this gives me an error:

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

I tried hunting down the error, and stumbled on Rick Strahl's post about a similar issue. Unfortunately, this didn't work for me.

Solution

Luckily some of my friends are better developers then I am. Turns out, the fix is to follow Rick Strahl's tip, but to databind() the head in the MasterPage's PageLoad()


<head id="html_head" runat="server">
	<title>City of Jacksonville</title>
	<script type="text/javascript" src="<%# Page.ResolveClientURL("~/javascript/jquery/jquery-1.2.6.min.js")%>"></script>
	<script type="text/javascript" src="<%# Page.ResolveClientURL("~/javascript/actions.js")%>"></script>
</head>

Then, in the MasterPage's code behind


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
	html_head.DataBind()
End Sub

1 of 1

Who?

Howdy. I'm Richard W. Baker - a designer based in Jacksonville, Florida with a passion for information architecture and usable interfaces. At my day job, I work for the City of Jacksonville as a User Interface Designer.

If you still have questions, or you're interested in hiring me for your next project, .

Active ingredients: XHTML + CSS + Expression Engine
Page rendered in 0.2188 seconds  |  51 SQL queries total