How to customize Ulysses

PDF/DOCX Styles

Ulysses lets you export your writings to a host of standard formats with just a few clicks. Thereby, the so-called styles are used to define the look of the final document. Ulysses ships with a couple of built-in styles, and you can download many more on the Styles & Themes website. With Ulysses for Mac, you can also create your own custom styles using Ulysses Style Sheets.

A Ulysses Style Sheet (ULSS) stores your style settings in a simple yet flexible text format. The ULSS format resembles the popular CSS (Cascading Style Sheets) format. If you’re familiar with CSS, you may skip the first part of this tutorial and start directly with our introduction for CSS artists.

For a full overview of the Ulysses Style Sheets syntax, descriptions and examples, please consult the ULSS reference. Also, whenever you click on a definition in the text below, it will take you directly to the respective paragraph in the reference.

Table of contents (use the links to jump directly to the respective article section):

Ulysses Style Sheets for Beginners

In the following, Ulysses Style Sheets will be explained step-by-step and without requiring any knowledge of other style sheet languages.

The single prerequisite for getting started is a text editor. To get auto-completion and colorful syntax highlighting, we suggest using either TextMate 2, Sublime Text 2 or Atom. We’ve also created a plugin for simple syntax highlighting in BBEdit and TextWrangler. For both applications, we provide plugins for ULSS.

Let’s Start

We suggest starting by modifying a copy of a built-in Ulysses style. This way you can use this style as a simple scaffold and don’t need to start from scratch. From the Ulysses menu, open Preferences and select the Styles section. Double-click the “Novel Cochin” style and duplicate it. After that, double-click the copied style again and click “Edit” to open it with a text editor of your choice.

Now you’ll see a text file containing a description of your export style. The description is divided into many different sections, and every section looks similar to the following example:

heading-all {
  font-family: "Futura"
  …   }

If you scroll through the file, you’ll see that there are sections for almost any of Ulysses’ markup definitions. For example, the section heading-all describes the generic styling of your headings. Another section, inline-strong, contains the styling of text using the strong markup. We call such a section style class.

Each style class begins with a style selector (like heading-all or inline-strong), which tells Ulysses when a style class should be applied. The selector is followed by a “block” surrounded with curly braces { }. This block contains the actual style settings as pairs of setting names and values. The example above specifies that all headings should use the font “Futura”.

So, let’s play. Change the font family of heading-all in your style sheet from “Futura” to “Avenir Next”:

heading-all {
  font-family: "Avenir Next"
  …
}

Save this change in your text editor and switch back to Ulysses. Then create a sheet that contains the following lines:

# This is a **heading 1**!
## This is a **heading 2**!
This is a normal **paragraph**!

Export this sheet to PDF using your modified style. As you will see, all headings are now styled with the font ”Avenir Next”.

Don’t Repeat Yourself!

When creating a style, you don’t need to repeat yourself over and again: instead of setting the font family or size for each markup definition individually, Ulysses automatically selects the right default value. This way, you can change settings consistently at a single point without losing track of your design. If you look inside your style sheet, you will see that all headings share the same font setting but use different font sizes:

heading-all {
  font-family: "Zapfino"
  …
}

heading-1 {
  font-size: 33pt
  …
}

heading-2 {
  font-size: 22pt
  …
}

When styling text, Ulysses scans all your style classes from top to bottom. Whenever a style class matches your content, it will be used for styling it. For instance, for styling text inside a heading 2, the classes heading-all and heading-2 may match. Depending on their ordering in your style sheet ulysses will mix them. In our example, it will mix the font-family of heading-all with the font-size of heading-1 or heading-2. If two styles contain the same settings, the settings of the later style will be used.

Cascading Styles

Recall our sample text:

## This is a **heading 2**!
This is a normal **paragraph**!

Besides a heading markup, it also contains a word marked up as “strong”. In one case, this text is part of a heading, while in the other case it belongs to an ordinary paragraph. In your export result, you see that the text marked up as strong is styled with a bold font, no matter the paragraph type. 

inline-strong {
  font-weight: bold
}

