Adjusting the margin at the beginning of each CSS page break

Excuse the title, I struggled to find a more fitting description for it.

I'm trying to break up long rows in a table across multiple pages. Everything works fine with the page-break-after for the <tr> tags. However, my main issue is that the breaks start at the beginning and end at the very bottom of a page, causing my header and footer to be obscured by the table data.

I've attempted adding margin and padding everywhere but nothing seems to solve the problem.

Here is my CSS code:

@media print {
    
    html, body {
        width: 210mm;
        height: 297mm;  
        background:#fff;
    }
    .page-layout {
        border: initial;
        border-radius: initial;
        width: initial;
        min-height: initial;
        box-shadow: initial;
        background: initial;
        page-break-after: always;           
    }
    
    table.report { page-break-after:auto }
    table.report tr    { page-break-inside:avoid; page-break-after:auto }
    table.report td    { page-break-inside:avoid; page-break-after:auto }
    table.report thead { display:table-header-group; margin-top:50px; }
    table.report tfoot { display:table-footer-group }
    
    .header {
        display:block; 
        position:fixed; 
        top: 0px;   
        font-weight:bold;
        font-size:14px;
        text-align:right;
        right:0px;
    }
    .footer {
        z-index: 1;
        position: fixed;
        left: 0;
        bottom: 0;
        text-align: left;
        left: 0;
        width:100%;
        display:block;
    }       
}

And here is the corresponding HTML:

<div class="header">MY HEADER</div>

<div class="page-layout">
    <div style="font-weight:bold; font-size:14px; text-align:center; margin-bottom:20px">REPORT TITLE</div>

    <table width="100%" border="1" style="border-collapse:collapse" class="report">
        <thead>
            <tr>
                <th width="10%">Col1</th>
                <th width="60%">Col2</th>
                <th width="10%">Col3</th>
                <th width="20%">Col4</th>
            </tr>
        </thead>
        <tbody>
            <?php for ($x=1; $x<100; $x++) {//loop ?>
                <tr>
                    <td align="center"><?=$x?></td>
                    <td></td>
                    <td align="center"></td>
                    <td></td>
                </tr>
            <?php } //endloop ?>
        </tbody>
    </table>
</div>

<div class="footer">MY FOOTER</div>

Take a look at how it appears when printed: https://i.sstatic.net/DFAyG.png

Answer №1

Through my extensive online research, I discovered that there is currently no foolproof method to achieve this particular task.

I came across a discussion regarding the @page rule, which seemed like it could help me accomplish what I was aiming for. Unfortunately, my attempts with this rule were unsuccessful as it appears that most browsers have not yet implemented this feature. I am unsure about which browsers actually support it.

Ultimately, I stumbled upon a workaround solution. By utilizing the thead and tfoot elements, designed to repeat on print, I inserted an empty row in the thead section at the top. This created a blank space each time the header area repeated, allowing the header to display properly. Similarly, I added an empty row below the tfoot for the footer section.

Unfortunately, the tfoot did not repeat itself in Chrome, although it functioned correctly in IE and Firefox.

Answer №2

If you encounter issues where additional space is needed before and after the table start to accommodate other page elements, such as a footer:

https://i.sstatic.net/WGGRn.jpg

You can resolve this problem by implementing the following solution:

<style>
   @media print {
   .table-breaked {
      page-break-before: auto;
   }
   .no-border{
      border: none !important;
   }
   .footer-repeat {
      display: table-footer-group;
     }
   }
</style>

<div class="table-breaked">
 <table class="pt-20">
      <thead>
         <tr class="no-border">
            <td class="no-border">&nbsp;</td>
         </tr>
          <!-- Add extra space for printing -->
         <tr class="no-border">
            <td class="no-border">&nbsp;</td>
         </tr>
         <!-- Add extra space for printing -->
         <tr>
            <th class="text-center">Value 1<br/>№ Date</th>
            <th class="text-center">Value 2</th>
            <th class="text-center">Value 3</th>
            <th class="text-center">Value 4</th>
            <th class="text-center">Value 5</th>
         </tr>
      </thead>
      <tbody>
       <!-- Additional rows here -->
         <tr>
            <th>Data</th>
            <th>Data</th>
            <th>Data</th>
            <th>Data</th>
            <th>Data</th>
         </tr>
      </tbody>
      <tfoot class="footer-repeat">
         <!-- Repeat tfoot for extra space -->
         <tr class="no-border">
            <td class="no-border">&nbsp;</td>
         </tr>
         <tr class="no-border">
            <td class="no-border">&nbsp;</td>
         </tr>
         <tr class="no-border">
            <td class="no-border">&nbsp;</td>
         </tr>
         <tr class="no-border">
            <td class="no-border">&nbsp;</td>
         </tr>
         <tr class="no-border">
            <td class="no-border">&nbsp;</td>
         </tr>
      </tfoot>
   </table>
