Skip to main content

skip to main content

developerWorks  >  Sample IT projects | Open source  >

Using open source software to design, develop, and deploy a collaborative Web site, Part 8: Styling content for theming using CSS

developerWorks
Document options

Document options requiring JavaScript are not displayed

Discuss


Rate this page

Help us improve this content


Level: Intermediate

Alister Lewis-Bowen (alister.lewisbowen@gmail.com), Senior Software Engineer, IBM
Stephen Evanchik (evanchsa@gmail.com), Software Engineer, IBM
Louis Weitzman (louis.weitzman@gmail.com ), Senior Software Engineer, IBM

06 Oct 2006

Follow along in this series of articles as the IBM® Internet Technology Group designs, develops, and deploys an extranet Web site for a fictitious company, International Business Council, using a suite of freely available software. In Part 7 you learned the team's methods for structuring the content of this new Web site. This article continues with theming by focusing on turning that structure into styled XHTML using cascading stylesheets (CSS).

Introduction

In this series of articles, follow along as the Internet Technology Group team describes how to create a customized Web site for a fictitious company, International Business Council (IBC). The site requires document storage, discussion groups, specialized workgroups, conference scheduling, and schedule session descriptions.

In Part 7 learn how to create a new theme and construct structured XHTML within the theme for our Web site. This article continues with theming by focusing on turning that structure into styled XHTML using cascading stylesheets (CSS).

Drupal lets theme designers use CSS to alter the presentation of the XHTML content. Styling in CSS is general across all Web sites and not specific to Drupal, but it is part of creating a usable and desirable Web site. Therefore, this article focuses on common practices when using CSS styling. We'll summarize some of the techniques we used to style the IBC Web site to take advantage of the structure we created. You'll learn about the methods we used to:

  • Design maintainable CSS structure.
  • Provide proportional page layouts.
  • Identify and visualize Web site sections.
  • Create CSS-driven drop-down menus.
  • Enable user-switchable layouts.
  • Provide print styling.

The Drupal theming system, as explained in previous articles, lets us keep the structure and presentation separate from the program logic. We also try to keep the presentation of our Web content as separate from the content structure as possible. Now that we have well-prepared templates that structure the content using XHTML, we can style the content using CSS.

Information in this series should not be interpreted as a rigid set of development guidelines, but simply as a place to start when styling your own Web site.

Compatibility

Styling Web sites is an exercise in patience and determination. If your XHTML structure is sound, then your life is made easier. However, theme designers know only too well the frustration of making your CSS work across different browsers, browser versions, platforms, and so on.

Although it is becoming easier, backward compatibility depends on the expectation of your client and needs of your client's users. Make sure you understand these requirements and clearly define them. With the IBC site, we are working with a fairly technically savvy user base that, for the most part, uses up-to-date browsers. By using the ideas of semantic markup for the content structure, we can produce Web pages with a reasonable layout on older browsers, even when styling is not available. Figure 1 compares the presentation of the IBC homepage when styling is available and when it is not.


Figure 1. Styled and non-styled home page
Styled and non-styled home page

Without styling, the presentation is much more sequential, causing it to occupy more vertical space. However, the semantic structure remains intact. Some otherwise hidden content is displayed, helping the reader recognize certain sections of content, including a link to jump straight to the start of the main content in the page. These are typical structural techniques used for accessibility (discussed in Part 7).

There are plenty of workarounds, or hacks, to achieve similar presentations in different environments. We tried not to use any. Instead, we were willing to accept that there would be slight differences in the way content might be presented in one browser or platform compared to another. As long as this content was still readable, functional, and semantically correct in its layout, we accepted the slight variations.



Back to top


CSS file organization

In Part 7, we create a new theme directory under the themes directory by copying the Bluemarine theme that comes with the Drupal distribution. To organize this directory we decided to create a c directory under this theme directory to contain all our styles. We also created an i and j directory for images and JavaScript files, respectively, specific to this theme.

You can also tell Drupal what stylesheet you want to add to your theme using the theme_add_styles function in your module's hook_init function or the theme templates.php. This function lets you add a path to your stylesheet and the media type associated with it. It appears to your templates as a constructed set of LINK elements in the $styles variable passed by the phptemplate engine. Instead, we hand-coded our own LINK elements to the page.tpl.php file. This method may be preferable to your theme designer because they can control the use of stylesheets directly from the page template file.

By default, Drupal applies style through the styles.css file in the misc directory. Instead of having all our styles in one large stylesheet, we want to define several stylesheets and associate them with particular styling tasks. Instead of using a LINK element for each of these in the HEAD section of the page.tpl.php template, we chose to create one containing stylesheet where we could include all the task-specific stylesheet files. Listing 1 shows the contents of the screen.css file we used to define our main screen media-specific styles.


Listing 1. Included stylesheets in the screen.css file
                
