Iframe tables cause overflow scrolling on iOS


At Shopify, we have something we call the assets gem. It’s a collection of our core styles that we can use on any project not hosted directly in our admin. Many of our channels (Amazon, Facebook, etc) use this assets gem in their projects which are then loaded in an iframe inside of our admin.

Working in iframes so much leads us to finding strange bugs — the latest about some extra horizontal scrolling on iOS when using a scrollable parent div on tables.

To start, responsive tables are hard. A colleague, Tetsuro, has a great post on building mobile-friendly and accessible tables — a testament to how difficult they can be to work with. Short of that implementation, the easy way to keep tables accessible (visually at least) on small screens is to add a .table-wrapper class that allows horizontal scrolling.

.table-wrapper {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

The result is a horizontal scrollbar around the table, allowing you to side-scroll to see all the information.

See the Pen Table wrapper by Carson Shold (@cshold) on CodePen.

And it works great on all screens and devices, so what’s the problem?

The Problem

On iOS the max-width of an element with overflow scrolling is ignored and instead defaults to the width of the children. In the case of a table — where the width can be much wider than the viewport — the entire iframe is forced larger than what the parent page defines.

Take this example:

  • Parent page includes an iframe with width: 100% in CSS
    • On an iPhone SE, for example, that’s typically 320px
  • Inside the iframe create a table with the .table-wrapper class and use the styles above
  • Put enough content in the table to make its native width wider than 320px

You would expect the iframe to maintain its 320px width, regardless of the content. On iOS, the table’s width will somehow force the iframe to be wider. See the example screenshot below. The “Listings” title bar is on the parent page while everything below it is in the iframe.

iOS scrollable tables cause overflow in iframes

This adds horizontal scrolling to the parent.

The solution

We can get a little cheeky with the styles to trick iOS into respecting the table-wrapper class and its overflow scrolling.

.table-wrapper {
  width: 1px;
  min-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

See the Pen Table wrapper | iOS iframe fix by Carson Shold (@cshold) on CodePen.

This result will look identical to you unless you’re on an iPhone. See below for a demo of each if you’re not.

Setting the wrapper’s width to 1px makes sure our scrollable div is smaller than the viewport, avoiding the iOS bug of ignoring max-width. By adding min-width: 100% we effectively push the wrapper to the full width of the viewport — an attribute that is read properly by iOS.

Showcase the problem on iOS

Since the examples on CodePen are in an iframe, it illustrates the point perfectly. The first example will scroll the entire page while the second one — with the fix — only the table’s parent div scrolls.

Before the fix: Using max-width and scrolling overflow:

table-scroll-1

After the fix: Using width: 1px, min-width: 100%, and scrolling overflow:

table-scroll-2



Leave a Reply