Table alignment

Tables that are less that the full page width are generally left-aligned. If you want a different alignment for tables in HTML output, then you can use CSS. For example, the following CSS fragment will center all table and informaltable elements:

div.table  {
   text-align: center;
}
div.informaltable {
   text-align: center;
}

This works because the HTML stylesheets add these class attributes to the HTML div elements containing a table.

Centering tables in XSL-FO is a different matter. What should work (but does not) is setting the text-align attribute to center in the attribute-set named table.table.properties. That attribute-set adds properties to the fo:table element in the output. Oddly enough, the text-align property is not allowed on fo:table, so that is why the attribute-set approach does not work to center tables.

The text-align property is allowed on fo:table-and-caption. However, the DocBook XSL stylesheet does not output a fo:table-and-caption element for this purpose because FOP does not support fo:table-and-caption, and XEP does not support the text-align property on it. Only Antenna House's XSL Formatter works to center a table inside a table-and-caption element.

There is a workaround in XSL-FO for centering tables, which involves creating an outer one-row table with your table contained in the center cell. But the DocBook stylesheets do not do that because of inconsistent behavior among the XSL-FO processors. See the XEP website at http://www.renderx.net/lists/xep-support/1444.html if you want to customize tables for centering.

The following customization will center tables in XEP output:

<xsl:template name="table.layout">
  <xsl:param name="table.content"/>

  <fo:table width="100%">
    <fo:table-column column-width="proportional-column-width(1)"/>
    <fo:table-column/>
    <fo:table-column column-width="proportional-column-width(1)"/>
    <fo:table-body start-indent="0pt">
      <fo:table-row>
        <fo:table-cell/>
        <fo:table-cell>

          <fo:table>
            <fo:table-body start-indent="0pt">
              <fo:table-row><fo:table-cell><fo:block>
                <xsl:copy-of select="$table.content"/>
               </fo:block></fo:table-cell></fo:table-row>
            </fo:table-body>
          </fo:table>

        </fo:table-cell>
        <fo:table-cell/>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</xsl:template>

This customization takes advantage of a placholder template named table.layout in the DocBook stylesheet. The table.content parameter passed to the template is the entire table, and this template wraps that in another fo:table for layout purposes. In this case, it defines proportional columns on either side of the second column, and those effectively center the middle column.

Full-width tables

Wide tables in print output may need more space than is available in the standard body text width. Indents that are often used for content formatting can shorten the available width for a given table. For example, the default layout in the print stylesheet indents body text relative to section headings. Also, a table inside a list is indented further. If a table in that context happens to need more columns and width than is available, then the table width needs to be expanded into the indent space.

The table and informaltable elements have an attribute named pgwide that can be used to indicate that a given table needs to expand to the full page width between the margins. When a table has pgwide="1", then the print stylesheet sets the start-indent property to 0pt, which removes all indents on the table, bringing its left edge out to the left page margin. This property is actually set by an attribute-set named pgwide.properties if you need to customize it.

The pgwide="1" attribute can also cause a table in a multi-column layout to span all columns by setting span="all" on the output table. However, this may not work in all XSL-FO processors because the span property is not on a block that is the direct child of the fo:flow element. For this reason, the span attribute is not automatically set in the pgwide.properties attribute-set, so you have to add it to a customization of that attribute-set. See the section “Attribute sets” for more information.

If you are using tabstyle attributes to select different table styles, then you can also customize the stylesheet to respond to such style names. For example, if you have a table style named smallfont-wide, then you could customize the table.properties attribute-set to use a smaller font and no indent.

<xsl:attribute-set name="table.properties">
  <xsl:attribute name="start-indent">
    <xsl:choose>
      <xsl:when test="@tabstyle = 'smallfont-wide'">0pt</xsl:when>
      <xsl:otherwise>inherit</xsl:otherwise>
    </xsl:choose>
  </xsl:attribute>
  <xsl:attribute name="font-size">
    <xsl:choose>
      <xsl:when test="@tabstyle = 'smallfont-wide'">8pt</xsl:when>
      <xsl:otherwise>inherit</xsl:otherwise>
    </xsl:choose>
  </xsl:attribute>
</xsl:attribute-set>

Each xsl:attribute element contains an xsl:choose statement to set its value. The choice is processed each time the attribute-set is used, so the context for @tabstyle is the current table. You could have additional xsl:when clauses for other table styles. Be sure to include the xsl:otherwise to provide the inherit value as a default so you do not end up with an empty attribute in the FO output.