When a page with theme is rendered, the stylesheets link tags in the given theme are rendered right before the closing head tag. Does anyone know of a way to change that? Is there a way that I could have those tags be placed right after the opening head tag?
I know it can be down with jquery by just selecting all the link tags and placing it right after the opening head tag, but is there a way to set it on the server end?
Clarification Let us say I have a single css file (themed.css) in my theme. In that css file, I have a single style definition for a div tag with an id of test:
#test {background-color:red; color:white;}
Let us also say I have a second css file (standard.css) that is NOT in my theme, but it has another definition of the div tag with an id of test:
#test {background-color:yellow;}
I have my page to use the theme, and I have a handwritten link tag to use standard.css. When the page is executed, the link tag for standard.css is before themed.css. When that happens my div tag with id of test has a red background and white forecolor. If I want the themed.css to apply and then standard.css to overwrite the necessary properties (yellow background with white forecolor), I would want themed.css and THEN standard.css. I can't do that because ASP.NET places the theme files right before the closing head tag.
I don't want to have to know that my theme's css files are the nth link tag in my head tag and then manual change any index whenever i may add a new css file outside of my theme.
Thanks!
I did a little checking in Reflector, and found something you may find interesting. The framework calls the SetStyleSheet
method of a PageTheme
-derived object to inject link controls in the header. This code snippet shows the relevant logic:
int num = 0;
foreach (string str in this.LinkedStyleSheets)
{
HtmlLink child = new HtmlLink { Href = str };
child.Attributes["type"] = "text/css";
child.Attributes["rel"] = "stylesheet";
if (this._styleSheetTheme)
this.Page.Header.Controls.AddAt(num++, child);
else
this.Page.Header.Controls.Add(child);
}
Translation? StyleSheetThemes inject the style sheets at the beginning of the header tag, and Themes inject the style sheets at the end.
This is consistent with the intended difference between themes and stylesheet themes; that is, that a theme always wins when there is a conflict between the skin and the control settings. Sure, a style in a non-themed .CSS file using the !important
attribute could still override a theme style, but the positioning of the CSS files within the head tag strategically facilitates override-ability stylesheet themes.
Note that you can have both a stylesheet theme and a regular theme. Naturally, leave to the stylesheet theme things you design to be override-able, and to the theme things that should not be overridden.
One final observation is that the method is internal
and non-virtual, so interfering with these two options would take some kung-fu-MMA-mad-reflection skills, and is probably not in the best interest of stability or maintainability.
As soon as your head
element has runat="server"
you can rearrange the collection in Page_PreRender:
protected void Page_PreRender(object sender, EventArgs e)
{
ControlCollection container = this.Page.Header.Controls;
foreach (var control in container.OfType<System.Web.UI.HtmlControls.HtmlLink>().ToArray())
{
container.Remove(control);
container.AddAt(0, control);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With