Introduction
Styling is a task that most web developers, if not every web developer, must have come across. Most also might have faced the problem of styling pages in a clear and flexible manner that can handle changing styles dynamically. This article tackles this problem in a clean, straightforward manner, benefiting from important features that CSS and ASP.NET provide.
The Problem
Let us say I have a site that responds to certain conditions by changing its look and feel automatically. Now, the word automatically is fuzzy, but I will keep it for the moment. You want a style for the holidays, another for normal days, others for every season, etc ... The common approach to accomplishing this is usually to create an ASPX file that dynamically (according to conditions it checks) generates the proper output. The pages would link to that dynamically generated CSS and it's done. Where is the flaw in that?
- The fact that this is generated through code makes recompiling on every change inevitable
- If I can lay off the ASP.NET runtime, why not?
- Changing the look and feel of the site would not only require a designer, we need a programmer along the side
- I like simple text files better (.css)
The Solution
I solved the above problems by using the same old CSS file with some spices. The main functionality resides in the CSS itself, a fact that many overlook. CSS lets you use an Object-Oriented like approach to solving this. Here is how it goes:
The CSS
We put the common styles for the "Main Title" (for example) in a class like this:
.MainTitle
{
text-decoration: underline;
color: Black;
}
and the "Main Title" styles when we are in Mode1
(maybe Summer):
.Mode1 .MainTitle
{
font-size: 16pt;
}
The Mode2
specific styles of "Main Title" go here:
.Mode2 .MainTitle
{
font-size: 18pt;
}
So as we notice, the common styles that would not change at all would belong to the first section, while the specifics of every styling mode go into its corresponding section.
Explanation
.ClassName
is called a class selector. By using the name (without the dot) as the value of the class attribute of any HTML element, we are actually applying the styles inside that class to the element.
Now what happens when we do something like:
.ClassName1 .ClassName2
like in:
.Mode1 .MainTitle
The styles that are contained in such a selector will be applied to any element having a "MainTitle
" as its class and is at the same time inside another element having "Mode1
" as its class. That raises the question: where would the class "Mode1
" be applied? We apply it at the nearly outermost element in our pages, the form
element. This way all elements are inside a form with a class "Mode1
", and if we give any such element a class "MainTitle
", then we would have applied the styles inside the ".Mode1 .MainTitle
" block.
Now, if we have .Mode2 .MainTitle
having other styles inside, and we need to apply them at a certain time, then all we need to do is give the "form
" element a style of "Mode2
", and all other elements with the class "MainTitle
" remain the same.
The next section explains how we can make the form
element have the appropriate class value at the right time.
The Spice
This is where ASP.NET is used to provide this functionality as automatically as possible. We need to make our pages inherit from a so called "Base Page" or "Master Page" where we can put the functionality common to all pages in our site.
Base or Master Pages are usually used for more than just styling. They are used to put all common behaiviour that needs to be available to all pages. Giving a common look (same Header, Left, Right, and Footer banners) across the site can be done by using a combination of a Base Page (functionality) with a template User Control (look). Discussing "Base Pages" is not the concern of this article. We are just using them to add our styling logic to all pages. It is possible though, but not recommended, that we add the same logic in every page that needs our styling features. So, the point is not to focus on the Base Page, but on what it provides.
First, we add this private member to represent the styling mode we are in:
private string _StyleClass;
public string StyleClass
{
get
{
return _StyleClass;
}
set
{
_StyleClass = value;
}
}
Then, we add this method inside our Base Page:
private void styleForm()
{
HtmlForm Form1 = (HtmlForm)this.FindControl("Form1");
Form1.Attributes.Add("class", _StyleClass);
}
Finally, we call the method inside the overridden OnPrerender
method:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender (e);
styleForm();
}
Explanation
As I mentioned earlier, the only action needed to flip the look of a page would be to change the class applied to the form
element. And here, we do it dynamically by setting the value of a property StyleClass
inside the page we want to change the style, like this:
StyleClass = ddlMode.SelectedValue;
where ddlMode.SelectedValue
is a DropDownList
holding the many styling modes we want to switch between.
<asp:DropDownList id=ddlMode AutoPostBack="True" Runat="server">
<asp:ListItem Selected="True" Value="Mode1">Mode1</asp:ListItem>
<asp:ListItem Value="Mode2">Mode2</asp:ListItem>
</asp:DropDownList>
The method styleForm
gets a reference to the form that is called (the name must not be changed) "Form1
". Then, a class is added to the form
element and that class' name would be the value that we set in our page using the StyleClass
property.
The styleForm
method is called in the OnPrerender
method to ensure that the StyleClass
property is set before used.
And, that is it. All that is needed is setting a property, and the styles in our stylesheet are applied.
Possible Uses
There are many uses for this technique. Here, I mention a few:
- Giving your site user selectable themes.
- Seasonal styles.
- Maybe one of the most important applications (one that I use) would be multilingual styling, where we require a style for every supported language.
Conclusion
With a bit of observation, one might notice that this way of using CSS emphasizes an Object-Oriented (more ore less) view of CSS. This is evident in using a general class holding the general styles, then specifying the styles in "subclasses" if the term is useable in the context. In our example, the main class would be .Mode1
while the "subclasses" would be ".Mode1 MainTitle
" and ".Mode1 .SubTitle
". In the end, this is in my opinion a better way of styling than putting it all in the code.
Like it? Vote for it...
References
For more on CSS, try W3Schools or W3C, or check this article for an advanced insight.
Concerning Base Pages, use Google; if you are facing problems there, tell me, I am still considering writing an article on that matter.