material-ui icon indicating copy to clipboard operation
material-ui copied to clipboard

[Select] Clicking a Select component when embedded within an iFrame causes the page to jump [Firefox]

Open stevegreenn opened this issue 4 years ago • 30 comments

  • [x] The issue is present in the latest release (and the v5 beta).
  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

When an app using Material-UI's Select component is embedded within an IFrame, you get behaviour like this: alt text

As you can see when you click the Select input, the page jumps to the top of the IFrame

Expected Behavior 🤔

The options menu should open without causing the page to jump as it does.

Steps to Reproduce 🕹

App.js:

import * as React from 'react';
import MenuItem from '@material-ui/core/MenuItem';
import FormHelperText from '@material-ui/core/FormHelperText';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';

function App() {
  return (
      <div>
        <div style={{ height: '250px', backgroundColor: '#aaa'}}>{ /* empty space */ }</div>
        <div style={{ height: '250px', backgroundColor: '#bbb'}}>{ /* empty space */ }</div>
        <div style={{ height: '250px', backgroundColor: '#ccc'}}>{ /* empty space */ }</div>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <Select>
            <MenuItem value="">
              <em>None</em>
            </MenuItem>
            <MenuItem value={10}>Ten</MenuItem>
            <MenuItem value={20}>Twenty</MenuItem>
            <MenuItem value={30}>Thirty</MenuItem>
          </Select>
          <FormHelperText>Without label</FormHelperText>
        </FormControl>
      </div>
  );
}

test.html:

<!doctype html>
<html lang="en">
    <body style="margin: 0;">
        <div style="height: 1000px;"></div>
        <iframe src="http://localhost:3000" style="border: 0; width: 100vw; height: 100vh;"></iframe>
        <div style="height: 1000px;"></div>
    </body>
</html>

Steps:

  1. Create an empty React project and use the above App.js
  2. Create the test.html using the provided code
  3. Start the server and open test.html in Firefox, at which point follow along with the above gif to see the page jumping.

Context 🔦

We have our app embedded in an IFrame as part of a wider application and came across this page jumping issue.

Your Environment 🌎

`npx @material-ui/envinfo`
  System:
    OS: Windows 10 10.0.18363
  Binaries:
    Node: 14.17.3 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.11 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 6.14.13 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Firefox: 90.0.2
  npmPackages:
    @emotion/react: ^11.4.0 => 11.4.0
    @emotion/styled: ^11.3.0 => 11.3.0
    @material-ui/core: ^5.0.0-beta.2 => 5.0.0-beta.2
    @material-ui/private-theming:  5.0.0-beta.2
    @material-ui/styled-engine:  5.0.0-beta.1
    @material-ui/system:  5.0.0-beta.2
    @material-ui/types:  6.0.1
    @material-ui/unstyled:  5.0.0-alpha.41
    @material-ui/utils:  5.0.0-beta.1
    @types/react:  17.0.15
    react: ^17.0.2 => 17.0.2
    react-dom: ^17.0.2 => 17.0.2

stevegreenn avatar Aug 03 '21 09:08 stevegreenn