@import url("base.css");
@import url("form.css");
@import url("layout.css");
@import url("banner.css");
@import url("nav_bar.css");
@import url("side_bar.css");
@import url("login.css");
@import url("home.css");
@import url("workgroups.css");
@import url("conferences.css");
@import url("members.css");
@import url("announcements.css");
@import url("action_items.css");
@import url("agenda_items.css");
@import url("search.css");
@import url("discussions.css");
@import url("comments.css");
@import url("filegallery.css");
@import url("companies.css");
	

There are several included stylesheets in this file, including a base set of styles of XHTML element selectors, form styling, page layout, the major areas of the layout (banner, navigation, sidebar), and the major sections of the Web site.

The speed of pulling one file over the wire on a request compared with the maintainability and findability of a style using an organized set of stylesheets remains a compromise. Since our stylesheets ended up being small, they downloaded quickly and, of course, once cached, are there to use. Depending on how much styling you need to create and how your theme designer likes to work, working with fewer stylesheets but bigger files may be preferable.

One limitation with this method of organization is in the case when a user saves a Web page to their computer to view while disconnected from the network. The stylesheets included within the screen.css file are not saved, so when the user looks at the page offline, the content is not styled. One way around this is to have a post-production script that parses the screen.css file and includes all the referenced stylesheets into screen.css.

Another method to improve findability within our stylesheets was to use a marker that helped us search for comments in the files. Listing 2 shows an example of using an equals sign, something not used within the CSS syntax, in section comments. This idea was presented by Doug Bowman (see Resources) and is a very useful way of quickly finding sections of styles.

Another useful method was to place all styles in alphabetical order. This technique provides some consistency when searching for styles.


Listing 2. Findable comment in a CSS file
                
/* -----------------------------------------------------------------
 *	=announcement_summary
 * -----------------------------------------------------------------
 */
.announcement_summary {
	margin: 0 0 .8em 0;
}
.announcement_summary h3 a {
	font-size: 90%;
}

A browser will apply default styles to XHTML, which can cause confusion for the theme designer. We chose to normalize all the XHTML element selectors we knew we wanted to use by setting the margin and padding to zero, as shown in Listing 3. The styling of these elements is now more predictable. Another way is to apply zero margin and padding to everything using a * selector. However, we wanted to retain some control over what was affected.

Eric Meyer's Web site gives you more details about the effects of default styling of browsers. (See Resources.)


Listing 3. Normalizing margin and padding styles for selectors we want to use
                
p, ul, li, ol, dl, dt, dd, h1, h2, h3, h4, 
form, fieldset, blockquote, table, th, tr, td {
	margin: 0;
	padding: 0;
}



Back to top


Styling for accessibility

Part 7 describes some of the accessibility techniques we used in our content structure. In this section you'll see how we used CSS to style for accessibility. Of course, there are many facets to accessible design. Some are standard design criteria, such as creating enough contrast in your colors, providing enough leading in your typography, and placing enough white space around logical areas of content. These design practices are beyond the scope of this article. Instead, we'll focus on the major areas of styling used to meet the accessibility requirements of the IBC Web site.

Proportional sizing

By proportional sizing we mean using percentages and em units for container sizes, field lengths, font sizes, and so on wherever possible. This approach allows for the creation of fluid layouts with fonts that all resize proportionately. Another consideration is the way we need to style images so that they work effectively within a fluid layout.

Flexible fonts
Modern browsers are able to vary the default font size of a displayed Web page. This is very useful when a user needs to see more content within the browser viewport by decreasing the font size or to make a Web page more legible by increasing the font size. Figure 2 and Figure 3 show how the IBC site layout changes with a small and then a large font size.


Figure 2. Layout with a decreased font size
Layout with a decreased font size

Figure 3. Layout with an increased font size
Layout with an increased font size

The effect is not perfect, but the presentation still holds up well when the font is significantly altered from its default. A common implementation technique is to set one initial font size, then use percentages for any other font sizes further down the stylesheet.

As shown in Listing 4, at the top of our base stylesheet (base.css) we defined the styles, including the font size.


Listing 4. Setting initial font styles for the body selector
                
body {
	background: #fff;
	color: #333;
	font-family: Verdana, sans-serif;
	font-size: small;
	line-height: 1.5em;
	margin: 0;
	padding: 0;
}

For any further alterations of the font size, we used the percentage unit to preserve proportionality if the browsers default font size is changed by the user. For example, Listing 5 shows how we set the size of the font for the sidebar container.


Listing 5. Styling of the sidebar container in layout.css
                
#sidebar {
  background: transparent url(/themes/ibc/i/bg_sidebar_right.gif) no-repeat top right;
  float: right;
  font-size: 80%;
  line-height: 1.4em;
  width: 30%;
}	
	

