What is the best way to prevent an iFrame from causing its parent window to scroll?

I recently came across an HTML document that includes an iframe towards the bottom of its content.

Specifically, the iframe is embedding a Google Spreadsheet, using the following code:

<iframe id="gsheet-group" width="100%" height="400" src="https://docs.google.com/spreadsheets/d/<!----DOCUMENT_KEY----->/edit?usp=sharing&rm=minimal&gid=0&single=true&widget=false&chrome=false&headers=false">Loading sheet..</iframe>

It seems like the iframe may contain some javascript that triggers the parent window to scroll to the top under certain conditions, such as when the content is fully loaded or when it is navigated in specific ways. This behavior persists even if the iframe is nested within another iframe.

If I'm unable to directly edit the source code of the iframe, is there a way to prevent the parent window from being affected by the javascript inside the embedded iframe?

My Attempts So Far

I appreciate the suggestions provided by other users, but unfortunately none of them have resolved this issue:

  • Adding
    sandbox="allow-scripts allow-forms allow-pointer-lock allow-same-origin"
    to the <iframe> element (to remove allow-top-navigation; @CBroe).
  • Attempting to override window.scrollTo (@Ryano)
  • Placing the iframe within a separate iframe (@Ryano)

Answer №1

There is an API that can enable cross-origin iframes to scroll the top document called Element#scrollIntoView(). While I haven't confirmed if this was used in your specific scenario, it seems like a plausible explanation.

Here's a simple example to demonstrate:

  • Execute the snippet
  • Manually scroll to the top of the page immediately
  • Wait for about 2 seconds for the snippet to automatically scroll back into view

(You can also click within the result iframe to trigger scrollIntoView again after 2 seconds).

onclick = e => setTimeout(() => {
  document.body.scrollIntoView();
}, 2000);
onclick();
Scroll to the top of the top page and wait 2s.

Upon further investigation, there doesn't seem to be a straightforward way to prevent this behavior... However, it's worth noting that Chrome won't scroll to fixed elements within an iframe. This insight suggests a workaround could be creating a "scroll-stop" layer by enclosing the target iframe within another iframe, setting its position to fixed to cover the wrapping iframe entirely. This would stop Chrome from scrolling the iframe's ancestors:

iframe { position: fixed; top: 0; width: 100vw; height: 100vh; border: none; padding: 0; margin: 0; }
<iframe srcdoc="
<script>
  onclick = e => setTimeout(() => {
    document.querySelector('h1').scrollIntoView();
  }, 2000);
  onclick();
</script>
<h1 style='margin-top: 100vh' >I still scroll into view, but not the top page.</h1>
"></iframe>

Keep in mind that this workaround is essentially exploiting a bug, may not function in other browsers, and could potentially be fixed in future Chrome updates.
For now, this is the only solution I've come across.

I suggest sharing your thoughts with the W3C's CSS working group on Github repo to propose adding a property that officially supports this feature.

Answer №2

After receiving advice from @Kaiido to raise this issue with W3C, feedback on the topic has indicated that the current standards do not support the desired functionality. If approved, a suggestion might allow for disabling vertical scrolling through:

<iframe src="..." allow="vertical-scroll 'none'"></iframe>

You can monitor the progress of the proposal here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Viewing HTML in Gmail shows the raw code with tags, making it easy to read with no fancy CSS or styling

This is a simple HTML document with test content that was sent in the message body by a mailing server to a Gmail account: <html> <body> Some text goes here <br><br> User who applied: Username <br> User's email: < ...

Issues with displaying or hiding a DIV using javascript - popup box unresponsive

I am working with this ASPX code: <div id="IsAccountingOk" class="modalDialog"> <div> <a href="#close" title="Close" class="close">X</a><br /> <asp:Label ID="lblIsAccountingOkHeader" runat="server" Text ...

Angular - Incorporating Query Parameters into URL

For instance, let's say I have the following URL: http://local.com/. When I invoke the function in my SearchController, I aim to set text=searchtext and generate a URL like this: http://local.com/?text=searchtext. Is there a way to achieve this? I at ...

Encountering a 403 Forbidden error while attempting to access a website built with Next.js

Every time I try to access the Next.JS website that's been deployed on IIS using the HTTP address, I'm faced with this error message: Get http://...../_next/static/chunks/webpack-73760e2208a549db.js net:: ERR_ABORTED 403 (Forbidden) However, w ...

