WeasyPrint icon indicating copy to clipboard operation
WeasyPrint copied to clipboard

Collapsed borders not drawn for tables in margin boxes

Open marcosn41 opened this issue 4 years ago • 10 comments

I made a complex document in it and I'm putting header and footer in @ top-center and @ top-bottom. The problem is that I use a simple 1-row table. On the first page everything is ok, on the second onwards ONLY the border does not work is borderless the rest everything is ok. This only occurs in the header and footer in the rest of the document is ok

First page: image

Second one: image

Code:

<div class="header">
        <table style="border-collapse: collapse; width: 100%; height: 84px;">
            <tbody class="bodyHeader">
                <tr style="height: 21px;">
                    <td style="width: 12.1754%; height: 21px; background-color: cornflowerblue;" rowspan="4">&nbsp;</td>
                    <td style="width: 64.5104%; height: 21px;" rowspan="2">&nbsp;</td>
                    <td style="width: 19.905%; height: 21px;">&nbsp;</td>
                </tr>
                <tr style="height: 21px;">
                    <td style="width: 19.905%; height: 21px;">&nbsp;</td>
                </tr>
                <tr style="height: 21px;">
                    <td style="width: 64.5104%; height: 21px;" rowspan="2">&nbsp;</td>
                    <td style="width: 19.905%; height: 21px;">&nbsp;</td>
                </tr>
                <tr style="height: 21px;">
                    <td style="width: 19.905%; height: 21px;">&nbsp;</td>
                </tr>
            </tbody>
        </table>
        
    </div>
div.header {
            /* display: block; */
            width: 100%;
            position: running(header);
            margin: 0mm;
            padding: 0mm;
        }
        @page iretrato{
            size: A4;
            margin: 2cm;
            margin-top: 3.5cm;

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

            @bottom-center {
                content: element(footer);
            }    
        }

marcosn41 avatar Dec 29 '20 16:12 marcosn41

Ok, i found why this happening, its border-collapse: collapse. I dont know if this is a bug because only shows border on first page but my problem is solved removing this param.

marcosn41 avatar Dec 30 '20 11:12 marcosn41

Ok, i found why this happening, its border-collapse: collapse.

Thanks a lot for taking the time to find this!

I dont know if this is a bug because only shows border on first page but my problem is solved removing this param.

It definitely is, let’s keep this issue open.

liZe avatar Dec 30 '20 12:12 liZe

I think found a decent workaround for this in css. For context, I was using tables in Fomantic-UI and experienced the same issue with the columns disappearing.

Haven't dug into weasyprint's code, but I'm including it in case it's helpful in diagnosing a root cause. Overriding with specific rules at the tr, th and td scopes brought them back:

.ui.table tr {
    border-collapse: collapse;
}

.ui.table th, .ui.table td {
    border: 1px solid rgba(34,36,38,.15);
}

boblannon avatar Apr 27 '21 15:04 boblannon

I have the exact same problem. @boblannon Your fix does not work for me (Maybe I do not understand how/where you use it. In your own css? Or is that fix related to the generating of the PDF)

MrUrdam avatar Jan 26 '22 10:01 MrUrdam

@MrUrdam I'm sorry, I don't have access to the code anymore, but I'm fairly sure that snippet was something I used to override the default styles of Fomantic-UI. You could try including it inline in your HTML...

boblannon avatar Jan 26 '22 11:01 boblannon

I already have those settings in my CSS and I get the described problem. I now only paint the borders I need (a single time) using way more complex css and I have set the spacing to 0. This fixes the issue for me but is not really clean.

MrUrdam avatar Jan 26 '22 11:01 MrUrdam

Hello, thank you very much for identifying the duplicate issue, sorry for not spotting it. I might be able to take a look into it. Can you be so kind and point me into the right direction as to where in the code the culprit might be buried? Which "dirty hack" do you reference in https://github.com/Kozea/WeasyPrint/issues/1687?

Grepping for "collapse" I guess "layout/table.py" is a hot candidate - but where might the combination with headers/footers come in?

Or can the bug be reproduced with just normal tables (is there a minimal example)?

benboeck avatar Jul 19 '22 05:07 benboeck

I might be able to take a look into it.

Cool!

Can you be so kind and point me into the right direction as to where in the code the culprit might be buried? Which "dirty hack" do you reference in #1687?

The collapse_table_border function is called on tables that have the border-collapse: collapse attribute set. This function resolves the borders conflicts and defines a "grid" that will be drawn instead of the cells’ borders. The "grid" is a list of vertical and horizontal borders, that’s what’s returned by the function.

To avoid drawing the cells’ borders, we set transparent borders instead of colored borders. That’s "the hack", it’s there:

https://github.com/Kozea/WeasyPrint/blob/5c91673b9d920c54a247acd7dc7abdc4e47ef4e6/weasyprint/formatting_structure/build.py#L1095-L1101

For tables that are only drawn once, it’s not a problem. But for tables in page margins, it causes the bug we’re talking about. The collapse_table_border is called each time the boxes of the table are built, ie. for each page in our case. It works the first time, but it doesn’t work after because the style has been changed: cells now have transparent borders, and the "grid" generated is thus transparent.

Changing the style dictionary is REALLY BAD, each time we do this we get bugs like this one. We’ve removed this kind of hacks from many places in the past, and we would be delighted to see it removed from one more place.

The solution may be to remove the set_transparent_border and remove_borders functions and handle this in the draw module where we would have dedicated code to draw tables with collapsed borders, avoiding to draw borders when we draw cells (and rows, row groups, columns, column groups…).

liZe avatar Jul 19 '22 08:07 liZe

The solution may be to remove the set_transparent_border and remove_borders functions and handle this in the draw module where we would have dedicated code to draw tables with collapsed borders, avoiding to draw borders when we draw cells (and rows, row groups, columns, column groups…).

Actually, that’s not enough. The set_transparent_border function also changes the width of the border, used for the layout. So, if we keep the style unchanged (and we should), changing the draw module to avoid displaying cells borders is required, but we also probably need to change the layout.table module to use the right value of the border width.

(Each time I try to solve this problem again, I rediscover why it’s more complex that it seems to be.)

liZe avatar Jul 19 '22 08:07 liZe

The good workaround involves using div tags instead of tables. I.e:

                <div style="display: table">                                                                                  
                    <div style="display: table-row">                                                                                                                        
                        <div style="display: table-cell; padding-right: 20px">A</div>                                         
                        <div style="display: table-cell">A</div>                                                                                                            
                    </div>                                                                                                    
                    <div style="display: table-row">                                                                                                                        
                        <div style="display: table-cell; border-top: 1px solid; padding-right: 20px">BBB</div>                
                        <div style="display: table-cell; border-top: 1px solid">CCCCC</div>                                                                                 
                    </div>                                                                                                                                                  
                </div> 

Divs do not use border-collapse property and do not have this problem.

usamec avatar Sep 09 '22 07:09 usamec

Fixed by #1884.

liZe avatar Jan 29 '24 15:01 liZe