A List Apart

Menu
Issue № 190

Cross-Column Pull-Outs

by Published in CSS, Layout & Grids · 64 Comments

Editor’s Note: The following technique accomplishes its goals by using a few markup elements that lack innate semantic value. For some of you, that may place this means of achieving cross-column pull-outs beyond the pale. For the rest of you, bon appetit.

Print designers have long relied on the ability to wrap text around anything — most commonly around a picture centered between two columns. This design option has not been available for web designers ... until now.

Basic two-column layout

Article Continues Below

To use this technique, we must first set the stage.

XHTML:

<div id="overall">
   <div class="col">
      <p>…</p>
      <p>…</p>
   </div>
   <div class="col">
      <p>…</p>
      <p>…</p>
   </div>
</div>

CSS:

* {margin: 0; padding: 0;}
/*Override defaults for all tags. */
p {padding: .625em 0; text-align: justify; 
  line-height: 20px;}
#overall {width: 755px; margin: 0 auto;}
.col {width: 365px; padding: 0 5px; float: left;}

This makes an “overall” container with two columns with a 10-pixel gutter between them. Setting the line height and padding allows for more uniform display in browsers.

Preserving space

The next thing is to make room for our pull-out. The concept is this: make room in the first column to allow the pull-out to step over its boundaries from the second column. This will give the illusion that we desire.

To do this, put a container in the middle of the first paragraph and float it to the right. It needs to have the same height as the image, and half the width of the image (350 x 300 pixels). Text will wrap around it since it is a floated element.

XHTML:

<p>…parturient  
  montes,…