Ways to design each element in React

I'm currently working on a React code that involves CSS for Scrolling functionality. When I try to use props.children.map, I encounter an error saying "TypeError: props.children.map is not a function". Since I am in the process of learning React.js, t ...

What are the steps to gather user data and generate a roster of individuals currently online?

I am currently working on a way to gather information about the users who are currently logged into my website. Here's how it works: When a user enters my website, they have the option to choose a nickname using an input box. Then, there are five diff ...

Tips on incorporating AJAX sorted outcome into HTML divs

Hey there, I have successfully implemented AJAX, PHP and MySQL Sorting to display results in tables, as shown in the code below. Now, my query is: How do I display the $result in HTML divs instead? Your assistance is highly appreciated. Here is the PHP c ...

Is it possible to incorporate RequireJS in importing VueJS components?

I am currently working on a project that involves using both RequireJS and Vue components. One of my goals is to break down the Vue components into smaller pieces for better organization, and I want to be able to export these smaller components so they can ...

Despite the use of v-if and v-else directives in Vue 2, a specific component properties are not being updated while the others are updating

Vue2 is not updating one specific component (<Button>) inside v-if and v-else, while the rest of the content is updated. I have recently discovered a solution to make this code function, but I am still unsure about Vue2 re-rendering behavior. I worr ...

Tips for saving multipart/form-data using ajax in Laravel 5.6

Looking for help to submit a multipart/form-data form through ajax. I've tried various solutions found online, but none seem to work for me. Hopefully, someone can point out what I might be missing! This is the HTML code of my form. It's being r ...

Improving ASP.NET MVC 4 output by bundling whitespace and formatting

While not a critical issue, I find it quite bothersome that when using the bundling feature in ASP.NET MVC 4, there is minimal white space in the output. For example: If manually rendered: <head> <title>Example page</title> < ...

Error message: "Issue encountered when trying to override styles in GWT DataGrid - ImageResource method value('cellTableLoading') not found"

Attempting to customize styles for the GWT DataGrid component following the instructions provided here. Here is my interface: public interface DataGridResources extends DataGrid.Resources { @Source({ DataGrid.Style.DEFAULT_CSS, "myDataGrid.css" }) DataGr ...

Selenium does not support running Javascript code

I am currently utilizing capybara in conjunction with Selenium as the driver. I am facing an issue where clicking on an element does not trigger the associated javascript to reveal a specific div. Below is my code snippet: scenario 'currently used t ...

Tips for adjusting the size of a v-text-field within a d-flex layout in Vue

I'm a beginner with Vue and I have encountered an issue with two v-text-field elements in a flexbox. They are currently taking up the entire available space on a line when displayed side by side. However, I would like to make them smaller. Despite try ...

Display a different image while another image is in the process of loading

I am currently facing an issue with a div that has a background image set up as follows: <div class="carousel-image" style="background: url(img/background.gif) no-repeat center center;"> </div> Upon loading my webpage, there is a brief ...

The issue with the autoresize feature in the tinymce plugin arises when trying to delete HTML img content using the backspace

When using the tinymce editor with the autoresize plugin enabled, I have noticed that it works correctly with text. However, there is an issue when inserting HTML content via execCommand. For example, if I insert the following code: <div> < ...

Executing a JavaScript file following an AJAX request in Ruby on Rails

Currently, I am utilizing prismjs to add syntax highlighting to my Rails application. The stylesheet and js file have been included in my layout, however, an issue arises where the code is only highlighted once during the initial page load. Subsequently, a ...

Fundamental modeling using Node.js with Mongoose

Currently, I am facing a challenge with developing a node.js application. My goal is to create a model for a musical scale that includes a name and a set of associated notes: var mongoose = require('mongoose'); var Schema = mongoose.Schema; var ...

Handling errors in Javascript asynchronous functions at the point of invocation

Adding the keyword async to a function seems to require catching errors within that function. However, there are situations where it doesn't make sense to catch errors and defer them to the caller instead, especially when the context of the function c ...

Steps to inserting a div element in the middle of two distinct background designs

I am looking to insert a div between two contrasting backgrounds. Here is an example of what it should look like: https://i.sstatic.net/5XUao.png As shown in the image, the div is positioned between a white and blue background. Can you help me achieve t ...