Scrollable Timeline

Fun with Overflows

by Avinashullal

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.11/jquery.mousewheel.min.js"></script>
<h1>Google 10 Year Timeline</h1>

<div id="timeline" style="overflow: hidden;">
    <ul class="tl-events">
        <li class="welcome">
            
<h2>Welcome to the interactive timeline of Google history!</h2>

            <p>Travel through time by dragging the timeline or the slider below. Click on any event to see more information.</p>
            <p></p>
        </li>
        <li class="first last">
            
<h3>
1995–1997</h3>

            <ul class="column">
                <li class="doodle" id="event-1997-1-doodle">
<a href="scrollable-timelines.html#1997-1-doodle" hidefocus="">

</a>

                </li>
                <li class="milestone" id="event-1995-when-larry-met-sergey">
<a href="scrollable-timelines.html#1995-when-larry-met-sergey" hidefocus="">
<span title="Milestones" class="tl-icon">
<span class="tl-msg">
<span class="tl-msg-inside">When Larry met Sergey</span>

</span>
</span></a>

                </li>
                <li class="milestone" id="event-1996-new-search-tool-named-backrub">
<a href="scrollable-timelines.html#1996-new-search-tool-named-backrub" hidefocus="">
<span title="Milestones" class="tl-icon">
<span class="tl-msg">
<span class="tl-msg-inside">New search tool named BackRub</span>
</span>
</span></a>

                </li>
                <li class="milestone" id="event-1996-backrub-search-index-grows">
<a href="scrollable-timelines.html#1996-backrub-search-index-grows" hidefocus="">
<span title="Milestones" class="tl-icon">
<span class="tl-msg">
<span class="tl-msg-inside">BackRub search index grows</span>

</span>
</span></a>

                </li>
                <li class="milestone" id="event-1997-google-com-registered-as-a-domain">
<a href="scrollable-timelines.html#1997-google-com-registered-as-a-domain" hidefocus="">
<span title="Milestones" class="tl-icon">
<span class="tl-msg">
<span...

CSS

body {
    margin: 0;
    padding: 0 20px;
    font: 1em"Trebuchet MS", verdana, arial, sans-serif;
    font-size: 85%;
}
div, ul, li {
    zoom: 1;
}
ul ul, ul ul li {
    zoom: 0;
}
#timeline {
    height: 350px;
    margin-top: 10px;
    padding: 20px;
    overflow: auto;
    /*cursor: -moz-grab !important;*/
    /* should this be applied with JS? */
    border: 2px solid #D9E4FF;
}
.tl-events {
    width: 11800px;
    list-style: none;
    padding: 0;
    margin: 0;
}
.tl-events li {
    float: left;
    width: 300px;
    margin-right: 10px;
}
.tl-events ul {
    list-style: none;
    margin: 0;
    padding: 0;
}
.tl-events ul li a {
    text-decoration: none;
    color: #000;
    background: #D9E4FF;
    border: 1px solid #D9E4FF;
    -moz-border-radius: 4px;
    display: block;
    margin: 5px 2px;
    padding: 2px;
}
.tl-events ul li a:hover, .tl-events ul li a:focus {
    outline: 0;
    background: #C2CCE4;
    border: 1px solid #B0BACF;
}
.doodle {
    display: none;
}
h1 {
    margin: 8px 0;
}

JavaScript

$(document).ready(function () {
        $('#timeline').mousedown(function (event) {
            $(this)
                .data('down', true)
                .data('x', event.clientX)
                .data('scrollLeft', this.scrollLeft);

            return false;
        }).mouseup(function (event) {
            $(this).data('down', false);
        }).mousemove(function (event) {
            if ($(this).data('down') == true) {
                this.scrollLeft = $(this).data('scrollLeft') + $(this).data('x') - event.clientX;
            }
        }).mousewheel(function (event, delta) {
            this.scrollLeft -= (delta * 30);
        }).css({
            'overflow': 'hidden',
                'cursor': '-moz-grab'
        });
    });

    $(window).mouseout(function (event) {
        if ($('#timeline').data('down')) {
            try {
                if (event.originalTarget.nodeName == 'BODY' || event.originalTarget.nodeName == 'HTML') {
                    $('#timeline').data('down', false);
                }
            } catch (e) {}
        }
    });