</div>

Check out the final layout:

https://i.sstatic.net/RAGSv.jpg

Answer №3

Feel free to utilize

@page{
  size: letter;
  margin-top: 1in;
  margin-bottom: 1in;
}

Answer №4

I found success by including page-break-inside:avoid in the cells:

table td, table th {
  page-break-inside: avoid;
}

Answer №5

I encountered the same issue and managed to solve it with a neat trick insert this line in your view :

<tr @if($key+1 ==3) class="break_page"  @endif>

and in your css :

/** Resolving Chrome problem #273306 **/
@media print {enter code here
    body.A3.landscape { width: 420mm }
    body.A3, body.A4.landscape { width: 297mm }
    body.A4, body.A5.landscape { width: 210mm }
    body.A5                    { width: 148mm }

    .break_page {page-break-after: always;}
}

then, ensure to include the following in your layout html :

@page { size: A4;
            margin-top: 50px;
            margin-bottom: 50px;
        } 

Answer №6

For my specific situation, resolving the issue involved applying position: relative; top: 100px; to the element at the top of the hierarchy.

Answer №7

My solution after numerous trials and errors involved adding an empty row with a fixed height at both the top and bottom of the table:

@page {
    size: A4 portrait;
    margin: 20px;
}

.header {
    border: 1px solid red;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    text-align: center;
}

table {
    width: 100%;
    break-inside: auto;
    border-collapse: collapse;
}

th {
    border-collapse: collapse;
}

tbody, th {
    border: 1px solid green;
}

th, td {
    padding: 4px 10px;
}

.header-space, .footer-space {
    height: 40px;
}

.footer {
    border: 1px solid blue;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    text-align: center;
}
<!DOCTYPE html>

<!-- HTML code here -->

Output:

https://i.sstatic.net/v8zjtv6o.png

Answer №8

Don't miss out on this!

@media print {
    html, body {
        width: 210mm;
        height: 297mm;  
        background:#fff;
    }
    .page-layout {
        border: initial;
        border-radius: initial;
        width: initial;
        min-height: initial;
        box-shadow: initial;
        background: initial;
        page-break-after: always;           
    }       
    table.report { page-break-after:auto }
    table.report tr    { page-break-inside:avoid; page-break-after:auto }
    table.report td    { page-break-inside:avoid; page-break-after:auto }
    table.report thead { display:table-header-group; margin-top:50px; }
    table.report tfoot { display:table-footer-group }

    .header {
        display:block; 
        position:fixed; 
        top: 0px;   
        font-weight:bold;
        font-size:14px;
        text-align:right;
        right:0px;
    }
    .footer {
        z-index: 1;
        position: fixed;
        left: 0;
        bottom: 0;
        text-align: left;
        left: 0;
        width:100%;
        display:block;
    }       
}
<div class="header">MY HEADER</div> 
<div class="page-layout">
<div style="font-weight:bold; font-size:14px; text-align:center; margin-bottom:20px">REPORT TITLE</div>

<table width="100%" border="1" style="border-collapse:collapse" class="report">
<thead>
<tr>
<th width="10%">Col1</th>
<th width="60%">Col2</th>
<th width="10%">Col3</th>
<th width="20%">Col4</th>
</tr>
</thead>
<tbody>
<tr>
...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps can be taken to address an IntegrityError issue?

Seeking assistance to resolve an issue I'm facing. I am in the process of developing a Django application for managing absences and notes at an establishment. My goal was to create a form that allows teachers to input absences, but I encountered a pro ...

Is it possible to locate an element using two attributes in C# WebDriver?

Can anyone assist me in finding elements based on their class and the text they contain? I have attempted the following methods without success, so any guidance would be greatly appreciated (I prefer using CSS for selection, but XPath is also acceptable): ...

Are DIV elements really impossible to click using selenium Web Driver?

Can DIV elements be clicked using selenium Web Driver? For example, I'm having trouble clicking the delete button in Gmail. https://i.stack.imgur.com/zsyio.png I've been trying to locate the element using the XPATH = //div[@aria-label='De ...

