How to create hanging indentation with Twine (any format)


I am trying to use Twine to create hipertextual editions of old poets, to make their work easily available and even to offer different ways of reading.

So, right from the start, I need to account for hanging indentation, which in poetry is “is a technique used by typesetters to, among other things, maintain the integrity of a line that is longer than the width of the page (less the margins).” (more here)

From what I read, the trick is to use padding to compensate for the negative indent, styling something like:

.hangingindent {
  padding-left: 22px ;
  text-indent: -22px ;

And then calling it.

I’ve tried to add the above information to Twine’s stylesheet and then call it in a passage using

<div class="hangingindent">very long verse</div>

And in Harlowe it works, but this means having to add this manually to all the long verses, which is definitely not the right way to do it. What I would like is for this to be the regular behaviour for all the text. And this I don’t how to do.

Could anyone help?

I’m more familiar with Harlowe and Chapbook, but if this is something easier accomplished with any other format, I don’t mind changing my project to that format.



A quick google search found this answer that seems to work.

.hangingindent {
    padding-left: 1.5em;

It’ll only work for block elements like div and p though, not inline elements like span.

The issue is that the negative text-indent technique is applied to all of the textual content within the element you are targeting the CSS selector at.

eg. If you added the following CSS to a Harlowe based project…

tw-passage {
	padding-left: 1.5em;

…then all lines of textual content within the main Passage area, except the first line, will be indented.

This is why you need to wrap each section of textual content you want to apply the effect to within a HTML element, so that the web-browser knows when to stop applying the indentation.

Thanks, Greyelf. So if do understand well, there is no way I can apply the “hanging indent” globally to a twine passage via “tw-passage”? So for instance for the following poem to get the right indentation:

The Tejo is more beautiful than the river that runs through my village,
But the Tejo is not more beautiful than the river that runs through my village
Because the Tejo is not the river that runs through my village.

I would have to do:

<div class="hangingindent">The Tejo is more beautiful than the river that runs through my village,</div><div class="hangingindent">But the Tejo is not more beautiful than the river that runs through my village</div><div class="hangingindent">Because the Tejo is not the river that runs through my village.</div>

I can get a sort of reversed effect (as the line breaks it loses the indentation) if I use the following Harlowe code in a passage with the 3 lines poem I mentioned at the beginning.

(enchant: ?passage's lines, (text-indent:12))

Is there any type of code, similar to this last one, that I could add to affect the whole passage. A solution like this would already make my life easier.



Thanks, tayruh, but that I had already managed to do. What I want is a way to apply that effect globally to all the the text in all the passages, without having to add the <div> block to every line in every passage.

Yeah, sorry. I guess I read too quickly and misunderstood. I see now that my answer is basically what you already had written. :x

Thank you for reminding me of a newish feature I had forgotten, namely the ability to use the lines property of the ?Passage built-in Named Hook to apply an (enchant:) macro to each ‘line’ (1) within the ‘current’ Passage. The following (enchant:) macro call uses the (css:) macro to apply the effect you asked for to each ‘line’ of textual Passage content…

First very long verse that ends with a line-break.
Second very long verse that ends with a line-break.

(enchant: ?Passage's lines, (css: "display: inline-block; width: 100%; padding-left: 1.5em; text-indent: -1.5em;"))


  1. A ‘line’ appears to be defined as a sequence of textual content followed by one or more line-breaks.
  2. The (enchant:) macro call wraps its ‘target’ within a custom <tw-enchantment> element, in this case that target is each & every ‘line’ of textual content, and then applies the enchantment to each of those <tw-enchantment> elements
  3. The additional display: inline-block; width: 100%; CSS is required to change the <tw-enchantment> elements from an inline based element, which ignores the text-indent property setting, to an inline-block base element.

warning: The above enchantment will also target the Link Text of any links within your Passage.

Amazing!!! Thank you so much, Greyelf, for this beautiful piece of code. It works perfectly! Now I should be able to apply this code globally by adding it to the header or the footer of the story.

Many thanks, once again, for all your assistance, Greyelf.