So now the font size within the sidebar is 80% of the initial size, small. However, remember that when applying percentages to styles of child selectors, the units accumulate. For example, if we chose to set a font size for a content area within this sidebar to be 90%, then this would be 90% of 80% of the initially set size. Using percentages deeper into the Document Object Model (DOM) becomes less effective.

Fluid layout
Some content on the IBC Web site has the potential of being quite wide, so we wanted to use as much of the browsers viewport as possible. We decided to go with a fluid layout rather than a fixed width. Figure 4 and Figure 5 show how the layout changes with the size of the browser viewport.


Figure 4. Layout with a narrow browser viewport
Layout with a narrow browser viewport

Figure 5. Layout with a wide browser viewport
Layout with a wide browser viewport

This meant that we use percentages on the main layout container widths, such as the main content area and the sidebar. In the sidebar style in Listing 5, the width is set to 30%. The main content container, shown in Listing 6, uses a width of less than 70% to cater to the Microsoft® Internet Explorer box model width implementation.


Listing 6. Styling of main content container in layout.css
                
#content {
	clear: both;
	float: left;
	width: 67%;
}

There are many techniques of creating fluid multicolumn layouts. We chose to float both containers left and right. We provide a sensible readable minimum width and a sensible maximum width to provide a limit on the size of images used in the design. In Listing 7 you can see the styling used to do this in the layout.css file. The wrap container styled here is shown in Figure 1 in Part 7 of this series. Be aware that max-width and min-width styles are not universally implemented across browsers. Because we chose to float the sidebar, there comes a point when the sidebar will flip under the main content area when the width of the viewport is too narrow.


Listing 7. Limiting width styling in layout.css
                
#wrap {
	max-width: 1600px;
	min-width: 750px;
}

We also applied proportional sizing to elements such as BUTTON or submit type INPUT elements. For these elements we used em units instead of percentages for things such as margin, padding and width styles. Listing 8 shows how we styled submit type INPUT elements.


Listing 8. Styling of the submit type INPUT element, form-submit, in forms.css
                
input.form-submit {
	background: #fff url(/themes/ibc/i/bg_btn.gif) repeat-x bottom left;
	border: 1px solid #ccc;
	border-bottom-color: #999;
	border-right-color: #999;
	cursor: pointer;
	font-size: 79%;
	margin: 1em 0 0 0;
	padding: 0.25em;
	text-align: center;
	width: 6em;
}	
	

Figure 2 shows a good example of a form element changing dimension. The text field used in the search form at the top of the page increases in width as the font size is increased.

There may be situations where you need to wrap DIV or SPAN containers around to a form widget to access it from your CSS stylesheets. The Drupal forms API allows you to define content before and after the XHTML generated for each form widget using the #prefix and #suffix array elements. (See an example in Listing 11 of Part 6.)

Styling images in a fluid layout
As shown in Figure 2, Figure 3, Figure 4, and Figure 5, changes in font size and viewport width can have potentially dramatic effects on visual elements placed on the page. Some of this is overcome by using pure color in the background of containers, such as the black background of the navigation bar. As font size is increased, the height of the navigation bar increases. Styling this container with a black background color means we don't have to worry. Similarly, we can use a percentage or em unit on a border style dimension.

Another common technique is to repeat the rendering of an image in the background of an element in a horizontal or vertical direction. This way, any size change is accommodated, assuming the edges of the image merge into the background color defined. Figure 6 shows how the image creating the gradient in the BUTTON or submit type INPUT element expands to fill the larger dimension created by the increasing font size.


Figure 6. Background style effect remains consistent

Figure 7 shows how the styling in Listing 8 creates this flexible background image in the button.


Figure 7. Construction of the button in Figure 6
Construction of the button in Figure 6

The background color is set to white for the submit type INPUT element. An image is used in the background to provide a gradient to white. It is one-pixel wide and is positioned at the bottom left of the container. Using the repeat-x attribute, this image is rendered repeatedly horizontally filling the container. If the size of the container changes, the background image fills appropriately to create the desired effect.

This technique works well for simple gradients that need to expand and contract in a horizontal or vertical direction. However, for more complex images, such as the background for the sidebar, we use images purposely made larger than their default display area and position them appropriately. When the layout expands, a visible part of the image being shown is always visible. This technique has been popularized by Doug Bowman's sliding doors technique. (See Resources.) Figure 8 shows how the sidebar background widens as the browser view port is changed from narrow to wide.


Figure 8. Sidebar viewed in narrow and wide format
narrow and wide format

This effect is created by placing one container inside another and giving each of them a background. One forms the top right side and the other the top left side. Since the outside DIV element constrains the dimensions of the sidebar and the inner DIV is set to expand to the full size of its parent, the images will overlay each other exactly. One image is very wide but will be clipped to the width of the outer DIV, as shown in Figure 9.


Figure 9. Background images styled to create sidebar background
Background images styled to create sidebar background

