Custom look-and-feel with Force.com Sites and Blueprint CSS

At the core of Force.com Sites is an extremely simple, yet powerful concept: the ability to address a set of related Visualforce pages with a publicly accessible URL. Anyone with a web browser can access your application’s Visualforce pages, which in turn can incorporate a completely custom look-and-feel.

The sky is the limit…but where do you begin? Most developers investigating the Force.com platform will have a background in programming rather than visual design, and may be intimidated when building a UI from scratch.

Fortunately, there are some HTML/CSS “frameworks” that can give you a jump start. I’ve had success with one called Blueprint, and in this article I’ll show you how to use it with Visualforce and Force.com Sites.

Media_httpimgskitchco_tcqkg

A brief intro to Blueprint

In practical terms, Blueprint is a set of CSS files that provides a predefined look-and-feel for a web site, though it’s specifically designed to be easy to extend. To use it, you build your HTML as you normally would, and include the CSS classes defined by Blueprint to apply a layout and styling.

Here’s one of the examples from Blueprint’s Quick Start Tutorial:

<div class="container">
    <div class="span-24 last">
        Header
    </div>
    <div class="span-4">
        Left sidebar
    </div>
    <div class="span-16">
        Main content
    </div>
    <div class="span-4 last">
        Right sidebar
    </div>
</div>

In a typical scenario, what’s shown above would be the entire contents of the HTML body tag. Blueprint’s styling will only be applied to content within the container, providing an easy way to enable or disable it. The content will be displayed in a centered grid, which is subdivided into 24 units of width. Here’s a quick walkthrough of the remaining div tags:

  1. Create a block 24 units wide (span-24) for header content, and wrap to the next line after this block (last)
  2. Create a block 4 units wide (span-4) for left sidebar content
  3. Create a block 16 units wide (span-16) for the main content of the page
  4. Create a block 4 units wide (span-4) for right sidebar content, and wrap to the next line after this block (last)

Click on the image below to see a full sized version of the output, with Blueprint’s grid shown for clarity:

Media_httpimgskitchco_dehed

Basic grid with dummy content

This example isn’t very exciting, but with a little imagination you can see how a menu would work nicely in the header, perhaps with site navigation on the left side, and so on. Other examples and tutorials have been created as well, including one pictured below so you can see what Blueprint is capable of.

Media_httpimgskitchco_nmijj

Sample Blueprint page

Use with Visualforce

You may have realized that the CSS classes used above are defined in external files. Indeed, Blueprint’s documentation indicates that the following code should be placed in the head of the HTML document:

<link rel="stylesheet" href="path/to/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="path/to/print.css" type="text/css" media="print">
<!--[if lt IE 8]>
  <link rel="stylesheet" href="path/to/ie.css" type="text/css" media="screen, projection">
<![endif]-->

In the context of Visualforce, these CSS files would become Static Resources, and the link tag would not be used. What’s trickier is handling the conditional comment for the Internet Explorer-specific stylesheet, since the head of the document is not directly accessible in Visualforce.

After some digging, I came up with this workaround:

<apex:page showHeader="false" sidebar="false" standardStylesheets="false">
<apex:stylesheet value="{!$Resource.blueprint}"/>

&lt;!--[if IE]&gt;
<link rel="stylesheet" type="text/css" media="screen, projection" href="{!URLFOR($Resource.blueprintIE)}">
&lt;![endif]--&gt;

<div class="container">
    <div class="span-24 last">
        <h1>Congratulations</h1>
    </div>
    <div class="span-24 last">
        This is your new <span class="ie-test">Page</span>
    </div>
</div>

</apex:page>

The use of &lt; and &gt; allow the conditional comment to sneak by the Visualforce parser, while still getting rendered in the browser. To validate this approach, I defined the ie-test class as being red and bold in the IE-specific stylesheet, allowing me to clearly test whether Blueprint’s IE-specific styles would only be applied in that browser.

Media_httpimgskitchco_qbajj

VF Sites page rendered in IE

Media_httpimgskitchco_frndq

VF Sites page rendered in Safari

Other features of Blueprint

Now that we’ve got Blueprint up and running, let’s dive a little deeper and look at some of its aspects that match up nicely with Visualforce. One of VF’s nicer features is the dataTable component, which provides significant power and flexibility when rendering columnar data in an HTML table. Blueprint’s default styling of tables handles this quite well.

Here’s a simple use of the dataTable component in Visualforce:

<apex:page controller="BPTestController" showHeader="false" sidebar="false" standardStylesheets="false">
<apex:stylesheet value="{!$Resource.blueprint}"/>

&lt;!--[if IE]&gt;
<link rel="stylesheet" type="text/css" media="screen, projection" href="{!URLFOR($Resource.blueprintIE)}">
&lt;![endif]--&gt;

<div class="container">
    <div class="span-24 last">
        <h1>DataTable</h1>
    </div> 

    <div class="span-14">
        <apex:dataTable value="{!accounts}" var="a" id="acctTable">
            <apex:facet name="caption">My Accounts</apex:facet>
            <apex:facet name="footer">Page 1 of 1</apex:facet>
            <apex:column >
                <apex:facet name="header">Name</apex:facet>
                <apex:outputText value="{!a.Name}"/>
            </apex:column>
            <apex:column >
                <apex:facet name="header">Street</apex:facet>
                <apex:outputText value="{!a.BillingStreet}"/>
            </apex:column>
            <apex:column >
                <apex:facet name="header">City</apex:facet>
                <apex:outputText value="{!a.BillingCity}"/>
            </apex:column>
            <apex:column >
                <apex:facet name="header">State</apex:facet>
                <apex:outputText value="{!a.BillingState}"/>
            </apex:column>
        </apex:dataTable>
    </div>
    <div class="span-10 last">
        <!-- large right margin -->
    </div>
</div>

</apex:page>

And here’s the table rendered with Blueprint’s styling:

Media_httpimgskitchco_biemr

DataTable test

Blueprint also includes some nice styles to handle user errors and notices. This maps nicely to the pageMessages component. Here’s a quick example in Visualforce:

<apex:page controller="BPTestController" showHeader="false" sidebar="false" standardStylesheets="false" action="{!throwError}">
<apex:stylesheet value="{!$Resource.blueprint}"/>

&lt;!--[if IE]&gt;
<link rel="stylesheet" type="text/css" media="screen, projection" href="{!URLFOR($Resource.blueprintIE)}">
&lt;![endif]--&gt;

<div class="container">
    <div class="span-24 last">
        <h1>PageMessages</h1>
    </div> 

    <div class="span-14 error last">
        <apex:pageMessages />
    </div
</div>

</apex:page>

Here’s the throwError method from the controller:

public PageReference throwError() {
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Sample error message'));

    return null;
}

And this is the rendered error widget:

Media_httpimgskitchco_glhse

PageMessages sample

Summary

Force.com Sites, when combined with Visualforce, is great in that you can present any look-and-feel to your web site’s visitors. But when presented with a blank canvas, developers may not know quite where to begin. That’s where Blueprint comes in.

Though it’s no substitute for having talented designers on your team, Blueprint usually saves time and can be very helpful for proof-of-concept work or internal applications. And what’s even better is how well it works with Visualforce and the Force.com platform.