A component that designers usually use when it is necessary to show extra content or important content is the modal windows, these are particularly useful because they allow to show content over the existing one without the need to hide or move something, they are convenient and the users are already very familiar with them.

With Vue it's easy to create a component of this kind that you can use in your projects. In this article I'll show you how.

First of all here you can see the finished component:

The template

<template>
  <transition name="modal">
    <div class="m-modal-overlay">
      <div class="m-modal-wrapper">
        <div class="m-modal-header">
          <slot name="title"></slot>
          <a href="#" class="m-modal-close" @click.stop.prevent="$emit('close')">
          	<i class="fa fa-times"></i>
          </a>
        </div>
        <div class="m-modal-body">
          <slot name="body"></slot>
        </div>
      </div>
    </div>
  </transition>
</template>
  • The first thing you have to notice is that all the markup is wrapped by the transition component with the name of modal assigned to it. This is because the component will have a slight transition of opacity and scale when it appears and when it hides.
  • There is a slot called title that will be the place where you can place the element you want to be the title.
  • There is another slot called body, here you can put the content you want, is perhaps the most important part of the template.
  • It is worth noting that the anchor with the m-modal-close class will be in charge of emitting an event called close that will hide the modal when it is open.

The styles

.m-modal-overlay {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
  background-color: rgba(0, 0, 0, 0.25);
  transition: opacity .3s ease;
}

.m-modal-wrapper {
  display: flex;
  flex-direction: column;
  width: 400px;
  height: 400px;
  border: 1px solid #f2f2f2;
  background-color: white;
  box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.12);
  transition: all .3s ease;
}

.m-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 20px;
  border-bottom: 1px solid #f2f2f2;
  h3 {
    color: #6f7279;
    line-height: 1.4;
    font-size: 16px;
    font-weight: 600;
    margin: 0;
    }
}

.m-modal-close {
  color: #c8ccd1;
  text-transform: uppercase;
  text-decoration: none;
  i {
    color: inherit;
    font-size: 20px;
  }
}

.m-modal-body {
  flex: 1;
  font-size: 14px;
  padding: 20px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  p {
    margin: 0;
  }
}

.modal-enter, .modal-leave-active {
  opacity: 0;
}

.modal-enter .m-modal-wrapper,
.modal-leave-active .m-modal-wrapper {
  transform: scale(1.1);
}
  • The m-modal-overlay class makes a dark, semi-transparent layer appear over the entire page content and behind the content of the modal window.
  • The styles of the m-modal-wrapper class create the box that stands out over the semi-transparent layer, in this case it is the white box where the title and the body of the component are shown.
  • The styles of the m-modal-header class make the title and the close icon vertically aligned and do not overlap. Note that for the title I'm using styles for an h3 element but you can apply those styles to the type of element you want to use instead.
  • Within the m-modal-close class you can notice that I apply styles for the i element, that's because in this case I'm using FontAwesome to show the close icon. You are free to change those styles according to your needs.
  • The styles of the m-modal-body class make the body of the modal window take up all the remaining vertical space and produce a vertical scroll in case the content exceeds the dimensions of the white box.
  • Up to the end there are a couple of styles applied to some selectors that start with modal-, these are (believe it or not) the only styles necessary to make the subtle but nice animation of opacity and scale that is shown when opening and closing the modal window.

Usage

From now on when you want to use this component in any page of your application it is necessary that you include a code similar to this one:

<modal v-if="displayModal" @close="displayModal = false">
  <h3 slot="title">My awesome title</h3>
  <div slot="body">
    <p>
      Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
    </p>
  </div>
</modal>

From the above code it is important to note that the component will be mounted when the displayModal property is true, otherwise the component will be destroyed. Also note that the component will hear the close event, when it is emitted by the close button then the modal window will close.

Also you must create a property in the page or component where you use the modal window to save a boolean value that will determine whether to show it or not, in this case I called it displayModal and by default it will be false so that it is hidden from the beginning.

export default {
  data () {
    return {
    	displayModal: false
    }
  }
}

Finally you will need to create some element that the user will have to click to display the modal window.

<button @click="displayModal = true">Show Modal</button>

As you can see, making a modal window with Vue is very simple, it's just a matter of writing the right styles to make it look good and easy for the user to use.