AppDividend
Latest Code Tutorials

How To Create Hover Animation In Vuejs

1,474

Get real time updates directly on you device, subscribe now.

In this example, I have taught How To Create Hover Animation In Vuejs. In this tutorial, we do not use any CSS frameworks. We use CSS3 properties to accomplish the goal. Apply animation effect on hover in Vue.js is very easy.  We create a simple card with text and image. Then when we hover that card, the image size will be increased but do not spread out of the card. So we use CSS transition property. Also, we use mouseover event from Vue.js to apply animation effect when the user hovers the particular card. Now let us start this Create Hover Animation in Vuejs example.

Create Hover Animation In Vuejs

Let us install Vue.js using the Vue CLI. If you have not installed the Vue CLI previously then install it using the following command.

#Step 1: Install Vue.js.

npm install -g @vue/cli
# OR
yarn global add @vue/cli

Now create a new Vue.js project using the following command.

vue create animation

Okay, now inside src >> App.vue file add the following code to create a Card. Remember, we are not using Bootstrap framework so that we will write the css from scratch.

<!-- App.vue -->

<div id="app">
  <div class="card-row">
    <div class="card">
      
      <img class="card-image" src="https://www.gstatic.com/webp/gallery3/2_webp_ll.png">
      
      <div class="card-footer">
        <h3 class="card-title">Title</h3>
        <p class="card-text">by 
          <span class="card-author">Author</span>
        </p>
      </div>
    </div>
  </div>
</div>

So, we have created the Card, but we need to build its styles. So inside src >> assets folder, create one file called style.css and add the css code inside it.

body {
  background-color: #E1E7E7;
}

.card-row {
  display: flex;
  justify-content: center;
  align-items: center;  
  min-width: 780px;
  width: 100%;
  height: 500px;
}

We use flexbox for styling because it is effortless to use. Next step is to style the card.

#Step 2: Style the Card.

Write the following code inside the style.css file.

.card {
  position: relative;
  background-color: #FFFFFF;
  height: 370px;
  width: 240px;
  margin: 10px;
  overflow: hidden;
  box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.5);
}

The position of the card will be relative. Overflow must be hidden because we do not need to display the image outside of the card when it is resized. So overflow will always be hidden. The box-shadow property adds the shadow to the card.

#Step 3: Style the Image.

Add the following code inside the style.css file.

.card-image {
  position: absolute;
  left: -9999px;
  right: -9999px;
  margin: auto;
  height: 220px;
  min-width: 100%;
}

The main reason I have taken a left and right to -9999px is that when we hover the image, animation effect will be applied so, it should center the image horizontally. The position is absolute, and min-width is 100%.

#Step 4: Style the Footer.

Write the following code inside a style.css file.

.card-footer {
  position: absolute;
  bottom: 0;
  height: 130px;
  padding: 10px 15px;
  font-family: Helvetica;
}
.card-text {
  font-size: 14px;
  color: rgba(0, 0, 0, 0.7);
}
.card-title {
  font-family: Serif;
}
.card-author {
  font-size: 14px;
  color: #BAB096;
}

It is pretty same stuff, we have assigned different classes to its styles. Nothing more complicated.

#Step 5: Add the data.

We have created one card, but now, we will create five cards. So we need an array of data. So let us define the data inside App.vue file. Also, we have to import the style.css inside App.vue file to see the changes.

// App.vue

import './assets/style.css';

export default {
  name: 'app',
  data() {
    return {
      cards: [
        {
         title: 'Gallery', 
         author: 'Walder Frey', 
         image: 'http://www.gstatic.com/webp/gallery/1.webp'
        },
        {
          title: 'Penguin', 
          author: 'Ramsey Bolton', 
          image: 'https://www.gstatic.com/webp/gallery3/2_webp_ll.png'
        },
        {
          title: 'Flower', 
          author: 'Joffrey Baratheon', 
          image: 'https://www.gstatic.com/webp/gallery3/1.png'
        },
         {
          title: 'Flower Pot', 
          author: 'Cersie Lannister', 
          image: 'https://www.fiftyflowers.com/site_files/FiftyFlowers/Image/Product/Make_Your_Own_Centerpiece_Close_Up_350_a425aad8.jpg'
        },
         {
          title: 'Rose', 
          author: 'Roose Bolton', 
          image: 'https://res.cloudinary.com/prestige-gifting/image/fetch/fl_progressive,q_95,e_sharpen:50,w_480/e_saturation:05/https://www.prestigeflowers.co.uk/images/NF4016-130116.jpg'
        }
      ]
    }
  }
}

And now in our template, we can render those cards with a v-for directive.

<!-- App.vue -->
<div id="app">
  <div class="card-row">
    <div v-for="(card, index) in cards" 
      :key="index"
      :ref="`card_${index}`"
         class="card">
      
      <img class="card-image" :src="card.image">
      
      <div class="card-footer">
        <h3 class="card-title">{{card.title}}</h3>
        <p class="card-text">by 
          <span class="card-author">{{card.author}}</span>
        </p>
      </div>
    </div>
  </div>
