Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behavior on mobile chrome and modals

I recently got informed that mobile users on chrome/android are experiencing a little "funny" behavior on modals. The autofocus does not work as expected and the view is always scrolled to the bottom.

This happens on modals, which are embedded at the end of the page.

Examples

Sandbox

I created this little sandbox (https://codesandbox.io/s/little-firefly-ruytgy?file=/src/App.vue) to demonstrate the issue.

Screencast

I also created a little screencast.

enter image description here

Code example

This is the code of App.vue in this example:

<template>
  <div class="h-screen">
    <div class="h-96 bg-red-500 flex justify-center items-center">
      <span class="text-white">Scroll down...</span>
    </div>
    <div class="h-96 bg-red-500 flex justify-center items-center">
      <span class="text-white">Just a little bit more...</span>
    </div>
    <div class="h-96 bg-red-500 flex justify-center items-center">
      <span class="text-white">You are almost there...</span>
    </div>
    <div class="h-96 bg-red-500 flex justify-center items-center">
      <span class="text-white"
        >Here we are. Now scroll down and click the button...</span
      >
    </div>

    <SimpleModal ref="mymodal">
      <template #dialog>
        <InputField name="test1" v-model="value1" />
        <InputField name="test2" v-model="value2" />
        <InputField name="test3" v-model="value3" />
        <InputField name="test4" v-model="value4" />
        <InputField name="test5" v-model="value5" />
        <InputField name="test6" v-model="value6" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
        <InputField name="test7" v-model="value7" />
      </template>
    </SimpleModal>
    <div class="flex justify-center items-center mt-4">
      <button class="border p-4" @click="$refs.mymodal.openModal">
        Open Modal
      </button>
    </div>
  </div>
</template>
<script>
import { ref } from "vue";
import InputField from "./components/InputField.vue";
import SimpleModal from "./components/SimpleModal.vue";

export default {
  components: {
    SimpleModal,
    InputField,
  },

  setup() {
    const isOpen = ref(false);

    return {
      isOpen,
      closeModal() {
        isOpen.value = false;
      },
      openModal() {
        isOpen.value = true;
      },
    };
  },
  data() {
    return {
      value1: null,
      value2: null,
      value3: null,
      value4: null,
    };
  },
};
</script>

Ugly workaround

For now I created a little ugly workaround: Before the modal is being opened, use

window.scroll(0,0);

to scroll to the top. That's not really what I want, because if the person closes the modal, the person has to scroll down all the way again.

like image 287
SPQRInc Avatar asked Oct 27 '25 13:10

SPQRInc


1 Answers

First, I'm not great with CSS, so it's very possible that there's a more elegant solution that what I'm suggesting.

I notice that the modal/dialog does not have a max-height and is ending up using the available height on the page. This is what is leading to the long modal in the first place---both on desktop and mobile. One way to fix the issue you're running into is to simply give it a max-height.

src/components/SimpleModal.vue
Add a class (e.g. .dialog) to the modal container (parent of DialogTitle) and simply apply some CSS rules to it.

<style scoped>
// Tailwind seems to be applying the following rules:
// margin-top: 2rem;
// margin-bottom: 2rem;
// Take control of this if needed and apply it ourselves

.dialog {
  --dialog-margin-y: 2rem;
  --dialog-max-height: 100vh;
  margin-top: var(--dialog-margin-y);
  margin-bottom: var(--dialog-margin-y);
  max-height: calc(var(--dialog-max-height) - calc(2 * var(--dialog-margin-y)));
  overflow-y: auto; // We're going to need this since we're fixing max-height
}
</style>

With these rules in place, this is what I observe:

Desktop enter image description here

Mobile enter image description here

Here's a screengrab of my Android device

enter image description here

like image 184
Guru Prasad Avatar answered Oct 29 '25 03:10

Guru Prasad