Scroll IFRAMEs on iOS

By  on  

For the longest time, developers were frustrated by elements with overflow not being scrollable within the page of iOS Safari.  For my blog it was particularly frustrating because I display my demos in sandboxed IFRAMEs on top of the article itself, so as to not affect my site's AJAX pageload strategy.  Some research revealed that there are only two CSS properties to set and one element to set them on.  Here we go!

The HTML

In the case of an IFRAME and all other HTML elements, you'll want a wrapping element like a DIV:

<div class="scroll-wrapper">
	<iframe src=""></iframe>
</div>

This DIV will serve as the base container for what's scrollable inside.

The CSS

One familiar property and one lesser-known property will be used to allow scrolling for the IFRAME:

.scroll-wrapper {
	-webkit-overflow-scrolling: touch;
  	overflow-y: scroll;

	/* important:  dimensions or positioning here! */
}

.scroll-wrapper iframe {
	/* nada! */
}

The -webkit-overflow-scrolling: touch; property and value were created especially for the case of overflow scrolling within the browser.  Without this the page will scroll when you scroll the IFRAME area; with it you get control of the IFRAME! For my site's case, I use the following:

.demo-iframe-holder {
  position: fixed; 
  right: 0; 
  bottom: 0; 
  left: 0;
  top: 0;
  -webkit-overflow-scrolling: touch;
  overflow-y: scroll;
}

.demo-iframe-holder iframe {
  height: 100%;
  width: 100%;
}

Keep this tip handy and remember the special CSS goes on the wrapper and not the scrollable element itself!

Recent Features

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

  • By
    6 Things You Didn&#8217;t Know About Firefox OS

    Firefox OS is all over the tech news and for good reason:  Mozilla's finally given web developers the platform that they need to create apps the way they've been creating them for years -- with CSS, HTML, and JavaScript.  Firefox OS has been rapidly improving...

Incredible Demos

  • By
    Use Custom Missing Image Graphics Using Dojo

    A few months back I posted an article about how you can use your own "missing image" graphics when an image fails to load using MooTools and jQuery. Here's how to do the same using Dojo. The HTML We'll delegate the image to display by class...

  • By
    CSS :target

    One interesting CSS pseudo selector is :target.  The target pseudo selector provides styling capabilities for an element whose ID matches the window location's hash.  Let's have a quick look at how the CSS target pseudo selector works! The HTML Assume there are any number of HTML elements with...

