I started the year by writing a stylesheet to a new customer of ours. Since I have spent a little over a year studying what CSS lets you do, I had a chance to make some additions that older customers’ stylesheets might not possess.
As such, I figured that it would be nice to raise awareness of them with an article on the subject.
Page Breaks After Empty Topics
Most stylesheets used with DoX CMS already contain rules which prevent page breaks between titles and the content below them. Such rules do not directly apply to topics which only have a title and which only act as higher level headings for other content modules. Personally, I avoid the use of such empty topics. However, it is common practice to include them.
Here is the rule that I used to prevent page breaks between such headings and the preceding sub-headings:
.topicBodyWrapper:empty {
page-break-after: avoid
}
Simple enough. This rule states that page breaks are to be avoided immediately after empty containers for the contents of topics. Such empty containers remain a part of the document template used to compile PDF files. As a result, alternatives such as preventing page breaks between two subsequent titles do not work.
This rule can be directly applied to the stylesheets in any copy of DoX CMS, if users want to avoid higher level headings that are left at the end of the previous page.
It is good practice to make sure that the other rules that control page breaks account for enough possible scenarios. Read more on the subject here, for example.
Hyphenation
Broken table layouts are a very common reason for contacting support. Almost invariably, the reason behind them is a combination of automated column widths and too wide content. Solutions to both issues are addressed below, even if the provided rule itself only concerns the latter.
I am of the opinion that automated column width does not belong in manuals. This is merely an aesthetic consideration, however: When content width controls column width, otherwise similar consecutive tables or the same tables in different languages can have different column widths.
Another reason to prefer fixed tables is how automated column width reacts to insufficient overall width to accommodate all content. Such situations cause columns with automated width values to spread past page margins. In practice, this breaks the table layout completely and the culprits are hard to find amidst said mess. Even when the table works in the source language, this issue can arise in translations. Tables are a major reason why you should review translations even if you cannot understand the language itself.
In the case of fixed tables, content that is too wide instead spreads past column borders. This makes tracking it easy: you just need to locate such positions and fix them. This still requires you to review the content. But you can do it by browsing through the document.
There are ways to avoid the need for at least some manual corrections, though.
CSS supports adding language-specific automated hyphenation where line breaks are needed. Not all languages are supported by default. Finnish, for example, would require you to specify a separate resource. You must add the required hyphens manually in such cases. Instructions for adding automated hyphenation are provided below.
body {
hyphens: manual;
}
[lang="En"] * {
hyphens: auto;
}
*[doxelementclass="NoHyphens"], [doxelementclass="NoHyphens"] * {
hyphens: none !important;
}
The first item included a default value to be applied when language-specific settings are not provided. It makes sure that line breaks are allowed to split hyphenated words when there is not enough horizontal space to accommodate them.
The second item is an example of a language-specific rule where said language is supported in this respect by default. English is one such language. Adding further resources for hyphenation would require further specifications which are not discussed here. If such resources are not available by default, it is unlikely that they exist at all. The language identifier here specifies that content in that language must be hyphenated according to the proper grammar of that language around line breaks. However, if there is too little space for single syllable words, no hyphenation is added. These words must be accounted for manually.
The third item provides an element class that can be used to prevent hyphenation and line breaks for specific elements. You may, for example, require a phrase element (ph) with this element class to write product codes that contain hyphens but that must be kept on a single line. Because this is an element class, you can specify its name yourself.
Element Classes As Glue
We do not generally recommend controlling page breaks in individual positions. Forced page breaks not set between topics are particularly harmful to reusing content and also cause issues with the translations that inherit them. There can be good reasons to situationally prevent page breaks, though.
The customer that inspired this list, for example, uses lots of lists that include paragraphs that are under one line long both before and after the lists. Page breaks between the lists and these paragraphs would thus not look appropriate. Since this is not a general rule about all their lists, it should not be treated as such. As such, a solution that involves element classes is needed here:
*[doxelementclass="NoPageBreaksBelow"] {
page-break-after: avoid !important;
}
This element class prevents page breaks immediately below the elements that have it. If it were applied to both the paragraph before the list and to the list itself in a situation like the one described above, it would prevent page breaks between the main components of the whole.
Another option would be to use section elements and an element class that prevents page breaks between their immediate child elements. This would be an easier way to build complex wholes where elements cannot be separated on different pages. However, it would require writing at least the associated topic inside section elements. Implementing this practice in hindsight may prove too laborious.
Horizontal Pages
The manuals that this customer makes are intended for digital use only. As such, how printed versions look is of no importance. Some pages may thus have different page proportions. They asked for the option to include horizontal pages within documents. My solution is below. However, DoX CMS only supports this option when you use DocRaptor.
*[doxelementclass="HorizontalPage"] {
page: landscape;
}
@page landscape {
size: A4 landscape;
margin-left: 20mm;
margin-right: 20mm;
margin-top: 20mm;
margin-bottom: 20mm;
}
These rules essentially categorize pages with elements that have this element class as their own page group. The pages of this page group have a landscape layout. You can specify appropriate page margins.
Horizontal pages let you have more available width. This is useful in situations such as when a table has more columns or especially wide columns.
This element class works best with topics and section elements. When it is applied elsewhere, the surrounding elements will be moved to different pages. If only the start of a topic must be on such a page and it has other content as well, this element class must be applied to both the title element of the topic and the other elements in question. You cannot select the title element directly. As such, you must apply the element class to its source code. To do this, you must copy the element class from a different element and add it as an attribute of the title element.
References to Other Elements
Since you can add ID values to different elements such as notes and paragraphs (p), you can also target them with internal links. Usually, internal links are only used with other topics, tables and figure elements. When you target other elements with them, the references will apply the generic ‘default-series’ variable and the target element will receive a corresponding title. The latter issue can be readily solved if you will always use such links with references that you write yourself.
.anchor-title:not(.dita-table .dita-title *):not(.dita-fig .dita-title *) {
display: none !important;
}
This rule hides the titles mentioned above. Using this tule makes the references provided by the system unviable because the target does no longer has the title that they mention. As such, it is important to always write references such as ‘here’ for such links.