One thing that really bugs me about ASP.NET is the way it deals with header management especially when working with Themes. One of the big problems I see is that ASP.NET embeds the Themes style sheet at the bottom of the header list. If you happen to be using Master Pages which can have a header content section or your are adding additional CSS or style tags to your header the Themes style sheet will always end up on the bottom of the header list:
<%@Page Language="C#"
MasterPageFile="~/TimeTrakkerMaster.Master"
AutoEventWireup="false"
CodeBehind="OpenEntries.aspx.cs" Inherits="TimeTrakkerWeb.OpenEntries"
Title="Open Entries - Time Trakker" %>
<asp:Content ID="Head" ContentPlaceHolderID="head" runat="server">
<style type="text/css">
#itemtemplate
{
border-bottom: dashed 1px teal;
padding: 9px;
padding-left: 30px;
}
#itemtemplate:hover
{
background: url(images/lightorangegradient.png);
cursor: pointer;
}
#itemtemplate b
{
color: Navy;
}
#itemtemplate a
{
text-decoration: none;
}
#itemtemplate a:visited
{
color: Navy;
}
#clockimg
{
width: 16px;
height: 16px;
margin-right: 15px;
margin-bottom: 5px;
background-image: url(images/punchout.gif);
float: left;
}
</style>
</asp:Content>
<asp:Content ID="Content" ContentPlaceHolderID="Content" runat="server">
...
</asp:Content>
And I render that I get:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
Open Entries - Time Trakker
</title>
<style type="text/css">
#pagecontainer
{ text-align:left; width: 850px; border: solid 1px silver; border-right: solid 2px silver;border-bottom: solid 2px silver; background: white; position:relative; }
</style>
<style type="text/css">
#itemtemplate
{
border-bottom: dashed 1px teal;
padding: 9px;
padding-left: 30px;
}
#itemtemplate:hover
{
background: url(images/lightorangegradient.png);
cursor: pointer;
}
#itemtemplate b
{
color: Navy;
}
#itemtemplate a
{
text-decoration: none;
}
#itemtemplate a:visited
{
color: Navy;
}
#clockimg
{
width: 16px;
height: 16px;
margin-right: 15px;
margin-bottom: 5px;
background-image: url(images/punchout.gif);
float: left;
}
</style>
<link href="App_Themes/Standard/Standard.css" type="text/css" rel="stylesheet" />
</head>
Notice that the style sheet I defined in the master content page as well as in the master page (#pagecontent) end up above the Standard.css themes file.
The same is true if you attempt to add any controls to the Page.Header controls collection - whatever you do there ends up BEFORE the themes style sheet as far as I can tell or if you add styles manually to the header section.
This means you effectively can't override the styles defined in the themes file which is uhm problematic in many situations. This bit me today once again as I was overriding one of the styles in the themes css and found that I couldn't override the class.
There's a way to work around this but it's not XHTML compliant - you can embed styles and style sheet references into the page's content which at least guarantees that the styles are rendered after the theme's CSS.
Loading a CSS stylesheet from a Control
Another related issue I ran into today as I was building a small wrapper control around the jQuery Calendar control is how do you effectively load a CSS style sheet from a custom control, without actually rendering the style sheet multiple times?
The problem here is that unlike Script references which have a clear API in the Page.ClientScript/ScriptManager which help to make sure you don't load multiple references to the same script files, there's no corresponding API for CSS files. However, you can fake out ASP.NET by using the ClientScript/ScriptManager for this anyway:
string css = @"<link href=""" + this.ResolveUrl("scripts/jquery-calendar.css") +
@""" type=""text/css"" rel=""stylesheet"" />";
ScriptManager.RegisterClientScriptBlock(this.Page, typeof(ControlResources), "_calcss", css, false);
You can also use Page.ClientScript.RegisterClientScriptBlock. Basically you can use this API to inject anything into the top of the page, just after the FORM tag as long as you pass the last parameter as false, which indicates that you're providing your own <script> tags - or that you are basically handling the full markup. The flag is there for compatibility with .NET 1.1 which requires that you add the script tags, but you can use this now for injecting code into the page. This isn't ideal for CSS in all cases though: if your CSS needs to modify the body tag then this might not work correctly and as mentioned this is not XHTML compliant.
Other Posts you might also like