Discussion

  1. Andrei

    Thanks for the tip! Don’t you name btw, is there another solution? The issue is that I develop a web-service that should be embeddable with iframe. Like youtube, gmap and any others.. So the code should be as simple as one iframe tag, not iframe plus wrapper plus styles… I am in stuck with this now

  2. Hi David,
    Thank you very much. I already wasted my two hours to find that popup iframe scrolling is not working on iphone. Very nice clue by you.

    You saved my lot of time. I was finding a wordpress plugin to do it.

    Thank you so much again. Keep it up.

    Cheers :)

    • Hi Hardeep. I am using WP Woocommerce to create the pages. These pages are loaded into an iframe (which dot not scroll very well with an IOS environment) Could you please let me know in which page and where you added the code? Thank you so much in advance.Ben

  3. Amazingly simple yet useful fix. This just saved me hours of banging my head.

  4. Andriy Kozachuk

    It works, but when I try to obtain window.pageYOffset it is always 0. Is there a way to fix it (I want to download additional content when user scrolls to the bottom of the page)?

  5. Nice solution… as long as it was working and Apple didn’t break it with iOS8. :(

  6. thinsoldier

    2014-10-17

    On your demo page the iframe is indeed scrollable, and it is the height of the full content of the page within the iframe.

    However, the contents of the iframe below the first paragraph are not rendered at all on my ipad or in the iOS emulator.

    http://davidwalsh.name/demo/scroll-iframes-ios.php

    I also have a project where I’m trying to use an iframe and I’m getting the same behaviour.

  7. thinsoldier

    2014-10-17

    Update: This information is still correct. But the content being clipped is a new problem. The problem can be fixed if you control the page being loaded by the iframe.

    Add body { -webkit-transform: translate3d(0, 0, 0); } or any other rule that will force hardware acceleration to the page being loaded by the iframe and it should prevent the rendering of the iframe from being cut off.

  8. werner

    Help,

    same problem in wordpress we load a Iframe on html5 but the iframe does scoll and return back to top everytime you touch the screen. Does anyone know where to fix this in wordpress?

  9. Thank you David. I was working on google form to be embedded on my wordpress website i am no coder like you but i tried understanding and trying it finally works flawlessly.
    Thank you so much!

  10. Hi, it did not work for me! but I could figure out a little trick after reading this post: https://css-tricks.com/forums/topic/scrolling-iframe-on-ipad/

    Just put an !important after that and works just fine!

    -webkit-overflow-scrolling: touch !important;
    overflow-y: scroll !important;
    
  11. James

    Thanks for posting this – I was having a really frustrating time including an externally hosted privacy policy (iubenda) in an ionic app. This tip solved it for me on iOS. Thank you!

  12. Very useful and interesting tip. I applied it in our PresentationTube project (which uses a scrollable slide thumbnail) and I’ll keep this test page to have a look and preview the script. Thank you David: http://presentationtube.com/watch/test5.php?v=jyFfl9VDCkK

    My only comment is adding the following to hide the wrapper vertical and horizontal bars:

    overflow-x:hidden;
    overflow-y:hidden;
    
  13. Alex

    Wow! Thanks David! You saved my day!

  14. oskar

    Thanks a lot David… You saved my day and night ;)

  15. Mark

    Thanks David, excellent tips, worked like a dream!

  16. Hi David, i’m almost done with my website & now i’m encountering a serious problem. My iframes (links to external websites) are not loading when used as tooltip in ipad (safari). Infact, the links are also not opening. Can you please let me know the possible solution to this problem? Will the above solution work for my problem too? All the iframes are in left hand side (advertising to wellness). The website is http://www.shortkut.in. Do i need to give any more details? Thanks in advance.

  17. The solution suggested here has been applied to a site that needs to generate reports and contain them in an iframe. That is the only way to get the app to be encapsulated as a Chrome App, and also work well in all browsers and platforms.

    However, this solution is not perfect, so far. As I scroll my iOS device (an iframe inside a div with the -webkit-overflow-scrolling: touch; and overflow: auto; in the container division) it suddenly resets itself and starts showing only the beginning of the document inside the iframe.

    It does not work; the user can never see the last part of the document.

  18. Andrew

    These codes aren’t working for my iframe. Here is the page with the iframe.

    http://bit.ly/1TuFSQx

  19. Hello…thanks for this great solution! I do have one glitch…on desktop view I have 2 scroll bars showing. When I remove your two lines of code from the media query for 768px, then get only one scroll bar on the desktop but the iframe then does not scroll on iPads. It still works on iPhones however.

    Any suggestions?

  20. Unfortunately, this doesn’t really work if the contents of the iframe need the correct scroll position. For example, I have a page with “to top / to bottom” navigation buttons, which appear / disappear depending on current scroll position. Obviously, they don’t work because the iframe content always “thinks” it’s at the top…

  21. hugo leiva

    The solution works on Chrome, but not in Safari.
    thanks

  22. Spring1993

    The solution works on Chrome, but not in Safari.
    thanks

  23. Hi all. Thanks for this interesting post. I am using Penscratch Theme from WordPress (Tarif Free). Thus I cannot use CSS. Is there a way to fix the problem that my wepbage is not scrolling on iphone/ipad. I am a beginner in designing webpages…
    Thanks for your answers.

  24. Erkin

    Hey,

    This works great for me. But revealed another problem. On iphone when the user clicks the input inside my iframe, keyboard causes the main body to scroll instead of iframes content and therefore iframes scrolls out of screen.

    Any solution to this?

  25. Sunny

    Thank you very much~ It really help a lot!

    By the way, I think it should be more exactly to let people know that the css property
    should be set to the container who responsible for scroll, not just the direct father of the iframe div.

    • Sunny

      I mean this property:

      -webkit-overflow-scrolling: touch !important;
  26. Mark

    Thank you for this solution. It works for me as far as fixing the scroll issue on iOS. The problem I have is that the page loaded into the iframe uses Bootstrap, and on iOS, while I can scroll, I loose all of the scrollspy functionality. For instance, the “Scroll to Top” no longer appears nor functions, and the left-hand navigation no longer updates based on where I have scrolled in the page.

    Everything works fine in all other OS’s, and when used outside an iframe on iOS. It’s only when running inside the iframe on iOS that I lose key bootstrap functionality, even with your scroll fix. Any ideas?

    Case in point: https://oraulearning.org/topclass/media/ad983b48-f7b2-47e6-ada3-2c317a0cd393/index_scorm.html

    (Ignore the SCORM error that appears; this is for use inside a Learning Management System)

  27. here is the CSS i am using:

    .scroll-wrapper {
      -webkit-overflow-scrolling: touch !important;
      overflow-y: scroll !important;
      position: fixed; 
      right: 0; 
      bottom: 0; 
      left: 0;
      top: 0;
    
    }
    
    .scroll-wrapper iframe {
      height: 100%;
      width: 100%;
    }
    
    body { -webkit-transform: translate3d(0, 0, 0); }
    
  28. Pier

    Hi everyone.

    The div wrapper solution works simply for scrolling the iframe, but since the height of the iframe never really changes this won’t solve other issues. The position coordinates inside the iframe will remain the same, so you won’t be able to position something in the center or bottom of the iframe in relation to the wrapper div.

    If you have control over the contents of the iframe here’s a solution I came up with when dealing with this problem.

    https://github.com/PierBover/ios-iframe-fix

    The idea is simply to wrap the contents of the iframe so that Safari thinks the content has no dimensions. This allows you to set the dimensions on the iframe as expected and then position stuff as usual inside the iframe.

  29. I added the following css. It’s working

    html, body{
        -webkit-overflow-scrolling: touch !important;
    }
    
  30. Pavan Dhananjaya

    Hi David , Thanks for the tips. It works great for me .

    But one issue is , contents inside iframe with

    position: absolute

    is not behaving as expected. In desktop and android am able to get sticky/fixed footer at the bottom , but in ipad footer is moved down till the actual content of the iframe. Any suggestions please. I am spending day and night on this isse :-( Even idea suggested by Pier doesn’t work for me
    Thanks In advance .

  31. RE: Double scroll bars in browsers
    For those who the original post works in IOS but get double scroll bars in web browsers, I did this to the CSS which works a treat:

    .scroll-wrapper {
    	display: inline-block;
    	-webkit-overflow-scrolling: touch !important;
    		overflow-y: auto !important;
    }
    .scroll-wrapper, .scroll-wrapper  {
    	width: 100%;
    	height: 500px;
    }
    
  32. The bit I changed was this

    overflow-y: auto !important;
    
  33. Tips to future me: Be sure the has display: inline. If it’s block it wont work for some wierd reason.

  34. Thanks so much! I had just the same problem on iPhone and

    -webkit-overflow-scrolling: touch;

    completely solved my problem!

    Thanks soooo much! I really couldn’t think of such an easy and versatile solution as this pretty oneliner!

  35. Jorge Piñon

    This is no longer needed on iOS 13 Safari but seems like it’s still different behavior than desktop Safari, at least in my particular case. I have a more complex html structure however. I suggest everyone test.

    Also

    @supports (-webkit-overflow-scrolling: touch)

    doesn’t include iOS 13 Safari.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!