DNN Theming Tips and Tricks

Skinning Responsively with Bootstrap - Part 1 (Preparing your Skin)

By Ralph Williams, Jr. on 6/10/2013

Creating a responsive skin can seem like a large task to take on when you think about the fact that there are several views to create using the same content. Now, I typically have not been a big fan of using HTML grid systems as I have felt I am able to write a much more lean skin on my own. However, with the new requirements of having flexible skins for multiple devices, I have felt that it is better to use a tool that helps me to be able to achieve great skins with only a bit of overhead.

Bootstrap is a grid system that is technically a 960 grid with views for devices with smaller screens such as tablets and mobile phones as well as a view for larger screens. Bootstrap allows for true responsive (fluid) layout as well as adaptive (what I call step-down) layouts. I tend to like to use the adaptive layout as I feel it still gives me a bit of control on my layout for each targeted screen size.

Why did I choose Bootstrap?

There are several grid frameworks out there that give you some tools to structure your responsive skin. However, Bootstrap is not just a grid system. It also has a lot of different components that are available to help in making the process much easier. Instead of having to create controls and JavaScript for things such as a collapsible menu on mobile view, if you structure your menu as Bootstrap does, it just works! Of course, you can still customize your menu on top of what is there with your own CSS and JavaScript, but it really just simplifies things quite a bit.

Implementing Bootstrap into DotNetNuke

Before we can actually begin skinning our design, we must build our Bootstrap package. The Bootstrap website has a great tool for customizing your Bootstrap package for whatever configuration you have. As I mentioned previously, there are quite a few components in Bootstrap and including the whole mess can really provide some overhead that you just don’t really need. You can go through the Customize page and un-check all of the components that you feel you  will not be using. Also, on this Customize page, are quite a few variables that can be adjusted to fit your project. For example, column and gutter widths for each step in screen size and colors for the components that you included in your package.

Once you have customized your package, click the download button at the bottom (it’s ridiculously large and blue). This zip file will include 3 folders for CSS, JS and images.

I typically create a “js” folder within my skin folder and extract the zip file in there so that the path is (relative to root) /Portals/[PORTALID]/Skins/[SKINNAME]/js/bootstrap/(js/css/img), where [PORTALID] is either _default or your portal name and [SKINNAME] is the name of your skin folder.

References and Dependencies in the Skin

Now that we have our Bootstrap in place, we can start getting into the actual skin. Create a new skin file (ex. Default-Layout.ascx) and insert the required declarations for your skin and skin objects.

Below are the common ones that I use:

<%@ Control language="vb" AutoEventWireup="false" Explicit="True" Inherits="DotNetNuke.UI.Skins.Skin" %>
        <%@ Register TagPrefix="dnn" TagName="LOGO" Src="~/Admin/Skins/Logo.ascx" %>
        <%@ Register TagPrefix="dnn" TagName="SEARCH" Src="~/Admin/Skins/Search.ascx" %>
        <%@ Register TagPrefix="dnn" TagName="USER" Src="~/Admin/Skins/User.ascx" %>
        <%@ Register TagPrefix="dnn" TagName="LOGIN" Src="~/Admin/Skins/Login.ascx" %>
        <%@ Register TagPrefix="dnn" TagName="PRIVACY" Src="~/Admin/Skins/Privacy.ascx" %>
        <%@ Register TagPrefix="dnn" TagName="TERMS" Src="~/Admin/Skins/Terms.ascx" %>
        <%@ Register TagPrefix="dnn" TagName="COPYRIGHT" Src="~/Admin/Skins/Copyright.ascx" %>
        <%@ Register TagPrefix="dnn" TagName="MENU" src="~/DesktopModules/DDRMenu/Menu.ascx" %>
        <%@ Register TagPrefix="dnn" TagName="JQUERY" Src="~/Admin/Skins/jQuery.ascx" %>

Bootstrap JavaScript

Next, we need to reference the Bootstrap JavaScript file in our skin. There are two different skin objects that I use to achieve this and it’s really up to you to pick the one you prefer. You can use either the built in DnnJsInclude that comes with more recent versions of DNN that have the CRM (Client Resource Management) in the core. The other technique is one of my favorite skin objects, 40Fingers StyleHelper, http://stylehelper.codeplex.com/. Note that for whichever way we choose, we need to register  the declaration for that object as well.

DnnJsInclude

<%@ Register TagPrefix="dnn" Namespace="DotNetNuke.Web.Client.ClientResourceManagement" Assembly="DotNetNuke.Web.Client" %>
        <dnn:DnnJsInclude ID="bootstrapInclude" runat="server" FilePath="js/bootstrap/js/bootstrap.min.js" PathNameAlias="SkinPath" />

40Fingers

<%@ Register TagPrefix="fortyfingers" TagName="StyleHelper" Src="~/DesktopModules/40Fingers/SkinObjects/StyleHelper/StyleHelper.ascx" %>
        <fortyfingers:StyleHelper ID="bootstrapInclude" Doctype="HTML 5" runat="server" AddJsFile="js/bootstrap/js/bootstrap.min.js"  />

See what I did there? Using the 40Fingers skin object, I was able to set the Doctype to HTML5, a requirement for Bootstrap, right there in the skin object for the Bootstrap include.

Bootstrap CSS

You can either use the 40Fingers or CRM’s DnnCssInclude to link to the Bootstrap CSS, but I typically just import it through my skin.css. To leverage the responsive part of bootstrap, we need to make sure to import the bootstrap-responsive.css as well. If you used the customize version of Bootstrap, it includes the responsive CSS in the bootstrap.min.css. Since we have already declared the skin object for the JavaScript we do not need to declare it again.We need to make sure to load the Bootstrap CSS before our skin.css so that our css takes priority. If we were to use the CRM, we have a very helpful attribute that is available for Relative Order, called Priority. We set this to less than 15 as that is the relative order for the skin.css. 40Fingers gives us an attribute, AddAtEnd, allows us to put it after the portal.css if set to true, or before module.css if set to false, which is the default value. If we are importing this within the CSS file, we just need to make sure that it is imported at the beginning of our skin.css file.

DnnCssInclude

<dnn:DnnCssInclude ID="bootstrapCSS" runat="server" FilePath="js/bootstrap/css/bootstrap.min.css" PathNameAlias="SkinPath" Priority="14" />

40Fingers

<fortyfingers:StyleHelper ID="bootstrapCssInclude" runat="server" AddCssFile="js/bootstrap/css/bootstrap.min.css" />

CSS

@import url(js/bootstrap/css/bootstrap.min.css);

Doctype

Also, set your Doctype to be HTML 5. This can be done with either the StyleHelper skin object, an xml file: [SKINNAME].doctype.xml, or in your Host Settings in DNN. I personally prefer the StyleHelper method (see Bootstrap JavaScript include for 40Fingers above).

META Information

The next step is to add some META information the the head of our HTML document. Being a skin, we do not have direct access to the head of the document as everything that we create in our skin is within the body of the document. Here again, we have the option to use 40Fingers or some DNN core secret skin object, dnn:META, to insert the code. In order for the browser to adjust to our various screen sizes, we need to set the zoom level of the browser to 1.

Below is the DNN META tag that needs to be insert to the head:

DNN Meta

<dnn:META runat="server" Name="viewport" Content="width=device-width,initial-scale=1" />

40Fingers

<fortyfingers:StyleHelper ID="META" AddMetaTags="viewport:width=device-width, initial-scale=1.0" runat="server" />

Next steps