The sidebar structure is shown in Listing 9. The outer DIV element with an ID attribute value of sidebar contains an inner DIV element with a class attribute called gutter. Within this, the content of the $sidebar_right region variable is displayed.


Listing 9. Containing structure of the sidebar in page.tpl.php
                
<div id="sidebar">
  <div class="gutter">
      <?php print $sidebar_right; ?>
  </div>
</div>
	

Listing 10 shows how we style these two DIV containers. The very wide image that forms the top right corner of the background is positioned in the top right of the sidebar container. The smaller image that forms the top left corner of the background image is positioned in the top left of the gutter container. If the width of the sidebar increases, the background images slide over each other (hence the name "sliding doors") revealing more and more of the lower image, seen in Figure 9. It appears as if the background graphic expands to fill the region. This employs the basic concept of layering background images that many techniques use.


Listing 10. Styling of sidebar background in layout.css
                
#sidebar {
  background: transparent url(/themes/ibc/i/bg_sidebar_right.gif) no-repeat top right;
  .
  .	
}
#sidebar .gutter {
  background: transparent url(/themes/ibc/i/bg_sidebar_left.gif) no-repeat top left;
  padding: 10px 20px 0 20px; 
}
	

Extra content for non-traditional browsers
This topic is discussed in Part 7. However, we still need to hide these extra items from view when using traditional browsers, so we apply a display: none style, with a class value of access, to these containers.



Back to top


Sectional styling

In Part 7 you saw how we implement our method of automatically setting a class value based on what section of the Web site is being displayed. This gives us a very useful hook onto which we can hang styles that change the look of a Web page on a section-by-section basis.

For the IBC site we wanted to preserve the basic layout throughout the Web site to reduce confusion for the IBC audience -- and to maintain visual consistency. However, using the primary palette we designed for the branding, we identified the major sections by changing the color of certain visual elements. Some of these elements are contained within the Web site banner, as shown in Figure 10. To achieve this effect we used CSS to change the background image of the banner, the icon next to the selected menu item, and the color of the bottom border.


Figure 10. Banners for each major Web site section
Banners for each major web site section

First we used a common technique of hiding the H1 element that presents the Web site title within the banner. (You can see this in Listing 1 in Part 7.) This way, we can use a background image instead, but still present the text heading when no style is applied. This is useful for print styling, which we discuss below. Listing 11 shows the method we used to hide the H1 text.


Listing 11. Providing an image for the site title in header.css
                
#banner {
	background: #ddd url(/themes/ibc/i/bg_header_home.gif) no-repeat top left;
	height: 100%;
	overflow: hidden;
	height: 61px;
}
#banner h1 {
	display: none;
}
	

A default background image is applied to the banner. The banner dimensions are fixed, but the height could have been made variable and the background image made much larger to provide another sliding doors effect if the text of the search form is increased in size. The H1 element is then hidden by taking it out of the flow altogether. Another way of hiding the H1 element is to move it out of the browser viewport using the style text-indent: --999em so that the text remains within the flow of the document.

Let's take the Workgroups section as an example. Since we know that the BODY elements class attribute value will be set to workgroup, we can style our banner elements accordingly. Listing 12 shows how the styles are altered to change the look for this section.


Listing 12. Workgroup section styles in workgroups.css
                
.workgroups #banner {
	background: #ddd url(/themes/ibc/i/bg_header_workgroups.gif) 
	            no-repeat top left;
}
.workgroups #nav_bar #pri_nav li#t_workgroups a {
	background: transparent url(/themes/ibc/i/icon_nav_workgroups.gif) 
	            no-repeat center left;
	color: #fff;
	font-weight: bold;
}
.workgroups #nav_bar #pri_nav li#t_workgroups ul li a {
	background: transparent url(/themes/ibc/i/icon_nav_bullet_workgroups.gif)
	            no-repeat top left;
	color: #d1d1d1;
}
.workgroups #nav_bar #pri_nav li#t_workgroups ul li a:hover {
	color: #fff;
}
.workgroups #nav_bar, .workgroups #nav_bar #pri_nav li ul {
	border-bottom: 6px solid #d50304;
}
.workgroups #footer {
	border-top: 3px solid #d50304;
}
	

You can see from the CSS that most of the styling occurs in the primary navigation UL element, shown in Listing 7 in Part 7. These styles modify the default styling found in the nav-bar.css file. In Listing 12 above, the background of the banner is changed to use the section-specific image. Then, the workgroup list item anchor background is changed so that what looks like the menu item bullet changes color. To add emphasis, the color and font weight is changed for this list item and any sub-level list items within it. The styling for the sub-level list items is also changed so that the background images used to create bullets appear in a corresponding color. This is a relatively simple level of sectional styling. Potentially, one could use CSS to alter the layout of a page more substantially.



Back to top


Navigation

