Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS Multi-column Layout #60

SimonSapin opened this issue Mar 21, 2013 · 15 comments

CSS Multi-column Layout #60

SimonSapin opened this issue Mar 21, 2013 · 15 comments


Copy link

@SimonSapin SimonSapin commented Mar 21, 2013

Column balancing is tricky, the rest is relatively straightforward. We should start with multicol without column-fill (balancing) or column-span (which also requires balancing).

Copy link

@barryvan barryvan commented Apr 10, 2013

Chiming in to answer your (probably rhetorical) question: yes, multicol would be very useful, even without balancing in play. We're migrating away from Apache FOP to WeasyPrint -- from what I can tell, XSL-FO supports multicol (via the column-count and column-gap properties), but doesn't have balancing, either. Implementing multicol without balancing would then at least give feature-parity with XSL-FO.

Copy link

@jacobheller jacobheller commented Jul 20, 2013

For whatever it's worth, multi-column print is a much-requested feature by users of my site -- so +1 for this!

Copy link

@blagasz blagasz commented Sep 25, 2013

Not so helpful, but a +1 from me as well :)

Copy link

@graingert graingert commented Dec 2, 2013

This is something I'm definitely interested in.

Copy link

@jdus jdus commented Mar 7, 2014

Multicol, with or without balancing, would be very useful, since multi column layouts are very common in professional print and reporting. I would definitely support this.

Copy link
Member Author

@SimonSapin SimonSapin commented Mar 7, 2014

Understood, multicol is useful even without balancing. No need to repeat it.

FYI, nobody is actively developing new WeasyPrint features at the moment. This is gonna make progress with somebody writing code, not with +1s. I’m happy to provide guidance to anyone interested in doing so.

Copy link

@thinkwelltwd thinkwelltwd commented Dec 19, 2015

I'm not able to develop multicol support, but would be interested in discussion financial support for this feature. Who would be the right person to talk to about that?

Copy link

@liZe liZe commented Jun 6, 2016

I'm not able to develop multicol support, but would be interested in discussion financial support for this feature. Who would be the right person to talk to about that?

