Making a visual story that goes down?

Twine Version: Latest!
[also choose a Story Format tag above]

Hey you beautiful people!
I want to create a visual story that goes down. It’s a mix with photography and text and I want to be able to click a word and then go down to next photo and for the next text to appear. Is this possible in twine Harlowe? And could you give me som pointers on how to start and maybe some code ideas?


If the only links in the story will be used to navigate passages (i.e. you want all links in the story to cause the sliding passage effect), you can use this code in a passage tagged as header or footer to enchant all the links:
(enchant: ?link, (t8n-arrive:"slide-up"))

I would also suggest looking into Ink/Inky, another IF creation tool. The default UI transitions for links seem like they’d be a perfect fit for what you’re describing.


As I understand it, you want to have a story continuously build by adding pictures and text below what’s already displayed.

You could “build” your story by using links that call the (display:) macro.

In your story’s style sheet passage:

html { scroll-behavior: smooth; }

The first passage will look like:

<div name="passage-top"></div>
Picture 1 & Text

(link-reveal: "2nd")[

(t8n: 'dissolve')[(display: "Passage 2")]{<script>
let elements = document.getElementsByName("passage-top");
let count = elements.length;
elements[ count - 1 ].scrollIntoView();

…and your second passage (labelled “Passage 2” in this case) would look like this:

<div name="passage-top"></div>
Picture 2 & Text

(link-reveal: "3rd")[

(t8n: 'dissolve')[(display: "Passage 3")]{<script>
let elements = document.getElementsByName("passage-top");
let count = elements.length;
elements[ count - 1 ].scrollIntoView();

…and so on. It uses a little HTML,CSS and JavaScript to make the content scroll smoothly into view. The CSS ensures a smooth scrolling action when the JavaScript calls the .scrollIntoView() command. The HTML gives the scrolling an actual target to hit. Because multiple <div name="passage-top"> tags are created (all with the same name), the JavaScript figures out the last one in the list of possible matches before scrolling it into view.

I had to create a <div> tag at the top of each passage because simply scrolling to the bottom of the page won’t work if the passage content is taller that the visible area. The top of the content would be cut off. Not desirable at all.

Note: A custom macro should be created for the links eventually to clean up the required code in your passages, but I’m heading off to bed now. Oh, and be careful not to put extraneous empty lines below your passage code.

Hopefully, this nudges you in the right direction. If it’s not what you were looking for, I had fun figuring it out at least. :wink: I might use this for my own IF one day. It works really well.

You can also play around with having everything in one passage and using the (link:)[== method.

1 Like

warning: The History systems of the main Story Formats are designed around transitioning from one Passage to another, during which the current state of all known Story variables are persisted to History. And any Save the end-user makes generally consists of persisting the current state of History.

Simply put, the current value of the Story variables is only added to History with a Passage Transition occurs. And a Save only contains what was currently in History when the save was created.

So while it is technically possible to create a project that dynamically reveals new content below the current content of a Passage, and Story variable changes made within that Passage or the new content being revealed won’t be persisted to History until the end-user visits the next Passage.

@HAL9000 has already shown you one technique for dynamically add new content to the current Passage being visited. I will demonstrate another that makes use of Hidden Hooks and the (show:) macro to reveal sections of the current Passage that start off hidden.

Where have you been?
(link: "Around.")[Around. (show: ?text2)]

And what have you been doing?
(link: "Things.")[Things. (show: ?text3)]

Could you answer in sentences rather than single words.
    (link: "OK.")[{
        (replace: ?choice)[OK.]
        (show: ?text4)
    (link: "Nothing.")[
        (replace: ?choice)[Nothing.]
        (show: ?text5)


OK, if you must know I went to London to visit the Queen!

And while I was there I bought a wheel barrow!

What, nothing at all?

(link-goto: "Yes", "Another Passage")

A couple of benefit of this technique are:

  1. Better control of where the revealed content is positioned on the page.
  2. No potential indentation issue that can come from having to embed one reveal link inside the Hook of another.
  3. You can apply the same “revealing” visual effects to the (show:) macro.
    eg. (t8n: 'dissolve')(show: ?text4)
  4. You can still use ‘child’ Passages to contain the content being revealed.
    eg. `|text4)[(display: ‘some other Passage’)]

Thanks for this!! … I tried it out a little bit today and it felt right. But Im going to have more time this evening…

But this might just work perfect…

1 Like

This could work to… Gone give it a go later tonight! Thanks a million! :slight_smile:

1 Like

Hey Jinx. I’m pretty new to code. And I do know what header and footer stand for and how they are usually displayed on a homepage. And yes I would like all the links to slide down. But where to put it? In every passage or in the stylesheet. I’m asking this because I want different images to appear as I slide down.

For example, if I would use the code you gave me: I’m in the first passage and I have a certain background image and I click the link to slide down. Now I would like another background image to appear in the next passage at the same time as the new text appears…

Could you give some example how to do this with the first code you gave me?
That would be fantastic.


This works pretty great! Im trying out the different ideas people have given me in this thread. And this way It works with the text, but I don’t know how to get a new image to appear right under the first one, like with the text.

I want to be able to change the background image when I change passage. So as I slide down and a new text appears a new background appears also that cover the whole window. And at the same time be able to place pictures infront of the background image…

Im studying all the different tutorials there are, but it takes a little bit of time to learn. And your help makes it easier. But this is my aim, maybe not as advanced though, but to make a more simpler version of it:smiling_face: The Boat | SBS

Here’s a very basic example of what I believe you are going for. I’m not versed at all in that sort of dynamic HTML so you are on your own, but I think this might guide you in the right direction.

Good luck!

1 Like

Yeah! Excellent!

1 Like

Hi, the code I suggested in my first message would go on its own in a passage tagged “header”, so it will be run at the beginning of each passage transition (that’s how it would affect all the links in the story). To add the tag, click the + Tag button on the passage toolbar in the Twine editor.

For the background images, you could use the same tagging principle and CSS to target passages and assign background images. For example, putting
tw-story[tags~="forest"] {background-image: url('forest.jpg')} in your Stylesheet would make it so that any passage tagged “forest” would use forest.jpg as its background image.

This would make the sliding transition happen when clicking a link and navigating to a new passage, so it would not be possible to scroll back up and view content from previous passages. The codepen Hal linked seems more in the right direction for that, though it would probably need some experimenting to work the javascript in Harlowe.

Good luck!