2022 / 07 / 31
2022 / 09 / 18
A basic modal component with Vue 3 and Tailwind CSS

Let's write a reusable modal with Vue and Tailwind CSS.

vue 3
common ui

Let’s go for a simple base modal implementation that provides a backdrop and a centered <div> where we can put any content we need.

Example usage in BaseModalExample.vue:

<script setup lang="ts">
import { ref } from 'vue'

import BaseModal from '@/components/modals/BaseModal.vue'

const showModal = ref(false)

    class="bg-indigo-200 px-3 py-1 font-medium"
    @click="showModal = true"
    Show modal

  <BaseModal :show="showModal">
    <div class="p-4">
      <div class="text-lg">Hello Modal World!</div>

      <div class="py-2 text-sm">Click to close:</div>

        class="bg-indigo-200 px-3 py-1 font-medium"
        @click="showModal = false"
        Hide modal

Let’s see how to implement the BaseModal.vue component, shall we? :monocle:


For this, you’ll need a Vue 3 + TypeScript (+ Tailwind CSS) project.

You can set up one following the instructions here:
Build a Vue 3 + TypeScript dev environment with Vite

Where modals go

It’s recommended that we display our modals in a div at the bottom of our main HTML file to avoid other elements accidentally rendering on top of them.

Add a new #modals element to your index.html:

  <div id="app" class="relative z-10"></div>
  <!-- >> This one is new! << -->
  <div id="modals" class="relative z-20"></div>
  <script type="module" src="/src/main.ts"></script>

We also add a z-index value and position: relative to the #app and #modals layers.
Now our modals will show on top of everything else thanks to stacking contexts.

Base modal

Let’s add a src/components/modals/BaseModal.vue:

<script setup lang="ts">
  show: boolean

  <!-- Render inside our `<div id="modals"></div>` in index.html -->
  <Teleport to="#modals">
    <!-- Show / hide the modal -->
    <div v-if="show" class="">
      <!-- The backdrop -->
      <div class="fixed inset-0 bg-gray-900 opacity-40"></div>

      <!-- Where the actual content goes -->
      <div class="fixed inset-0 flex items-center justify-center">
        <div class="bg-white text-black">

This example provides some basic styling.
Feel free to add props or slots to configure the different aspects of a modal — backdrop color, opacity, content background color, content text color, etc.

That’s it! :tada: