CSS Generation With JavaScript – An Underutilized Content Management Tool

There are some interesting new things going on the world of web site layouts with CSS and JavaScript all the time. Tricks and tools to add to a client side developer’s arsenal for making flexible, content accommodating navigation, layouts and presentations. Though I wouldn’t give away any of our progress, I can’t help but wonder if sometimes the amount of work we ask a visitor’s browser to do is overkill. One way to shift this workload off the browser — without placing undo burden onto the site management staff or its budget by requiring a high level of technical expertise with each site update — is to move the it to an offline or backend CMS tool creating static code for publication. This is particularly useful when doing multiple site deployments with a similar theme or building different localized site versions where the need for flexibility in type doesn’t change from user to user, but from content update to content update or deployment to deployment.

Through the use of fairly simple to create build tools we can create ‘static’ CSS for deployment and consumption and trim the amount and complexity of layout code sent with each page.

Example – Sizing Large Headings

On a site I worked on last summer I had the following scenario: Sectional headings on the web site should by default be a large fixed size, allowing for 8 or 10 characters to fill the given horizontal space. This worked 80% of the time when the site was in English, but as the site sections got translated it was clear that the default font size was too large.

What were our options at that point? We could guess at the smallest font size needed to fit the longest probable section name and then set all section headers to that resulting in a smallish feeling most of the time. We could write some client side JavaScript code to send to every visitor and resize the type on the fly [or use a tool like sIFR which does this type of thing as part of its text replacement]. Or we could create a tool that is used once as part of the deployment process or CMS to set the various heading sizes.

Defining the Rules and Constraints

Whether you’re putting the logic on the public web server for download, the CMS, or in some developer or designers brain you need to determine the contraints and parameters for setting the type size. For this section header example lets work as follows:

  • Headers fill a 600px wide column and in a 120px high block
  • 100px Georgia, Bold is the base font spec
  • When a header doesn’t fit it should be the largest font size possible but still fit inside the box

screenshot of sample header sizes

Applied to the phrases our site uses for each section we see that the base font size works in most cases, but for the one outlier ‘Privacy Policy’ we need to drop the size down to 82px or so.

Deciding on the Desired CSS

If we did the above exercise to a static site that would never get updated or translated we’d probably use some type of page or header ID to apply the one exception as well as other header style changes like color or background. Even though this isn’t the case we still need to plan what the static CSS we will generate looks like and what the HTML ‘hooks’ will be.

HTML
<div class="headerBox" id="hdr-blog">
    <h2>Blog</h2>
</div>
<div class="headerBox" id="hdr-archives">
    <h2>Archives</h2>
</div>
<div class="headerBox" id="hdr-calendar">
    <h2>Calendar</h2>
</div>
<div class="headerBox" id="hdr-privacy">
    <h2>Privacy Policy</h2>
</div>
CSS
.headerBox {
    width: 600px;
    height: 120px;
    border: 1px dashed #444;
}
.headerBox h2 {
    margin: 0;
    font-family: Georgia;
    font-weight: bold;
    font-size: 100px;
    white-space: nowrap;
}
/* section specific color themes */
#hdr-blog h2 {
  color: #f0f;
}
/* deployment specific font sizes */
#hdr-privacy h2 {
  font-size: 82px;
}

It is that last section — ‘deployment specific font sizes’ — that we need to generate once for each deployment based on the length of the varied text.

Developing the Custom Editor

I had arrived at the 82 pixel font size for ‘Privacy Policy’ by trial and error and editing the CSS manually. It took about 30 seconds to land on the right size, but that task doesn’t scale well. It gets boring and tedious over the span of a single site, and requires someone manually editing CSS code over the life of the various site deployments, translations and updates. By writing a highly site specific admin tool to do this task we can move this maintenance work out of the coder’s hands and into that of a designer, content manager or translator. With great scripting libraries out there this shouldn’t take very long to do either. For our example I’m going to grab jQuery and jQuery UI to build a static & offline tool to generate the desired CSS that can then be copied to a file in our project by anyone on the team with access.

screenshot of header tool

The resulting tool is made up of three parts:

  1. Display of the content you’re adjusting or adding
  2. Interface for adjusting content parameters
  3. Generation of CSS code based on customizations

jQuery UI sliders were initialized based on the outlined parameters above [default to 100px, move inside a reasonable range] and adjustments are seen on the fly.

CSS is then generated in kind of a brute force fashion going through the hidden fields set by the sliders:

JavaScript
$("fieldset.headerWidget").each(function(i) {
  var hdr = $(this).attr("id");
  var css = "";
  // First Line
  css += "#hdr-";
  css += hdr;
  css += " h2 {n";
  // font size
  if ($(this).find(".hdrsize").val()) {
    css += "font-size: ";
    css += $(this).find(".hdrsize").val();
    css += "px;n";
  }
  css += "}n";
  css += "n";
  output.css += css;
});
CSS Output:
#hdr-blog h2 {
}
#hdr-archives h2 {
}
#hdr-calendar h2 {
}
#hdr-privacy h2 {
font-size: 82px;
}

Even including whitespace and comments the JavaScript written to make the tool work is under 50 lines. If the changes were more complex or more parameters were set the CSS could alternately be generated based on the current appearance of the item, however this may result in more verbose CSS code to publish.

Manual Sliders vs. Automatic Adjustments

In this example I’ve used manual sliders for resizing the text. The same could have been done automatically by resizing the text with JS until it measured to fit the constraints. Which way you build a depends on the project and who is doing the content management or setting up the deployment and a balance between automation and intervention. For the example I pulled from we wanted to give the manager a little room to play and use their own judgement.

Expanding on the Idea

For simplicity I’ve shown build a standalone offline editor here, this works if you have other manual tasks as part of a deployment or site build process, but sometimes you’ll need more. It would be quite easy to build a tool like this into a CMS project and have the CSS generated then saved to the proper location. Given the common markup patterns the list of headers could also be generated based on server side content. It all could flipped on its side and rather then edit all section headers at once this this could be part of a record editor where the font size [or other specs] are saved with the individual record. While that might take more infrastructure work it may be what best fits your project.

These custom tools are not limited to the font size example here either. Anything that needs some finessing when text changes, items get added, deactivated, etc can be a candidate for content management tools rather then complex client side code. For the same site referred to earlier each deployment or localized version also had a top navigation bar that varied — both in length of text of each section but also some site features [read; nav items] were optional. To take the tedious task of re-spacing the navigation for each version of the site out by hand &the need for the coder to do it we instead took 2 days to create a custom tool to space the navigation and position the submenus according to the length of the translated section names and which of the optional elements were activated.

At the end of the day where these build tools fit into your site’s deployment process will vary, but creating custom or one off tools can be an interesting and quick problem for a web developer to solve and the time spent doing so can pay great dividends over the life of a web site or product.

Comments Temporarily(?) Removed