Skip to content

Vue JS – How to change the position of a component that is displayed on mouse hover

I have one problem related to the location of the component. I have four pictures, when you hover over them, a certain component is displayed, it looks like this

enter image description here

If, for example, hover the mouse cursor over a yellow picture, then another component will be displayed below, and so on with all components

My problem is when the screen reaches 568 pixels, that is, the mobile version, because I need to change the position of the displayed components, because at the moment in the mobile version my components that should be displayed they look like this

enter image description here

Notice all the components are displayed at the bottom, and I need them to be displayed at the bottom of each of my images

That is, I want them to look like this.

enter image description here

You can see the given code in codesandbox

App.vue

<template>
  <div>
    <div class="enjoy_headline_container">
      <div class="EnjoyGirlsContainer">
        <div>
          <h3>Shrink the screen to 568 pixels or lower to see the problem</h3>
        </div>

        <div class="EnjoyGirlsList">
          <div
            v-for="(chunk, index) in Math.ceil(EnjoyGirlsList.length / 2)"
            :key="'chunk-' + index"
            :class="'wrap-' + index"
          >
            <div
              v-for="(item, index) in EnjoyGirlsList.slice(
                (chunk - 1) * 2,
                chunk * 2
              )"
              :key="'img-' + index"
              class="EnjoyCard"
              :class="'EnjoyCard-' + index"
            >
              <div>
                <img
                  @mouseover="mouseOver(item, (hover = true))"
                  v-bind:src="item.imagePath"
                  alt="Snow"
                />
              </div>

              <div class="EnjoyCardContainer">
                <div
                  :style="{ background: item.textColor }"
                  class="EnjoyCardChildContainer"
                >
                  <h3 class="EnjoyCardChildContainerTitleName">
                    {{ item.titleName }}
                  </h3>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="EnjoyGirlsHoverEffect">
        <div
          class="HoverLogic"
          @mouseleave="mouseout(enjoy, (hover = false))"
          v-for="(enjoy, index) in EnjoyGirlsList"
          :key="index"
        >
          <div class="EnjoyGirlsChildHoverEffect">
            <component
              v-show="enjoy.hovered"
              v-bind:is="enjoy.componentName"
            ></component>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import EnjoyBlue from "./components/EnjoyBlue";
import EnjoyGreen from "./components/EnjoyGreen";
import EnjoyYellow from "./components/EnjoyYellow";
import EnjoyRed from "./components/EnjoyRed";

export default {
  name: "HomePage",
  components: {
    EnjoyRed,
    EnjoyYellow,
    EnjoyGreen,
    EnjoyBlue,
  },

  data() {
    return {
      homePageImageList: [
        {
          imageURL:
            "http://astragem.com/static/images/MenuGirl/HomePageBackground/15-min.png",
        },
        {
          imageURL:
            "http://astragem.com/static/images/MenuGirl/HomePageBackground/15-min.png",
        },
        {
          imageURL:
            "http://astragem.com/static/images/MenuGirl/HomePageBackground/15-min.png",
        },
      ],
      hover: false,
      sectionGirlsListComponentsNames: [
        "EnjoyRed",
        "EnjoyYellow",
        "EnjoyGreen",
        "EnjoyBlue",
      ],
      EnjoyGirlsList: [
        {
          imagePath:
            "https://lh3.googleusercontent.com/_0OiZeWgElIETUMZW8B9wEZR-V0BLMyDBHfK6hdYQVGzsryLQAZ0GEL9_PDi5NlzmpK8bETuJcZ0CtUQKnErvs36Xw=w640-h400-e365-rj-sc0x00ffffff",
          titleName: "TEENS",
          textColor: "#74C8C5",
          hovered: false,
          componentName: "EnjoyBlue",
        },
        {
          imagePath:
            "https://p0.piqsels.com/preview/32/831/578/leaf-malina-garden-nature-thumbnail.jpg",
          titleName: "MINXES",
          textColor: "#76ED00",
          hovered: false,
          componentName: "EnjoyGreen",
        },
        {
          imagePath:
            "https://dandelionmarketing.com/wp-content/uploads/2020/01/yellow-09.jpg",
          titleName: "MILFS",
          textColor: "#FFE600",
          hovered: false,
          componentName: "EnjoyYellow",
        },
        {
          imagePath:
            "http://pm1.narvii.com/6691/30c6c5246b1aee0e676f741f63ab144bbdb77da2_00.jpg",
          titleName: "COURGARS",
          textColor: "#CC003D",
          hovered: false,
          componentName: "EnjoyRed",
        },
      ],

    };
  },
  methods: {

    mouseOver: function (enjoy) {
      this.EnjoyGirlsList.forEach((enjoy) => (enjoy.hovered = false));
      enjoy.hovered = true;
    },

    mouseout: function (enjoy) {
      enjoy.hovered = false;
    },

  },
};
</script>

EnjoyBlue

<template>
   <p>Blue Component</p>
</template>

EnjoyGreen

<template>
   <p>Green Component</p>
</template>

EnjoyYellow

<template>
   <p>Yellow Component</p>
</template>

EnjoyRed

<template>
   <p>Red Component</p>
</template>

Answer

There are a million ways to do this. One simple way to accomplish what you want is to include the information in “both” places at the same time and control it’s appearance with CSS media queries. See here: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries

So basically it would look something like this

<Cougars>
 <EnjoyRed class="next-to-description" />
</Cougars>
<MINXES>
 <EnjoyGreen class="next-to-description" />
</MINXES>
<MILFS>
 <EnjoyYellow class="next-to-description" />
</MILFS>

<component :is="enjoy.componentName" class="below-all-description" />

Then setup some css like:

.next-to-description {
  display: block;
}

.below-all-description {
  display: none;
}

@media screen and (min-width: 568px) {
  .next-to-description {
    display: none;
  }
  .below-all-description {
    display: block;
  }
}

Now you’d just need to make sure that whenever <Cougars> is gets the mouseover event you populate the EnjoyRed component with a v-if or something and also continue to use the <component :is="..">

The CSS will control and ensure only 1 is shown at a time.

I added a barebones example of my idea on jsfiddle:

https://jsfiddle.net/y8k1pgd9/