This guest post was written by Jay Slagle, an independent consultant and certified MadCap Software Advanced Developer who is passionate about using CSS to enhance the power of MadCap Flare. After discovering MadCap Software tools over a decade ago while working as a technical writer in Seattle, he has designed and implemented Flare projects for clients in government, law, education, healthcare, and technology. When he’s not occupied with all things Flare, Jay writes fiction under the pen name JB Strand.

In my last two articles, I introduced CSS complex selectors and showed how to use them to manage lists and cut down on the number of paragraph classes in your MadCap Flare projects. In this article, I will look at an area in which descendant selectors are incredibly useful: managing tables. Using complex selectors, you can maximize the flexibility of tables while minimizing the number of paragraph styles (and even table styles) that you need to create.

Flare Table Designer

The Flare TableStyle Editor is an excellent tool for defining the styles of the overall table structure, such as margins, borders and background colors. To maintain flexibility with table content styling, though, do not use the table style editor to define classes or styles for table content. As illustrated here, leave properties for the paragraphs inside of table cells set to their defaults:

TableDesignerRowDefaults

Table Structure

To use CSS selectors with tables, it's important to understand XHTML table structure. Each table in a Flare source topic uses a similar structure, although tables are not required to have headers:

<table>
    <thead>
        <tr>
            <th>...table header cell contents...</th>
        </tr>
    </thead>
    <body>
        ...table body...
        <tr>
            <td>...table body cell contents...</td>
        </tr>
    </tbody>
</table>

Tables are tailor-made for descendant selectors because they define a nested structure in which you can select the entire table or just one part of it. You can use a descendant selector to define content styles for all tables, for example. Or you can select a particular table class and drill down to table elements such as <th> (table header cell) or <td> (table body cell) elements.

Style Overrides for Paragraphs and Lists in Tables

It is easy to modify paragraphs that appear in tables without creating new styles specifically for those table elements. In my last article, I demonstrated CSS syntax for making lists and paragraphs similar. The following syntax modifies those values when the paragraphs or lists appear in tables. It changes the typeface as well as the font size, line height and margins using values set through variables defined in the CSS root element:

td,
td p,
td li
{
    font-family: var(--FontSansSerif);
    font-size: var(--FontSizeSmall);
    line-height: var(--LineHeightSmall);
    margin-top: 4pt;
    margin-bottom: 2pt;
}

The first line above selects the table cell, <td>. This keeps text in the table looking the same whether it is directly in the cell (<td>My Text</td>) or contained within a <p> element (<td><p>My Text</p></td>). The second and third lines use descendant selectors to select paragraphs (<p>) and list entries (<li>) that appear in table cells.

Tip: It's best to put table override styles below the default styles within the stylesheet. This guarantees that they inherit the default values.

List Type Overrides for Lists in Tables

If lists are styled entirely through CSS, you can change numbering or bullet styles whenever a list appears within a table cell:

td ol
{
    list-style-type: upper-roman;
}
td ol ol
{
    list-style-type: lower-roman;
}
td ul
{
    list-style-image: none;
    list-style-type: disc;
}
td ul ul
{
    list-style-type: circle;
}

Table Style Example

Here is an example of a list I used in my previous article. This demonstrates my standard list structure in body text:

BulletedNumberedList

Here is the exact same list inside a table:

ListInsideTable

As you can see, the descendant selectors for table cells allow you to change virtually any aspect of a list when it appears within a table. Best of all, you can copy and paste lists between the regular text column and a table cell without needing to assign different style classes. CSS takes care of everything.

Selecting a Specific Table Style

Each table you create with the Flare TableStyle Editor has a table class name in this form:

TableStyle-Table_CSS_File_Name

For instance, if my table stylesheet is named PatternedRows.css, the class name for those tables within the Flare topics will be TableStyle-PatternedRows. In the topic Text Editor, you can find the class name within the <table> tag:

<table style="margin-left: 0;margin-right: auto;width: 50%;
mc-table-style: url('../Resources/TableStyles/PatternedRows.css');"
class="TableStyle-PatternedRows" cellspacing="0">

Setting a Heading Style in a Specific Table Style

Once you know the table class name, you can use a descendant selector to target specific elements within this type of table. In this example, I'll use a table with a header that has a dark background and white text:

TableHeadingHTML

Instead of creating <th> or <p> classes that specify white text in the header, I can use a descendant selector to identify the headers for this specific table style. First, I set font attributes for table header cells (<th>) in the default medium. Because a table header cell may encapsulate a standard paragraph, I add another descendant selector to style any standard paragraph that appears within the table header:

table.TableStyle-PatternedRows the,
table.TableStyle-PatternedRows th p
{
    font-family: var(--FontSansSerif);
    font-size: 12pt;
    line-height: normal;
    letter-spacing: 1px;
    color: var(--White);
    text-align: center;
    margin: 0;
    padding-bottom: 6pt;
    padding-top: 6pt;
}

Because the table header provides padding, I can eliminate padding from any encapsulated paragraphs if needed by adding the following below the preceding entry in the stylesheet.

table.TableStyle-PatternedRows th p
{
    padding-bottom: 0;
    padding-top: 0;
}

Changing the Header Text Style in the PDF Output

Suppose that I want to change this table's header background color to a light gray in PDF outputs. I can do this in the Flare TableStyle Editor, which supports changes in the print medium:

TableDesignerPrint

But if I change the table header backgrounds to white, the white header text will not show up. I can rectify this in the stylesheet’s print section by specifying the color black for <th> and <p> elements contained within this table:

table.TableStyle-PatternedRows the,
table.TableStyle-PatternedRows th p
{
    color: var(--Black);
}

The table in the PDF then looks like this:

TableHeadingPDF

Reducing Text Size in Large Tables

Squeezing content into a table can be frustrating when tables have many columns and the table cell text shouldn't wrap. PDF outputs can be particularly vexing because of the limited width of the page. Of course, you can create paragraph styles at smaller font sizes and laboriously tag every paragraph in the table, but why not let CSS eliminate the drudgery?

One solution is to create a new table style and use a descendant selector to reduce the font size of paragraphs in that type of table. But this requires creating an additional table style just so you can use the unique table name in a descendant selector. Feels like overkill, right?

An alternative is to create a table body style that reduces font sizes for the data cells in any table you choose. The following markup selects table cells and, using an asterisk as a wildcard character, all elements within each table cell:

tbody.SmallText td,
tbody.SmallText td *
{
    font-size: 9pt;
}

There is one hitch with this solution. The Flare GUI does not let you assign a class to a table body element. (This is not a common use-case.) However, you can add the style class manually using the Flare Text Editor. In the XHTML markup, find the table’s <tbody> tag and add the class designation:

<tbody class="SmallText">

Here's an example of a standard PDF table in which the table data cell is the standard size, which causes the text in each cell to wrap:

TableTextNormal

Here's the same table with the SmallText class assigned to the table body. Note that the text in the header cells is not affected because it falls outside of the table body, though you could reduce it too using the appropriate selector:

TableTextSmall

Tip: If you reset or change the table style, the table body class will be lost. When you apply this type of style to a table, it's a good idea to note this using an annotation.

Summary

If you have followed along with my last few articles, you can see how CSS complex selectors provide tremendous power for formatting HTML and PDF outputs while also keeping your stylesheet simple. It's a win-win. If you have a bunch of special classes that you use to change the styling for paragraphs, lists, or notes embedded in tables, you can often use complex selectors to eliminate most if not all of these classes.