Check out my
new book!
HTML5 Games book
Sandbag text wrapping with Canvas
Text wrap with sandbags
A JavaScript/Canvas based approach to dynamically applying the sandbag technique to get pretty text wrapping around images. Building on the work done by Rob Swan, this is an attempt at mimicking the effect, making text flow nicely around shapes in images.


With CSS you can make text wrap around an image using the float property and for most purposes this is quite adequate. However, it doesn't take into account the actual image and treats it as one big block, even if you'd prefer the text to wrap around the actual content in the picture, magazine style.

Along came a technique called sandbag DIVs (first published by Rob Swan a few years ago, I believe) that solved the problem for those odd cases where you need something fancier than float:left. The idea is to build a structure of virtual "sandbags" out of DIV elements and then let the text flow around those instead of the image. This can be done either manually for each image or with a serverside script as shown in the ALA article.

Since we now have pixel access (in cool browsers, anyway) via the Canvas element, this technique can now be implemented dynamically with a bit of JavaScript.The approach is very similar to the one at ALA, in that we scan from either left or right looking for the first solid pixel and then use that information to create a bunch of DIVs of suitable dimensions, only we're doing it client side with JS. These DIVs are then styled with the original image as a background image, positioned to make it all appear as one whole image.

Using the small script linked below you simply give your image a CSS class of either "sandbag-left" or "sandbag-right", depending on how your image should float. If the browser does not support Canvas and image data access, a fallback mechanism simply sets the CSS float property to "left" or "right", degrading to the old rectangular text wrap.

Example usage:
<div><img class="sandbag-left" src="image.png">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
Compatibility and issues

Firefox 2 and 3 + Opera 9.5 looks fine here. IE and Chrome degrades to rectangular wrapping, as does Safari although it should hopefully get the image data methods soon.There are a few limitations, such as problems with opposing sandbagged images (one left-aligned, one right-aligned).
You also must use a transparent background in your image, since the script relies on detecting the transparent pixels to create the DIVs.
The page may look messed up until the sandbags have been created (can be minimized by also setting float:left/right on the image.)
Finally, since the original image is replaced by DIVs with background images, accessibility could be a problem, depending on where it's used.

Live examples : http://www.nihilogic.dk/labs/prettyfloat/example.htm
Download code : prettyfloat.js
⇓ 9 comments Anonymous

wow, nicely done, that is a pretty slick effect and doing the whole thing in JS really opens it up for use by anyone

September 16, 2008 at 3:58 AM
Unknown

Works with Safari 4 beta I have - very cool thing. Thanks :)

September 18, 2008 at 5:51 AM
Anonymous

That's a really nice expansion on the original concept - always nice to see ideas being developed. Good stuff.

September 19, 2008 at 1:49 AM
Jacob Seidelin

Thanks Rob, glad you liked it!

September 19, 2008 at 12:28 PM
Anonymous

Cool idea using canvas for this. FYI Eric Meyer came up with the original technique (w/ images) in 2000! http://meyerweb.com/eric/css/edge/raggedfloat/demo2.html

September 22, 2008 at 6:36 PM
vitamine h

So nice article!Actually i don't have much idea about text wrapping using canvas.The article you have posted is so far useful for me.I will look forward for more such articles.Thanks.

December 12, 2009 at 1:49 AM
Eleştirel Haber

Thanks. ı aslo liked it. because Rob sent it ;)

April 8, 2010 at 5:18 AM
Elestirel Haber

Thanks. ı aslo liked it. because Rob sent it ;)

April 8, 2010 at 5:20 AM
Robert "Anaerin" Johnston

It's nice, it works very well, but I've run into an issue.
If I have a series of P elements with the style
p:first-letter { float: left; font-size: 300%; }
And an image that's sandbagged right, then the first letters for the p elements all end up gathered in a nice row at the bottom. This is (obviously) not the desired effect. Any ideas as to a fix?

February 6, 2014 at 9:24 AM
Post a Comment