You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue CLI+Tailwind+Flowbite弹出Modal后部分组件未暗化求助

问题描述

使用Vue CLI、Tailwind CSS与Flowbite构建移动端适配网站,点击底部按钮触发Modal弹窗时,导航栏(NavbarWhite组件)和底部按钮(ButtonBottom组件)未被暗化遮罩,其余页面内容正常变暗。


<template>
  <header class="sticky h-14 top-0 z-50 bg-white" :class="boxShadow">
    <div class="flex flex-row">
      <div class="absolute" v-if="srcPictureLeft">
        <img
          @click="onClickBack"
          class="ml-7 py-4 cursor-pointer text-black"
          :src="require(`../assets/icon/${srcPictureLeft}`)"
        />
      </div>
      <div v-else></div>
      <div class="py-4 relative mx-auto font-semibold text-black text-xl">
        {{ title }}
      </div>
    </div>
  </header>
</template>
<style>
</style>
<script>
export default {
  name: "NavbarWhite",
  props: {
    onClickBack: {
      type: Function,
    },
    title: String,
    srcPictureLeft: String,
    boxShadow: String,
  },
};
</script>

ButtonBottom.vue代码

<template>
  <div
    class="
      sticky
      w-full
      absolute
      mb-0
      bottom-0
      z-50
      bg-white
      h-16
      drop-shadow-[0_0_4px_rgba(0,0,0,0.25)]
    "
  >
    <div class="mx-[30px] py-2">
      <button-primary
        class="
          bg-green-button
          text-white
          hover:bg-green-button-darker hover:rounded-[32px]
        "
      >
        <slot>Button</slot>
      </button-primary>
    </div>
  </div>
</template>
<script>
import ButtonPrimary from "@/components/ButtonPrimary.vue";
export default {
  name: "ButtonBottom",
  components: {
    ButtonPrimary,
  },
};
</script>

父组件TransactionSummary.vue代码

