0

IPhone Keyboard block Bootstrap 5 Bottom Canvas

Describe the issue

I'm building a Vue 3 project with Bootstrap 5, and I've implemented a dynamic bottom canvas (offcanvas) where users can add and interact with content. However, on iPhones, when the keyboard pops up (e.g., during form input), it blocks the bottom canvas, preventing the content from being displayed or accessed properly.

I've tried using CSS solutions like position: fixed;, bottom: 0;, and overflow: auto;, but they didn't resolve the issue. The problem seems specific to iOS handling of fixed-position elements when the keyboard is active.

Has anyone faced a similar issue with iOS keyboards and dynamic bottom canvases? Any suggestions or workarounds would be greatly appreciated!

my code

<template>
  <TransitionGroup
    enter-active-class="animate__animated animate__slideInUp animate__faster"
    leave-active-class="animate__animated animate__slideOutDown"
    :duration="45"
  >
    <div
      v-for="(modal, index) in modalStore.modals"
      :key="index"
      :class="['offcanvas', 'offcanvas-bottom', { show: modal.isOpen }]"
      data-bs-backdrop="false"
      tabindex="-1"
      aria-labelledby="offcanvasBottomLabel"
      :style="{ height: modal.height }"
    >
      <!-- Modal Header -->
      <!-- <div class="offcanvas-header" v-if="modal.props.title">
        <h5 class="offcanvas-title">{{ modal.props.title }}</h5>
      </div> -->
      <!-- Modal Body -->
      <component :is="modal.component" v-bind="modal.props"></component>

      <!-- Modal Footer (conditionally rendered) -->
      <div class="offcanvas-footer" v-if="modal.showFooter == true">
        <div class="d-grid">
          <button
            type="button"
            class="modal-close-btn"
            @click="closeModal(modal.name)"
            aria-label="Close"
          >
            <i class="fa-solid fa-chevron-down"></i>
          </button>
        </div>
      </div>
    </div>
  </TransitionGroup>
  <!-- Conditionally Render Backdrop -->
  <div
    v-if="modalStore.modals.length > 0"
    class="offcanvas-backdrop fade show"
    @click="handleBackdropClick"
  ></div>
</template>

<script>
import { useModalStore } from "../../../libs/store/modalStore";

export default {
  setup() {
    const modalStore = useModalStore();

    const closeModal = (name) => {
      modalStore.closeModal(name);
    };

    // Backdrop click handler
    const handleBackdropClick = () => {
      // Get the most recent modal (top-most on the stack)
      const currentModal = modalStore.modals[modalStore.modals.length - 1];

      // Close the modal if `closeOverlay` is not explicitly false
      if (currentModal.props.closeOverlay !== false) {
        closeModal(currentModal.name);
      }
    };

    return {
      modalStore,
      closeModal,
      handleBackdropClick,
    };
  },
};
</script>

i try adding this to script but still didnt work

    const adjustModalForIOSKeyboard = () => {
      const modalElement = document.querySelector(".offcanvas-bottom");

      if (!modalElement) return;

      const onKeyboardShow = (event) => {
        // Get the keyboard height from the event (iOS provides it)
        const keyboardHeight = event?.keyboardHeight || 300; // Fallback height

        // Adjust modal height to avoid being blocked by the keyboard
        modalElement.style.height = `calc(100vh - ${keyboardHeight}px)`;
      };

      const onKeyboardHide = () => {
        // Reset modal height when the keyboard is hidden
        modalElement.style.height = "100%";
      };

      // Listen to iOS-specific keyboard events
      window.addEventListener("keyboardDidShow", onKeyboardShow);
      window.addEventListener("keyboardDidHide", onKeyboardHide);

      // Fallback for other platforms: focus events
      document.body.addEventListener("focusin", onKeyboardShow); // Simulates `keyboardDidShow`
      document.body.addEventListener("focusout", onKeyboardHide); // Simulates `keyboardDidHide`
    };

    onMounted(() => {
      adjustModalForIOSKeyboard();
    });

    onUnmounted(() => {
      // Cleanup event listeners
      window.removeEventListener("keyboardDidShow", adjustModalForIOSKeyboard);
      window.removeEventListener("keyboardDidHide", adjustModalForIOSKeyboard);
    });
5
  • It's quite a popular issue and there are a few relative units that could solve that specific issue I think.
    – kissu
    Commented Jan 11 at 10:17
  • very seripus issue that need to be resolved Commented Jan 12 at 8:55
  • 1
    Yeah, like quite a few other bugs running around, and that is decision-driven by money. There are CSS workarounds tho.
    – kissu
    Commented Jan 12 at 9:14
  • @kissu kindly share the css work arond you can come up with Commented Jan 12 at 10:55
  • 1
    For example, this one and that one are a good start.
    – kissu
    Commented Jan 12 at 11:20

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.