Overthrow: An overflow polyfill for responsive design
April 2020 note: Hi! Just a quick note to say that this post is pretty old, and might contain outdated advice or links. We're keeping it online, but recommend that you check newer posts to see if there's a better approach.
We’ve come to take the CSS overflow
property for granted when
designing websites for desktop browsers. Scrolling regions offer a
powerful tool in UI design that we would love to have at our disposal on
mobile devices —especially when building app interfaces.
But overflow support among mobile devices is spotty: some browsers
support it, but many popular ones at best require 2-finger gestures to
scroll the content, and at worst treat the content the same as
overflow: hidden
, making it inaccessible to users. Newer mobile
browsers are making fantastic progress, but when we look across the full
landscape, we see many gaps.
So we set out to build a solution that smoothes the way. Overthrow.js is a conservative attempt at filling the gaps in overflow support, with an emphasis on letting native implementations do their thing, and ensuring a usable experience in all browsers.
For cross-device overflow, no perfect solutions
Permalink to 'For cross-device overflow, no perfect solutions'Overflow support is gaining rapidly in newer versions of mobile
browsers. For example, iOS5’s Mobile Safari, the new Chrome for Android,
BlackBerry 7+, PlayBook, Android 3+, Firefox Mobile, and WebOS 3
(including) TouchPad, all support the native CSS overflow
property.
This is terrific news, in theory… But, with the exception of IOS5 and
Chrome – which offer a secondary CSS property (momentum scrolling via
-webkit-overflow-scrolling: touch
) we can use to test and determine
that overflow is supported – it’s virtually impossible to detect proper
support for overflow. And unfortunately, a significant number of very
popular mobile devices run earlier browser versions that don’t support
overflow partially or improperly, and will abjectly fail.
This leaves us with a dilemma. Scrolling regions provide great benefits when they work, but unqualified use of them can lead to major accessibility problems. When building with a responsive design approach, we want to deliver a single solution that will serve a variety of devices from handheld to desktop, and we need to know reliably that the tools we use will either work or fail gracefully. With the lack of a definitive test on so many devices and platforms, we were hesitant to use overflow at all. But with the potential benefits, and with so many new devices adding support, it seems important to try to somehow make overflow work.
First, we looked to a number of popular open-source projects that bring overflow support to touch devices to see whether any would satisfy our requirements. Specifically, we were searching for an approach that:
- Applies overflow as a qualified progressive enhancement, only applying it in devices that we can trust to get it right,
- Simulates overflow support in popular browsers that do not support overflow natively, but are capable of reasonably handling it with JavaScript,
- Is lightweight, framework-independent, and can be delivered to any browser without introducing lots of unnecessary overhead,
- Uses native scroll properties like scrollTop, to play nicely with native browser behavior such as deep-linking to document fragments,
- Requires no additional markup containers and simulates scroll without introducing unexpected positioning contexts, rendering issues, or problems with form control accessibility,
- Provides an accessible experience to every browser.
Most importantly, we wanted an approach that is designed to slowly kill itself off, allowing native implementations to do their thing as support becomes better and better.
In reviewing the existing solutions, we determined that none we could find satisfied all the above criteria. So we set out to build one that does.
Introducing Overthrow, a solution to bridge the gaps
Permalink to 'Introducing Overthrow, a solution to bridge the gaps'Overthrow is a conservative attempt at addressing inconsistent overflow support, and ensuring a usable experience in all browsers.
Simply put, Overthrow provides a means to take advantage of native overflow in browsers we know can support it, deliver simple content that’s left uncropped and fully accessible in cases where we know overflow will not work, and delivers a polyfill solution to provide a little ‘help’ to a subset of mobile browsers that need it.
Basic use
Permalink to 'Basic use'First, download and reference overthrow.js from your document. Anywhere’s fine.
<script src="overthrow.js"></script>
Then put a class of overthrow
on any elements in which you’d like to
apply overflow: auto
or scroll
CSS.
<div id="foo" class="overthrow">Content goes here!</div>
In browsers that Overthrow deems capable of scrolling overflow content
(either natively, or using its touch polyfill), it will add a class of
overthrow-enabled
to the html
element. Add the following CSS to your
stylesheet somewhere, enabling overflow on all elements in your document
that have an overthrow
class.
/* Overthrow CSS:
Enable overflow: auto on elements with overthrow class when html element has overthrow-enabled class too */
.overthrow-enabled .overthrow {
overflow: auto;
-webkit-overflow-scrolling: touch;
}
That’s it. Design away! Any time you want to set dimensions on an
element to use overflow scrolling, just be sure to key off that
overthrow
class on the HTML element, and overflow: auto
will apply.
.overthrow-enabled #foo {
height: 280px;
}
Overthrow is still in initial development (version 0.1 at publishing time), but the results so far are quite promising. We’re looking to continue developing Overthrow in the open and would greatly appreciate help with testing and code improvements, particularly related to any issues in the tracker.
Please check out the project website for more information on Overthrow and how to use it in your projects. There are also a couple of quick & dirty examples that demonstrate Overthrow in real-world layouts: a Responsive Columned Layout and a Responsive Dialog Layout.
The code is hosted on Github; if you’re able, please file bugs and suggest improvements in the issue tracker.