XSL FO losing styling on header rows of a table using border-collapse=separate

387 Views Asked by At

For the project I am working on the default for the tables we are using is to have the border-collapse property set for collapse, essentially, the outcome I am looking for will make the table rows closer together

<table class="otherClasses compact" cols="3">
         <thead class="left">
          <tr><td>
            <p>Header 1</p>
           </td>
           <td>
            <p>Header 2</p>
           </td>
          </tr>
         </thead>
         <tbody class="left">
          <tr>
           <td>
            <p>Cell 1</p>
           </td>
           <td>
            <p>Cell 2</p>
           </td>
          </tr>
          <tr>
           <td>
            <p>Cell 3</p>
           </td>
           <td>
            <p>Cell 4</p>
           </td>
          </tr>
         </tbody>
        </table>

With my Stylesheet boiling down to something like this

<fo:table-and-caption margin-left="0pt" border-collapse='collapse'>

    <xsl:if test="contains(@class, 'compact')">
        <xsl:attribute name="border-collapse">separate</xsl:attribute>
        <xsl:attribute name="border-spacing">0pt -4pt</xsl:attribute>
    </xsl:if>
    <fo:table>
        <fo:table-header>
            <xsl:apply-templates select="tr[th]"/>
        </fo:table-header>
        <fo:table-body>
            <xsl:apply-templates select="tr[td]"/>
        </fo:table-body>
    </fo:table>
</fo:table-and-caption>    

Outcome of compact vs none

So the image above shows the result of rendering when I use the class compact vs when I don't. I'll be honest, I don't really know that I understand why this is breaking the styling on the header row, when looking into border-collapse separate vs collapse I really thought separate would be the better setting for the general case but it seems to be breaking things for me in this instance

Solution to my specific issue I ended up going a different route and leaving the border collapse property as is. I ended up adjusting padding to achieve my wanted effect.

1

There are 1 best solutions below

0
On

Start with a minimal sample that would render through some XSL FO engine and work from there. This simple example could be like this:

<xsl:template match="table">
    <fo:table-and-caption margin-left="0pt" border-collapse='collapse'>
        <xsl:if test="contains(@class, 'compact')">
            <xsl:attribute name="border-collapse">separate</xsl:attribute>
            <xsl:attribute name="border-spacing">0pt -4pt</xsl:attribute>
        </xsl:if>
        <xsl:apply-templates/>
    </fo:table-and-caption>   
</xsl:template>
<xsl:template match="thead">
    <fo:table-header>
        <xsl:apply-templates/>
    </fo:table-header>
</xsl:template>
<xsl:template match="tbody">
    <fo:table-body>
        <xsl:apply-templates/>
    </fo:table-body>
</xsl:template>
<xsl:template match="tr">
    <fo:table-row>
        <xsl:apply-templates/>
    </fo:table-row>
</xsl:template>
<xsl:template match="td | th">
    <fo:table-cell>
        <xsl:apply-templates/>
    </fo:table-cell>
</xsl:template>
<xsl:template match="p">
    <fo:block><xsl:apply-templates/></fo:block>
</xsl:template>

Considering only the "table" part (you of course need to adding page-sequence, root, to this. This simple example gives you a minimal fo:table structure that can be rendered with all the required elements:

<fo:table-and-caption xmlns:fo="foo" margin-left="0pt" border-collapse="separate" border-spacing="0pt -4pt">
<fo:table-header>
    <fo:table-row>
        <fo:table-cell>
            <fo:block>Header 1</fo:block>
        </fo:table-cell>
        <fo:table-cell>
            <fo:block>Header 2</fo:block>
        </fo:table-cell>
    </fo:table-row>
</fo:table-header>
<fo:table-body>
    <fo:table-row>
        <fo:table-cell>
            <fo:block>Cell 1</fo:block>
        </fo:table-cell>
        <fo:table-cell>
            <fo:block>Cell 2</fo:block>
        </fo:table-cell>
    </fo:table-row>
    <fo:table-row>
        <fo:table-cell>
            <fo:block>Cell 3</fo:block>
        </fo:table-cell>
        <fo:table-cell>
            <fo:block>Cell 4</fo:block>
        </fo:table-cell>
    </fo:table-row>
</fo:table-body>
</fo:table-and-caption>