Kozea / WeasyPrint

The awesome document factory
https://weasyprint.org
BSD 3-Clause "New" or "Revised" License
6.91k stars 661 forks source link

Incorrect rendering of flex boxes #1208

Open afzalIbnSH opened 3 years ago

afzalIbnSH commented 3 years ago

I can't get weasyprint to correctly render my template.

Eg html:

<html>

<head>
  <title>Sample for WeasyPrint</title>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;1,400&display=swap');
    @import url('https://fonts.googleapis.com/icon?family=Material+Icons');
    .qr-page{
      display: flex;
      flex-wrap: wrap;
      height: 100%;
      margin: 0 70px;
    }
    .left-section{
      font-family: 'Open Sans';
      width: 50%;
      display: flex;
      flex-direction: column;
      justify-content: space-around;
    }
    .left-section .title-section{
      display: flex;
      flex-direction: column;
      width: 80%;
      height: 140px;
    }
    .left-section .title-section .company-name{
      color: #333333;
    }
    .left-section .title-section .heading{
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      height: 70px;
      font-size: 40px;
      font-weight: 700;
      margin-top: 20px;
    }
    .left-section .scan-txt{
      font: 24px/24px Open sans;
      font-weight: 600;
      display: flex;
      align-items: center;
    }
    .left-section .scan-txt i{
      margin-left: 25px;
    }
    .left-section .guidelines{
      width: 90%;
    }
    .left-section .guidelines .description{
      color: #333333;
    }
    .left-section .guidelines .procedure{
      display: flex;
      flex-direction: column;
      font-weight: 600;
      margin-top: 20px;
    }
    .right-section{
      width: 50%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    .right-section .logo-container{
      width: 360px;
      text-align: end;
    }
    .right-section .logo-container .company-logo{
      width: 150px;
      height: 50px;
      margin-bottom: 50px;
    }
    .right-section .qr-container{
      width: 360px;
      height: 360px;
      border: 1px solid #B5BCC1;
      margin-bottom: 100px;
    }
    .right-section .qr-container .qr-code{
      width:360px;
      height:360px;
    }
    </style>
</head>
<body>
  <div class="qr-page">
    <div class="left-section">
      <div class="title-section">
        <label class="company-name">Name, Country</label>
        <label class="heading">YOU'RE AWESOME</label>
      </div>
      <div class="scan-txt">Scan this QR Code <i class="material-icons" style="font-size:48px;">east</i></div>
      <div class="guidelines">
        <label class="description">
          Blaa blaaaaaa bla blaaaaa blaaaaa blaaaaaa,
          Blaa blaaaaaa bla blaaaaa blaaaaa blaaaaaaa blaaaaaaa bla blaa blaa blaa,
          Blaa blaaaaaa bla
        </label>
        <div class="procedure">
          <label>1. Action 1</label>
          <label>2. Action 2</label>
          <label>3. Action 3</label>
          <label>4. Action 4</label>
        </div>
      </div>
    </div>
    <div class="right-section">
      <div class="logo-container">
        <!-- Company Logo -->
        <img
          src="logo_url"
          class="company-logo"
          alt="company logo"
        />
      </div>
      <div class="qr-container">
        <!-- QR Code -->
        <img
          id="barcode"
          src="qr_data_url"
          class="qr-code"
          alt="QR Code"
        />
      </div>
    </div>
  </div>
</body>

</html>

This is what was rendered: weasyPrintGeneratedPDF.pdf

I then removed % for px to fit an A4 sheet assuming relative values could be the problem. The result is much better but still wrong.

Rewritten html:

<html>

<head>
  <title>Sample for WeasyPrint</title>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;1,400&display=swap');
    @import url('https://fonts.googleapis.com/icon?family=Material+Icons');
    .qr-page{
      display: flex;
      flex-wrap: wrap;
      padding-top: 40px;
    }
    .left-section{
      font-family: 'Open Sans';
      width: 300px;
      display: flex;
      flex-direction: column;
      justify-content: space-around;
    }
    .left-section .title-section{
      display: flex;
      flex-direction: column;
      width: 340px;
      height: 250px;
    }
    .left-section .title-section .company-name{
      color: #333333;
    }
    .left-section .title-section .heading{
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      height: 70px;
      font-size: 40px;
      font-weight: 700;
      margin-top: 20px;
    }
    .left-section .scan-txt{
      font: 24px/24px Open sans;
      font-weight: 600;
      display: flex;
      align-items: center;
    }
    .left-section .scan-txt i{
      margin-left: 25px;
    }
    .left-section .guidelines{
      width: 265px;
      height: 320px;
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
    }
    .left-section .guidelines .description{
      color: #333333;
    }
    .left-section .guidelines .procedure{
      display: flex;
      flex-direction: column;
      font-weight: 600;
      margin-top: 20px;
    }
    .right-section{
      width: 390px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    .right-section .logo-container{
      width: 360px;
      text-align: end;
    }
    .right-section .logo-container .company-logo{
      width: 150px;
      height: 50px;
      margin-bottom: 50px;
    }
    .right-section .qr-container{
      width: 360px;
      height: 360px;
      border: 1px solid #B5BCC1;
      margin-bottom: 100px;
    }
    .right-section .qr-container .qr-code{
      width:360px;
      height:360px;
    }
    </style>
</head>
<body>
  <div class="qr-page">
    <div class="left-section">
      <div class="title-section">
        <label class="company-name">Name, Country</label>
        <label class="heading">YOU'RE AWESOME</label>
      </div>
      <div class="scan-txt">Scan this QR Code <i class="material-icons" style="font-size:48px;">east</i></div>
      <div class="guidelines">
        <label class="description">
          Blaa blaaaaaa bla blaaaaa blaaaaa blaaaaaa,
          Blaa blaaaaaa bla blaaaaa blaaaaa blaaaaaaa blaaaaaaa bla blaa blaa blaa,
          Blaa blaaaaaa bla
        </label>
        <div class="procedure">
          <label>1. Action 1</label>
          <label>2. Action 2</label>
          <label>3. Action 3</label>
          <label>4. Action 4</label>
        </div>
      </div>
    </div>
    <div class="right-section">
      <div class="logo-container">
        <!-- Company Logo -->
        <img
          src="logo_url"
          class="company-logo"
          alt="company logo"
        />
      </div>
      <div class="qr-container">
        <!-- QR Code -->
        <img
          id="barcode"
          src="qr_data_url"
          class="qr-code"
          alt="QR Code"
        />
      </div>
    </div>
  </div>
</body>

</html>

If you print this html directly from the browser as a PDF, this fits nicely on an A4 sheet. See here: whatIExpect.pdf.

Weasyprint's rendering on the other hand, puts the right section below the left section. See here: whatWeasyPrintGIves.pdf

Please fix.

entityleak commented 3 years ago

I'm having a similar issue with flexbox. All that is required is two columns that flow side by side down the document (they do not flow into each other) and across page breaks.

Instead, the second column doesn't start until after the first page.

This is such a basic layout I'm very surprised it does not work at all.

This is the code I'm using to debug in the weasyprint renderer.

<style>
@page {
  size: a4;
  margin:19mm 12.8mm 15mm 12.8mm;
  background-color: white;
}

body { margin: 12mm; border: 1px solid black; background-color: white;}
h1 { text-decoration : underline; position: absolute; color:blue;}
div { border: 1px solid; background: #black }
img{ width: 70mm; }
figure{ margin:0; }

.container { 
  display: flex; 
  flex-flow: row nowrap;
  justify-content: space-between;  
}

.block{ display: block; width:70mm; max-width:70mm;}
.block:nth-of-type(1){color:red}
.block:nth-of-type(2){color: blue}
.block:nth-of-type(3){color: green}
.block:nth-of-type(4){color: grey}
.block:nth-of-type(5){color: orange}
</style>

<h1>Weasyprint testing</h1>

<div class='container'>
  <div class='column-wrap l'>
    <figure><img src="http://placekitten.com/g/200/380"></figure>
    <figure><img src="http://placekitten.com/g/500/300"></figure>
    <figure><img src="http://placekitten.com/g/200/300"></figure>
  </div>

  <div class='column-wrap r'>
    <div class='block'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam consequat laoreet lectus, vel viverra nibh volutpat quis. Donec volutpat mi vitae sapien posuere, quis tincidunt enim volutpat. Cras facilisis at velit in hendrerit. Pellentesque elementum fermentum metus, ac tristique ipsum pharetra eu. Curabitur rhoncus augue et vehicula accumsan. In sed mauris et ex aliquet consectetur. Quisque nec nunc dapibus, ornare purus eleifend, consequat quam. Nulla cursus ullamcorper tellus sed molestie. Etiam sit amet lobortis diam. Etiam aliquet pulvinar ante faucibus efficitur. Nullam sit amet nibh porttitor, vestibulum sapien eu, tristique sem. Nulla facilisi. Vestibulum sodales gravida justo ac euismod. Phasellus viverra varius sapien in feugiat. Duis augue dui, dapibus ut faucibus at, tristique vitae ante.</div>
    <div class='block'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam consequat laoreet lectus, vel viverra nibh volutpat quis. Donec volutpat mi vitae sapien posuere, quis tincidunt enim volutpat. Cras facilisis at velit in hendrerit. Pellentesque elementum fermentum metus, ac tristique ipsum pharetra eu. Curabitur rhoncus augue et vehicula accumsan. In sed mauris et ex aliquet consectetur. Quisque nec nunc dapibus, ornare purus eleifend, consequat quam. Nulla cursus ullamcorper tellus sed molestie. Etiam sit amet lobortis diam. Etiam aliquet pulvinar ante faucibus efficitur. Nullam sit amet nibh porttitor, vestibulum sapien eu, tristique sem. Nulla facilisi. Vestibulum sodales gravida justo ac euismod. Phasellus viverra varius sapien in feugiat. Duis augue dui, dapibus ut faucibus at, tristique vitae ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam consequat laoreet lectus, vel viverra nibh volutpat quis. Donec volutpat mi vitae sapien posuere, quis tincidunt enim volutpat. Cras facilisis at velit in hendrerit. Pellentesque elementum fermentum metus, ac tristique ipsum pharetra eu. Curabitur rhoncus augue et vehicula accumsan. In sed mauris et ex aliquet consectetur. Quisque nec nunc dapibus, ornare purus eleifend, consequat quam. Nulla cursus ullamcorper tellus sed molestie. Etiam sit amet lobortis diam. Etiam aliquet pulvinar ante faucibus efficitur. Nullam sit amet nibh porttitor, vestibulum sapien eu, tristique sem. Nulla facilisi. Vestibulum sodales gravida justo ac euismod. Phasellus viverra varius sapien in feugiat. Duis augue dui, dapibus ut faucibus at, tristique vitae ante.</div>
    <div class='block'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam consequat laoreet lectus, vel viverra nibh volutpat quis. Donec volutpat mi vitae sapien posuere, quis tincidunt enim volutpat. Cras facilisis at velit in hendrerit. Pellentesque elementum fermentum metus, ac tristique ipsum pharetra eu. Curabitur rhoncus augue et vehicula accumsan. In sed mauris et ex aliquet consectetur. Quisque nec nunc dapibus, ornare purus eleifend, consequat quam. Nulla cursus ullamcorper tellus sed molestie. Etiam sit amet lobortis diam. Etiam aliquet pulvinar ante faucibus efficitur. Nullam sit amet nibh porttitor, vestibulum sapien eu, tristique sem. Nulla facilisi. Vestibulum sodales gravida justo ac euismod. Phasellus viverra varius sapien in feugiat. Duis augue dui, dapibus ut faucibus at, tristique vitae ante.</div>
  </div>
</div>

Expected: expected

Result render