The IBC primary navigation is dynamic. The structure of the navigation uses an unordered list of anchor elements. To achieve sub-menus, we embedded another level of UL elements. Listing 7 in Part 7 shows the XHTML. Using this method, the semantics of the navigation are preserved even when no styling is applied, as shown in Figure 11. It also allows us to use repeated images in the backgrounds of the anchor elements in the CSS. This makes adding new menu items easy and decreases download time.


Figure 11. Web site navigation with no styling
The web site navigation with no styling

CSS is used to create the effect of a drop-down menu with embedded UL elements. There are many references on the Web and in print explaining how to use CSS to achieve menu drop-downs. We chose the technique based on the Suckerfish Dropdowns. Listing 13 shows the style applied to the first level UL element.


Listing 13. Styling first level of unordered list items for the site navigation in nav-bar.css
                
#pri_nav {
	float: left;
	display: block;
	list-style: none;
	margin: 0;
	padding: 0 1em .5em 1em;
}
#pri_nav li {
	float: left;
}
#pri_nav li#t_home {
	width: 5.1em;
}
#pri_nav li#t_workgroups, #pri_nav li#t_workgroups ul li {
	width: 10em;
}
#pri_nav li#t_conferences, #pri_nav li#t_conferences ul li {
	width: 10em;
}
#pri_nav li#t_members, #pri_nav li#t_members ul li {
	width: 8em;
}
#pri_nav li a {
	background: transparent url(/themes/ibc/i/icon_nav.gif) 
	            no-repeat center left;
	border: 0;
	color: #d1d1d1;
	color: #e0e0e0;
	display: block;
	float: left;
	font-family: Arial, Helvetica, sans-serif;
	margin: 0;
	padding: 0;
	text-decoration: none;
	text-indent: 16px;
	text-transform: uppercase;
}
#pri_nav li a:hover {
	color: #fff;
}
	

The first two styling rules set up the UL element to display all the LI element children horizontally with no bullets. The next four styling rules set the widths on each of the LI elements representing the major sections of the sites. They also make sure that any embedded drop-down lists take on the same width. Figure 12 shows what the menu looks like with the first level UL element styled using the CSS above.


Figure 12. Navigation with only the first level UL element styled
Navigation with only the first level UL element styled

The first level items are presented appropriately. The embedded UL elements, however, need to be aligned correctly, styled with better bullet images and made to appear only when the mouse hovers over the LI that contains them. Listing 14 shows the CSS to style these embedded UL elements.


Listing 14. Styling embedded unordered list elements for site navigation in nav-bar.css
                
#pri_nav li {
	position: relative;
}
#pri_nav li ul {
	background: #000;
	border-bottom: 6px solid #666;
	left: -999em;
	margin: 0;
	padding: .7em .1em 0 .5em;
	position: absolute;
	top: 1.3em;
	width: 10em;
}
#pri_nav li:hover ul, #pri_nav li.over ul {
	left: 0;
}
#pri_nav li ul li {
	float: left;
	list-style: none;
	width: 10em;
}
#pri_nav li ul li a {
	background: transparent url(/themes/ibc/i/icon_nav_bullet.gif) 
	            no-repeat top left;
	border-top: 1px solid #333;
	display: block;
	font-size: 95%;
	padding-left: 12px;
	text-indent: 0;
	text-transform: capitalize;
	width: 9em;
}
#pri_nav li ul li a:hover {
	color: #fff;
}
	

The more interesting part of this CSS is contained within the first three styling rules. The first rule makes sure that we can position the embedded UL elements relative to the LI elements that contain them. The second styling rule positions the embedded UL element outside of the browser viewport using the left: -999em; style so they cannot be seen. We use absolute positioning here to take these UL elements out of the flow of the page so that their height is not added to the height of the containing elements. If relative positioning was used here instead, Figure 13 shows what will happen. The last three styling rules shown here align and style the text and provide new background images for the embedded items that represent the drop-down lists.


Figure 13. Using relative positioning for the #pri_nav li ul selector in nav-bar.css
Using relative positioning for the #pri_nav li ul selector

It is the third styling rule in Listing 14 that makes the illusion of the dropdown appear by moving the embedded UL element from outside of the browser viewport back to its aligned position under the LI element that contains it.

Now the styling of the dropdown is complete. Figure 14 shows what happens when the mouse hovers over the MEMBERS link.


Figure 14. Hovering the mouse over a link on the completed dropdown menu
Hovering the mouse over the members link on the completed dropdown menu

At the time of this writing, Internet Explorer (IE) did not support the hover pseudo class on an LI element. In Listing 14, you can see the selector #pri_nav li.over ul. The use of the over class is used by IE as a hook to reveal the embedded UL elements. These classes could be put manually into the navigation XHTML. Or, as based on the Suckerfish Dropdown technique, a simple bit of JavaScript can be triggered by the onload event to parse the DOM and insert the over class into the containing LI elements.



