A List Apart

Menu
Issue № 191

Cross-Column Pull-Out Part Two: Custom Silhouettes

by Published in CSS, Layout & Grids · 38 Comments

Warning: Experimental/controversial content. Proceed with caution.

The cross-column pull-out gave us a new technique for marking up a layout with a pull-out positioned between columns. Now we examine a variation of the technique for wrapping around the edges of a non-rectangular image positioned between columns. But first we need to update the original technique.

Upgrading the cross-column pull-out

After ALA published Cross-Column Pull-Out Part One, Daniel Sheppard shared a technique that lets us avoid character counting, the most cumbersome part of the original method. Let me briefly explain this new technique.

XHTML:


<div id="leftCol" class="col">
  <div class="preImageBuffer"></div>
  <span class="CCspace"> </span>
  <p>…</p>
  </div><div id="rightCol" class="col">
  <div class="preImageBuffer"></div>
  <span class="CCpullout">
    <del> [Pullout: </del>
    <span>
      <img src="monkey.jpg" alt="" />
      The office monkey, riding the office camel.
    </span>
    <del>] </del>
  </span>
  <p>…</p>
</div>

CSS:

.CCspace {… clear:right;}
.CCpullout {… clear:left;}.preImageBuffer {height:9em;width:1px;}
#leftCol .preImageBuffer {float:right;}
#rightCol .preImageBuffer {float:left;}

Identify both columns using leftCol and rightCol. Remove the CCspace and CCpullout from the middle of the content. Put it before all of the paragraphs. Make sure you add the preImageBuffer DIV prior to the CCspace and CCpullout in the columns. Make adjustments to the CCspace by adding a clear: right; and CCpullout by adding a clear: left; Add the three new CSS lines .preImageBuffer and the information about the left and right columns.

To adjust the location of the pullout in the content, simply change the height in .preImageBuffer (height is in EMs.) Now we have the ability to change the vertical height of the pull-out without character counting!

Example 0 — The fixed cross-column pull-out

The only design error is on IE 5 on a Macintosh, which we’ll get to later. Now that we’ve improved the core technique, we can move on to the fancy stuff.

Setting the stage for the silhouette

To begin, you will need a GIF or PNG with a transparent background. Our test subject is the Office Monkey: monkey.gif. (Note: We’ve added a border here to show that the background is transparent.)

monkey

The goal of the silhouette is to wrap the text around our diamond-shaped graphic. As in the basic cross-column pull-out, we’ll start with two columns and the image will be placed at the top of the second column, right after the preImageBuffer.

XHTML:

<div id="overall">
   <div id="leftCol" class="col">
      <div class="preImageBuffer"></div>
      <p>…</p>
      <p>…</p>
   </div>
   <div id="rightCol" class="col">
      <div class="preImageBuffer"></div>
      <span class="CCsilhouette">
        <span>
          <img
            src="monkey.gif"
            alt="Office Monkey" />
        </span>
      </span>
      <p>…</p>
      <p>…</p>
   </div>
</div>

CSS:

* {
  margin: 0;
  padding: 0;
}
p {
  padding: 0.625em 0;
  text-align: justify;
  line-height: 20px;
}
#overall {
  width: 755px;
  margin: 0 auto;
}
.col {
  width: 365px;
  padding: 0 5px;
  float: left;
}
.CCsilhouette {
  float: left;
  clear: left;
  margin-left: -180px;
}
.CCsilhouette span {
  position: absolute;
}
.preImageBuffer {
  height:9em;width:1px;
}
#leftCol .preImageBuffer {
  float:right;
}
#rightCol .preImageBuffer {
  float:left;
}

Perhaps the most important piece to this CSS is in the

where we set the top and bottom margin to 0.625 pixels and the line height to 20 pixels. This standardizes the text to allow us to position the silhouette in a more predictable manner.

Figure 1: Example 1

monkey

Preserving silhouette space

The image is in the middle of both columns, but the text is not wrapping yet, so we need to make room for our pull-out. Unlike the original cross-column technique, this method floats only small sections of the text at a time. Let’s start by adding space to the leftCol.

XHTML:

<div class="preImageBuffer"></div>
<span class="LS1"> </span>

CSS:


.LS1 {
  /*  Float the <span> right and clear it right.  
   */
  float: right; clear: right; 
  /*
    The height will be arbitrary based on the
    section of the image that you want to float
    text around.
  */
  width: 50px; height:40px;
  /*
    Use a background color to see the space you
    are creating. Remove it later.
  */
  background: #f00;
}

Figure 2: Example 2

monkey

By using height increments of 20 pixels (same as the line-height in the <p>), we are able to wrap the text a line at a time (20px = 1 line; 40px = 2 lines; etc). You can see the space with the background color turned on. Use it until you have the space you desire. Then remove the background color.

Finishing the first column

One space down and a bunch to go! Let’s add some more spans right after the first. The number of spans is based on the image that you have and how close you want the text to float to the image.

XHTML:

<div class="preImageBuffer"></div>
   <span class="LS1"> </span>
   <span class="LS2"> </span>
   <span class="LS3"> </span>
   <span class="LS4"> </span>
   <span class="LS5"> </span>
   <span class="LS6"> </span>
   <span class="LS7"> </span>
<p>…</p>

