acroscene
acroscene

Reputation: 1067

Overlay on hover in vue.js

Im trying to implement displaying text when hovering over an image in vue.js but I am a bit stuck. Im trying to implement this example on an array with multiple images: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_image_overlay_fade

I got a pretty big vue file but here is the essential:

template:

</template>

[...]

<div v-for="item in filteredPeople" v-bind:key="item.id" class="list-complete-item">
  <router-link @mouseover.native="hovertext" :to="'/'+item.link">
    <img class="list-complete-img" :src="'http://placehold.it/400x300?text='+item.id" alt>  
  </router-link>
</div>

[...]

</template>

script

<script>
export default {
  data() {
    return {
      info: [
        {
          id: 1,
          title: "Title one",
          link: "project1",
          hovertext: "project1 hover text lorem lorem lorem",
          category_data: {
            "1": "Category 1"
          }
        },
[...]
  methods: {
    hovertext() {
      console.log("");
    },

I had some idea to try to use a method to put the text in a div under the image but then I cannot get the text to get above the image on hover. And I cannot get the method right ... Not really sure this is a good way doing it,

I also found this codepen example: https://codepen.io/oliviaisarobot/pen/xzPGvY

This is pretty close to what I want to do but I cannot get the text to display here either.

I am a bit lost. Any help how to do this in vue?

---------- UPDATE ----------

I want the image boxes to stretch so they always fits the window but I seems to get a gap between my flexbox rows which I cannot seem to get rid of. You can see the white space. I attach my stylesheet.

.list-complete { display: flex; height: auto; flex-direction: row; flex-flow: row wrap; }

.list-complete-item {
  flex: 0 1 50%;
  display: inline-block;
}

.list-complete-item a {
  display: inline-block;
  position: relative;
  width: 100%;
  height: auto;
  outline: 1px solid #fff;
}

.list-complete-img {
  width: 100%;
}

.text {
  color: rgb(186, 74, 74);
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  text-align: center;
}

.list-complete-item a:hover .overlay {
  opacity: 1;
}

.overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  overflow: hidden;
  height: 60%;
  width: 100%;
  opacity: 0;
  transition: 0.5s ease;
  background-color: #008cba;
}

Upvotes: 0

Views: 5312

Answers (1)

Daniel
Daniel

Reputation: 2777

You don't need to use js(vue) events. Do it with plain css, like in example you linked to.

Go with this template:

<div v-for="item in filteredPeople" v-bind:key="item.id" class="list-complete-item">
    <router-link :to="'/'+item.link">
        <img class="list-complete-img" :src="'http://placehold.it/400x300?text='+item.id" alt>
        <div class="overlay">
            <div class="text">{{ item.hovertext }}</div>
        </div>
    </router-link>
</div>

And style it up:

.list-complete-item {
    width: 400px;
    height: 300px;
    display: inline-block;
}
.list-complete-item a {
    display: inline-block;
    position: relative;
    width: 400px;
    height: 300px;
}
.list-complete-item a .image {
    display: block;
    width: 100%;
    height: auto;
}
.list-complete-item a .overlay {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    height: 100%;
    width: 100%;
    opacity: 0;
    transition: .5s ease;
    background-color: #008CBA;
}
.list-complete-item a:hover .overlay {
    opacity: 1;
}
.list-complete-item a .text {
    color: white;
    font-size: 20px;
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    text-align: center;
}

And the final result:

enter image description here

Upvotes: 4

Related Questions