There are numerous tricks in that simple span:

  • Use a span instead of a div. We are inside a paragraph, and a block level element (div) can not be a child of an inline element (

    ).

  • Use a class attribute instead of an id so you can do more than one pull-out on a page (if the images are the same size).
  • Use a non-breaking space as the content of the span. (This fixes a problem with IE 5.2 on a Macintosh.)
  • Make sure you do NOT have a space between the prior word and the span (example: parturient

CSS:

.CCspace { width: 175px; height: 315px; 
/*Set the width to half of the image and set the 
  height to the image height plus a little room 
  for the caption. */
float: right; padding: 5px;} 
/*Float the span right and include any padding. */

Figure 1: Example 1 In this figure, space has been created for the pull-out in the left column, but not the right.

Inserting the pull-out

Next, we need to put a container in a paragraph in the second column to hold an image and its caption information.

XHTML:

<p>… condimentum
    The office 
  monkey, riding the office camel. 
sit amet, …

As before, use a span instead of a div because we are inside a paragraph and we want the XHTML to validate. The class attribute enables reuse. Again, make sure you do not have a space between the word and the span (example: condimentum and the caption.

CSS:

.CCpullout { width: 350px; height: 315px;
/*Set the width and height of the span 
  to the image size. */
float: left; padding: 5px;
/*Float the span left and give it the 
  same amount of padding as CCspace. */
margin-left: -185px;
/*Move the image into the first column by negative 
  margin. The number is half the width of the  
  image (175px) plus the gutter (10px). */
text-align: center; font-size: .9em; 
  font-weight: bold; }
/*Add styling to the caption text*/

The real trick to this technique is lining up the “CCspace” (first column) and the “CCpullout” (second column). The solution is to do some quick character counting. Highlight the text from the beginning of the paragraph up to “CCspace.” There are 294 characters. Go to the second column and try to find a space in the first paragraph that is as close to possible to 294 characters. In the example, there is room after 292 characters, so the “CCpullout” sits in that space right after the word “condimentum.” You may need some minor adjustments, but this technique works well within a two-character (+/-) range.

This example works in the current releases Mozilla, Netscape, Safari, Camino, Konqueror, and in IE 5.2 on a Mac. The most noticeable problem is IE on a PC, which displays the following.

Figure 2: Example 2 A half-functional cross-column pull-out -- the left half of the picture is missing, but the appropriate amount of space has been allocated for the image

Cooking for picky eaters (IE and other bugs)

Warning: If you must make the design work in Netscape 4, then use the “@import” CSS rule to hide this design and protect the browser. Netscape 4 doesn’t play well with CSS and should be handled delicately.

To fix the remaining issues, we need to add some more information to the “CCpullout” and adjust the CSS.

XHTML:

<span class="CCpullout">
  
    The office 
  monkey, riding the office camel. 
  

By nesting another span inside the “CCpullout” we can remedy the problems with CSS.

CSS:

.CCpullout {width: 350px; height: 315px; 
  padding: 5px; float: left; margin-left: -185px;}
/*Note the removal of the caption styling.*/.CCpullout span {width: 350px; position: absolute;
/*Set the width of the nested span to the image 
  width. Position the span absolutely, so it 
  will appear in IE for the PC. */
text-align: center; font-size: .9em; 
  font-weight: bold;}
/*Caption styling appears at this level.*/

Figure 3: Example 3 Example of a fully functional cross-column pull-out

Accessibility

There is one big concern with this technique. We’re interrupting the flow of a paragraph with additional and potentially unrelated content. What happens when a screen reader hits this?

We need to identify the pull-out for screen readers so that users will understand what’s going on. This requires additional information in the content and styling.

XHTML:

<span class="CCpullout">
    [Pullout: 
   
    The 
   office monkey, riding the office camel.    
   
   ] 

By inserting another inline element, such as the del, we can make the screen reader aware that something different is about to happen. The square brackets “ [  ] ” are used to indicate that something different is being read. Any special character could be used, but make sure it’s different enough so the screen reader user will notice the change in content. Make sure you put a space before and after the square bracket so the del doesn’t become part of the word immediately before it (example: [Pullout: …). We then use CSS to hide the information in the pull-out.

CSS:

.CCpullout del {font-size: 0px; color: #fff; 
  position: absolute;}

We want to hide the content from the computer while allowing the screen readers to read the information. A solution is to make the font zero pixels high and use a color that matches the background of the page since some browsers force a one-pixel minimum size. The last part of this trick is to remove the inline del from content flow. This can be achieved with absolute positioning. (Note: Using “display: block;” gave an unexpected display error in Konqueror.)

Using the del tag in this way is arbitrary and not particularly semantic. Another span could take care of that issue, but it would have to contain a class, etc. or another tag entirely could be used as long as it was an inline element.

The example was tested with the JAWS screen reader; it did not read a style of “visibility: hidden;” nor a “display: none;” which is why neither technique is used. A large negative left margin was unstable in some user agents. The bottom line is that JAWS is able to read the content inside del with this technique, yet it remains invisible to browsers. It reads as follows:

… condimentum Left bracket. Pullout Colon The office monkey, riding
the office camel. Right bracket. sit amet, …”

That’s not perfect, but it’s a lot better than just surprising screen reader users with unexpected content.

Another accessibility option is to avoid the use of an image and a caption. Use CSS to make the image appear as a background in the child span. It’s less messy, and the screen readers will skip over it entirely since it would then be a design element.

Review of the cross-column pull-out technique

This technique is a bit picky when you try to line up the span tags in both columns — but it gives us the option to use a cross-column pull-out on a web page. The CSS validates. The XHTML validates Strict 1.0. The page even prints correctly with the pull-out. The pull-out will scale with text size adjustments in the user agent (Note: major adjustments to text size could break the design.)

I want to thank my student Matthew Latzke for his assistance and hard work helping to develop this technique! We’ll be back soon to explain the next version: “Cross-Column Pull-Out Part Two: Custom Silhouettes.”

Completed Code

XHTML:

[Column 1 paragraph]

<p>…parturient  
  montes,…

[Column 2 paragraph]

<p>… condimentum
    [Pullout: 
    The office 
   monkey, riding the office camel.] 
  
 sit amet, …

CSS:

* {margin: 0; padding: 0;}
p {padding: .625em 0; text-align: justify; 
  line-height:20px;}
#overall {width: 755px; margin: 0 auto;}
.col {width: 365px; padding: 0 5px; 
  float: left;}
.CCspace {width: 175px; height: 315px; 
  padding: 5px; float: right;}
.CCpullout {width: 350px; height: 315px; 
  padding: 5px; float: left; margin-left: -185px;}
.CCpullout span {width: 350px; position: 
  absolute; text-align: center; font-size: .9em; 
  font-weight: bold;}
.CCpullout del {font-size: 1px; color: 
  #fff; position: absolute;}

Additional Examples

Example 4 — Double-column image pull-out.
Example 5 — Double-column pull-quote.
Example 6 — Three-column double pull-out.
Example 7 — Three-column single pull-out (Fails in IE 5.2 Mac).

Enjoy!

64 Reader Comments

Load Comments