Back to top


Switching layouts

Communication and collaboration between individuals involved with IBC is important, and one of the requirements for the Web site is to provide different ways of viewing the member profiles. We use tabs to view IBC members by their company or Web site involvement. Providing photographs of each member, as shown in Figure 15, proved to be a valuable feature based on our user testing.


Figure 15. The photo layout of Web site members
The photo layout of web site members

However, the IBC site administrators found it easier to view a more traditional list view, as shown in Figure 16, which lets them see more user information faster.


Figure 16. The compact layout of Web site members
The compact layout of the web site members

While the content is essentially the same, the layout of the member data is substantially different. Since we could control both layouts using CSS, we chose to use a simple style-switching technique.

We already have one stylesheet that deals with the styling of the photo layout, members.css. To create a stylesheet to render the compact layout, we copied this into the same directory and renamed it to members_alt.css.

Since the alternate set of member styles can be grouped with our regular stylesheets, we copied the screen.css into the same directory and renamed it to screen_alt_members.css. In this file we replaced the include for the members.css, as seen in Listing 1, to members_alt.css.

To complete the process and present the alternative style to the browser, we added a new LINK element to the page head section in page.tpl.php. Listing 15 shows the LINK elements and how the title attribute distinguishes between the two.


Listing 15. Defining alternative styles in page.tpl.php
                
<link rel="stylesheet" 
      type="text/css" 
      media="screen" 
      href="themes/ibc/c/screen.css" 
      title="Default layout"/>
<link rel="alternate stylesheet" 
      type="text/css" 
      media="screen" 
      href="themes/ibc/c/screen_alt_member.css" 
      title="Alternate member layout"/>
	

The browser recognizes that there is an alternative way to style the Web site and lets you select this new presentation through the browser interface, as shown in Figure 17.


Figure 17. Switching styles through Firefox browser interface
Switching styles through Firefox browser interface

However, some browsers do not recognize alternate styles; we still need to present a visual clue on the member's section page indicating that the style can be switched and allow the user to activate the layout change. There are various ways to do this, but we chose to use a method based on the technique described by Paul Sowden. (See Resources.)

In the template that controls the layout of the list of member nodes, we added a couple of links. As shown in Listing 16, these anchor elements contain onclick triggers that call the setActiveStyleSheet JavaScript function.


Listing 16. Links to switch styles
                
<span class="actions common"><a 
   href="#" onclick="setActiveStyleSheet('Default layout');return false;" 
   title="Display the member information using member photographs">Photo layout</a>
</span>

<span class="actions common"><a href="#" 
   onclick="setActiveStyleSheet('Alternate member layout');return false;" 
   title="Display the member information using a compact layout">Compact layout</a>
</span>
	

The JavaScript parses the LINK elements with a media attribute of screen from the DOM and sets the disable attribute on whichever LINK elements do not match the title attribute passed by the setActiveStyleSheet function. This selection is stored in a cookie to preserve the state of the active stylesheet.



Back to top


Styling for print media

A lot of reference material is stored on the IBC site. Our initial user testing found that many IBC members preferred to print materials for offline viewing, such as conference agendas and session materials. Styling a printed version of the Web content was important. By using a print-media-specific style, we were able to create readable layouts on most printing devices.

The following two figures show how a conference page on the IBC Web site in Figure 18 is output using a print-media-specific stylesheet in Figure 19.


Figure 18. A conference page with agenda
A view of a conference page with agenda

Figure 19. Printed pages representing the Web page in Figure 18
Printed pages representing the Web page in Figure 18

A few things become apparent when styling for print media.

  • Testing using a real printer is costly and time consuming.

  • Usually, you don't have access to a wide range of printing devices for testing.

  • We wanted to take into consideration printing to a monochrome palette, which might have a limited spectrum of grays.

  • Highlight colors are sometimes so desaturated that a printer might not print them. Any highlighted information is lost. Alternative ways of presenting that information need to be created.

  • Most printing devices don't offer font sizing or zooming the way a Web browser does. A basic font size needs to be used that is readable for most people.

  • Information useful to a Web page, such as a hyperlink or a form, may not be useful on a printed page.

  • Since our Web page layout is fluid, a user can resize the browser viewport to create a more useful presentation. A standard printed page doesn't offer that flexibility.

  • A standard printed page presents real estate in a vertical aspect. Decisions need to be made about how content blocks, such as sidebar information, should be placed on the page.

  • Styling for print media is not as completely implemented in modern browsers as we thought. Therefore, tradeoffs were made when doing things like page breaks using the page-break-before, page-break-inside and page-break-after styles. In one version of a well-used browser, the use of a page break crashed the application.

Creating a print media stylesheet

For our purposes, we created a new stylesheet called print.css in the same directory as our other stylesheets. To present this stylesheet to the browser, we added another LINK element before those shown in Listing 15 into the page.tpl.php template file. Listing 17 identifies the purpose of this stylesheet by setting the media attribute value to print.