Can you please provide a CodeSandbox (https://material-ui.com/r/issue-template-next), or a link to a repository on GitHub that reproduces the problem?

mnajdova avatar Aug 03 '21 10:08 mnajdova

Here is a CodeSandbox: https://codesandbox.io/s/429zg Here is a direct link to the page containing an IFrame: https://429zg.csb.app/iframe.html

stevegreenn avatar Aug 03 '21 10:08 stevegreenn

Alright, I can reproduce

mnajdova avatar Aug 03 '21 14:08 mnajdova

Cannot reproduce on Firefox 88.0.1 nor 91.01 with a viewport of 320x1280 when scrolled to the bottom and opening the Select.

@mnajdova, @stevegreenn Can you still reproduce the problem? Could you include a screen recording using

eps1lon avatar Aug 18 '21 07:08 eps1lon

Hi @eps1lon, I can still reproduce the problem. Here is a link to a screen recording: https://streamable.com/10ohzw

I'm on Firefox 91 now.

stevegreenn avatar Aug 18 '21 10:08 stevegreenn

Any idea how to solve this issue? I already thinking to give up on Material UI since it happens for all my forms.

ValeryP avatar Jun 13 '22 09:06 ValeryP

Hi Team,

Any idea on how to solve this issue. This is a big blocker for us in using material-ui.

StormRyders avatar Jul 05 '22 19:07 StormRyders

We are also experiencing this issue. A few notes, we are currently seeing this issue in both Chrome and Firefox. The top of the iFrame needs to be a bit scrolled off the top of the window in order to reproduce consistently. We've noticed this issue with both Select and Menu components.

trismi avatar Jul 06 '22 16:07 trismi

Solved this issue by disabling auto-focus for all problematic view types: Select, DatePicker, etc.

<DatePicker
   {...{autoFocus: false}}
   minDate={minDate} 
   ...
</DatePicker>

ValeryP avatar Jul 06 '22 16:07 ValeryP

<DatePicker {...{autoFocus: false}} minDate={minDate} ... </DatePicker>

Hi Valery

Created one sandbox for the issue that we are seeing. Can you please look into that? https://429zg.csb.app/iframe.html

StormRyders avatar Jul 06 '22 17:07 StormRyders

Solved this issue by disabling auto-focus for all problematic view types: Select, DatePicker, etc.

<DatePicker
   {...{autoFocus: false}}
   minDate={minDate} 
   ...
</DatePicker>

I am not able to get this working for me. Can you provide a demo where this solved the issue?

trismi avatar Jul 06 '22 17:07 trismi

In some testing I've been doing, I think this may actually be an issue with Popover. To see what I mean, try this snippet of HTML:

<!doctype html>
<html lang="en">
    <body style="margin: 0;">
        <div style="height: 1000px;"></div>
        <iframe src="https://v4.mui.com/components/popover/#popover" style="border: 0; width: 100vw; height: 100vh;"></iframe>
        <div style="height: 1000px;"></div>
    </body>
</html>

When opening the Popover, the screen will jump.

Online link to example: https://erehd6.csb.app

trismi avatar Jul 06 '22 21:07 trismi

Hi folks! I'm trying to find the root cause of the issue right now. I've noticed that the new implementation of Select - SelectUnstyled from the @mui/base package does not suffer from this issue (it also fixes a couple of other problems the Material UI version has). If you're willing to style it yourselves, it may be a viable option. Of course, I'll try to fix the Material UI Select as well.

michaldudak avatar Jul 08 '22 08:07 michaldudak

I managed to improve things a little. Changes in #33437 (available to try using under https://pkg.csb.dev/mui/material-ui/commit/011091b0/@mui/material) seem to make the Popover work better, but the issue with Select still exists. It doesn't happen 100% of the time, though - it looks like a race condition somewhere. Still, with the fix I mentioned, the page doesn't scroll to the top of the iframe but it centers the Select in the viewport. I'll keep investigating it for some more time.

michaldudak avatar Jul 08 '22 16:07 michaldudak

I managed to improve things a little. Changes in #33437 (available to try using under https://pkg.csb.dev/mui/material-ui/commit/011091b0/@mui/material) seem to make the Popover work better, but the issue with Select still exists. It doesn't happen 100% of the time, though - it looks like a race condition somewhere. Still, with the fix I mentioned, the page doesn't scroll to the top of the iframe but it centers the Select in the viewport. I'll keep investigating it for some more time.

We are using mui version @4.11.x and wanted to ensure that if the fix mentioned here will fix the issue in [email protected]

StormRyders avatar Jul 08 '22 17:07 StormRyders

I posted this question on Stack Overflow and received a helpful answer that does work. However, it requires that I then manage the focus state myself, and it'd be nice if that was not necessary.

trismi avatar Jul 11 '22 16:07 trismi

In the same vein as @trismi, we've disabled all of the autofocus in a project I'm working on (also on v4, but I'm hopeful that we can port a fix back to that even if it's not brought in to the older version of MUI), but we're now in a state where all keyboard-based input is broken.

I'll keep working to root cause this issue as well (as best we can on our end), but would love to see it resolved in the core library so we don't have to hack our fixes together.

miketierney avatar Jul 18 '22 23:07 miketierney

@StormRyders as v4 is not in active development anymore, we focus only on providing fixes to the latest version.

michaldudak avatar Jul 20 '22 11:07 michaldudak

I Managed to solve it as follows:

SelectProps={{ MenuProps:{ autoFocus: false, disableAutoFocusItem: true, disableEnforceFocus: true, disableAutoFocus: true, } }}

guilhermeabell avatar Jul 26 '22 18:07 guilhermeabell

I Managed to solve it as follows:

SelectProps={{ MenuProps:{ autoFocus: false, disableAutoFocusItem: true, disableEnforceFocus: true, disableAutoFocus: true, } }}

While it successfully resolved the scrolling issue, it inadvertently introduced a new problem. Specifically, after implementing the suggested fix, the Select component does not lose focus when clicking outside of it; instead, it remains in focus. This behavior is not expected and needs to be addressed.

arfa123 avatar Jan 29 '24 12:01 arfa123

interesting. I didn't get this unexpected behavior, can you put your code in codesandbox?

guilhermeabell avatar Feb 01 '24 19:02 guilhermeabell

@mnajdova

guilhermeabell avatar Feb 01 '24 22:02 guilhermeabell

interesting. I didn't get this unexpected behavior, can you put your code in codesandbox?

Sure, here you see the effects after adding these props: https://codesandbox.io/p/sandbox/selectlabels-material-demo-forked-pj62hj chrome-capture-2024-1-4

arfa123 avatar Feb 04 '24 13:02 arfa123

Thanks for tagging me @guilhermeabell. @michaldudak was the last one who was looking into this, maybe he will have more info. If I remember correctly this was fixed in Base UI and we were looking into adopting Material UI to use the Base UI's hooks.

mnajdova avatar Feb 05 '24 11:02 mnajdova

I was never able to get to the root of this problem. Since this will ultimately be fixed when we use Base UI's Select in Material UI, I didn't spend extra time on it.

michaldudak avatar Feb 05 '24 13:02 michaldudak

Thanks for tagging me @guilhermeabell. @michaldudak was the last one who was looking into this, maybe he will have more info. If I remember correctly this was fixed in Base UI and we were looking into adopting Material UI to use the Base UI's hooks.

Could you kindly elaborate on how the hooks in Base UI were used to resolve this issue? Your guidance would be greatly appreciated.

arfa123 avatar Feb 17 '24 16:02 arfa123

They were not used to fix the problem specifically. We created a new implementation of Select in Base UI that happens to be free from this issue.

michaldudak avatar Feb 20 '24 07:02 michaldudak

Hi @arfa123 what solved it for me in all the cases where I came across this problem was to disable autoFocus on the components that jumped SelectProps={{ MenuProps:{ autoFocus: false, disableAutoFocusItem: true, disableEnforceFocus: true, disableAutoFocus: true, } }} It's worth remembering that I was only able to reproduce/come across this problem using MUI when inside an application injected into iframes like iframe-resizer.

guilhermeabell avatar Apr 02 '24 07:04 guilhermeabell

Hi @arfa123 what solved it for me in all the cases where I came across this problem was to disable autoFocus on the components that jumped SelectProps={{ MenuProps:{ autoFocus: false, disableAutoFocusItem: true, disableEnforceFocus: true, disableAutoFocus: true, } }} It's worth remembering that I was only able to reproduce/come across this problem using MUI when inside an application injected into iframes like iframe-resizer.

By doing this, the keyboard accessibility of the Select component does not function correctly.

arfa123 avatar Jun 27 '24 14:06 arfa123

They were not used to fix the problem specifically. We created a new implementation of Select in Base UI that happens to be free from this issue.

I am already using Material UI in my React app. Can I use Base UI along with Material UI together? If yes, how can I apply the same Material Design styles to a Base UI Select component?

arfa123 avatar Jun 27 '24 14:06 arfa123