Search code examples
javascriptreactjsz-indexmaterial-ui

FloatingActionButton z-index change delay


I have a problem where a div that's supposed to always be below a FloatingActionButton (FAB) is temporarily above it when changing z-index values. When clicking the FAB, an invisible overlay is added at z-index 1000, then the div and the FAB are set to 1001 and 1002, respectively, to be clickable over the overlay.

But when changing their z-index values, the FAB seems to have a delay when it is applied, causing a visual artifact of the hidden portion of the div to be visible for ~½ second or so.

I believe it to be linked to the animation/transition of the FAB, but even with disableTouchRipple and disableFocusRipple the problem remains.

Here is an MCVE:

import React from 'react';
import {render} from 'react-dom';
import {FloatingActionButton, MuiThemeProvider} from 'material-ui';

const styles = {
  s1: {
    position: 'absolute',
    width: 100,
    height: 32,
    top: 32,
    left: 10,
    background: 'black'
  }, s2: {
    position: 'absolute',
    left: 80,
    top: 20
  }, overlay: {
    position: 'fixed',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    zIndex: 1000
  }
};

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      open: false
    };
  }

  onClick = () => {
    this.setState({open: !this.state.open});
  }

  render() {
    let menuStyle = {
      ...styles.s1,
      zIndex: this.state.open ? 1001 : 10
    };

    let fabStyle = {
      ...styles.s2,
      zIndex: this.state.open ? 1002 : 20
    };

    return (
     <MuiThemeProvider>
      {this.state.open && <div style={styles.overlay}/>}
      {this.state.open && <div style={menuStyle}/>}
      <FloatingActionButton style={fabStyle} onClick={this.onClick}>{'\u2728'}</FloatingActionButton>
     </MuiThemeProvider>
    );    
  }
}

render(<App />, document.getElementById('root'));

You can see it running here: https://codesandbox.io/s/k97m0yryw5

I made a workaround with a timeout and a delay state member, only changing the menu's z-index after about 400ms. But since this menu has buttons on it with tooltips, it is weird if you are quick with your mouse.


Solution

  • I've found a transition: 450ms in the FAB component, and suspected that is the cause of your problem.

    Just forcing transition: 0 was enough for solving, but I can't guarantee if any animation will cease working.

    import React from 'react';
    import {render} from 'react-dom';
    import {FloatingActionButton, MuiThemeProvider} from 'material-ui';
    
    const styles = {
      s1: {
        position: 'absolute',
        width: 100,
        height: 32,
        top: 32,
        left: 10,
        background: 'black'
      }, s2: {
        position: 'absolute',
        left: 80,
        top: 20
      }, overlay: {
        position: 'fixed',
        top: 0,
        bottom: 0,
        left: 0,
        right: 0,
        zIndex: 1000
      }
    };
    
    class App extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          open: false
        };
      }
    
      onClick = () => {
        this.setState({open: !this.state.open});
      }
    
      render() {
        let menuStyle = {
          ...styles.s1,
          zIndex: this.state.open ? 1001 : 10
        };
    
        let fabStyle = {
          ...styles.s2,
          zIndex: this.state.open ? 1002 : 20,
          transition: 0,
        };
    
        return (
         <MuiThemeProvider>
          {this.state.open && <div style={styles.overlay}/>}
          {this.state.open && <div style={menuStyle}/>}
          <FloatingActionButton style={fabStyle} onClick={this.onClick}>{'\u2728'}</FloatingActionButton>
         </MuiThemeProvider>
        );    
      }
    }
    
    render(<App />, document.getElementById('root'));
    

    You can check here: https://codesandbox.io/s/m5xwj6j9q9