Codeable info

How to flow text tightly around images

Posted on by in WordPress Tutorials

At one of the SXSWi conferences last year, Interactive 2010, one of the panels was actually called “Is WordPress Killing Web Design?” Yeah, jaw dropping. The panel’s big issue was everything was in boxes. Ok, fine. Some people don’t like the organization boxes bring to design. They like free flow. I know I do in some cases.

My quest for free flowing design is recent. On one of my own sites I wanted to talk about the language Python which is named for the comedy group Monty Python and not the snake. In talking about the language I wanted the text to ‘snake’ around one of the more iconic Monty Python images – a big foot. You can see it about 25 seconds into this video and it gets reused many times over through out the entire run of the TV series. You can see the article about Python I wrote where I use that image.

My First Attempt

I considered this at first to be an easy task. HTML and CSS are well developed at this point. This should be a piece of cake, I thought. The image of the foot I had was dominated by white space. Using Photoshop I simple used the slice tool to divide the image into 3 pieces. The white space, the toes and the leg/ankle were my parts. I of course tossed the white space. I added in the leg/ankle, floated it to the right then the toes and floated it right, as well. Switching to HTML editing I did the following to the toes:

<img style=”position: relative; top: 248px; float: right;” …>

The position relative style says that this object can be moved relative to the spot it was initially placed on. Setting top at about 230px pushes it further down the page. I got the pixel amounts from my image slices so I knew exactly how much displacement it would take to put the toes in the right position. The height of the white space graphic was 230px.

When I did this and previewed it I was dismayed to see that the text did not wrap in the right place. It was wrapping where the image would have started from. The space where the wrapping was is called the “reserved space”, as I found out by searching the web for a solution. I was further dismayed to see almost all of the advice to this problem was that you are out of luck if you want to move an image vertically. There was no way to tell the browser to recalculate the reserved space at the new location. I don’t give up easy and neither should you. Just because people on the Internet says it can’t be done – until you really dig into the problem you can’t be sure they are right. I felt strongly there had to be a solution. I tried all sorts of tricks over the next 24 hours to try and get the text to reformat (javascript, odd css tweeks, etc.). For example if you resize the browser window it recalculates the placement of the text! However it doesn’t ever recalculate the reserved space! After a day I gave it a break.

A Solution is Found

The next morning I woke up at 5:30AM with a “Ureaka!” idea! I was going to fake out the HTML. I knew that my WordPress theme had a nice horizontal limit for the content. That meant I could count on where the toes were going to be. So I moved my IMG tag down to about where it should be in the text. This got me close, but it wasn’t pixel precise. Vertical displacement with the TOP attribute still was a problem and though the toes were covering less text they still were covering some of it. But this led me to the real breakthrough: remove the graphics from the text entirely, put them on their own absolutely positioned framework. Put invisible DIVs in the text near where they need to be.

Screen Shot
The blocking DIVs have borders turned on for illustration

This solutions is good because it is fairly easy to replicate. The DIVs are there only to reserve space and don’t have to be precisely lined up with each other and are fully controllable. By utilizing the CSS “position: absolute” I made the graphics non-interacting with the text. I could then push them down onto a lower z-index. This is all standard CSS.

CSS guidelines that come into play are: objects affect anything that comes after them. CSS works best with horizontal displacement but not with vertical displacement. As stated earlier, absolute positioning means that the object doesn’t affect anything else.

In the above illustration we see the results of a test file I made in an HTML editor. In my proof of concept I had the upper layer consist of text and two divs and the bottom layer consist of the two images, absolutely positioned and lined up. I placed the images first, wrapped in their own div and the text following, also wrapped in it’s own div. The divs were set to the width of my WordPress theme. I also set the inner blocking divs to have borders to show exactly where they were. As you can guess, one could use multiple divs to create even more detailed blocking. You can take this as far as your creative skill will go.

Implementing in WordPress

Start with a DIV for your graphics. It needs to have its width set the same as the width of the space for your content. You can find this using a tool like Firebug if you don’t know. In my case my width was 530px. I found putting a DIV around the text was both destructive to the layout and not necessary. Here is what my graphics DIV looks like:

<div style=”position: absolute; width: 530px; height: 400px;”>

Here is the DIV to make room for the first graphic. I put this one at the start of the text.

