Skip to content

Vanilla Timeline: a zero-dependency Javascript library for beautiful, responsive horizontal and vertical timelines.

License

Notifications You must be signed in to change notification settings

kendawson-online/vantl

Repository files navigation

Vantl - Vanilla Timeline

Vanilla Timeline (Vantl) is a lightweight, responsive timeline library created with vanilla Javascript for creating beautiful horizontal and vertical timelines with zero dependencies. Inspired by timeline originally created by squarechip in 2018. You can load your timeline data via a variety of methods and, you can include multiple timelines on a single page.

Features

  • ✨ Zero dependencies - Pure vanilla JavaScript (jQuery optional)
  • πŸ“± Fully responsive - Auto-switches between horizontal/vertical layouts
  • 🎨 Customizable colors - Theme nodes, lines, and navigation
  • πŸ–ΌοΈ Rich content - Support for images, HTML, and modal popups
  • πŸ”— Deep linking - Link directly to specific timeline nodes via URL
  • πŸ“¦ Multiple layouts - Vertical scroll or horizontal carousel modes
  • πŸ’Ύ Smart caching - LocalStorage caching for JSON data
  • πŸš€ Auto-init - Just add a data attribute to load from JSON
  • πŸ“ Small footprint - Minified and tree-shakeable

Online Demo:


Screenshot


Getting Started:

Load stylesheet and Javascript functions to your document via CDN links:

<!DOCTYPE html>
<html>
<head>
  <!-- load stylesheet -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@latest/dist/timeline.min.css">
</head>
<body>
   
  <!-- your timeline will go here --> 
  
  <!-- load functions -->
  <script src="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@latest/dist/timeline.min.js"></script>
</body>
</html>

1️⃣ CREATE A TIMELINE USING BASIC HTML


Add some timeline node data in HTML. If you want your timeline to be oriented horizontally, set data-mode="horizontal" on the parent element (see code below). If you omit this setting, the timeline will be oriented vertically by default.

<!-- your timeline --> 
<div class="timeline" data-mode="horizontal">
  <div class="timeline__wrap">
    <div class="timeline__items">
        <div class="timeline__item">
            <div class="timeline__content">
                <h5>Jan. 1, 2000</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum.</p>
            </div>
        </div>
        <div class="timeline__item">
            <div class="timeline__content">
                <h5>Dec. 31, 2000</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum.</p>
            </div>
        </div>
        <div class="timeline__item">
            <div class="timeline__content">
                <h5>Jan. 1, 2001</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum.</p>
            </div>
        </div>
    </div>
  </div>
</div>

Add one line of code at the bottom to initialize your timeline. It goes after the CDN link but before the closing </body> tag and looks like this:

  <!-- load functions -->
  <script src="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@latest/dist/timeline.min.js"></script>

  <!-- initialize the timeline -->
  <script>
    timeline(document.querySelectorAll('.timeline'));
  </script>

</body>
</html>



jQuery

Note: if you're using jQuery in your document, you can initialize your timeline like this:

    <!-- load functions -->
    <script src="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@latest/dist/timeline.min.js"></script>

    <!-- initialize timeline with jQuery -->
    <script>
        jQuery(function () {
            $('.timeline').timeline({
              mode: 'horizontal'
            });
        });
    </script>

  </body>
</html>

For more info check the Advanced Usage section below




2️⃣ USE DATA ATTRIBUTES TO CUSTOMIZE YOUR TIMELINE

You can add data attributes to the timeline element to control how it looks and/or functions. For example, this is how you would set the orientation of the timeline to be horizontal instead of vertical (default):

<div class="timeline" data-mode="horizontal">
  ...
</div>  

If you don't pass an attribute, the app will simply use the default values.

Here are the available data attributes:

