Posted by Vasilis on Sunday, September 21, 2008
If you ever tried to view the source code when a DotNetNuke page is loaded in the browser, you probably noticed that there are several CSS files attached in the head area. In this article we'll try to break down this concept and understand how it works and how we can benefit from it. I think it's essential knowledge for administrators who need to make simple tweaks to the appearance of their DNN web sites, but also for developers and designers who make their first steps into the module and skin development.
Not only on a DNN web site but even on a single static web page, when we attach more than one CSS files, the styles that are included in all of them will be applied to our document. Many web designers use this method to separate their styles so for example they can have one stylesheet to control the layout, another one for the typography and so on. Another common technique is to have browser specific stylesheets, like one that includes styles only for IE6. Using IE conditional comments, we can attach this stylesheet only when the the request comes from a user with IE6. This technique has been very popular lately.
DotNetNuke makes extensive usage of this method but not for the reasons we described above... at least not until version 04.09.00 where having browser specific stylesheets is also possible. We need to talk a little more about this method so we can better understand the DNN reasons.
Let's assume we have two CSS files attached to an HTML document and both of them include the same classes and style rules. What will happen in this case? Which styles will finally be applied to our page? Here comes the interesting part... The styles that are included in the second CSS file will override those in the first one. In the following example the font size of our paragraphs will be 14px.
<link rel="stylesheet" type="text/css" href="Stylesheet1.css" />
<link rel="stylesheet" type="text/css" href="Stylesheet2.css" />
Stylesheet1.css
p{font-size:12px;}
Stylesheet2.css
p{font-size:14px;}
The browsers load the CSS files from top to bottom. If they find the same rules in two or more files, they apply the one found last. Even in just one CSS file, when a rule exists more than once, the lower in our CSS code is the one that will be applied. Let's see now how DNN uses this method to offer a flexible solution to developers and administrators.
The following list of CSS files is what we usually find when we view the source of a DNN page.
/Portals/_default/default.css
/Portals/0/Skins/SkinName/skin.css
/Portals/0/Skins/SkinName/container.css
/Portals/0/portal.css
Well, we can find more but let's keep it as simple as possible for now. Later we will see when and why more CSS files find their place in this list. Two of the above files are really important, the first one (default.css) and the last one (portal.css).
This is the first stylesheet that we will find attached to all DNN web sites. It is responsible to bring some style to our pages no matter what. We can describe it as a fall back solution... when there are no other styles to be applied, our pages will still have some basic format with styles that come from this file. As you can understand, all CSS files to follow can override this one.
Like default.css, we will find portal.css attached to all DNN web sites but this time at the end of the list. The zero in the middle of the path is the portal ID. As you probably know, with one DNN installation we can have more than one portals and each one of them will have its own portal.css that can be found at /Portals/PortalID/portal.css.
On a fresh DNN installation, this file includes a list of CSS classes without style rules in them. These empty classes are there to give us an idea of what this file is all about. The portal.css is the last one in our list so we can use it to override styles that exist in the other CSS files. Can you now tell what those empty classes are? I guess you can! They are classes we can also find in the default.css but in the default.css they are not empty. So the DNN guys have kindly put the names of the most common default CSS classes in portal.css for us to have quick access and be able to override them, giving a personal touch to our DNN web site. Quick access means that all we have to do to edit this file, is to go to our Site Settings and open the Stylesheet Editor. Oh yeah... the file we're editing in there IS the portal.css. Cool eh?
Anyway, the point is that using the Stylesheet Editor, we can override not only the default DNN styles but also skin styles, container styles and module styles. But let's walk the bridge and move on to the next level. Are you following?
Having a better understanding of how things work, I think we can now talk about the DotNetNuke CSS hierarchy. With the term "CSS hierarchy" we mean which CSS files will be at what position in our list and why. So let's first create a quick diagram and then we'll get into the details.
1. default styles: default.css
2. module styles: module.css or styles that come from module templates
3. skin styles: skin.css, PageskinName.css, container.css, ContainerName.css
4. administrator styles: portal.css
There are two categories we have not examined yet, the module styles and and the skin styles. We need to make clear though that the files these styles reside in, are optional and we will not find the same files attached to all DNN web sites... not even from page to page on the same DNN web site.
DotNetNuke module developers have the ability to optionally define CSS styles that will be applied to their modules, in a file called module.css. The number of module.css files we will find attached to a page of our DNN web site obviously depends on the number of modules we have put in our page and how many of them do have a module.css. If there are more than one, the order they will appear in our list is the same with the order the modules appear in our source code.
/DesktopModules/ModuleName/module.css
Some more advanced modules support templates. This means that the appearance of the module can be controlled with additional files, usually HTML and CSS. As administrators we can alter these files or add a new template and then select it from the admin interface of the module. The templates usually live under the module's directory. Can be something like /DesktopModules/ModuleName/Templates/Templatename/. So when a module supports templates and the template we're using includes a CSS file, for example template.css, this will appear in our list under the module.css of that module.
/DesktopModules/ModuleName/Templates/Templatename/template.css
The CSS files that are responsible for the appearance of the modules, come after the default.css in our list so the module developers can override the default styles, but also come before the skin styles and administrator styles, so either with a skin or using the Stylesheet Editor, we can override the module's styles and make it look good upon our needs.
Before we talk about the CSS files that can be included in a skin, we need to explain that a skin may have one or more page skins. Page skins are the HTML or ASCX files that are included in a skin and define the structure of a page. We call them page skins because they can be applied on pages. A simple and common example is the home page skin and the inner page skin. The home page skin is the one we can use for our home page and usually has a more complicated layout, with more panes. The inner page skin is the one we can apply to the inner pages of our site and usually includes two or three panes.
Now let's see how many CSS files can be included in a skin. First of all the skin.css. The styles that we put in skin.css will be applied to all page skins. Then comes the PageskinName.css, for example home.css or inner.css. The styles we put in the PageskinName.css will be applied only to PageskinName.ascx or, to make it more familiar, the styles we put in home.css will be applied only to home.ascx and can override the skin.css styles.
/Portals/PortalID/Skins/SkinName/skin.css
/Portals/PortalID/Skins/SkinName/PageskinName.css
In most cases the skins include also a set of containers. The containers have their own place under the DNN directory which is the /Portals/PortalID/Containers/. A set of containers consists of one or more ACSX or HTML files, a container.css file and one or more containerName.css files. As in the skins, the container.css will be applied to all the containers and ContainerName.css will be applied only to ContainerName.ascx. When there are more than one ContainerName.css, the order they will appear in our list is the same with the order the containers appear in our source code.
/Portals/PortalID/Containers/SkinName/container.css
/Portals/PortalID/Containers/SkinName/ContainerName.css
DotNetNuke version 04.09.00 introduced a new skin object that give us the ability to attach even more stylesheets to our pages. The new skin object's name is "Styles" and its purpose is to allow skinners attach browser specific stylesheets. The position of these files can be defined from the skinner to be either at the top or at the bottom of the list.
Now that we know how CSS works in DNN, we need a way to identify an element's CSS class so we can override its styles. With the evolution of the browsers this is not a problem. All modern browsers have tools, either built-in or developed as plug-ins, that make this task really easy. Opera has built-in Developer Tools. We can find them under Tools > Advanced. In Google Chrome the only thing we have to do is right-click anywhere in a page and select the Inspect element option. For Firefox there is Firebug, an excellent tool for everyone and a must-have for developers. Internet Explorer users can install the Developer Toolbar and Safari users the Web Inspector.
Summarizing we can say that the DotNetNuke CSS file system and hierarchy, probably seems to be too complicated for the newcomers. Believe me, it's not that much. After a few hours of practicing, we can enjoy the power and flexibility of this platform.