6/27/2018 - #development #ecommerce #magento
by: Etienne Gutbub

Products images are really important for an online store. It is one of the most interesting components for the customer as it will bring his experience closer to reality. Usually, online stores have multiple photos available on the product page. However, the customer needs to be on the product page in order to see more images.

How about showing more images on the products list? What about showing another image for each product when the customer’s cursor hovers over a product item?
This is simple, fast and will provide for sure a better customer experience on your online store. 
I will show you in this article how to achieve this step by step.



1) Attribute Creation

First of all, we need to create a product attribute. To achieve this, nothing easier: Either you create your attribute directly in the Magento Back-Office or you can create it by using a setup file. Here, we will create it directly in the Back-Office of Magento as it is faster and easier. 
As with any other product attribute, go to Stores > Attributes > Products and click on the button “Add new Attribute”. Find a cool name for your attribute, we will call it “hover” (really cool, right?).
Select "Media Image" in the "Catalog Input Type for Store Owner" dropdown menu. You will have already guessed it, this is the important part. You need to be careful because you can’t change the input type of an attribute afterwards. You can now save your attribute and go to the Attribute Set section Stores > Attributes > Attribute Set. Add your newly created attribute “hover” (or whatever you called it) to the “Images” Attribute Group of every Attribute Set that you would like to configure in this way.


Back-end image hover

We are almost done with creating the attribute. We just have one piece of data that is not right yet and unfortunately, for some reason you can’t update it from the Back-Office. If you created it from a setup you should be fine as you could set the data as you wanted. 
For the attributes of type “Media image” you can’t change the storefront properties from the Back-office so you will have to change one piece of data directly in the database. The incorrectly set data point is the one that is used to display the images on the product listing. It can be problematic when we want to use this attribute specifically for this page...

However, here are the steps to correct this. You can go to your “hover” attribute page on the Back-Office and find the id of you attribute. For this, you can just check the URL of the page, as an example:


Your attribute id is just after attribute_id in the url, in our case it’s 212.
Now, we have to go to our database and go to the “catalog_eav_attribute” table. Select the attribute with id 212 (of course change 212 to your id) and change the value of the `used_in_product_listing` column to 1. Obviously, if you used a setup file you will need to use `used_in_product_listing` to force the value to 1.
Well, if you are lazy you can also use this SQL line, just replace 212 with the id of your hover attribute:

UPDATE `catalog_eav_attribute` SET `used_in_product_listing` = '1' WHERE `catalog_eav_attribute`.`attribute_id` = 212;

Now that our attribute is usable we will have a quick look at a product page on the Back-Office to see what changed.
We can see that we can choose a new role for our picture which is “hover”. If the new role doesn’t show up yet you should just clear the cache and it will appear.


Back-end image hover 1

Front-end prouct


2) View.xml

Now that our attribute is fully created we will need to use it on frontend to display an image. However, we still need to do one more thing to make this attribute usable on the product listing. You have to declare it in the view.xml file of your theme. If you don’t have this file in your theme you will have to create it following this path:


The view.xml file is used to store the properties of product images. 
In this file add the following piece of code:


<?xml version="1.0"?>

<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/view.xsd">
  <images module="Magento_Catalog">
   <image id="hover_product_list" type="hover">


Here you will have only a few things to change. The image id will be used in the product listing template so you can choose something else other than “hover_product_list”. The “type” will need to be exactly the same as the attribute code that you choose for your hover attribute. Finally, the width and height values should match the values that already exist for your listing product image. If you don’t know these values they should be written in a view.xml file. If you didn’t overwrite them they should be in the view.xml of your parent theme. Find this file and search for the id “category_page_list” or “category_page_grid”.

3) Use in template listing

We configured everything so we can finally use our new attribute. If your custom theme doesn’t already extend the product list template, it should do it now. Create a file named list.phtml following this path:


and for the moment make it a copy of the original file located under:


We can now start to adapt this template to our needs. Our objective is to load both our normal image and our image for hover. Also, we will display them at the same location. We will initially hide our hover image with CSS and then use JavaScript to display it and hide the normal image when a product item is hovered over. It seems pretty easy, right? 
Let’s start by adding an image helper from Magento at the beginning of the template and declaring a variable with the same value as the id that we gave in the view.xml file.


$_imageHelper = $this->helper('Magento\Catalog\Helper\Image');
$_imageHover = 'hover_product_list';

