Forum How do I...?

Float images in multi-column layouts

bmotters
When using the columns property in CSS to flow text into multiple columns, how do you get the columns to float around elements. The floating elements are typically images. There are lot of different use cases.

Sometimes the floating element is the width of 1 to N columns, where N is the number of columns. In the following the XXX is the image, the text flows down column 1, to column 2 where it is interrupted by the image, continues below the image in column, and then into column 3, where it flows like in column 2. You can have the same situation with the image floating to the left.

----------- ------------ ------------
----------- ------------ ------------
----------- XXXXXXXXXXXXXXX
----------- XXXXXXXXXXXXXXX
----------- XXXXXXXXXXXXXXX
----------- XXXXXXXXXXXXXXX
----------- ------------ --------------

In the general case the floating image is not an integral number of columns in width. In that case, you want it to look like this:

----------- ------------ ------------
----------- ------------ ------------
----------- ----- XXXXXXXXXXX
----------- ----- XXXXXXXXXXX
----------- ----- XXXXXXXXXXX
----------- ----- XXXXXXXXXXX
----------- ------------ --------------

That is, the central column narrows as it goes around the image.

If you look in almost any magazine layout involving images and sidebars, you will see these kind of image treatments all over the place. I just picked up a few magazines to check this statement, and

I am trying to do a magazine layout previously done in Quark that floats images that are an integral number of columns. floated to the the left and right horizontally, and vertically to the (or section) top, bottom. They float both within a page, but also with a containing block. Such as to the right- of the containing article (which may itself not be across all the columns.)

From experimenting with PrinceXML, I see that one column images are not a problem as long as they don't float. And I seem to be able to get headings or images to span all the columns. But I cannot get elements to span across more than one column but less than all the columns. And floating within a multi-column layout seems totally unpredictable, and to be blunt, broken.

The layout I am trying to replicate doesn't have any cases where you need to narrow a column to get it to flow around an element, but that is pretty common and I can see the designers wanting to do that too.

Possibly, PrinceXML doesn't support some of the CSS3 columns functionality yet. OK, but I can't see even how to achieve any of this without doing a lot of non-semantic markup and writing very detailed stylesheets to move every little element into position precisely. This is much worse than the old-fashioned table-based layouts.

How are these kind of layouts achieved with PrinceXML, given its current state of compliance with the specs?
mikeday
There are still magazine layouts that cannot be achieved with CSS in Prince at the moment. In Prince 8.1 we have expanded column floats in conjunction with column span, so that an image can be floated to the top or bottom and span more than one column. But it is still not possible to put an image in the middle and have columns flow around it.
bmotters
Great. So how do you do float, say, a two column image to the left in a three-column flow? I've tried using doing something like the following

<html>
<body style="width:6in">
<div style="columns:3;">
text text text text text text text text text text text text text text text text text text
<div style="column-span:2; float:left; width:4in; height:1in" >
inset inset inset inset inset inset inset inset inset inset inset inset inset inset inset
</div>
text text text text text text text text text text text text text text text text text text
</div>
</body>
</html>

With this, I get three columns of text and the inset is two columns wide. Column 1 of the text flows around the inset, but column 2 just flows through inset so that the inset text and the column text just overlap. Column 1 knows about the inset and flows around it, but column2 just barges through as if it doesn't know the inset is even there.

So how do I do it correctly? Sorry to ask for tutorial information in this forum, but there isn't a lot of information about CSS3 multi-column properties out there, because most browsers don't really support them. (Having said that, if I change "columns" to "-moz-columns", and "column-span" to "-moz-column-span", Firefox will process the above, but exactly the same way as PrinceXML. I'd appreciate your help in how this is supposed to be done correctly.)
mikeday
You can use float column-top, column-bottom, column-top-corner, column-bottom-corner in conjunction with column-span. This will work in Prince, but only offers a limited subset of layouts that may not include what you are trying to achieve. It's an active topic of development in the CSS community at the present moment in time.
web559
Just checking up on this topic—is it still unsupported at this time to float an element, e.g., more than one column but less than two columns in a two-column layout? I've tried various permutations of float and column-span, but haven't gotten it to work.
mikeday
At the moment this is not possible in Prince, the element has to span one or two columns, not one and a half columns.
ccarey75
Could you elaborate on the use of the float properties and what layout options they provide? The documentation on the expanded float properties is incomplete at the moment.

I tried float:column-top which makes my image go to the top of the column, but it doesn't appear to "span" the column as such (the next column just overlaps it)

I'm using

IMG { display:block; column-span:2; float:column-top; }
bobr666
Has there been any movement on this area? It's causing me a big issue in a newsletter automation project.
mikeday
Not for floats that intrude half-way into a column, no.
bobr666
We could live with complete columns - i.e. one or two in a three column layout?
mikeday
Here is an example document with a three column layout. Unfortunately column corner floats with column span are still very new, and can produce odd results in some configurations.
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body>
<div style="columns: 3">
<div style="float: prince-bottom; column-span: 1; background: yellow; border: solid red">
BOTTOM x 1
</div>
<div style="float: prince-top-corner; column-span: 2; background: yellow; border: solid red">
TOP CORNER x 2
</div>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
<p>some text some text some text some text some text</p>
</div>
</body>
</html>