User Tools

Site Tools


This is an old revision of the document!

Adding New Behaviors


If you'd like to change the colors, typeface, or other parts of your story's visual appearance, you may do so by creating a stylesheet passage and writing CSS code.

When a story is first loaded, all passages tagged stylesheet are added to the page's CSS. Tags are case-sensitive, so tagging a passage Stylesheet or STYLESHEET will have no effect. Also, there is no guaranteed order in which rules are added, so conflicting rules may produce unpredictable results.

Remember: stylesheet passages must only contain CSS.

A very quick summary of CSS

Cascading stylesheets is a web programming language used alongside HTML that defines the appearance and “look” of web page elements. By “style”, I mean things like italics, red colouring, centered positioning, shadows, and every other visual element which differentiate web pages from, say, plain text files.

CSS code, known as stylesheets, is code that resembles this structure:

  property-name : property-values ;
  property-name : property-values ;

That is to say, it involves a property name (which is a keyword for a certain aspect of a HTML element, like “background-color” or “text-shadow”) followed by a colon, followed by property values (which are keywords representing certain styles, like “bold” or “1px” or “black”), followed by a semicolon. This assigns the value to the property - font-weight: bold; is an instruction to make the element's font become bold.

These pairings of properties and values are assigned to HTML elements by selectors, which are basically vague, general descriptions of HTML elements. Any element that matches the description obtains the contained styles. For instance, :first-child selector causes the style to apply to every HTML element that is nested inside another element and is the topmost one within that element.

Example selectors

All of these are just standard ways to select HTML elements in CSS, but specifically targeting elements in the Twine story formats.

If you understand HTML and want a better sense of what elements these selectors are targeting, see the following reference pages:

Selector Description
.passage All the passages on the page. In Sugarcane, unlike Jonah, there's only ever one such passage. Note that this element fades in whenever you change passages, whereas #passages remains constant.
.passage:last-child In Jonah, this solely targets the “current” passage - the one at the bottom of the page.
.passage:not(:last-child) In Jonah, this solely targets the past passages.
.passage .title The passage title in Jonah.
.passage .toolbar The passage toolbar in Jonah.
.passage a Every link in a passage.
.passage a:hover A link that the cursor is hovering over.
.passage a:active A link that is in the midst of being clicked. (You can use this to make a link “light up” when clicked.)
.passage a.internalLink Only links to other passages (and not, say, other websites).
.passage a.visitedLink Every link to another passage that the player's visited at least once.
.passage a.internalLink:not(.visitedLink) Every link to another passage that the player's not visited yet.
.passage a.externalLink Only external links. Doesn't include HTML <a> links.
.passage li Bulleted or numbered list items in a passage.
.passage img Images in a passage.
.passage hr Horizontal lines in a passage.
.disabled Links that are not longer available to the reader, created through the «choice» macro, or by turning the Undo StorySetting to off.
#passages A container for all passages displayed on the page.
body The body of the HTML page – a great place to change the typeface for the entire page. But, individual elements' styles will usually override this.
#sidebar The Sugarcane sidebar, containing the StoryMenu.
#sidebar li List items inside the Sugarcane sidebar.
#floater The Jonah StoryMenu (which usually only contains 'Restart Story')
#footer The footer at the bottom of Jonah (e.g. “This story was built with Twine and is powered by TiddlyWiki”).
#credits The credits in Sugarcane's sidebar (e.g. “This story was built with Twine and is powered by TiddlyWiki”).

Example CSS code

This hides all passage titles, except for the current passage, from view in the Jonah story format:

.passage:not(:last-child) .title { display: none }

For more examples, see the frequently asked questions page.

Default CSS

In addition to your own CSS code, the story formats' HTML templates come with their own CSS code which provides their default look-and-feel. The code used in version 1.4.2 is listed here:

You can eliminate some of this CSS by selecting “Don't use the Story Format's default CSS” in StorySettings, or by including the words “blank stylesheet” in a CSS comment inside your own stylesheets. (This allows other people to create portable stylesheet code that doesn't require the story author to change their StorySettings manually.)

Tagged stylesheets

Normally, every stylesheet applies to all of the passages. If a passage has additional tags apart from 'stylesheet' (for instance, 'stylesheet forest'), then it will only apply to passages which themselves have that tag. This allows you to easily make different sections of a story have different styles to distinguish them.

Because the passage in the above figure has the same tag as the stylesheet, the stylesheet applies only to it, and any others with the same tag.

A note about Jonah

Tagged CSS in Jonah that uses the .passage selector will continue to affect the tagged passage even when the player advances to a different-tagged passage. But, CSS that targets the whole page, such as the body element, will not be retained. So, for instance, different link colours for a passage will remain on the passage as the game progresses, but changes to the page background will not.

Information about how Twine accomplishes this is available in this commit message.

Transition stylesheets

A special tag exists: transition. If a stylesheet has this tag, then its styling will replace the default passage transition animation.

When writing a transition animation in CSS, you will make use of the following selectors:

Selector Description
.transition-out A passage that is disappearing. This is only used in Sugarcane and similar formats. The styles in this CSS block define the final state of the passage's appearance - for instance, if this passage is fading out, its .transition-out style could have opacity: 0;.
.transition-in A passage that is appearing. The styles in this CSS block define the initial state of the passage's appearance - for instance, if this passage is fading in, its .transition-in style could have opacity: 0;.
.passage Passages should have additional CSS attributes: transition (used by most browsers) and -webkit-transition (used by certain older mobile browsers). This defines how long and in what manner the .transition-in styles are removed when passages appear, and how the .transition-out styles are added when passages disappear. See this documentation.

As an example, the following CSS defines a smooth “dissolve” transition:

.transition-in {
	opacity: 0;
	position: absolute;
.passage {
	transition: 1s;
	-webkit-transition: 1s;
.transition-out {
	opacity: 0 !important;
	position: absolute;

Adding New Behaviors

twine1/stylesheet.1503188229.txt.gz · Last modified: 2017/10/09 20:38 (external edit)