This helper will simply help us to initialize our image for hover. We will now modify the basic template to add a new class to the normal image but also to add our new image. Find the div with the class “product-item-info”. This div contains a few data like the product image and the name of the product, but also the “add to cart” button, so you might as well be careful when you are updating this part.

On this div, only the first part interests us because it’s here that the photo is added. So it’s from the beginning of the div the <div class=”product details product-item-details”> excluded.

We will add what we need for our hover image but also add a class to the normal image so it will be easier to hide it with CSS.


<div class="product-item-info" data-container="product-grid">
$productImage = $block->getImage($_product, $image, ['class' => 'photo-currently-hovered']);
$productImageHover = $_imageHelper->init($_product, $_imageHover);
if ($pos != null) {
$position = ' style="left:' . $productImage->getWidth() . 'px;'
. 'top:' . $productImage->getHeight() . 'px;"';
<?php // Product Image ?>
<a href="<?php /* @escapeNotVerified */
echo $_product->getProductUrl() ?>" class="product photo product-item-photo" tabindex="-1">
<?php echo $productImage->toHtml(); ?>
<?php //Product Image Hovered ?>
<a href="<?php /* @escapeNotVerified */
echo $_product->getProductUrl() ?>" class="product photo product-item-photo-hovered"
  <img src="<?php echo $productImageHover->getUrl(); ?>"
   class="photo-image-hover" width="<?php echo $productImage->getWidth(); ?>"
   height="<?php echo $productImage->getWidth() ?>"
   alt="<?php echo $productImageHover->getLabel() ?>"/>
<div class="product details product-item-details">


Here we added the class =”'photo-currently-hovered'” by default to the normal images. We are also getting our hover image by using the method init() from the $_imageHelper that we declared above. Then, we added what was necessary to create the image that will be used when a customer will hover over a product item with his cursor.

For the moment we have both images displayed on the listing products and the only things that we are missing are some styles for the positioning of the hover image and to display the correct image on the page load. We are also missing a piece of JavaScript to change the image on the hover action.

4) CSS and JS

For the CSS part we will simply put the 2 images over each other as they are not supposed to be displayed at the same time anyway. Also we use a few classes that will be used initially but also used in our JavaScript to display the correct image corresponding to the user actions. Here is my piece of CSS:


.product-item-photo-hovered {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
.photo-image-hover {
opacity: 0;
.photo-currently-hovered {
opacity: 1 !important;
.photo-currently-not-hovered {
opacity: 0 !important;


Here I used the opacity attribute, but I could also have used the visible attribute or the display one. To go further you can add some transitions to make it look smoother for the customer. You can also add some box-shadow attribute to make it look cooler. It’s up to you to make it look like you want.

Let’s go back to our listing template because it is over here that we will add our script at the end of the template. I’m sure you can probably write your own piece of JavaScript to achieve what we want, but for the purpose of our example I will give you the one I used.
What this script is doing is pretty simple. When a product item is hovered over it will change the classes of the images elements to display the one we want. Don’t forget to process and revert the classes when the customer stops hovering over the product item.


<script type="text/javascript">
  function ($) {
   //Selector to select the products li items
   var productItem = $('.product-item-info');
   //Function to replace the picture of the product when the product item is hovered with mouse
   productItem.hover(function (event) {
     //Hover on product li Item
     var productImage = $(event.target).parents('.product-item-info').find('.photo.image'),
      productImageHover = $(event.target).parents('.product-item-info').find('.photo-image-hover');
    //Hover out
    function (event) {
     var productImage,
     myTarget = $(event.target);

     if ($(event.target).hasClass('product-item-info')) {
      productImage = myTarget.find('.photo.image');
      productImageHover = myTarget.find('.photo-image-hover');
     } else {
      productImage = myTarget.parents('.product-item-info').find('.photo.image');
      productImageHover = myTarget.parents('.product-item-info').find('.photo-image-hover');


That’s it! You have now a product list with other images when a product item is hovered over. Isn’t your product listing cooler than before?

Your comments

Sonu Kumar
Apr 27, 2019
Working fine for me magento 2.3 Enterprise

Write your comment

for take-off?

Blackbird is a web agency specialized in the development of eCommerce websites. We are Magento Experts and we offer our services and advice for e-marketing, strategy, branding, deployment and methodology.

+339 50 66 21 38

Legal terms
Agency 30, Avenue du Rhin
67100 Strasbourg