Weasyprint: Don't apply max-width to flex items unless their flex container has an absolute width

Created on 21 Sep 2018  ·  19Comments  ·  Source: Kozea/WeasyPrint

Did some styling with Bootstrap, everything works fine except the grid system.
Did this in my HTML-File:

<div class="container">
    <div class="row">
      <div class="col">
      </div>
      <div class="col">
      </div>
    </div>
  </div>

PDF-File ignores complete the grid system (div class="col") from bootstrap

bug

Most helpful comment

I know that the problem probably comes from a problem in the flex layout.

Problem is that bootstrap css defines both, a flex-basis and a max-width for the col-* flex items and that confuses WeasyPrint resulting in wrong column sizes.
There a two workarounds to prevent the confusion and achieve the desired (proportional) column widths:

  1. Apply an absolute width to the flex container, e.g.: .row {width: 20cm}
    This isn't a good one -- 20cm, huh?

  2. Hide the (superfluent?) max-width from WeasyPrint by unsetting it for all .col-* definitions.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Bootstrap test</title>
  <link rel="stylesheet" href="./bootstrap.min.css">
  <style>
    .col,
      *[class^="col-"] {
        border: 1px solid #eee;
      }
    @media print {
      .col,
      *[class^="col-"] {
        max-width: none !important;  
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
    </div>
    <div class="row">
      <div class="col-5">col-5</div>
    </div>
    <div class="row">
      <div class="col-3 text-center">
        <p>3 columns</p>
      </div>
      <div class="col-2 text-center">
        <p>2 columns</p>
      </div>
    </div>
  </div>      
</body>
</html>

renders as expected:

workaround

All 19 comments

Not enough info!
What's the CSS declaration of your "col" and "row" classes?

Hi @hybridpicker, Bootstrap 4.x uses a CSS flex layout which is currently not supported by WeasyPrint.
However, it seems like it was implemented recently in https://github.com/Kozea/WeasyPrint/pull/579, but I didn't try it yet.
I used for my project a modified version of the column CSS from Bootstrap pre 4.x: https://github.com/senaite/senaite.impress/blob/master/src/senaite/impress/static/css/bootstrap-print.css, but there you need to keep in mind that WeasyPrint does not break in between floating blocks, see here: https://github.com/Kozea/WeasyPrint/issues/36

Not enough info!
What's the CSS declaration of your "col" and "row" classes?

as I mentioned before I used the CSS from bootstrap (version 4) thats all

Now, thanks to @ramonski, I know that Bootstrap 4.x uses a CSS flex layout.

Could anybody try with the current master branch?

ping?

Feel free to reopen if needed.

Hi @liZe, sorry, I missed that one.
Unfortunately I'm stuck on Python 2.7.x because of Plone/Zope and can not use the latest WeasyPrint version. Are there any technical reasons why Python 2.x support was dropped? I mean besides that Python 2 is obsolete and shouldn't be used anymore ...

Are there any technical reasons why Python 2.x support was dropped? I mean besides that Python 2 is obsolete and shouldn't be used anymore ...

That's a pretty good reason! More seriously, I was tired of having lots of little hacks everywhere in the code to make code work with both Python 2 and Python 3. I prefer spending my time adding cool features (like flexbox) than debugging Python 2 problems. And Python 3 has great new features! 2 small examples:

  • pathlib is really, really useful to handle paths everywhere and avoid special cases for Windows
  • urllib.request opens data URLs for me

Python 3 is 10 years old next month. It's not the future anymore :smile:.

Thanks for your reply @liZe and pointing out the two gems in Python 3 👍
Hopefully we can switch in the future to Python 3, because as you said, it is not the future anymore...

Btw, this is the Add-on we used WeasyPrint for: https://github.com/senaite/senaite.impress/#readme
It is working very robust in there, so thanks a lot for all of your efforts you put into WeasyPrint! You are all doing great work 👏🥇

Hi,
issue still persists for me. Weasyprint 45, bootstrap 4.3.1.
The columns are way off and the numbers (below in <p>) are rendered as images?
Simple HTML example:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Bootstrap test</title>
    <link rel="stylesheet" href="./vendor/bootstrap/css/bootstrap.min.css">
</head>
<body>
   <div class="container">
      <div class="row">
        <div class="col-3 text-center">
           <p>3 columns</p>
        </div>
        <div class="col-9 text-center">
           <p>9 columns</p>
        </div>
      </div>
   </div>
</body>
</html>

Hi,
I tried the same example like mzanders on Wasyprint 47 (bootstrap 4.3.1.) and the layout is still broken

If anyone's still running into an issue with this (I arrived here via a web search for a similar issue), what worked for me was to replace this:

<div class="row">
    <div class="col-6">Col #1</div>
    <div class="col-6">Col #2</div>
</div>

With this:

<div class="row d-print-table-row">
    <div class="w-50 p-2 d-print-table-cell">Col #1</div>
    <div class="w-50 p-2 d-print-table-cell">Col #2</div>
</div>

Bumping. Is this being worked on? I might be able to contribute if not.

Bumping. Is this being worked on? I might be able to contribute if not.

The first step is to understand why it does not work: is it because of a CSS property not supported yet, is it because there's a bug somewhere?

When you find where the problem comes from, you can try to find if an issue related to the problem is already open (and leave a message to tell that it prevents Bootstrap from working), or otherwise open a new issue.

@lize what? Everything related to the issue is above. Flex is not working. Col-6, etc are not working. I asked is anyone working on the fix because there is no need to double the work

@liZe what? Everything related to the fix is above. I asked is anyone working on the fix... no need to double the work

As far as I know, nobody's working on the fix.

I know that the problem probably comes from a problem in the flex layout. My proposition was to find where the problem really comes from (bug, property not supported…) and to open an issue if needed. A small example (ie. with only a few HTML and CSS lines, not using Bootstrap) is often a good start.

I know that the problem probably comes from a problem in the flex layout.

Problem is that bootstrap css defines both, a flex-basis and a max-width for the col-* flex items and that confuses WeasyPrint resulting in wrong column sizes.
There a two workarounds to prevent the confusion and achieve the desired (proportional) column widths:

  1. Apply an absolute width to the flex container, e.g.: .row {width: 20cm}
    This isn't a good one -- 20cm, huh?

  2. Hide the (superfluent?) max-width from WeasyPrint by unsetting it for all .col-* definitions.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Bootstrap test</title>
  <link rel="stylesheet" href="./bootstrap.min.css">
  <style>
    .col,
      *[class^="col-"] {
        border: 1px solid #eee;
      }
    @media print {
      .col,
      *[class^="col-"] {
        max-width: none !important;  
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
    </div>
    <div class="row">
      <div class="col-5">col-5</div>
    </div>
    <div class="row">
      <div class="col-3 text-center">
        <p>3 columns</p>
      </div>
      <div class="col-2 text-center">
        <p>2 columns</p>
      </div>
    </div>
  </div>      
</body>
</html>

renders as expected:

workaround

Ah, the new issue should be along the lines of "don't apply max-width to flex items unless their flex container has an absolute width"

Was this page helpful?
0 / 5 - 0 ratings