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

md-dialog: scrollbar Flash on opening

Open vdegenne opened this issue 1 year ago • 8 comments

What is affected?

Component

Description

The scrollbar flashes when the dialog opens even in the case the content is not scrollable. It's particularly more apparent in dark mode. See below playground for a demonstration of this issue.

Reproduction

https://lit.dev/playground/#gist=825f3acbc05233df00a8cdb1bd9693c2

Workaround

Could this issue be fixed by hidding the overflow on animation start?

Is this a regression?

No or unsure. This never worked, or I haven't tried before.

Affected versions

@material/[email protected]

Browser/OS/Node environment

Any browser/system

vdegenne avatar Oct 25 '23 07:10 vdegenne

I'm not able to reproduce on Chrome macOS. Which browser/os environment are you seeing the issue? Can you upload a screen recording too?

asyncLiz avatar Oct 26 '23 20:10 asyncLiz

I can reproduce on Linux Mint 21.2 Chrome 118.0.5993.88.

I cannot reproduce on FF.

https://github.com/material-components/material-web/assets/1168053/871fb0f6-b29b-497c-a96c-fce37b3e8f1c

christophe-g avatar Oct 27 '23 10:10 christophe-g

I can reproduce on Windows with Edge. No issue with FF.

SummersRA avatar Oct 27 '23 11:10 SummersRA

Firefox is doing great (you can even select text in the dialogs 😹)

vdegenne avatar Oct 27 '23 12:10 vdegenne

Still can reproduce in Edge - Version 121.0.2277.98 (Official build) (64-bit)

Basyras avatar Feb 03 '24 13:02 Basyras

Can reproduce this with Chrome M114 and M122 running through Electron V0.25.X and V0.29.X, respectively

SDBonhof avatar Feb 22 '24 14:02 SDBonhof

I found an interim fix, adding overflow: visible to the .scroller seems to be fix the issue. Not sure what side-effects will it cause, but works fine for small dialogs.

function fixScrollFlash(mdDialog: MdDialog) {
    const shadowRoot = mdDialog.shadowRoot;
    if (shadowRoot) {
      const scroller = shadowRoot.querySelector<HTMLElement>(".scroller");
      if (scroller) {
        scroller.style.overflow = "visible";
      } else {
        console.log("scrollernot found");
      }
    } else {
      console.log("shadowRoote not found");
    }
  }

shhdharmen avatar Apr 06 '24 20:04 shhdharmen

My workaround. Slightly inspired by @shhdharmen workaround.

Using these 2 events it will make sure the scrollbar will work as needed after animation is played and the shadowRoot children are present - so no check for .scroller shouldn't be needed.

open: Dispatched when the dialog is opening before any animations. opened: Dispatched when the dialog has opened after any animations.

static showDialog(dialog) {
    dialog.addEventListener("open", () => {
        this.changeScrollerOverflow(dialog, "visible");
    });

    dialog.addEventListener("opened", () => {
        this.changeScrollerOverflow(dialog, "hidden");
    });

    dialog.show();
}

static changeScrollerOverflow(mdDialog, overflowValue) {
    const shadowRoot = mdDialog.shadowRoot;
    const scroller = shadowRoot.querySelector(".scroller");
    scroller.style.overflow = overflowValue;
}

Basyras avatar May 05 '24 18:05 Basyras