Here's a few good reasons why not to serve responsive web apps within iframes.

If you're starting a project with this kind of iframe restriction, please take this advice from someone who has taken the wrong advice multiple times and misdiagnosed the problems.

Seriously though - your app is going to have some major issues if you're not careful!


Chrome has a weird fixed scrollbar bug

The scroll bar handle doesn't appear to move when you scroll.

  • The only solution is for every window resize event (you can debounce it with caution), send a message from the child to the parent frame asking for a window resize to the height of the content (passed as a param).
  • This means for Chrome (if you're just sniffing for window.chrome) the iframe will potentially be thousands of pixels high, and the scrollbar works because it's actually scrolling the parent page and not the child. A reprocussion of this is that no scroll events get fired ont he child page, so avoid relying on scroll events all together.
  • If you debounce the resizing be careful, as some supressed resize events may be significant ones, which may cause double scrollbars and a rare phenomenon what I like to call 'iframe dancing'. This is where the client sends a resize request, the parent resizes (but adds an extra scrollbar temporarily), then due to the extra scrollbar the client width changes and some content wraps, so the client sends another resize request, the parent scrollbar disappears, then the whole thing is repeated. etc, etc. You're basically going to need some additional logic within the resize request code to make sure you're not sending a resize request which is going to cause this loop. If you're struggling with this, get in touch! It's not pretty.

Mobile Safari resizing iframes by default, and you can't override it!

  • Mobile Safari will resize the iframe to the height of the content, regardless of any styles or attributes declared on the iframe (including !important rules).
  • The solution is to wrap the iframe in a div with overflow:auto, but this may have some reprocussions for other mobile browsers.
  • Fix

Avoid fixed position elements at all costs.

Politely TELL your UX that 'sticky' navigation is NOT an option!

  • Due to the above Chrome scroll bug fix, fixed position elements will not appear fixed, as the child page never scrolls (the parent page simply scrolls it's 'view' of the iframe).
  • Due to the mobile safari fix, it's exactly the same situation, fixed position elements will never appear to be fixed, they'll simply scroll away with the content.

Mobile Safari applies the elastic out-of-bounds effect to the x-axis as well.

This is due to the app being a page within an iframe.

  • There may be a fix for this, but I've avoided supressing touchmove events as it's bad practice.
  • If there's a nice fix, I'd love to hear it in the comments below :-)

CSS Hardware Acceleration appears to be affected

  • On some mobile devices performance for transformed layers is jerky and flickers. This is not apparent when the app is served outside the iframe.
  • I haven't found a fix for this yet, and I'm not really a fan of applying hardware acceleration to large elements due to the memory and GPU consumption.
  • If somebody insists on serving an app within an iframe, they can't expect a smooth native app experience, so my advice is to remove transitions on transforms so they move between states discretely.

Summary

If you are restricted to serving your app within an iframe:

  • Avoid all fixed position elements. Rethink your sticky navigation.
  • Accept that CSS animation is not going to be smooth on some mobile devives.
  • Chrome will need a scroll fix, unless you want to take an accessibility hit and expose a rare bug in the latest modern browser. This means you will need JavaScript on the parent page to respond to resize requests via postMessage from the client, or you'll see multiple scrollbars.
  • You shouldn't be doing anything on scroll events.

Andy Shora: AI, Engineering and Innovation Leader