Option Type Default Description
data-mode string 'vertical' Layout mode: 'vertical' or 'horizontal'
data-min-width number 600 Minimum viewport width (px) to maintain horizontal mode
data-max-width number 600 Maximum viewport width (px) to maintain vertical mode
data-move-items number 1 Items to scroll per navigation click (horizontal)
data-start-index number 0 Initial item index (horizontal mode)
data-horizontal-start-position string 'top' First item alignment in horizontal layout: 'top' or 'bottom'
data-vertical-start-position string 'left' First item alignment in vertical layout: 'left' or 'right'
data-same-side-nodes string boolean false
data-vertical-trigger string '15%' Scroll trigger distance: percentage or px (e.g., '20%' or '150px')
data-rtl-mode boolean false Right to left mode: true or false (only works in horizontal mode and overrides startIndex setting)
data-node-color string β€” Node circle color (hex/rgb/hsl)
data-line-color string β€” Timeline line color (hex/rgb/hsl)
data-nav-color string β€” Navigation button color (hex/rgb/hsl)
data-json-config string β€” path to a JSON data file (e.g., /path/to/valid/file.json)

See the API Documentation for a more detailed description of all options.




3️⃣ USING A JSON FILE TO LOAD TIMELINE DATA


A great way to use Vanilla Timeline is to store and load your data from an external JSON file. JSON stands for: "JavaScript Object Notation".

It's a lightweight text format stored in a file with a .json extension. It's easy for humans to read and write and for machines to parse and use in apps. JSON is based on a web standard so you have to follow the rules to produce "well-formed JSON" that is formatted a specific way. A simple JSON file might look something like this:

{
  "timelineName": "Timeline Title",
  "layoutMode": "horizontal",
  "minWidth": 700,
  "maxWidth": "",
  "nodeColor": "",
  "lineColor": "",
  "navColor": ""  
}

To use JSON, you add a data attribute called data-json-config to your HTML to tell the app which JSON file you want to load:

<div class="timeline" data-json-config="/path/to/timeline.json"></div>

⚠️ Important: if you set a data-json-config value, the app will prioritize JSON file settings and ignore any other data attribute values being passed inline via HTML.

If you load your timeline data using the JSON method, you don't have to add the extra line of code at the bottom of the page (used to initialize the timeline). When a JSON file is loaded, the app is initialized automatically.

Here are some examples of JSON files you can use as templates to build your own timelines:


πŸ—“οΈ A NOTE ABOUT DATES IN JSON πŸ—“οΈ

Dates stored in JSON data files (e.g. the lastupdated field) are stored in a special format called ISO 8601. The vanilla timeline app expects dates to be in this specific format.

There is a demo page which displays dates in this format for you. The page also teaches you how to generate ISO 8601 timestamps in the developer console of your own web browser. Open the demo/time.html file in a browser to see a current ISO 8601 timestamp. You can copy/paste this date string directly to your JSON timelines.



Deep Linking

Link to a specific timeline node using URL parameters:

https://example.com/page.html?timeline=myTimelineId&id=3


https://[domain name]/[page name]?timeline=[timeline ID]&id=[node id]

  1. Add an id attribute and value to your timeline container:
    <div id="myTimeline" class="timeline">
       ...
    </div>  

  1. Add a data-node-id to each node you want to link to
    <div class="timeline__items">
        <!-- node 1 -->
        <div class="timeline__item" data-node-id="1">
            <div class="timeline__content">
                <h5>Jan. 1, 2015</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore.</p>
            </div>
        </div>
        <!-- node 2 -->
        <div class="timeline__item" data-node-id="2">
            <div class="timeline__content">
                <h5>Dec. 31, 2016</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore.</p>
            </div>
        </div>
    </div>    

Note: you can also add an id attribute directly like so:

    <div class="timeline__items">
        <!-- node 1 -->
        <div class="timeline__item" id="1">
            <div class="timeline__content">
                <h5>Jan. 1, 2015</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore.</p>
            </div>
        </div>
        <!-- node 2 -->
        <div class="timeline__item" id="2">
            <div class="timeline__content">
                <h5>Dec. 31, 2016</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore.</p>
            </div>
        </div>
    </div> 

Deep linking works automatically with JSON-loaded timelines


Advanced Usage:

Installing with npm

npm install @kendawson-online/vantl

Importing timeline functions into your Javscript app:

