Kozea / WeasyPrint

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

Allow page breaks inside flex items #1967

Open shadoworion opened 1 year ago

shadoworion commented 1 year ago

For some reason, my PDF always starts content (table) from the second page

<html>
  <head>
    <meta charset="utf-8" />
    <style type="text/css" media="all">
        @import url("https://fonts.googleapis.com/css2?family=Rubik:wght@600;700");
        html {
          font-family: "Rubik", sans-serif;
          font-weight: 600;
        }
        header {
          position: running(header);
          width: 21cm;
          height: 6cm;
          display: flex; 
          flex-direction: column;
        } 
        header > .banner {
          width: 21cm;
          height: 3cm;
          background-image: url("data:image/png;base64,...");
          background-repeat: no-repeat; 
          background-size: cover; 
          background-position: center; 
          display: flex; 
          align-items: center;
          justify-content: flex-start;
        }
        header > .banner > .logo {
          width: 200px;
          margin: 0 50px; 
        }
        header > .info { 
          width: 21cm;
          height: 3cm;
          display: flex; 
          flex-direction: row-reverse; 
          justify-content: space-between;
          align-items: center;
        }
        header > .info > .name { 
          direction: rtl;
          width: 4cm;
          display: flex; 
          flex-direction: column; 
          margin-right: 30px;
        }
        header > .info > .name > label { 
          font-size: 1.75rem;
          font-weight: 700 !important;
          color: #3e1c96;
        }
        .header > .info > .name > span { 
          margin-top: 10px;
          font-size: 0.875rem;
        }
        header > .info > .user { 
          width: 50%;
          display: flex; 
          flex-direction: row-reverse; 
          justify-content: flex-end;
          margin-left: 30px;
        }
        header > .info > .user > div { 
          direction: rtl;
          display: flex; 
          flex-direction: column; 
          margin-right: 40px;
        }
        header > .info > .user > div > label { 
          color: #475467;
          font-size: 0.625rem;
        }
        header > .info > .user > div > span { 
          margin-top: 10px;
          font-size: 0.75rem;
        }
        footer { 
          position: running(footer);
          width: 21cm;
          height: 2cm;
          display: flex; 
          flex-direction: column;
        }
        footer > .info {
          width: 21cm;
          height: 1cm;
          display: flex;
          flex-direction: row-reverse;
          justify-content: space-between;
          align-items: center;
        }
        footer > .info > span {
          color: #475467;
          margin-right: 30px;
          font-size: 0.5rem;
        }
        footer > .info > .pages {
          direction: rtl;
          border-left: 2px solid #3e1c96;
          padding: 0 5px;
          margin-left: 30px;
        }
        footer > .info > .pages > span {
          color: #3e1c96;
          font-size: 0.7rem;
        }
        footer > .info > .pages > span.pageNumber {
          content: counter(page);
          margin: 0 2px;
        }
        footer > .info > .pages > span.totalPages {
          content: counter(pages);
          margin: 0 2px;
        }
        footer > .contacts {
          background: #4332B2;
          width: 21cm;
          height: 1cm;
          display: flex;
          flex-direction: row-reverse;
          justify-content: space-between;
          align-items: center;
        }
        footer > .contacts > span {
          color: #d9d6fe;
          font-size: 0.625rem;
        }
        footer > .contacts > span:first-child {
          margin-right: 30px;
        }
        footer > .contacts > span:last-child {
          margin-left: 30px;
        }

        @page {
          size: A4 portrait;
          margin: 0;
          counter-increment: page; 
          margin-top: 5.5cm;
          margin-bottom: 3cm;

          @top-center {
            vertical-align: top;
            margin: 0;
            content: element(header);
            width: 100%;
          }

          @bottom-center {
            vertical-align: bottom;
            margin: 0;
            content: element(footer);
            width: 100%;
          }
        }

        main > .info {
          display: flex;
          flex-direction: row-reverse;
          justify-content: flex-end;
          align-items: center;
          margin-left: 30px;
        }
        main > .info > div {
          direction: rtl;
          display: flex;
          flex-direction: column;
          margin-right: 40px;
        }
        main > .info > div > label {
          color: #475467;
          font-size: 0.625rem;
        }
        main > .info > div > span {
          margin-top: 10px;
          font-size: 0.75rem;
        }
        main > .content {
          direction: rtl;
          display: flex;
          flex-direction: column;
          padding: 30px;
          font-size: 0.875rem;
        }
        main > .content > label {
          font-weight: 700 !important;
          color: #3e1c96;
        }
        table {
          width: 100%;
          border-collapse: collapse;
            vertical-align: middle;
          text-align: right;
          margin-top: 1rem;
          page-break-inside: auto;
        }
        th, td {
          padding: 0.8rem;
        }
        thead {
          border-top: 2px solid #000;
          border-bottom: 2px solid #000;
        }
        tbody tr {
          border-bottom: 1px solid #D0D5DD;
        }
        .primary {
          color: #3e1c96 !important;
          font-size: 1rem !important;
        }
        .pagebreak {
          clear: both;
          page-break-after: always !important;
        }
    </style>
  </head>
  <body>
    <header>
      <div class="banner">
        <div class="logo">
          <svg>
            ...
          </svg>
        </div>
      </div>
      <div class="info">
        <div class="name">
          <label>דוח פעולות</label>
          <span>שנת המס 2020</span>
        </div>
        <div class="user">
          <div>
            <label>שם הלקוח</label>
            <span>test</span>
          </div>
          <div>
            <label>תאריך הדפסה</label>
            <span>18/09/2023</span>
          </div>
        </div>
      </div>
    </header>
    <footer>
      <div class="info">
        <span>123</span>
        <div class="pages">
          <span>עמוד</span>
          <span class="totalPages"></span>
          <span>/</span>
          <span class="pageNumber"></span>
        </div>
      </div>
      <div class="contacts">
        <span>הופק במערכת בלוקסטקס כל הזכויות שמורות.</span>
        <span>09-00000000</span>
        <span>contact@bloxtax.co.il</span>
      </div>
    </footer>
    <main>
      <div class="info">
        <div>
          <label>שיטת חישוב</label>
          <span>FIFO</span>
        </div>
        <div>
          <label>סה״כ פעולות</label>
          <span class="primary">400</span>
        </div>
        <div>
          <label>נפח מסחר</label>
          <span>0 $</span>
        </div>
        <div>
          <label>עמלות מסחר</label>
          <span>0 $</span>
        </div>
      </div>
      <div class="content">
        <label>סך כל אירועי המס</label>
        <table>
          <thead>
            <tr>
              <th>זירה / שנה</th>
                <th>2020</th>
                <th>2019</th>
                <th>2018</th>
                <th>2017</th>
                <th>2016</th>
                <th>2015</th>
            </tr>
          </thead>
          <tbody>
              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

              <tr>
                <td>test</td>
                  <td>100</td>
                  <td>200</td>
                  <td>300</td>
                  <td>400</td>
                  <td>500</td>
                  <td>600</td>
              </tr>

            <tr>
              <th>סה״כ</th>
                <th>100</th>
                <th>200</th>
                <th>300</th>
                <th>400</th>
                <th>500</th>
                <th>600</th>
            </tr>
          </tbody>
        </table>
      </div>
    </main>
  </body>
</html>
shadoworion commented 1 year ago

Okay, the problem is - if the parent block is "flex", - page break doesn't work.

grewn0uille commented 1 year ago

Thansk for the issue.

Let’s keep it open as it should break :)

StephanPillhofer commented 5 months ago

@grewn0uille Any updates on this matter? My flexbox containers still don't allwo for page-breaks.

grewn0uille commented 5 months ago

Any updates on this matter?

The issue is still opened, not linked to a PR nor a milestone. So sadly there is no update on this issue :(

dhdaines commented 1 month ago

This requires implementing the Flex Fragmentation Algorithm. As you can see, it's a bit complicated!