Sorry for being so long. If anyone is interested in financial support, you can contact me (guillaume.ayoub[at]

Copy link

@StephanMeijer StephanMeijer commented Jun 14, 2016

I'd really like this functionality. +1

liZe added a commit that referenced this issue Aug 14, 2016
Related to #60.

This commit adds a really simple support of multi-column layouts.
Copy link

@liZe liZe commented Aug 14, 2016

I've added a really simple multi-column layout support.

What's implemented:

  • the pseudo-algorithm defining how many columns must be used,
  • the replacement of normal layout with multi-column layout when needed,
  • the layout of the columns,
  • a stupid balancing algorithm,
  • multi-column blocks cut between multiple pages.

What can be probably easily added:

  • paddings, borders, margins,
  • management of column-gap and column-rule-* properties.

What seems to be a bit harder (and less interesting):

  • a real shrink-to-fit algorithm (the spec says that "CSS does not define the exact algorithm", funny as usual),
  • a clean way to add column boxes (it's currently added with a huge hammer),
  • check that everything goes well with the various values of the "position" and "display" properties on the container (for ex. check that the columns are applied to "non-replaced block-level elements (except table elements), table cells, and inline-block elements"),
  • check that everything goes well with the various values of the "position" and "float" on the children,
  • check that everything goes well when a block is split between multiple pages,
  • forced column breaks and page breaks,
  • column spans.

What seems to be really hard:

  • a better balancing algorithm (contrary to what I was thinking, without this the feature is actually pretty useless),
  • break-inside, break-before and break-after in columns (other than forced breaks),
  • overflows,
  • orphans and widows in columns.

I'm testing this branch with WeasySuite, the tests from the W3 suite seem to be really good.

I'll implement the easy part soon and add some tests (and renderings) in this issue.

Copy link

@liZe liZe commented Aug 15, 2016

I've added the easy part, everything is in the columns branch.

An ugly sample, with colors, margins, borders, paddings, hyphenation, gap, rule and justification:

<html lang="en">
body { -weasy-hyphens: auto; font-size: 10pt }
div { columns: 3; padding: 1em; background: red; background-clip: content-box; border: 3px solid; text-align: justify; column-gap: 3em; column-rule: 1px dashed blue }
p { background: yellow; padding: 0.5em }
<p>A multi-column element (or multicol element for short) is an element whose ‘column-width’ or ‘column-count’ property is not ‘auto’ and therefore acts as a container for multi-column layout.
<p>In the traditional CSS box model, the content of an element is flowed into the content box of the corresponding element. Multi-column layout introduces a new type of container between the content box and the content, namely the column box (or column for short). The content of a multicol element is flowed into its column boxes.
<p>Column boxes in a multi-column element are arranged into rows. Like table cells, the column boxes in a row are ordered in the inline direction of the multicol element. The column width is the length of the column box in the inline direction. The column height is the length of the column box in the block direction. All column boxes in a row have the same column width, and all column boxes in a row have the same column height. Within each row in the multi-column element, adjacent column boxes are separated by a column gap, which may contain a column rule. All column gaps in the same row are equal. All column rules in the same row are also equal, if they appear; column rules only appear between columns that both have content.
<p>In the simplest case a multicol element will contain only one row of columns, and the height of each column will be equivalent to the used height of the multi-column element's content box. If the multi-column element is paginated, the height of each row is constrained by the page and the content continues in a new row of column boxes on the next page; a column box never splits across pages. The same effect occurs when a spanning element divides the multi-column element: the columns before the spanning element are balanced and shortened to fit their content. Content after the spanning element then flows into a new row of column boxes.
<p>It is not possible to set properties/values on column boxes. For example, the background of a certain column box cannot be set and a column box has no concept of padding, margin or borders.


There's a lot of things to do, help and reviews are welcome!

Copy link

@liZe liZe commented Aug 15, 2016

You can take a look at the diff.

Copy link

@liZe liZe commented Aug 15, 2016

It's now quite clean and ready to be tested. Some of the tests of the W3C test suite pass, and many simple real-life results could be really good.

Copy link

@mb21 mb21 commented Aug 22, 2016

wow, cool :) I'm looking forward to take a better look at this in the next couple of weeks!

@liZe liZe added this to the v0.31 milestone Aug 27, 2016
Copy link

@liZe liZe commented Aug 28, 2016

I've added the W3C test suite to the next version of WeasySuite, the results are pretty good for a feature that has just been added (42% tests pass). Solving many stupid corner cases (mostly about collapsing margins and absolute positioning) will easily make this number reach 50~60%.

After playing with the implementation, I think that column-breaking is much easier than page-breaking, and that this feature could be added in a couple of hours. Orphans and widows are painful, but possible. Column spans are even more painful.

A real balancing algorithm would probably take days to imagine and to code, with a small benefit. That's not my priority for the next months.

And about shrink-to-fit, well… I'm sure that David Baron would be delighted to solve this easy problem for us 😉.

If anyone is interested in testing and/or adding new features and/or fixing bugs, I'll be happy to help!

@liZe liZe closed this Aug 28, 2016
jsonn pushed a commit to jsonn/pkgsrc that referenced this issue Jan 15, 2017
Version 0.34

Released on 2016-12-21.

Bug fixes:

* `#398 <>`_:
  Honor the presentational_hints option for PDFs.
* `#399 <>`_:
  Avoid CairoSVG-2.0.0rc* on Python 2.
* `#396 <>`_:
  Correctly close files open by mkstemp.
* `#403 <>`_:
  Cast the number of columns into int.
* Fix multi-page multi-columns and add related tests.

Version 0.33

Released on 2016-11-28.

New features:

* `#393 <>`_:
  Add tests on MacOS.
* `#370 <>`_:
  Enable @font-face on MacOS.

Bug fixes:

* `#389 <>`_:
  Always update resume_at when splitting lines.
* `#394 <>`_:
  Don't build universal wheels.
* `#388 <>`_:
  Fix logic when finishing block formatting context.

Version 0.32

Released on 2016-11-17.

New features:

* `#28 <>`_:
  Support @font-face on Linux.
* Support CSS fonts level 3 almost entirely, including OpenType features.
* `#253 <>`_:
  Support presentational hints (optional).
* Support break-after, break-before and break-inside for pages and columns.
* `#384 <>`_:
  Major performance boost.

Bux fixes:

* `#368 <>`_:
  Respect white-space for shrink-to-fit.
* `#382 <>`_:
  Fix the preferred width for column groups.
* Handle relative boxes in column-layout boxes.


* Add more and more documentation about Windows installation.
* `#355 <>`_:
  Add fonts requirements for tests.

Version 0.31

Released on 2016-08-28.

New features:

* `#124 <>`_:
  Add MIME sniffing for images.
* `#60 <>`_:
  CSS Multi-column Layout.
* `#197 <>`_:
  Add hyphens at line breaks activated by a soft hyphen.

Bux fixes:

* `#132 <>`_:
  Fix Python 3 compatibility on Windows.


* `#329 <>`_:
  Add documentation about installation on Windows.

Version 0.30

Released on 2016-07-18.

WeasyPrint now depends on html5lib-0.999999999.

Bux fixes:

* Fix Acid2
* `#325 <>`_:
  Cutting lines is broken in page margin boxes.
* `#334 <>`_:
  Newest html5lib 0.999999999 breaks rendering.

Version 0.29

Released on 2016-06-17.

Bug fixes:

* `#263 <>`_:
  Don't crash with floats with percents in positions.
* `#323 <>`_:
  Fix CairoSVG 2.0 pre-release dependency in Python 2.x.

Version 0.28

Released on 2016-05-16.

Bug fixes:

* `#189 <>`_:
  ``white-space: nowrap`` still wraps on hyphens
* `#305 <>`_:
  Fix crashes on some tables
* Don't crash when transform matrix isn't invertible
* Don't crash when rendering ratio-only SVG images
* Fix margins and borders on some tables

Version 0.27

Released on 2016-04-08.

New features:

* `#295 <>`_:
  Support the 'rem' unit.
* `#299 <>`_:
  Enhance the support of SVG images.

Bug fixes:

* `#307 <>`_:
  Fix the layout of cells larger than their tables.


* The website is now on GitHub Pages, the documentation is on Read the Docs.
* `#297 <>`_:
  Rewrite the CSS chapter of the documentation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants
You can’t perform that action at this time.