Skip to content

Last updated: First published:

The Turn-Signal

Backward/forward view transitions for intuitive history navigation.

The Turn-Signal is a lightweight script for purely progressive enhancement of cross-document view transitions. It detects the direction of browser navigation and signal it with view transition types or html attributes to guide directional styling. This enables developers to create smooth, responsive transitions that adjust based on forward or backward navigation, delivering a more intuitive user experience.

PREREQUISITE

Demo

Turn-Signal Demo

Animation detailsAnimation details

Check out the Turn-Signal Demo to see the Turn-Signal in action. Click the link to move to the next page, then use your browser’s back button to return. Notice how the slide animation changes direction based on your navigation.

Installation

To use the Turn-Signal, you can install the npm package in your project. Alternatively you can load the script from one of the global content delivery networks that provide npm packages.

  1. Install @vtbag/turn-signal@latest from npm.
  2. In your project, add @vtbag/turn-signal/index.js as an inline script at the beginning of the <head> element on all pages of your site.

Details depend on your project setup and the frameworks used, but it can be as simple as:

import signal from "@vtbag/turn-signal?url";
<html>
<head>
<script src={signal} />
...
</head>
...
</html>;

Forced Traversal

@vtbag/turn-signal also defines a second script that can be used with the main functionality or independent of it: It is called forced-traversal and replaces forward navigation with history traversals if the target pages has been visited before.

Users may be annoyed when a website messes up their history entries, but there are situations where replacing navigation with traversals has its appeal. Use at your own discretion.

The forced-traversal feature is not covered by the example above. But the there is another demo on the astro-vtbot-website that demonstrates the replacement.

use it in the same way as the main script:

import forcedTraversal from "@vtbag/turn-signal/forced-traversal?url"
...
<script src={forceTraversal} />

or

<script src="https://.../@vtbag/turn-signal/forced-traversal" />

There are no configuration options and the forced-traversal script does not take any parameters.

Configuration and Usage

@vtbag/turn-signal main script accepts several config options. Those are specified as data-* attributes on the <script> element. They are all optional. If used without any parameters, the Turn-Signal detects backwards history traversals and sets the backward view transition type for those. Navigation to the current page sets the same type. For all other navigation, the forward type is set.

You can use these view transition types to style different animations dependent on the direction of the navigation

CSS for Reverse Animation

Chances are more often then not that you can not simply revert the direction of your animation for the backward effect. Assume you have slideOutToLeft for the old image and slideInFromRight for the new image.

::view-transition-old(main) {
animation-name: slideOutToLeft;
}
::view-transition-new(main) {
animation-name: slideInFromRight;
}
@keyframes slideOutToLeft {
to {
transform: translateX(-100%);
}
}
@keyframes slideInFromRight {
from {
transform: translateX(100%);
}
}

Just changing the direction of the animations would lead to something best named slideInFromLeft for the old image and slideOutToRight for the new image. While the animations are about right, just setting animation-direction: reverse would apply them to the wrong images. You do not want to slide in the old image or slide out the new image. So better you swap the keyframes, too …

:active-view-transition-type(backward) {
&::view-transition-old(main) {
animation-name: slideInFromRight;
animation-direction: reverse;
}
&::view-transition-new(main) {
animation-name: slideOutToLeft;
animation-direction: reverse;
}
}

… or even explicitly define keyframes for slideOutToRight and slideInFromLeft if you feel that is clearer.

… and you can also define different animations for :active-view-transition-type(same), i.e. for links to the current page, e.g. in a navigation bar.

Config Options

Config optionTypeEffect
data-selectora CSS selector

If your site has a concept of previous and next page, use this to tell the Turn-Signal about your pages and their order. One selector to find them all.

The selector should return one element per page of your site, and each element must have an href attribute. Typically, you would select <a> elements from your navigation bar, such as data-selector="nav a".

If your site doesn’t already have a suitable structure, consider generating a list of pages in a non-intrusive way. For example, you could use <a> elements inside a <template> element or <link> elements with a custom rel attribute.

The sequence of selected URLs is used to derive the navigation direction. Navigation to a page that comes later in the sequence of selected URLs will be a forward navigation. Navigation to a page that comes earlier in the sequence of selected URLs will be a backward navigation.

data-direction-typesbackward-value, same-value, forward-value

The Turn-Signal sets view transition types to convey the derived direction in a form that can easily be used for styling your animations.

By default, the types are backward, same, and forward, i.e. as if set using data-direction-types="backward, same, forward".

An alternative would be data-direction-types="reverse,," This would do nothing for same page and forward navigation, but would set the reverse type on backward navigation.

data-direction-attributeattribute-name, backward-value, same-value, forward-value

For compatibility with existing code you might want to use attributes rather than view transition types to select different styling for your animations.

You can specify what attribute to use and what values to set. Here is an example of how to make Turn-Signal directions compatible with th CSS Astro generates for transition:animate: data-direction-attribute="data-astro-transition, back, forward, forward".