Whenever a markup is nested inside another markup, Ulysses automatically mixes their styles during export: the actual style is composed by adding the styles of inner markups (e.g. inline-strong) to the styles of outer markups (e.g. heading-2). You don’t have to create style classes for all possible combinations; one is enough.

Conditional Styles

However, in some cases, you may want to style your text depending on its position. Let’s assume you don’t want to export any bold text inside a heading. How do you prevent styles from being mixed? The solution is to use conditional selectors. Just add another class after your inline-strong class:

heading-all inline-strong {
  font-weight: none
}

The style selector of this class must be read from right to left. It means: “A strong text inside any heading”. The settings of this style class state that such strong text should not be styled as bold. Since this style class is placed after the occurrence of inline-strong (inside the style sheet), it will override it.

Of course, there are other scenarios for conditional styles. For example, you may like to vary the first line indentation of a paragraph, depending on whether it is the first paragraph after a heading or not. In this case, you can create a conditional style using the “+” relation:

paragraph {
  first-line-indent: 10pt
}

heading-all + paragraph {
  first-line-indent: 0pt
}

The first style class causes any paragraph to be styled with a first-line indent of 10 points (pt). The second class overrides this setting for all paragraphs that immediately follow a heading.

There are much more possibilities to style your content conditionally; you can find a full overview of style selectors in the syntax overview.

How to Continue?

So far, you’ve changed the style of some headings. When reading through the style sheet, you will find many more style classes. Many of them are similar to the definition names of your Ulysses markup: e.g., inline-emphasisstyles emphasis text, block-code styles code blocks, and list-ordered your ordered lists.

However, there are also some special style classes: the class defaults is used as a base style for all text inside your document. If you change it, all unstyled text will change as well. The style class document-settings contains details applying to the entire exported document, like the paper format or the way footnotes are enumerated.

We’ve assembled a couple of How-To’s to explain a few common style tweaks, depending on what you want to achieve, they will lead you pretty far.

To learn more about all existing style classes and their style settings, you may use our comprehensive reference. To dig deeper into some more advanced features of ULSS, we recommend taking a look at the syntax overview.

Ulysses Style Sheets for CSS Artists

If you are familiar with CSS, learning Ulysses Style Sheets will be pretty easy. Just duplicate one of the built-in styles by double-clicking it and edit it with your favorite text editor. We provide plugins for autocompletion and syntax highlighting in Text Mate 2, Sublime Text 2 and Atom. There is also a simple syntax-highlighting plugin for BBEdit and TextWrangler.

Similar to CSS, a ULSS style sheet consists of style classes that will be applied to your text depending on a style selector. For example, setting the font size of a level 1 heading can be easily done with the following style class:

heading-1 {
  font-size: 33pt
}

To simplify styling, we’ve added some advanced features to ULSS and skipped some less relevant features from CSS. This chapter will give you a short overview of important differences and similarities. To get a comprehensive overview of all available style settings, have a look at the full reference.

Generic Selectors

Besides selectors for particular markups (e.g. inline-strong), ULSS also supports generic selectors. A generic selector is matching an entire category of markups. For example, you may create a style for all headings using the heading-all class. Currently, the following generic classes are available:

Relative Selectors

Similar to CSS, a style selector may not only select a single markup but may contain a condition to relate multiple styles. For example, the selector heading-all + paragraph states that a certain paragraph class should only be applied when the paragraph is following a heading. ULSS supports the following relations from CSS:

  • parent child
  • parent > immediate-child
  • predecessor + successor
  • several pseudo-classes like :first or :last

Style Inheritance

Like CSS, Ulysses Style Sheets are cascading: the style of an inner markup overrides the style of an outer markup.

If multiple style classes can be applied to a markup (e.g. heading-all and heading-1), styles are preferred by their order in the style sheet. Styles declared later in the style sheet will override earlier declarations. Style classes for nested element (e.g. table-cell paragraph) are prioritized over style classes that are not nested (e.g. just paragraph).

Mixins

If you like to share style settings among multiple style classes, you can use style mixins. A mixin extends a style class just as if it would be a part of it:

@code {
  font-face: "Menlo";
  font-weight: normal;
  font-slant: normal;
}