</div>

 

How To Create Hover Animation In Vuejs

#Step 6: Add the hover effect.

I am writing the whole code here. So bear with me.

Related Posts
1 of 15

First, I am showing the full code of the style.css file.

body {
    background-color: #E1E7E7;
  }
  
  .card-row {
    display: flex;
    justify-content: center;
    align-items: center;  
    min-width: 780px;
    width: 100%;
    height: 500px;
  }
  
  .card {
    position: relative;
    background-color: #FFFFFF;
    height: 370px;
    width: 240px;
    margin: 10px;
    overflow: hidden;
    box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.5);
  }
  
  .card-image {
    /* center horizontally overflown image */
    position: absolute;
    left: -9999px;
    right: -9999px;
    margin: auto;
  
    height: 220px;
    min-width: 100%;
  
    transition: height 0.3s, opacity 0.3s;
  }
  .card-image.selected {
    height: 410px;
    opacity: 0.3;
  }
  
  .card-footer {
    position: absolute;
    bottom: 0;
    height: 130px;
    padding: 10px 15px;
    font-family: Helvetica;
  }
  .card-text {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.7);
  }
  .card-title {
    font-family: Serif;
  }
  .card-author {
    font-size: 14px;
    color: #BAB096;
    transition: color 0.3s;
  }
  .card-author.selected {
    color: #6a6456;
  }
  .card {
    /* the other rules */
    transition: height 0.3s, box-shadow 0.3s;
  }
  .card:hover {
    height: 410px;
    box-shadow: 20px 20px 40px 0px rgba(0,0,0,0.5);
  }

Also, write the following code inside App.vue file.

<!-- App.vue -->

<template>
  <div id="app">
    <div class="card-row">
    <div v-for="(card, index) in cards" 
        :key="index"
        :ref="`card_${index}`"
        @mouseover="hoverCard(index)"
        @mouseout="hoverCard(-1)"
        class="card">
      
      <img class="card-image" 
        :class="{'selected': isSelected(index)}"
        :src="card.image">
      
      <div class="card-footer">
        <h3 class="card-title">{{card.title}}</h3>
        <p class="card-text">by 
          <span 
            class="card-author" 
            :class="{'selected': isSelected(index)}">
                {{card.author}}
          </span>
        </p>
      </div>
    </div>
  </div>
  </div>
</template>

<script>

import './assets/style.css';

export default {
  name: 'app',
  data() {
    return {
      selectedCard: -1,
      cards: [
        {
         title: 'Gallery', 
         author: 'Walder Frey', 
         image: 'http://www.gstatic.com/webp/gallery/1.webp'
        },
        {
          title: 'Penguin', 
          author: 'Ramsey Bolton', 
          image: 'https://www.gstatic.com/webp/gallery3/2_webp_ll.png'
        },
        {
          title: 'Flower', 
          author: 'Joffrey Baratheon', 
          image: 'https://www.gstatic.com/webp/gallery3/1.png'
        },
         {
          title: 'Flower Pot', 
          author: 'Cersie Lannister', 
          image: 'https://www.fiftyflowers.com/site_files/FiftyFlowers/Image/Product/Make_Your_Own_Centerpiece_Close_Up_350_a425aad8.jpg'
        },
         {
          title: 'Rose', 
          author: 'Roose Bolton', 
          image: 'https://res.cloudinary.com/prestige-gifting/image/fetch/fl_progressive,q_95,e_sharpen:50,w_480/e_saturation:05/https://www.prestigeflowers.co.uk/images/NF4016-130116.jpg'
        }
      ]
    }
  },
  methods: {
    hoverCard(selectedIndex) {
      this.selectedCard = selectedIndex
    },
    isSelected(cardIndex) {
      return this.selectedCard === cardIndex
    }
  }
}
</script>

So, here, I have defined the two events.

  1. @mouseover
  2. @mouseout

So when we hover any image, we pass an index to the function defined in mouseover event.

Now, that function assigns that index to the selected property.

The reason behind that is very simple when the user hovers the image at that time, that image is selected and we need to apply the hover css classes to that image. 

<img class="card-image" 
        :class="{'selected': isSelected(index)}"
        :src="card.image">

So, if the selected image has that index then we bind the selected class and the animation effect will be applied. The following style.css code help us to apply the animated effect. It is a simple CSS 3 rules.

.card-image {
  /* the other rules */
  transition: height 0.3s, opacity 0.3s;
}
.card-image.selected {
  height: 410px;
  opacity: 0.3;
}

Now, If you have written both style.css and App.vue file then go to the browser and see the result.

Finally, our  How To Create Hover Animation In Vuejs tutorial with an example is over. Thanks!!

2 Comments
  1. Pierre says

    Why even using Vue just to toggle a `selected` class on `card-image` when you can use CSS and do `.card:hover .card-image` ? 🤔 (Note: i’m ok to use Vue to build the markup)

    1. Nope says

      Cuz, the other title is so much more catchy! 🙂

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.