Refactoring CiviCRM's templating system (starting with CSS)

2009-09-22 11:53
Written by

In the course of the recent NYC Developer camp, I had the opportunity to discuss the state of CiviCRM's templating system with members of the core team .  In the course of our work with CiviCRM we have done extensive theming and have discovered a number of opportunities for improvement over the current system. In this post I will outline a quick overview of the current state of affairs, and then I'll move on to a broad overview of the changes we would like to see and then specific goals for the 3.1 release.

Current state of affairs


The current templates make extensive use of tables when divs would be more appropriate. This is not in keeping with the Web Content Accessibility Guidelines, specifically, separating structure from presentation (refer to the difference between content, structure, and presentation).  While it may not be possible to follow the WCAG to the letter, it is my contention that we can and should follow these guidelines as closely as reasonably possible.    


There is a dearth of css classes for use in customization - it is currently impossible to access a specific form element using CSS without going into the templating system and adding your own class.  Briefly, css classes should follow sensible naming conventions and provide as much contextual information about each element as possible.  Additionally, we could be leveraging the recently adopted jquery-ui.css files for "common" elements, such as errors/alerts/buttons. 


Generally, the CSS classes used are applied "too specifically" - throughout the templating system we should move classes as far up" the DOM tree as possible. An example would be moving the "error" class from the individual elements to the "common parent" element:

<div>             <div class="label">                         <label for="credit_card_number">                                       <span class="error upper">Card Number</span>                         </label>             </div>             <div>                         <input type="text" class="form-text medium error" id="credit_card_number" value="" name="credit_card_number" autocomplete="off" maxlength="20" size="20"/>                             <span class="error">Card Number is a required field.</span>                             <span class="description">Enter numbers only, no spaces or dashes.</span>             </div> </div>            

would become:

<div class="error">             <div class="label">                         <label for="credit_card_number">                                       <span class="upper">Card Number</span>                         </label>             </div>             <div>                         <input type="text" class="form-text medium" id="credit_card_number" value="" name="credit_card_number" autocomplete="off" maxlength="20" size="20"/>                             <span class="reason-for-error">Card Number is a required field.</span>                             <span class="description">Enter numbers only, no spaces or dashes.</span>             </div> </div>            

This simplifies the controlling CSS, and provides a more comprehensive target for themers (for example, this simple change allows us to alter the entire block containing the label and input field as opposed to simply change the fonts of the label and error description).


Currently there is very inconsistent use of jquery-ui elements - a medium-term goal of this project will be to acknowledge our commitment to the jquery-ui.css and deploy templates which use jquery-ui framework classes extensively.


The css files in CiviCRM are in multiple locations and are not organized. Locations for CSS files should be better documented (this will be done on the wiki) and inline comments should be used to explain the purpose/utility of each css file.  Kurund has also stated that it will be a goal of CiviCRM to use Drupal's drupal_add_css hook in order to leverage the power of built in compression/collation of the parent CMS (I assume that there is something similar for Joomla but am not familiar with it).


CiviCRM's icons do not have a consistent "feel," and css sprites are not in use for CiviCRM-specific elements (such as print and help). Having a consistent feel for all icons will unify the interface and result in a more pleasing user experience.  To this end, we should use as many of the icons from the jquery-ui as possible, and for CiviCRM-specific icons (such as print), we should create a CiviCRM-sprites.png file and use this for all CiviCRM icons.  This will reduce download time and make it easier to adjust icons to a specific organizations look and feel.

Primary Goals


I've outlined some of the problems that I see in the current templates, and would like to give a brief overview of the broader goals that we have identified for the templating system moving forward. 


Firstly, we must focus on providing an attractive and usable default look and feel, right "out of the box."  Many organizations will not alter the look and feel of CiviCRM, and it is extremely important that we provide them with a product that "feels right."