Listing 17. Including the print-media-specific stylesheet in page.tpl.php
                
<link rel="stylesheet" 
      type="text/css" 
      media="print" 
      href="themes/ibc/c/print.css" />
	

Of course, if we had defined our screen.css with a media attribute value of all and placed this LINK element after it, our print styling would have inherit all the screen styles. To give ourselves more control, however, we decided not to do this.

Printer-friendly content

Let's use an IBC Announcement page as an example of how we made our print style decisions. Figure 20 highlights the Web site title and the actual content of the announcement because they translated well to the print media. The rest of the page presents links that offer no further function other than to hide information on the Web site, provide links to those pieces of information, or trigger actions on those pieces of information.


Figure 20. The title (A) and content (B) translate well from Web page to printed media
The title and the content translate well from the Web page to printed media

The power of semantic markup

You could imagine that for a new media type, everything needs to be restyled yet again. However, this is where using the correct XHTML element to provide semantic meaning to the content really reaps some rewards. Figure 1 shows how the unstyled site looks, without the banner, search bar, accessibility information, navigation, and sidebar. This creates a very clean printable representation of the Web site. The proper use of markup makes for readable content and doesn't require much restyling to create a reasonable print media output that should work on most print devices.

A basic layout

So how do we start to create our print styling? The first thing we did was to define a basic font family and font size. While we could have defined the background color, font color, and margins, we left this to the default settings of the printing device. The next thing was to hide those areas of the Web page not useful for print media. As highlighted in Figure 20 above, we used only the site title and the main content area of the page. Listing 18 shows the basic styles with which we started.


Listing 18. Basic print style used in print.css
                
body {
	font: 12pt Georgia, "Times New Roman", Times, serif;
}
#nav_bar, #sidebar, #footer {
	display: none;
}
.action, .more, .return_top, .tabs, .index {
	display: none;
}
	

The font style uses a value of 12pt, which is a common print media size. We chose standard serif fonts for readability. The second and third styling rules hide those parts of the content that did not need to be in the printed document.

Testing print styles

Testing print styles using the print devices available to you is a good idea. However, given the number of iterations you might have to go through to get the presentation you want, you may end up wasting a lot of time waiting for printouts and spending more money on paper than you'd like. A better way is to use the print preview option commonly available across most browsers, as shown in Figure 21.

We found there were some variances in the way browsers applied print styles, but these differences were far fewer than those encountered for screen media. Plug-ins such as the Web Developer extension for Firefox (see Resources) allow you to view a Web page using the different media types that are defined in the XHTML. However, we found that the print preview option presented a more reliable representation of how a printed page might look. The real test, of course, is to actually print your Web page. At least this way, you can do so only when you think the page looks good in the preview.


Figure 21. Print preview of an announcement
Print preview of an announcement

Tweaking the print style

You can quickly get to a reasonable print representation of the Web content, but we found there were a lot of little things that could improve readability. For example, applying a border style to a heading could help readability. The following list shows examples of the modifications applied to the print style of the IBC site.

White space
The default print styling of a browser will create a fairly readable document. However, we found that some margins between elements were not ideal. For example, we ended up increasing the white space around paragraphs to help readability. Listing 19 shows the style applied to the P element to adjust the spacing above and below a paragraph.


Listing 19. Paragraph tweak in print.css
                
p {
	margin: 0.2em 0;
}
	

Links
We mentioned that links don't present useful information in a print media context. This is debatable, depending on the needs of your readers. You might want to add emphasis to a word or phrase that is hyperlinked to another Web document. This should probably be an underline, since bold and italicized texts are common print emphasis techniques and may confuse the meaning of the content. Color might be considered and is discussed below. Another technique is to print the URL of the link after the associated text. Listing 20 shows how we used the after pseudo element and content style to display the URL of the link.


Listing 20. Display a URL after its link text
                
a:link:after, a:visited:after {
	content: "[link:"attr(href)"]";
	font-size: 90%;
}
	


Figure 22. IBC link on a Web page and in print
An IBC link on a web page and in print

If a relative URL is used in the XHTML link, then the readability of the printed version may be confusing to a reader. An absolute URL, http://intbizcouncil.org:96/forum, means more in this context than a relative one, forum.

Colors
We wanted the IBC content to print well on as many printing devices as possible, so we wanted to control the way a color might print. An example is the banding used to identify alternate rows on tabular data, or to emphasize parts of a conference agenda. We could have used the same color definitions as the screen styling, and left the defaults of the print device to work out the grayscale shade. By defining the color in our styling, however, we could at least make an effort to define a better shade of gray.

Another use of color was to show the status of some entity, such as an IBC member. On the Web site a member only visible to the operations staff would be highlighted with a color. Translating this to the printed page, we use a similar technique shown in Listing 21 to add some clarifying text, as shown in Figure 23.