block-code : @code { }
inline-code : @code { }

In the above example, the settings from @code are applied in both block-code and inline-code, saving you the need to write the same settings multiple times.

Variables and Expressions

To improve the readability of your style and to make it easier to create variants of it, you may use variables. For example, you can store a commonly used color inside a variable and re-use it among multiple styles:

$light-grey = #eeeeee

inline-mark { background-color: $light-grey; }
inline-annotation { background-color: $light-grey; }

Variables can even contain simple calculations (“expressions”) anywhere in your style sheet:

$base-color = #FEFECC
$dark-base-color = $base-color * 0.8

Of course, expressions may be also used inside style settings:

inline-annotation {
  background-color: $base-color * 0.5;
}

Ulysses Style Sheets: How To…

…Create a New Style?

The best way to start is by duplicating one of the built-in style sheets. Via the Ulysses menu, open Preferences and enter the “Styles” section. Double-click one of the built-in DOCX/PDF styles and duplicate it. If you double-click the copy again, you may edit it with a text editor. For some text editors, we provide plugins for syntax highlighting and auto-completion.

…Set a Custom Font?

Change the setting font-family inside the style classes you want to change. If you like to change the font of a heading, change heading-all or heading-1. If you want to change the general font, modify the defaults style:

defaults {
  font-family: "Avenir Next";
}

heading-all {
  font-family: "Futura";
}

…Use the Light or Condensed Variant of a Font?

To use a certain variant of a font family, use the font-style setting:

heading-all {
  font-family: "Helvetica Neue"
  font-style: "UltraLight"
}

You get an overview on all font families and font styles from the Font Book application in macOS. Inside the font list, just expand the font family entry and you will get a list of all available font styles.

Set the text-alignment of a heading:

heading-all {
  text-alignment: center
}

If you’d like to center only a specific heading level, use selectors like heading-1 or heading-4.

…Add a Page Break Before a Heading?

If you like to add a page break before a certain heading level, add the page-break: before setting to the heading class.

Additionally, if page breaks should also restart numbering of footnotes, you should consider updating the section-break setting in the document-settings class.

…Change the Indent of the First Paragraph?

Using the pseudo-class :first, you can create styles that only match the first paragraph of your sheet:

paragraph {
  first-line-indent: 10pt
}

paragraph :first {
  first-line-indent: 0pt
}

If you like to vary the first line indent after a heading, you may use a class relation:

heading-all + paragraph {
  first-line-indent: 0pt
}

This style only matches those paragraphs which follow a heading. To learn more about pseudo-classes and style relations, please refer to the syntax reference.

…Change the Enumeration of Lists?

The enumeration style of text lists can be set using the enumeration-format and enumeration-stylesettings. For instance, to set alphabetic enumeration of text lists, just change the style of list-ordered:

list-ordered {
  enumeration-format: "%p)"
  enumeration-style: lowercase-alpha
}

The placeholder %p will be replaced by the enumeration character during export. Using this style, your list will be enumerated by “a), b), c)”. If you would like to vary enumerations among list levels, use a relative style:

list-ordered {
  enumeration-format: "%p."
  enumeration-style: decimal
}

list-ordered list-ordered {
  enuemration-format: "%p)"
  enumeration-style: lowercase-alpha
}

Using this style, the first level will be enumerated by “1., 2., 3.”. All nested levels will be enumerated alphabetically: “a), b), c)”.

…Change the Enumeration or Placement of Footnotes?

To change the way footnotes are enumerated or placed, adjust the footnote-enumeration and footnote-placement settings inside the document-settings class.

…Export My Original Markup?

For all technical content, you can use classes like ulysses-tag or ulysses-escape-character. These classes are invisible by default. To make them visible, insert the following code snippet:

ulysses-tag {
  visibility: visible 
}

…Set the Paper Format?

To adjust the paper format for your PDF file, you can use the page-height and page-width settings inside the document-settings class. You may also create a two-sided document with varying page insets there.

…Create a Table of Contents, Bibliography or Reference?

Unfortunately, this is currently not supported. However, we have plans to add it in future releases of Ulysses.

This article was last updated on March 6, 2019.