Putting carriage returns after the <span> doesn’t alter the effect and it makes it a lot easier to spot when editing code.

CSS:

.LS1, .LS2, .LS3, .LS4,
.LS5, .LS6, .LS7
{
  float: right; clear: right;
}
.LS1 {width: 50px; height:40px; background: #f00;}
.LS2 {width:100px; height:40px; background: #0f0;}
.LS3 {width:140px; height:40px; background: #00f;}
.LS4 {width:170px; height:60px; background: #f00;}
.LS5 {width:140px; height:40px; background: #0f0;}
.LS6 {width:100px; height:40px; background: #00f;}
.LS7 {width: 50px; height:40px; background: #f00;}

To make things more visible for the example, there are different background colors to show the location of each <span>. (Note: The class name LS stands for “left side” and is arbitrary.)

Figure 3: Example 3

monkey

The second column

The technique is similar for the second column, rightCol, but there is one minor change in the XHTML:

XHTML:

<div class="preImageBuffer"></div>
<span class="RS1">
   <span class="CCsilhouette"><del> [Pullout: 
      </del>
      <span>
        <img
          src="monkey.gif"
          alt="Office Monkey" />
      </span>
      <del> ] </del></span>
</span>
<span class="RS2"> </span>
<span class="RS3"> </span>
<span class="RS4"> </span>
<span class="RS5"> </span>
<span class="RS6"> </span>
<span class="RS7"> </span>

The trick is to make the very first space (RS1) have the pull-out (CCsilhouette) as a child. We do this to make IE on the Macintosh behave better. It still doesn’t completely solve the problem, but without the pull-out nested in the first space, the text would be nearly impossible to read in IE 5 Mac. The rest of the spacer <span> behaves as the first column. (Note: RS stands for “right side.”)

CSS:

.RS1, .RS2, .RS3, .RS4,
.RS5, .RS6, .RS7
{
  float: left; clear: left;
}
.RS1 {width: 50px; height:40px; background: #f00;}
.RS2 {width:100px; height:40px; background: #0f0;}
.RS3 {width:140px; height:40px; background: #00f;}
.RS4 {width:170px; height:60px; background: #f00;}
.RS5 {width:140px; height:40px; background: #0f0;}
.RS6 {width:100px; height:40px; background: #00f;}
.RS7 {width: 50px; height:40px; background: #f00;}

As you look through the CSS, you will realize that the image being used is symmetrical. The heights and widths are the same as the first column, so the CSS could be optimized. This exercise is left up to the designer, and will not be true when dealing with odd shaped and non-symmetrical images.

Figure 4: Example 4

monkey

Recap of the cross-column silhouette pull out

To finish the pull-out, remove all references to the background colors from the CSS.

Figure 5: Example 5

monkey

This particular technique works great in most browsers. IE on a Macintosh has some issues with spacing, but the error is tolerable. (The design forces space above the image as in Figure 6.)

Figure 6: the design error for IE on a Macintosh

monkey

Please be aware of this discrepancy as you decide whether to use this technique.

There are a few points that should be made clear. Remember to keep the non-breaking spaces ( ) in the <span> tags. Though it doesn’t fix IE on a Macintosh, it does make it a bit more presentable. The choice to make the pull out an image instead of a background image is up to the designer. If you desire a background image, then add the CSS to the .CCsilhouette span.

Once again, I want to thank my students Matthew Latzke for his assistance and Andrew Assarattanakul for helping discover and resolve the nesting problem for IE on a Macintosh. Most importantly, I want to thank Daniel Sheppard who helped eliminate the character counting and showed us how to use the preImageBuffer.

Completed Code

XHTML:

<div id="leftCol" class="col">
   <div class="preImageBuffer"></div>
   <span class="LS1"> </span>
   <span class="LS2"> </span>
   <span class="LS3"> </span>
   <span class="LS4"> </span>
   <span class="LS3"> </span>
   <span class="LS2"> </span>
   <span class="LS1"> </span>
   <p>…</p>
</div><div id="rightCol" class="col">
   <div class="preImageBuffer"></div>
   <span class="RS1">
      <span>
        <img
          src="monkey.gif"
          alt="Office Monkey" />
      </span>
   </span>
   <span class="RS2"> </span>
   <span class="RS3"> </span>
   <span class="RS4"> </span>
   <span class="RS3"> </span>
   <span class="RS2"> </span>
   <span class="RS1"> </span>
   <p>…</p>
</div>

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;
}
.CCsilhouette {
  float: left;
  clear: left;
  margin-left: -180px;
}
.CCsilhouette span {
  position: absolute;
}
.preImageBuffer {
  height: 9em;
  width: 1px;
}
#leftCol .preImageBuffer {
  float: right;
}
#rightCol .preImageBuffer {
  float: left;
}
.LS1, .LS2, .LS3, .LS4 {
  float: right; clear: right;
}
.RS1, .RS2, .RS3, .RS4 {
  float: left; clear: left;
}
.LS1, .RS1 {
  width: 50px; height:40px;
}
.LS2, .RS2 {
  width:100px; height:40px;
}
.LS3, .RS3 {
  width:140px; height:40px;
}
.LS4, .RS4 {
  width:170px; height:60px;
}

Additional examples

Example 6—Non-symmetrical variation

Example 7—Double face (or is it a vase?)

Enjoy!

38 Reader Comments

Load Comments