How can I move a nested child component out of an ancestor element with overflow set to hidden?

I'm facing an issue with a sliding carousel where the overflow-x property is set to hidden. The carousel displays 4 items at a time, and each item contains a button that triggers a pop-out menu positioned relative to its parent item. The problem arise ...

What is the best approach for managing routing in express when working with a static website?

Whenever a user navigates to mydomain.com/game, I aim for them to view the content displayed in my public folder. This setup functions perfectly when implementing this code snippet: app.use('/game', express.static('public')) Neverthel ...

Configuring Google Maps API (including charts) for maximum height of 100%

I am having trouble getting my map to display at 100% height using the Google Maps API. I've encountered similar issues in the past with the Google Charts API as well. From what I've gathered, it seems like setting the height of the html and bod ...

Getting creative with jQuery: Adding a random class using addClass()

The html/css: <style> div.myWords p { display: hidden; } p.show { display: block; } </style> <div class="myWords"> <p>Hello</p> <p>Hola</p> <p>Bonjour</p> </div><!-- myWords --> Is ther ...

Surprising behavior of translateZ in Framer Motion

Trying to position elements in a circular layout has led to unexpected behavior when using framer motion's translateZ. By applying styles with a template literal without shorthand for transforms, the desired effect is achieved: transform: ` rotateY( ...

Is it possible to alter the background behind each word in a text using only CSS?

I have a question about styling quotes by highlighting each word in the text with a background color. The issue I'm facing is that when using a solid background, there are no gaps between the colors. How can I achieve a result similar to this, but wit ...

What is the best way to define a recursive object type in TypeScript specifically for managing CSS styles?

I have implemented React.CSSProperties to generate css variables, allowing me to define styles like let css: React.CSSProperties = { position: "relative", display: "inline-block", background: "red" } My goal is to build a theme with css variables ...

Clicking on text triggers image display

My journey in coding is just starting and I have a good understanding of the basics of HTML, CSS, Javascript, and jQuery. I am trying to make an image appear when I click on text but struggling with the implementation. I'm working on a restaurant web ...

The custom HTML menu implementation is causing the jQuery autocomplete to lose its "Select" functionality

Seeking assistance in implementing jQuery autocomplete with a custom drop down menu. I have managed to customize menu items using the data()._renderItem method (which is currently commented out), however, this approach disables the menu "Select" function ...

JavaScript: Remove just the specific user input without affecting the rest of the HTML block

I'm facing a dilemma with deleting a specific user input without removing the entire HTML block. I know that the delete button triggers on the HTML ID 'noteDelete', which is the parent of each user input. However, I'm unsure about how t ...

Linked CSS Bullet Points

Typically, I focus on the backend of websites, but I am now attempting to add a new feature to my resume site. I want to connect bullet points with a vertical line that breaks at each point and does not overlap with the bullets themselves. I have created ...

Is this hyperlink accurately displayed?

Let me just say upfront that I am a complete novice when it comes to coding, and I have only been at it for about 3 weeks. Right now, I am in the process of creating a Bootstrap website, but I am having a hard time getting my links to work properly, and i ...

Format specific words or characters in a text input

In HTML, when I want to display strings in a Text Input or TextArea, I am looking for a way to have specific substrings render with a box around them. I envision these boxed substrings as being treated as a single entity, similar to how highlighting or tex ...

Deactivate interactive functions on the mat-slider while preserving the CSS styling

I'm attempting to create a mat-slider with a thumb label that remains visible at all times. Below is my mat-slider component: <mat-slider class="example-margin" [disabled]="false" [thumbLabel]="true" [tickInterval]="tickInterval" ...

Mastering the Zurb Foundation equalized grid: aligning content at the bottom of a div within a grid cell

One common challenge is how to position content at the bottom of a div, but with Flexbox, it's becoming easier nowadays. In my case, I'm using the Zurb Foundation grid with equalisation. This equalisation is crucial because my cells have an imag ...

Tips for positioning text, video, and images using HTML

I'm currently working on a webpage and trying to figure out how to align an "index" box on the left side and a video on the right. My goal is to have the video box positioned right next to the index box. Any ideas on how I can achieve this? I'v ...

A complete div component with a minimum height that is sandwiched between a fixed size header and

I'm currently facing a challenge with setting up my webpage due to the height of my elements causing a bit of a frenzy. Specifically, I have a specific layout in mind: At the top, there should be a header that has a fixed height (let's say 150p ...