Menu
#3

Creating an infinite scrolling datepicker

Datepickers which resemble the traditional paper calendar are omnipresent. But if time is moving on, why not scroll through it? Of course, Apple has done it in iOS. As we think it’s a great idea we decided to build our own version of it. For the web.

The datepicker in action.

The datepicker we all know and love shows one month at a time. A good, well known and widespread example is the jQuery UI datepicker. Such a datepicker resembled the look and feel of a traditional calendar consisting of 12 sheets, one for each month in a year. While that metaphor works well, it’s an answer to the limited surface area that a sheet of paper provides. Putting yourself under that limitation on a screen which provides virtually endless real estate simply is ignoring a chance to build a better user interface. Especially with powerful scrolling gestures on touch panels being literally “at hand”, scrolling through time provides faster and more natural access.

We’ve tempered with the idea of a scrolling datepicker for quite a while now, since we first saw the new Calendar app in Apple’s iOS which provides infinite scrolling through time as well. Few websites have taken on the idea to date. For example, the Dutch airline KLM has a scrolling datepicker on their website to pick travel dates. As they only sell flights a couple of months from now, the scroll range is pretty limited there. So the decision was obvious: We needed to build something new.

At the same time, it was clear that we wouldn’t go for an all-new, all-unfamiliar user interface. Especially because the classic datepicker had served us well for so many years. Instead, we decided to keep the classic look, and just add some scrolling fancyness. Therefore, the user experience of those who feel comfortable using the buttons to skip months is not disrupted. For the more adventerous ones, there’s an additional way to access time.

Feel it’s time to see it in action? We’ve prepared a demo for you to look.

The endless scroll

So how does this work? We’re using a structure with one <div> per month, something along this:

<div class="sys-datepicker-month">...</div>
<div class="sys-datepicker-month">...</div>
<div class="sys-datepicker-month">...</div>
<div class="sys-datepicker-month">...</div>
<div class="sys-datepicker-month">...</div>

We’re only maintaining divs for a limited number of months, say 5. Each month has the height of the datepicker itself, and the wrapping div is scrolled so that the active div is the one in the middle.

When the scrolling starts, we constantly add new divs ahead where the user is scrolling towards. At the same time, old divs are removed from the far end. That way, we keep the number of divs in the DOM reasonable. That way, even many datepickers on a single page aren’t causing performance issues.

Hiding the scrollbars

The whole datepicker is entirely CSS stylable. We don’t plan to ship any default CSS besides the demo CSS. There is some basic CSS styling that’s necessary for the scrolling effects to work properly, which is this:

.sys-datepicker {
    // Background color is important to overlay the page’s contents
    background-color: #fff;
    // Height should match whatever a month div is high, plus the button controls
    height: 300px;
    // Relative position is required to give position to the child elements
    position: relative;
}

.sys-datepicker-content {
    // All three styles are required to hide the scrollbars
    // on the right of .sys-datepicker-body
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.sys-datepicker-body {
    // Make it scrollable
    overflow: scroll;
    // Make it smooth scrollable on iOS/Webkit
    -webkit-overflow-scrolling: touch;
    // Give it relative position for the childs
    position: relative;
    // Fill the datepicker’s height
    height: 100%;
    // Even if floats are positioned in it, maintain a height
    clear: left;
    // Be 15px wider than the datepicker’s body
    // which should be enough for most scrollbars
    width: calc(100% + 15px);
}

This code for hiding the scrollbars works properly on all tested platforms. As it assumes a maximum width of the scrollbars (15px in the example given), it can’t deal with scenarios where scrollbars are wider than that assumption. Even though that’s not a common scenario, it might happen on operating systems or browsers when users are allows to style scrollbars and go for super fat ones. Setting the 15px from the example to a higher value, say 100px, may compensate that to some extent, though.

Get the code

If you want to follow development or even contribute, fork the datepicker on GitHub.

Desktop: 1025px and above

12 column responsive grid
Tablet: from 768px to 1024px

4 column responsive grid
Mobile: up to 767px

4 column responsive grid