Ask the Guru: How do I make text flow around complex images

October 18th, 2006

In the the first of FFE’s (From the Front End’s) “Ask the Guru” features we look at shaping text so it flows nicely around images, even if the user is viewing your page with a different text size or browser than you.

Guru: Well a valid question asked have you!

Here we see an example (click any of the example images to view the XHTML page):
Fig 1a
Download the example files here

There is not 1 but 3 possible solutions!

The recommended technique is not to try and bend the spoon, but realise - there is no spoon. What I mean is - don’t think about how to get your text to bend around your complex image instead set the image as the background of whatever a div that contains the text.
Example:

<div id="wrapper">
<h1>Ask the Guru: How do I make text flow around complex images</h1>
<div id="flowingtext">
<img src="../imageadds/compleximage.jpg" alt="complex image" width="171" height="300" />
<p>In reprehenderit in voluptate quis nostrud exercitation consectetur adipisicing elit. Ut labore et dolore magna aliqua. Cupidatat non proident, ut aliquip ex ea commodo consequat. Velit esse cillum dolore qui officia deserunt excepteur sint occaecat. Ullamco laboris nisi ut enim ad minim veniam, ut aliquip ex ea commodo consequat.</p>
<p>Sed do eiusmod tempor incididunt lorem ipsum dolor sit amet, qui officia deserunt. Duis aute irure dolor sunt in culpa. Consectetur adipisicing elit, lorem ipsum dolor sit amet, ut labore et dolore magna aliqua. Ut aliquip ex ea commodo consequat.</p>
<p>Velit esse cillum dolore sunt in culpa in reprehenderit in voluptate. Ut enim ad minim veniam, eu fugiat nulla pariatur. Excepteur sint occaecat ut labore et dolore magna aliqua. Consectetur adipisicing elit, mollit anim id est laborum.</p>
</div>
</div>


The stylesheet linked to this document contain the following styles:

body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 16px;
font-weight: normal;
color: #000000;
}
#wrapper {
width: 700px;
margin: 0 auto;
}
h1 {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 100%;
font-weight: bold;
color: #003366;
text-align: center;
}
img {
float: right;
}

You can see I’ve named the div “flowingtext”. You can name this whatever you want, but this is the box that will contain the image and text.

Now delete the reference to the image from your html.

Next open your style sheet and add the following styles to your div.

#flowingtext {
background-image: url(../imageadds/compleximage.jpg); /* replace with path to your image */
background-repeat: no-repeat;
background-position: top right;
height: 350px;
/* because user can change the size of the text we need to set a height so the image doesn’t get cropped */

}

Looking back at our page you should have something like this.

Fig 1b

Not quite what you had in mind?
Well here is where the fun begins. Using the clear.gif (a 1px1px transparent GIF file in the example downloadable tutorial files) we will force the text to move.

The more complex the shape the more times we will need to use the image. Insert the images before the text as shown here:
….
<div id="flowingtext">
<img src="../imageadds/clear.gif" />
<img src="../imageadds/clear.gif" />
<img src="../imageadds/clear.gif" />
<img src="../imageadds/clear.gif" />
<img src="../imageadds/clear.gif" />
<img src="../imageadds/clear.gif" />
<img src="../imageadds/clear.gif" />
<img src="../imageadds/clear.gif" />
<p>In reprehenderit in voluptate quis nostrud exercitation consectetur adipisicing elit. Ut labore et dolore magna aliqua. Cupidatat non proident, ut aliquip ex ea commodo consequat be. Vel esse cillum dolore qui officia deserunt excepteur sint occaecat. Ullamco laboris nisi ut enim ad minim veniam, ut aliquip ex ea commodo consequat.</p>

Next update the style sheet:

#flowingtext {
background-image: url(compleximage.jpg)
/* replace with path to your image */
background-repeat: no-repeat;
background-position: top right;
height: 350px;
}

#flowingtext img {
float: left;
border: 1px solid blue;
}

I’ve made the complex image (the cat) a background image and aligned it to the top right. I have also added a ble border around all other images so we can see the invisible clear.gif

Next in your browser try to work out how far you will need to push text back to clear the top part of the image. In this case the little curl at the top of the cats tail. Measure from the right edge of the image rather from where the text stops. If you have FireFox then either the extention - measureIt or the measuring tool in the webdeveloper toolbar will help a lot. Internet explorer also has it’s own version of the web developer toolbar available. Failing that estimating and correcting through trial and error will do just fine.

Once you’ve figured out the width the first clear gif needs to be, work out how far down you can go with the same width before text will need to start getting closer or further from the image. Set these values as the width and the height.

Do this for each clear.gif. Add more gifs if needed. I personally don’t measure the shape of each GIF as I go along. Once I’ve measured and set he first one I can fairly accurately estimate the size of the next one. With the help of the blue border I can see when I’ve got it just right.