<template>
  <div class="h-screen relative">
    <div class="h-[94%]">
      <navbar-white
        boxShadow="shadow-[0_0_10px_0_rgba(0,0,0,0.25)]"
        srcPictureLeft="backIconBlack.svg"
        :onClickBack="goBack"
        title="Ringkasan Transaksi"
      />
      <div class="mt-10 mx-[30px]">
        <div class="flex flex-row justify-between mb-7">
          <div class="font-semibold">No. Rekening</div>
          <div>12345678</div>
        </div>

        <div class="flex flex-row justify-between mb-7">
          <div class="font-semibold">Nama Penerima</div>
          <div>Lorem Ipsum</div>
        </div>

        <div class="flex flex-row justify-between mb-4">
          <div class="font-semibold">Bank Tujuan</div>
          <div>12345678</div>
        </div>

        <hr class="mb-4" />

        <div class="flex flex-row justify-between mb-7">
          <div class="font-semibold">Nominal</div>
          <div>Rp 200.000</div>
        </div>

        <div class="flex flex-row justify-between mb-4">
          <div class="font-semibold">Fee</div>
          <div>Rp 2.500</div>
        </div>

        <div class="flex flex-row justify-between">
          <div class="font-semibold">Total</div>
          <div class="font-semibold">Rp 202.500</div>
        </div>
      </div>
    </div>
    <button-bottom data-modal-toggle="biayaAdmin">Selanjutnya</button-bottom>
    <!-- modal start here -->
    <div
      id="biayaAdmin"
      tabindex="-1"
      class="
        hidden
        overflow-y-auto overflow-x-hidden
        fixed
        top-0
        right-0
        left-0
        z-50
        w-full
        md:inset-0
        h-modal
        md:h-full
      "
    >
      <div class="relative p-4 w-full max-w-md h-full md:h-auto">
        <!-- Modal content -->
        <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
          <!-- Modal header -->
          <div
            class="
              flex
              justify-between
              items-center
              p-5
              rounded-t
              border-b
              dark:border-gray-600
            "
          >
            <h3 class="text-xl font-medium text-gray-900 dark:text-white">
              Small modal
            </h3>
            <button
              type="button"
              class="
                text-gray-400
                bg-transparent
                hover:bg-gray-200 hover:text-gray-900
                rounded-lg
                text-sm
                p-1.5
                ml-auto
                inline-flex
                items-center
                dark:hover:bg-gray-600 dark:hover:text-white
              "
              data-modal-toggle="biayaAdmin"
            >
              <svg
                aria-hidden="true"
                class="w-5 h-5"
                fill="currentColor"
                viewBox="0 0 20 20"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  fill-rule="evenodd"
                  d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
                  clip-rule="evenodd"
                ></path>
              </svg>
              <span class="sr-only">Close modal</span>
            </button>
          </div>
          <!-- Modal body -->
          <div class="p-6 space-y-6">
            <p
              class="text-base leading-relaxed text-gray-500 dark:text-gray-400"
            >
              With less than a month to go before the European Union enacts new
              consumer privacy laws for its citizens, companies around the world
              are updating their terms of service agreements to comply.
            </p>
            <p
              class="text-base leading-relaxed text-gray-500 dark:text-gray-400"
            >
              The European Union’s General Data Protection Regulation (G.D.P.R.)
              goes into effect on May 25 and is meant to ensure a common set of
              data rights in the European Union. It requires organizations to
              notify users as soon as possible of high-risk data breaches that
              could personally affect them.
            </p>
          </div>
          <!-- Modal footer -->
          <div
            class="
              flex
              items-center
              p-6
              space-x-2
              rounded-b
              border-t border-gray-200
              dark:border-gray-600
            "
          >
            <button
              data-modal-toggle="biayaAdmin"
              type="button"
              class="
                text-white
                bg-blue-700
                hover:bg-blue-800
                focus:ring-4 focus:outline-none focus:ring-blue-300
                font-medium
                rounded-lg
                text-sm
                px-5
                py-2.5
                text-center
                dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
              "
            >
              I accept
            </button>
            <button
              data-modal-toggle="biayaAdmin"
              type="button"
              class="
                text-gray-500
                bg-white
                hover:bg-gray-100
                focus:ring-4 focus:outline-none focus:ring-gray-200
                rounded-lg
                border border-gray-200
                text-sm
                font-medium
                px-5
                py-2.5
                hover:text-gray-900
                focus:z-10
                dark:bg-gray-700
                dark:text-gray-300
                dark:border-gray-500
                dark:hover:text-white
                dark:hover:bg-gray-600
                dark:focus:ring-gray-600
              "
            >
              Decline
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import ButtonBottom from "@/components/ButtonBottom.vue";
import NavbarWhite from "@/components/NavbarWhite.vue";
export default {
  name: "TransactionSummary",
  components: {
    ButtonBottom,
    NavbarWhite,
  },
  methods: {
    goBack() {
      this.$router.go(-1);
    },
  },
};
</script>

解决方案

问题根源是导航栏和底部按钮的z-index与Modal弹窗的z-index相同:

  • NavbarWhite和ButtonBottom都设置了z-50
  • Flowbite Modal的容器和遮罩层默认也是z-50

这导致导航栏和底部按钮的层级与Modal遮罩层平级,无法被遮罩覆盖。推荐以下两种解决方法:

方法1:降低导航栏和底部按钮的z-index

将两个组件的z-50改为z-40,让Modal的z-50层级更高:

修改NavbarWhite.vue

<header class="sticky h-14 top-0 z-40 bg-white" :class="boxShadow">

修改ButtonBottom.vue

<div
  class="
    sticky
    w-full
    absolute
    mb-0
    bottom-0
    z-40
    bg-white
    h-16
    drop-shadow-[0_0_4px_rgba(0,0,0,0.25)]
  "
>

方法2:自定义Modal遮罩层z-index(可选)

如果不想修改组件层级,可以在自定义CSS中调整Modal遮罩层的z-index,确保它比导航栏和底部按钮高:

[data-modal-backdrop] {
  z-index: 45 !important;
}

保持Modal内容的z-50不变,这样遮罩层会覆盖在导航栏/按钮上方,弹窗内容仍处于最顶层。


内容的提问来源于stack exchange,提问作者Avalon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 04:15:36