vue-select icon indicating copy to clipboard operation
vue-select copied to clipboard

z-index problem when container is scrolling

Open ccleve opened this issue 4 years ago • 2 comments

Describe the bug

My issue is the same as @mgiraldo's comment on #823. I've created a small test case.

To Reproduce

https://codesandbox.io/s/vigorous-ellis-950up?file=/src/App.vue

Click on the dropdown. You can see that that dropdown appears behind the enclosing containers, even though append-to-body is there.

This appears to be an odd combination of factors. Outer div must be positioned (position: relative). Inner div must have overflow-y: something. Outer div must have a big z-index. The bug appears with an outer div z-index of 9999; it does not appear with just 999.

Setting the z-index of .vs__dropdown-menu to a larger number does not solve the problem.

This is a problem because modal dialog boxes will often have a big z-index to appear on top of the rest of the app, and they are always positioned, and often the contents scroll.

Desktop (please complete the following information):

Happens on both Firefox and Chrome.

I'm using the latest vue-select, 3.11.2.

ccleve avatar Feb 02 '21 23:02 ccleve

yes this is very similar to my problem. in my case i decided not to use append-to-body so that the user can scroll the container and reach the options

mgiraldo avatar Feb 04 '21 22:02 mgiraldo

In my case I am successfully setting zIndex to a number higher than the modal, which results in showing the dropdown in correct position, above the modal.

Using append-to-body and :calculatePosition="withPopper"

function withPopper(
  dropdownList: HTMLElement,
  component: { $refs: { toggle: Element | VirtualElement } },
  { width }: { width: number; top: number; left: number }
) {
  /**
   * We need to explicitly define the dropdown width since
   * it is usually inherited from the parent with CSS.
   */
  dropdownList.style.width = width.toString();
  dropdownList.style.zIndex = (500000).toString(); // Need to be larger than the z-index of the modal

  const popper = createPopper(component.$refs.toggle, dropdownList, {
    modifiers: [
      {
        name: "offset",
        options: {
          // We offset be window.height since it for some reason spawn outside the viewport
          // I suspect this is because we have an application where all views are supposed to be 100vh
          offset: [0, -window.innerHeight],
        },
      },
    ],
  });

  /**
   * To prevent memory leaks Popper needs to be destroyed.
   * If you return function, it will be called just before dropdown is removed from DOM.
   */
  return () => {
    popper.destroy();
  };
}

mathiash98 avatar Nov 09 '21 10:11 mathiash98