import { timeline } from '@kendawson-online/vantl';
import '@kendawson-online/vantl/dist/timeline.min.css';

timeline(document.querySelectorAll('.timeline'), {
  mode: 'vertical',
  nodeColor: '#2d6cdf'
});

Setting options

// vanilla Javascript
timeline(document.querySelectorAll('.timeline'), {
  mode: 'horizontal'
});


// jQuery
$('.timeline').timeline({
  mode: 'vertical',
  verticalTrigger: '20%'
});

Available API Options

All options can be set via JavaScript API, data attributes, or with JSON config.

Option Type Default Description
mode string 'vertical' Layout mode: 'vertical' or 'horizontal'
minWidth number 600 Min viewport width (px) to maintain horizontal mode
maxWidth number 600 Max viewport width (px) to maintain vertical mode
moveItems number 1 Items to scroll per navigation click (horizontal)
startIndex number 0 Initial item index (horizontal mode)
horizontalStartPosition string 'top' First item alignment: 'top' or 'bottom'
verticalStartPosition string 'left' First item alignment: 'left' or 'right'
sameSideNodes string boolean false
verticalTrigger string '15%' Scroll trigger distance: percentage or px (e.g., '20%' or '150px')
rtlMode boolean false Right-to-left mode (horizontal)
nodeColor string β€” Node circle color (hex/rgb/hsl)
lineColor string β€” Center line color (hex/rgb/hsl)
navColor string β€” Navigation button color (hex/rgb/hsl)

Custom Image Path

Override the auto-detected image path:

<script>
  window.TimelineConfig = {
    basePath: '/custom/path/to/images'
  };
</script>
<script src="dist/timeline.min.js"></script>

Programmatic control

// Load from JSON programmatically
loadDataFromJson('/data/timeline.json', '#myTimeline');

// Clear cache
clearTimelineCache();                         // Clear all cached JSON timelines
clearTimelineCache('/data/my-timeline.json'); // Clear cache for specific JSON URL

// Navigate to node (horizontal mode)
navigateTimelineToNodeIndex(containerElement, 5);

// Open modal
openTimelineModal(itemElement);

// Close modal
closeTimelineModal();

More Information


Optional SwiperJS add-on (not bundled or supported)

  • SwiperJS is a third-party library; Vantl only ships an adapter. You must bring Swiper yourself and consult the Swiper docs for setup and features.
  • Resolution order when useSwiper is enabled: options.swiperCdn (ESM URL) β†’ installed swiper package (dynamic import) β†’ window.Swiper from a UMD CDN. If none are found, Vanilla Timeline falls back to its built-in carousel controls.
  • Enable with data-use-swiper="true" (or boolean true) in HTML or useSwiper: 'true' | 'auto' | true in JS. Pass Swiper options via swiperOptions.
  • Build warning about unresolved swiper is expected when you have not installed it; either ignore, mark it external (e.g., external: ['swiper']), or install Swiper to silence the warning.

UMD CDN example (provides window.Swiper):

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12.4.7/swiper-bundle.min.css">
<script src="https://cdn.jsdelivr.net/npm/swiper@12.4.7/swiper-bundle.min.js"></script>
<script src="dist/timeline.min.js"></script>
<script>
  timeline(document.querySelectorAll('.timeline'), { useSwiper: 'auto' });
  // Swiper-specific options: { swiperOptions: { loop: true } }
</script>

Browser Support

  • Chrome/Edge (2018+)
  • Firefox (2018+)
  • Safari (2018+)
  • Requires: ES6, IntersectionObserver, CSS Custom Properties

Contributing

See Development.md for build instructions and an architectural overview.

See API Documentation for details about how the API works.

You can report issues and open pull requests on GitHub:

Links

NPM Package: @kendawson-online/vantl

Repository: github.com/kendawson-online/vantl

CDN: cdn.jsdelivr.net/npm/@kendawson-online/vantl

License

MIT License

Credits

Originally inspired by timeline by Mike Collins (2018).

Refactored and maintained by Ken Dawson (2026).