You code should eventually look something like this.

<h1>Ask the Guru: How do I make text flow around complex images</h1>
<div id="flowingtext">
<img src="../imageadds/clear.gif" width="172" height="47" />
<img src="../imageadds/clear.gif" width="158" height="20"/>
<img src="../imageadds/clear.gif" width="140" height="20"/>
<img src="../imageadds/clear.gif" width="135" height="40"/>
<img src="../imageadds/clear.gif" width="140" height="60"/>
<img src="../imageadds/clear.gif" width="135" height="30"/>
<img src="../imageadds/clear.gif" width="130" height="30"/>
<img src="../imageadds/clear.gif" width="70" height="30"/>
<p>In reprehenderit in voluptate quis nostrud exercitation consectetur adipisicing elit. Ut labore et dolore magna aliqua. Cupidatat non proident, ut aliquip ex ea commodo consequat be. Vel esse cillum dolore qui officia deserunt excepteur sint occaecat. Ullamco laboris nisi ut enim ad minim veniam, ut aliquip ex ea commodo consequat.</p>
<p>Sed do eiusmod tempor incididunt lorem ipsum dolor sit amet, qui officia deserunt. Duis aute irure dolor sunt in culpa. Consectetur adipisicing elit, lorem ipsum dolor sit amet, ut labore et dolore magna aliqua. Ut aliquip ex ea commodo consequat.</p>
<p>Velit esse cillum dolore sunt in culpa in reprehenderit in voluptate. Ut enim ad minim veniam, eu fugiat nulla pariatur. Excepteur sint occaecat ut labore et dolore magna aliqua. Consectetur adipisicing elit, mollit anim id est laborum.</p>

</div>
</div>

And the style sheet:

body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 16px;
font-weight: normal;
color: #000000;
}
#wrapper {
width: 700px;
margin: 0 auto;
}
h1 {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 100%;
font-weight: bold;
color: #003366;
text-align: center;
}
img {
float: right;
clear: right;
border: 1px solid blue;
}
#flowingtext {
background-image: url(../imageadds/compleximage.jpg); /* replace with path to your image */
background-repeat: no-repeat;
background-position: top right;
height: 350px; /* because user can change the size of the text we need to set a height so the image doesn’t get cropped */
border: 1px solid red;
}

You should now have a page looking like this:

Fig 1c

Finally remove borders. You may need to compensate for them with margins or padding.
When you get more familiar with this technique you can create the effect without using borders as guides and this will save you having to compensate later. Here is the final style sheet:

img {
float: right;
clear: right;
margin: 1px;
}
#flowingtext {
background-image: url(../imageadds/compleximage.jpg); /* replace with path to your image */
background-repeat: no-repeat;
background-position: top right;
height: 350px; /* because user can change the size of the text we need to set a height so the image doesn’t get cropped */
padding: 1px;
}

And Viola! You should have the following:

Fig 1d

I mentioned 2 other ways you can produce a siilar effect.
1) Set height but 1px width for you clear.gif and use margins to control the text.
2) Slice up your image to the dimensions that you would have used for the clear gif.


2 Responses to “Ask the Guru: How do I make text flow around complex images”

  1. James Cohen on October 26, 2006 9:28 am

    I wonder if you could achieve a similar effect by using DIVs with specified CSS widths/heights instead of the clear.gifs? This will save you making at least one (possibly eight in your example) requests to the webserver depending on how the image is cached.

  2. admin on May 17, 2008 1:01 pm

    Fixed width divs or even divs with appropriate margins might work. It didn’t work for this demo though when I adjusted text size so I stuck with the images but they would be a better solution.

Trackback URI | Comments RSS

Leave a Reply

Name (required)

Email (required)

Website

Speak your mind

    About

    Although originally designed to document my work and new web development tricks I learnt it has expanded to cover tech and news that I find interesting so in addition to tutorials and interviews expect to see product reviews and tech news too. If you enjoy please comment. David

    Blogroll
    • Display: Block - Blog of fellow developer Savell Martin
    • Molly E. Holzschlag - Web standards advocate and Genious
    • Nate Laxon - Funny guy and music guru
    • Paul Boag - Helping website owners and promoting webstandards. The King of Web Design Podcasts
    • Poached Online - news/current affairs/political comment: no eggs
    • Tale of 2 Blogs - Blog about my other blogs
    Admin
  • From Display:Block
    • SpringWidgets
      RSS Reader
      This widget is the staple of our platform. Read all your feeds right here with this one widget - Supported feeds are OPML, RSS, RDF, ATOM. Watch your favorite Podcast in the embedded Video Player on the Desktop or publish your own video playlist to your site for others to view!
      Visit the Widget Gallery