Defining Styles

With Ulysses Style Sheets you are able to create custom rich text styles for exporting your Ulysses documents. In order to assign a style to a certain definition in Ulysses, you just write a so-called style class. A style class consists of a style selector and some style settings:

inline-strong {
	font-family: "Cochin"
	font-weight: bold
}

Style settings are written as key-value pairs, like font-family: "Cochin". A style setting ends on a line break. To place multiple settings in a line a semicolon ';' can be also used:

inline-strong { font-family: "Cochin"; font-weight: bold; }

Ulysses style sheets provide you a many flexible way to re-use style settings through variables and expressions. We give a more detailed overview on style settings later. You will find an overview on all style settings in the Settings Reference.

Style Selectors

A style selector specifies when a style should be applied. The most simple style selector is a definition selector, like inline-strong or heading-1. However, if you want to create a style for an entire class of definitions, you may also use definition class selector, like list-all. These selectors match any contents of a certain type: For example the selector list-all matches all lists: e.g. list-ordered and list-unordered.

Besides the definitions used in your Ulysses document, there are also some general class selectors that describe settings regarding the visual appearance of the entire exported document. For example, the selector area-header and area-footer can be used to style of the header or footer area of any page in your document. The class document-settings contains general settings of the document, like the paper format. The setting defaults describe the base style for any node inside your document.

You will find a comprehensive overview of all possible definitions and their settings in the Class Reference.

Relative Selectors

Style selectors can be used in a very flexible way: with a relative style selector, you can specify that a style should be only used for content placed in a special position relative to other content. For example you can declare a style that should be only used for paragraphs following a heading1 in your document:

heading-1 + paragraph {
	margin-top: 0pt
}

The following relations can be used for relative style selectors:

Relation Example Description
Definition strong The style class matches all nodes using a certain Definition.
Definition + SuccessorDefinition heading1 + all-paragraphs The style class matches all nodes using SuccessorDefinition that follow immediately a node using Definition.
ParentDefinition ChildDefinition area-footnotes image The style class matches all nodes using ChildDefinition that are somewhere nested under a node using ParentDefinition.
ParentDefinition > ChildDefinition orderedList > unorderedList The style class matches all nodes using ChildDefinition that are immediately nested under a node using ParentDefinition.

Pseudoclasses

Further refinements on a style selector can be done with pseudoclasses. Some pseudoclasses may be used to determine the position of a node inside its parent node. For example, by using the :first pseudoclass you can specify that a certain style may be only applied to the first paragraph of a block quote:

block-quote > paragraph :first {
   first-line-indent:	0pt
}

It is also possible to specify multiple pseudoclasses at once:

block-quote > paragraph :first :last {
   first-line-indent:	0pt
}

There are also pseudoclasses that match depending on the position on the generated output. For example, the pseudoclasses :left-page, :right-page can be used to specify the format of a header or footer when exporting the left or right pages of a two-sided document. Finally, there are pseudoclasses used to specify a certain aspect of a style. For example the :enumerator pseudoclass is used to style the enumerator of an ordered list (e.g. to make a bullet point bold).

Currently, the following pseudoclasses exist:

Name Availability Description
:first-page Headers and Footers The style will be only applied to headers or footers that are on the first page of a section.
:left-page Headers and Footers The style will be only applied to headers or footers that are on the left page of a section.
:right-page Headers and Footers The style will be only applied to headers or footers that are on the right page of a section.
:anchor Footnotes Area The style of the anchor inside the footnote area. See Inline Class. Defaults to superscript text.
:first Inline, Headers and Footers, Footnotes Area, Media, Footnotes, Paragraph, Figures, Figure Captions, Divider, Block, List, Table, Table Cell, Syntax Highlight, Technical The style matches any node that is the first child of its parent.
:last Inline, Headers and Footers, Footnotes Area, Media, Footnotes, Paragraph, Figures, Figure Captions, Divider, Block, List, Table, Table Cell, Syntax Highlight, Technical The style matches any node that is the last child of its parent.
:anchor Footnotes Used for styling referencing anchor of an annotation separated from the annotated content. See Inline Class. Defaults to superscript text.
:enumerator List The style of the enumerator of a list. Supports all Inline style settings.
:body Table Cell, Table The style will be applied to all cells of a table that are not part of the header.
:header Table Cell, Table The style will be applied to all header cells of a table.
:header-row Table Cell, Table The style will be applied to all header cells of a table that form a continuous row.
:header-row-boundary Table Cell, Table The style will be applied to all cells that are on the boundary between regular cells and cells around one or multiple header rows. I.e. it will style all cells before the first row and on the last row of any continuous header row area. This is especially useful to style the separators enclosing multiple continuous header rows using row-separator-*.
:header-column Table Cell, Table The style will be applied to all header cells of a table that form a continuous column.
:header-column-boundary Table Cell, Table The style will be applied to all cells that are on the boundary between regular cells and cells around one or multiple header columns. I.e. it will style all cells before the first column and on the last column of any continuous header column area. This is especially useful to style the separators enclosing multiple continuous header columns using column-separator-*.
:header-top Table Cell, Table The style will be applied to all header cells are place in the topmost header rows of the table.
:header-top-boundary Table Cell, Table The style will be applied to the cells of the lowest row among the topmost headers. This is especially useful to style the separator between the topmost header rows and the rest of the table using row-separator-*.
:header-left Table Cell, Table The style will be applied to all header cells are place in the leftmost header columns of the table.
:header-left-boundary Table Cell, Table The style will be applied to the cells of the last column among the leftmost header columns. This is especially useful to style the separator dividing the leftmost header columns and the rest of the table using column-separator-*.
:header-bottom Table Cell, Table The style will be applied to all header cells are place in the bottommost header rows of the table.
:header-bottom-boundary Table Cell, Table The style will be applied to the cells of the row before the bottommost header rows. This is especially useful to style the separator dividing the bottommost header rows and the rest of the table using row-separator-*.
:header-right Table Cell, Table The style will be applied to all header cells are place in the rightmost header columns of the table.
:header-right-boundary Table Cell, Table The style will be applied to the cells of the columns before the rightmost header columns. This is especially useful to style the separator dividing the rightmost header columns and the rest of the table using column-separator-*.

Evaluation Order

In some cases multiple styles may match your content like the following example shows:

list-all {
	margin-top:			5pt
	margin-left:		10pt
}

list-ordered {
	margin-left:		20pt
}

defaults {
	font-size:		14pt
}

In this case, styles are applied in the order of their occurrence. For example, if a node of the type list-ordered should be styled first list-all will be applied, then list-ordered and finally defaults. Thus, the computed style will be:

margin-top:		5pt			// from list-all
margin-left:	20pt		// from list-ordered
font-size:		14pt		// from defaults

Inheritance

If you are exporting nodes that are nested in other nodes, the nested contents inherits all styles of higher level that it does not define by itself. Consider, you have the following Markdown document and the following Ulysses Style Sheet:

> # Heading with **strong text**
> Normal text inside quote

block-quote {
	font-family:	"Cochin"
	font-slant:		italic
}

heading-1 {
	font-family:	"Futura"
	font-size:		24pt
}

inline-strong {
	font-weight:	bold
}

The style of “strong text” will be derived by mixing the style of block-quote with heading-1 and inline-strong. Whereas the settings of inner elements overwrite the settings of outer elements. Thus, the computed style will be:

font-family:	"Futura"			// heading-1 overwrites the font-family of block-quote
font-slant:		italic				// Inherited form block-quote
font-size:		24pt				// Set by heading-1
font-weight:	bold				// Set by inline-strong

Mixins

Sometimes it is useful to create general presets that can be shared around multiple styles. For example the style inline-code and code-block may share the same font settings. This can be done by using mixins. A mixin is a set of predefined settings that can be embedded into other styles. The following example shows how a mixin @general-code-style is defined and how it is embedded to a style:

@general-code-style {
	font-family: "Courier"
	font-size:   12pt
}

inline-code : @general-code-style {
     font-color: #0000ff
}

block-code : @general-code-style {
      font-color: #ffffff
      background-color: #0000ff
}

A mixin identifier always starts with an “@” character. A mixin identifier may contain any alphanumeric character. Multiple words are typically separated by dashes: @my-mixin-name. It is applied to a style definition after the style selector using a colon “:”. To apply multiple mixins to a style, just use a comma separated list:

some-style : @first-mixin, @second-mixin, @third-mixin {
}