Because CiviCRM caters to many government and government-affiliated entities, it is important to begin to follow the Web Content Accessibility Guidelines ( and section 508 of the U.S. HHS Web Communication & New Media guidelines ( as much as reasonably possible, with an eye towards full compliance (I do not have experience with the usability guidelines of other governments, but welcome input from people with experience in other countries).


CiviCRM should reflect font/style declarations that are made in the parent theme (excepting possibly layout).  Ideally, this means that CiviCRM will obey the style declarations of your Drupal/Joomla theme (for example, setting the base font to Georgia in your CMS theme will mean that Georgia will be used within CiviCRM as well) with minimal to no configuration.  The current thinking is that we will provide a "default styling" css file that could be deleted/removed and would allow CiviCRM to listen to your theme's CSS. Difficulties may arise with layout adjustments, so the "default styling" will probably only include font and color declarations.


The CiviCRM front end should be easy to customize, especially the client facing templates (Contribution and Profile pages come to mind). CiviCRM's templates should integrate as seamlessly as possible with an organization's CMS, and the ability to make donations pages look like the rest of an organization's website has been a major selling point (few donation solutions offer this option).


Generally, CiviCRM's templates suffer from markup bloat.  We should avoid adding markup when possible and look to lighten up templates by removing tables that are used for layout only, and use more appropriate markup such as divs in their place (this is also crucial to coming in line with the WCAG).


CiviCRM should provide an extensive framework for customization.  CSS classes should be used to contextualize elements such that developers have the ability to easily override the design provided - specific form elements (such as radio buttons with an error) should be easily targeted based both on "type" (for example, "auto-suggest-box") and specific field name (for example "qa_first_name"). Additionally, a developer should be able to re-roll a theme using the jquery-ui Themeroller, drop the resulting files into CiviCRM and see all of the changes propagate across the application without further modification.


New templates should anticipate solutions to as yet undeveloped functionality.  I expect that the solution to this lies primarily in providing example markup for commonly used "widgets" (accordions come to mind, as do label+form-element+description blocks). 

Specific Goals for 3.1 Release


The first task for the 3.1 release is to analyze the current templating system and provide suggestion for markup that can be used throughout CiviCRM.  Suggested naming conventions for css classes for all elements that are in keeping with the naming conventions used throughout the rest of CiviCRM will be a part of this work. Additionally, sample html for commonly used "widgets" such as accordions, select lists, radio buttons, help menus etc. will be placed in the Layout standards document on the wiki (  Recommendations will be made about css classes to be added to the body element so that themers always know "where you are" (e.g. front-end vs back-end, logged-in, logged-in-as-role). A comprehensive list of available body tags will be made available on the wiki along with the conditions that will trigger the presence of each tag (this may not be fully implemented for 3.1 release). All recommendation should hew as closely as reasonably possible to web content accessibility guidelines.


We will use the client-facing sections of Donation, PCP, and Profile pages to test the suggested markup changes for viability.  This will result in fully resolved templates for the client-facing Donation processing, PCP and Profile sections of CiviCRM, to be included in the 3.1 release. The new template files will use as much of jquery-ui css as possible and will set the precedent for a complete overhaul of the templating system.


For the 3.1 release, we will remove unused css declarations (excepting jquery-ui.css, which will remain unmodified), and CSS declarations that we expect to deprecate in near-term future release will be marked as such and singled out. The new CSS files will provide inline documentation of CSS declarations to help themers make better use of the existing CSS.  All new CSS will be tested to ensure that css works in all A-grade browsers with minimal differences. 

Longer term goals that may be brought in to 3.1 depending on demand/time


I have tried to isolate attainable goals for the 3.1 release that will provide both specific improvements to the existing software and a clear way forward for the user interface of CiviCRM as a whole while recognizing the limited resources available to this piece of the project. However, there is always more to do, and I thought it appropriate to outline a few of the specific medium-term (3.x) goals that I anticipate working on. Among the top priority items I see for future release are:

  • standardizing the position of elements (e.g. action buttons)
  • creating style rules for tables and applying them across the board (alternating row background color instead of borders, adjust padding, etc...)
  • adjusting class names to jquery-ui/CiviCRM standard across all templates
  • bringing WCA Guidelines to bear on all CiviCRM templates


Thanks for your time in reading all this (I know it's a lot).  I look forward to working with the community on refining these goals and improving CiviCRM! To that end, we will be using the following pages as part of the active discussion (you may notice that a few of the points in this post were gathered from them).


Dave Greenberg has also created an issue here:

rayogram - has committed resources to implement the first round of improvements for the 3.1 release. We look forward to getting feedback from interested folks both on the goals and the details as the project progresses. We'll post follow-up blogs as we move forward.


A couple of comments:

- jquery-ui has been introduced recently, and applying in to all the elements in the templates is a long term goal, not even sure to see when it has been achieved. Shall we introduce a {* This template needs to be modifified according to the v3 guidelines for the ids and classes *} in all the templates, so we can see the progress ?

- id is also very important to add jquery behaviour. eg to store meta data
", or to be able a specific field/item

- some layouting (eg. the zebra striping) should be added by a one line of jquery instead of carrying an extra odd event class in all the rows

- some complex forms/views (eg contact edit/view) couldn't be done properly without using table layout. Not sure anymore that it is that bad to have a table for layout instead of zillions of float/clear divs that aren't that semantic either

- we should try using more microformats while we are at it


great ideas xavier:

  • let's definitely add "not yet converted to v3.1" to templates
  • i definitely see a place for ids in the templates - my primary concern is that in some cases i expect that we will be using user-generated text for "unique" form items (specifically, custom profile fields) and fear conflicts. my solution (you may have a better one) - has been to use "unique" class names to target individual elements, which minimizes the potential risk. i have not run into any situations where an id was required and a unique class name could not be used, but maybe i'm missing something?
  • zebra striping: this may be a matter of stylistic preference, but i prefer to keep the classes in the html - in my experience rendering speed is improved (especially for extra long tables) and we don't see any other performance gain by doing the striping in jquery (except for developer convenience ;)
  • Dave and i discussed the table-layout issue on complex forms - there is certainly room for debate. My goal for moving to divs is not so much to become strictly semantically accurate, but rather to empower developers to make style choices more easily. (for example, currently it takes changes in .tpl files to move labels from one side of an input field to another - if we'd like to accommodate right to left languages using CiviCRM, it behooves us to turn this into a simple CSS change...)
  • i totally agree on microformats, as long as Advisory Group/CiviCRM agrees - if so, let's try to include this into the markup recommendations with 3.1. - issues i see related to this are that the jquery-ui date picker does not use hcalendar formats, and there may be other cases in which other choices we've made will make using microformats difficult - would this be something you would be willing to look into?

I'll piggyback on X's comments re: tables. Civi does render a lot of content as tabular data, which semantically justifies the use of tables. Where I think divs are most needed is the higher level page organization, which is properly a layout issue, not data.

The biggest issue I've run into when styling tpls with css is that there's currently a lot of inconsistency. Divs are used in some places, tables for field layout in some, dl/dt tags in other places, and descriptive tags (label) are not always applied consistently (e.g. the table class may be different so the cell tag is applied differently). In order to create a consistent layout, for even something as basic as an event registration page, you have to do a lot of work in the tpl and css just to bring the markup tags in line.

tabular data should always be rendered as tables - and the dl/dt/dd system seems to have become incredibly cumbersome. the primary goal of this project is to come up with a consistent system for displaying/formatting page elements (accordions/form fields/help blocks etc...)

my aim is to slowly overhaul the tpl files so that tables are only used for tabular data and that there is a consistent class-naming system for all layout blocks/elements This will make it easy to predictably target "all elements of the type-x" as well as target an individual elements such that with only a css change we should be able to:

easily give all text input fields a background-color of gray,


set the border to yellow on the credit card input field of a specific donation form,

without having to change any .tpl files


Really, not going to fight that one.

However and FYI, jquery got a ":odd" selector, so you can $("#contactlist tr:odd").addClass("odd"). Hardly visible on the rendering time when you have small lists (like on jquery, max 100 rows)

One of the things I would like to see is the addition of a hook to allow add-ons/modules to ship with their own templates. The main use case I see is allowing templates to be overridden without adding a step the module install process of copying templates into the the custom template directory declared under Global Settings.

This is essentially mimicking Drupal's themeing functionality to allow for more robust support for a CiviCRM modules repository. This does get away from integrating with the CMS's template system, but I have to admit I'm of the opinion that the future of CiviCRM is in being CMS ambiguous (note this is coming form the guy who does most of the Views2 integration support with Drupal :))

If ya'll are interested in that route Rooty Hollow would be happy to donate the time to make it happen in this process.

i've got it close to working in the SFS module. I do agree that modules should be able to set their own PHP/template path and not have folks tweak the admin settings. I'll polish it off when i migrate SFS to the newer version


What about adding a hook that allows changing the administration page. For example say a module wanted to add an options list or a Global setting. How much work would that be?

can u use the pageRun / buildForm / postProcess hooks available for all pages? We can chat more on IRC. We dont have a generalized good way of storing settings as yet, and thus using drupal's variable_set/get is probably a better mechanism for your storage needs :)


Really happy that more people are doing stuff with Layout and CSS and cool that you are building on the stuff in the wiki.

I've been the layout and css person on the advisory group for a while - haven't got passed the brainstorming stage that you saw on the wiki as yet, but would like to put some resources aside for a implementing these improvements - so please keep me in the loop / i'll stay in the loop.

And I'll add my thoughts on zebra striping to the wiki page :p

Another item for this discussion --
There should be better handling of print-specific css styles. Since Civi provides the ability to print pages via icon on just about every page, we should develop a print only stylesheet and have better control over how those display.

Print styles will be much easier to implement from css as we refactor the html - there has been a fair amount of progress on the end-user side of the application, but there is still lots of html refactoring to be done in order to get the "admin-side" (whih I assume is what will be most printed) up to snuff for styling for print. But, definitely something that we are looking towards implementing properly once the html has been fully re-factored.