Listing 21. Display the status of an invisible IBC member
                
.member_summary.hl_red .fn:before {
	content: "(Not visible) ";
}
	


Figure 23. Nonvisible IBC member on Web page and in print
Nonvisible IBC member on Web page and in print

Hidden and linked information
Hiding and revealing content using CSS is very easy and can provide useful methods of including information in printed content that might otherwise be presented on a different page. Two examples are the accessibility content explaining the alternate keys and the conference agenda page.

The node object given to the template file that structured the layout of the conference page includes not only the agenda, but summaries about things such as the logistics of getting to a conference location. In the screen-media-specific stylesheet (conference.css), we hid the logistics summary in a DIV element but provided a link to a separate page that held the logistic details. In the print-media-specific stylesheet, the logistics summary information is displayed, giving the reader more information on the page about the conference. However, this may present some interesting design discussions about consistent presentation of information.

Page breaks
The presentation of some information might require the logical separation between pages. Page break styles, page-break-before, page-break-inside, and page-break-after, provide a way to force this condition within your CSS.

We used a page-break-before style for each table containing the agenda for a day. The printed effect was very readable but, unfortunately, on the version of browser popular at the time of testing, it crashed the entire application. We think this bug has since been fixed, but this raised our awareness that some print style features are still not fully implemented.



Back to top


Anticipation and testing

Styling a Web site with dynamic content is not a trivial exercise. A Web site containing static content provides a very stable base on which to apply your CSS. There is no unexpected content changing the structure of your XHTML and, potentially, the effect of the CSS. For example, a content editor of the IBC site might decide that they want to cut and paste some text from a document they just read into a field in a new announcement. A theme designer cannot possibility predict what this pasted content will be! Is this content structured so that any XHTML tags aren't left open? Does it exceed a certain length, so that the presentation of that text doesn't overflow into some other element on the page? Are there any special characters in this content that will not be rendered correctly on the page? At some level there's a compromise, and using things like maximum field lengths and tinyMCE for controlling user input can help. But, surprises happen.

As you add more roles to your system and use these roles as a way of changing what the user sees, you add an extra dimension of changeability to the content structure and presentation. So how can you lessen these surprises? If a theme designer cannot predict exactly how the content structure changes, then they can try to predict at least 80% of the scenarios through anticipation and testing.

In Part 7 we discuss effective containers that provide logical separations for the semantics of our content. For a site containing static content, the id or class attributes applied to these containers might be all you need to style this content. However, when styling a site whose content can change, theme designers will typically need to iterate on the content structure in the templates to add more id and class attributes, or additional containing DIV and SPAN elements to control the presentation. Many of these iterations can be lessened by anticipating the effects of changing content. The template used for the Zen Garden is a great example. (See Resources.)

Testing

To test for these anticipated effects we need data, users, and their applied roles. Populating your Drupal site with test data helps, but at this stage of development you should be able to use real data that can seed your Web site. Of course, if you are redesigning a Web site, there will probably be enough real data to migrate from the old site to seed the Drupal database. For the IBC site, this was the stage in our process where we asked the client to start entering real data. Not only did this supply us with the data we needed to start our styling of the theme, but it also provided:

  • Education on the Drupal administration interface
  • Testing of any new modules
  • Refinement of structural layout of content
  • Valuable prerelease feedback from the client
  • A feeling of involvement by the client



Back to top


Summary

In this article you learned how to take a semantically structured Web site and apply styling techniques using CSS to achieve the screen and print styles desired. You also learned how the team organized its stylesheets, several standards-based styling techniques, and testing methods.

The next article in this series describes the Drupal database abstraction layer, and how DB2 Express-C could be used as an alternative to MySQL or PostgreSQL.



Resources

Learn

Get products and technologies

Discuss


About the authors

Alister's photo

Alister Lewis-Bowen is a senior software engineer in IBM's Internet Technology Group. He has worked on Internet and Web technologies as an IBM UK employee since 1993. Alister was brought to the U.S. to work on the Web sites for the IBM-sponsored sports events, then as senior Webmaster for ibm.com. He is currently helping create semantic Web prototypes. Contact Alister at alister@us.ibm.com.


Stephen's photo

Stephen Evanchik is a software engineer in IBM's Internet Technology Group. He has been a contributor to many open source software projects, the most notable being his IBM TrackPoint driver in the Linux kernel. Stephen is currently working with emerging semantic Web technologies. Contact Stephen at evanchik@us.ibm.com.


Louie's photo

Louis Weitzman is a senior software engineer in IBM's Internet Technology Group. For 30 years he has worked at the intersection of design and computation. He helped develop an XML, fragment-based content management system in use by ibm.com, and currently is involved with bringing the design process to emerging projects. Contact Louis at louisw@us.ibm.com.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top