<div style=”position: relative; float: right; width: 224px; height: 400px;”>

Down about the third paragraph I have the smaller DIV:

<div style=”position: relative; float: right; width: 165px; height: 150px;”>

So far everything looks great. I tested the solution in IE (the most likely for it to fail in), Firefox, Safari and Chrome. It looked good in all of those places.

Addressing the Mobile Viewing Experience

However we are not done. The finally test was to check my mobile to see how it looked. Sadly it did not work there. I knew I was in for some tricky coding to fix that because my iPhone doesn’t recognize the CSS @media descriptor ‘handheld.’ However some research produced a solution that would work with all handhelds. I modified my stylesheet.css file and added the following:

@media handheld, only screen and (max-device-width: 480px) {
div.textblock { display: none }

I then added the attribute class=”textblock” to the DIV containing the graphics and the two DIVs that  did the blocking. When rendered on an iPhone or other portable device with limited screen resolution the images and blocking DIVs simply don’t show or interact. Note that I did not use display: hidden. This is on purpose. If I had done that the blocking DIVs still would have left reserved space for the text. By setting none, not only don’t they show up but they also don’t interact with the the other elements on the page.

By testing with all the major browsers and eliminating the trick from affecting mobile apps the solution is complete. The work needed isn’t great and the results are a nice counter to those who think WordPress is only good for box-like design. You may have a client that wants a design that flows like this on some pages. Now you can give them it with confidence.

There is one lingering issue – you have to also update your mobile theme if your site uses one. You can always view the site as it appears to non-mobile browsers by selecting a link. I’ve decided that since the mobile site is still mostly readable I’d leave as is just to give an example. If you click to viewing the site normally then you will see it is corrected. Mobile Themes are great but give you one extra step when testing changes.

One of you smart people probably has already figured out there was a way of doing this without going through all of this trouble. There is another solution that also uses slicing. If you think you’ve got it, put it in the comments and I’ll respond!

Codeable info

Comments (8)

Comment by REON says:

Argh, the comment system omitted my tag. The above sentence should read something like: âہ“You could possibly use the span tag too, with inline style. itâ€â„¢s a drag, but it should work fine.

Comment by Peter Mancini says:

You could add “display: block” to the span but without trying it I am not sure how it would look and you’d also have to try every single browser out there just to make sure it actually works. I found subtle variation in all of them as to how things ended up looking just using my solution. You should try it out and let us know how it works. I am curious.

Comment by Peter Mancini says:

Yes, both of those solutions work, sort of. Creating PNG images just to reserve space takes extra time and if you don’t get it exactly the way you want then that extra time multiplies. You can alter the DIVs width and height with very little effort and refresh to see the result very quickly. Setting the text in a paragraph block won’t work in WordPress (WP will strip the ) but even if it did, you’d be limited to just square blocking. With multiple DIVs you can create a variety of shapes and effects.

I originally thought of doing the invisible image solution but never tried it because the DIV solution was much lower effort and bandwidth.

Comment by Peter Mancini says:

You would have to experiment with that. The difference is that a DIV is a block element and a SPAN is an inline element. The key to getting this to work is getting the space reserved and so far as I know only block elements will do that. Give it a try though. I would love to see variations of this work. It might be possible to generalize this even more.

Comment by John Flower says:

It won’t take that long, now that I think about it. If you’re gonna make it all square, then you simply need a few paragraphs with block display and width, and a container dive with background image.


a single PNG image (with transparent background), with some paragraphs and negative margins or some such. Should do the trick too.

Comment by John Flower says:

No problem though. Add a “display: block;” to the span and you’re good to go. It’ll take a long time to implement, but it’ll work.
A container div with the foot as background, then the text in a few spans, or even paragraphs, with the block display added. Then you need to line it all up. That’s gonna take some time, but for sures you’ll be able to do it. This method also means that you require only one image. You don’t have to split the foot. Chances are it’ll look better in a mobile browser.
I think Stu over at CSSplay’s created one or two similar things.

Comment by John Flower says:

Argh, the comment system omitted my tag. The above sentence should read something like: “You could possibly use the span tag too, with inline style. itâ€â„¢s a drag, but it should work fine.

Comment by John Flower says:

You could possibly use the tag too, with inline style. it’s a drag, but it should work fine.

Codeable info