ASP.NET 2.0’s Themes and Skins have a number of design flaws - Themes and Skins depend almost entirely on
Cascading Stye Sheet (CSS), but don’t fully support CSS - I’ve listed some "Work Arounds" for a couple design flaws. I don’t recommend any of these "Work Arounds" since they contribute to software entropy before your application is even developed, instead I suggest sticking with CSS and perhaps using some default Skins that define CSS selectors like classes or IDs.
The Problem / Question:How can I add Internal (embedded) style sheets (the ones that use the
Style element) inside the Head tag when using Master Pages and Themes? How can I override (overload)
External style sheets for local pages or specific Web User Controls?
A Solution / Work Around:One option is to create an ASP Placeholder (
asp:contentplaceholder) in the Master Page's Head tag to add the Style element into the Head of your Web Form (.aspx page). However, this solution doesn't work well when using Themes, since themes automatically include the External style sheets after the Style element - I demonstrate this and provide an alternative solution later on in this post.
The Caveat / Warnings:In most current-generation browsers the loading order for Internal style sheets, and External style sheets depend on their position in the Head tag. This behavior seems to go against what the W3C intended.
Generally speaking we can say that all the styles will "cascade" into a new "virtual" style sheet by the following rules, where number four has the highest priority:
- Browser default
- External style sheet
- Internal style sheet (inside the <head> tag)
- Inline style (inside an HTML element)
- Taken from: http://www.w3schools.com/css/css_intro.asp
As I understand and as the w3schools point out (I can't find a reference from the depths of the
W3C), Internal style sheets should have a higher priority than External style sheets, unfortunately this isn't the reality. Instead External style sheets and Internal style sheets depend on the loading (cascading) order. An Internal style sheet will only override an External style sheet (in current-generation browsers) if the External style sheet is loaded first. This behavior introduces problems when using an ASP Placeholder because ASP.NET automatically includes the Style Sheets (.css) from the active Theme (App_Theme) directories into the Head tag after the ASP Placeholder's contents have been loaded.
An example of the problem:The directory structure:

The active Master Page:
<%@ Master
Language="C#"
EnableTheming="true"
AutoEventWireup="true"
CodeFile="MasterPage.master.cs"
Inherits="MasterPage"
%>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"
>
<head runat="server">
<title>The
Problems With Themes and Skins in ASP.NET 2.0</title>
<asp:contentplaceholder id="ContentPlaceHolderHead" runat="server"
/>
</head>
<body>
<form id="form1" runat="server">
<h1>Hello World!</h1>
</form>
</body>
</html>
Note: the ASP Content Place Holder between the Head tags and "Hello World!" between the H1 tags.
The default Web Form (.aspx page) providing the Content for the Master Page's Content Place Holder:
<%@ Page
Language="C#"
Theme="Default"
MasterPageFile="~/MasterPage.master"
AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="Default"
%>
<asp:Content ID="Content1"
ContentPlaceHolderID="ContentPlaceHolderHead"
Runat="Server">
<style type="text/css">
H1{
color: red;
}
</style>
</asp:Content>
Note: the Style element between the ASP Content Place Holder tag - H1 should now be colored red.
The contents of StyleSheet.css, the only CSS file in the Active Theme (App_Theme) directory:
H1{
color: blue;
}
Note: H1 should still be red because Internal style sheets are supposed to have priority over External style sheets.
The rendered XHTML:
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"