How to transform a hyperlink into a clickable element within an absolutely positioned container

I'm currently working on a photo gallery project and using magnific popup to create it. However, I ran into an issue with the hover event on the images that displays an icon when it's hovered over, indicating that it can be clicked to view more. To position this icon correctly, I had to make it absolute. The problem is, this prevented the image from being clickable to open the gallery carousel as intended. I attempted to solve this by adding z-index: 1 in my code but unfortunately, it did not work. Here is the snippet of my code:

$(document).ready(function() {
  $('.seller-gallery').magnificPopup({
    delegate: 'a',
    type: 'image',
    tLoading: 'Loading image #%curr%...',
    mainClass: 'mfp-img-mobile',
    gallery: {
      enabled: true,
      navigateByImgClick: true,
      preload: [0, 1] // Will preload 0 - before current, and 1 after the current image
    },
    image: {
      tError: '<a href="%url%">The image #%curr%</a> could not be loaded.',
      titleSrc: function(item) {
        return item.el.attr('title') + '<small>by Marsel Van Oosten</small>';
      }
    }
  });
});
.grid-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.gallery-item {
  cursor: pointer;
  position: relative;
  z-index: 1;
}

.gallery-item a {
  pointer-events: all;
}

.gallery-item:hover .gallery-item-info,
.gallery-item:focus .gallery-item-info {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.2);
}

.gallery-item-info {
  display: none;
}

.gallery-item-info span {
  display: inline-block;
}

.img-fluid {
  max-width: 100%;
  height: auto;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.min.js"></script>
<div class="seller-gallery gallery-item">
  <a href="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80">
    <img src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80" alt="" class="img-fluid">
  </a>
  <div class="gallery-item-info">
    <span><i class="fas fa-eye fa-2x text-white"></i></span>
  </div>
</div>

Answer №1

If you want to resolve the issue, simply include pointer-events: none in the .gallery-item-info element that appears over your content. This way, it will not respond to mouse input, allowing events to pass through to the underlying content.

$(document).ready(function() {
  $('.seller-gallery').magnificPopup({
    delegate: 'a',
    type: 'image',
    tLoading: 'Loading image #%curr%...',
    mainClass: 'mfp-img-mobile',
    gallery: {
      enabled: true,
      navigateByImgClick: true,
      preload: [0, 1] // Will preload 0 - before current, and 1 after the current image
    },
    image: {
      tError: '<a href="%url%">The image #%curr%</a> could not be loaded.',
      titleSrc: function(item) {
        return item.el.attr('title') + '<small>by Marsel Van Oosten</small>';
      }
    }
  });
});
.grid-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.gallery-item {
  cursor: pointer;
  position: relative;
}

.gallery-item a {
  pointer-events: all;
}

.gallery-item:hover .gallery-item-info,
.gallery-item:focus .gallery-item-info {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.2);
  pointer-events: none;
}

.gallery-item-info {
  display: none;
}

.gallery-item-info span {
  display: inline-block;
}

.img-fluid {
  max-width: 100%;
  height: auto;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.min.js"></script>
<div class="seller-gallery gallery-item">
  <a href="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80">
    <img src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80" alt="" class="img-fluid">
  </a>
  <a href="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80">
    <img src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80" alt="" class="img-fluid">
  </a>
  <a href="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80">
    <img src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80" alt="" class="img-fluid">
  </a>
  <div class="gallery-item-info">
    <span><i class="fas fa-eye fa-2x text-white"></i></span>
  </div>
</div>

Answer №2

Using Pseudo-elements and Font Awesome for a Different Approach

Consider an alternative method where the icon and gray overlay are generated using a pseudo-element within the .gallery-item a selector. By incorporating the pseudo-element as a child of the link, you can avoid any interference with click actions while eliminating the need for an extra span element. This approach also offers the flexibility to apply the same overlay effect to multiple linked images on a webpage.

To explore this technique further, refer to the documentation on utilizing pseudo-elements with Font Awesome available at: https://fontawesome.com/v5/docs/web/advanced/css-pseudo-elements

If you require a detailed breakdown of the CSS used in the provided example, I have included comments within the code snippet:

$(document).ready(function() {
  $('.seller-gallery').magnificPopup({
    delegate: 'a',
    type: 'image',
    tLoading: 'Loading image #%curr%...',
    mainClass: 'mfp-img-mobile',
    gallery: {
      enabled: true,
      navigateByImgClick: true,
      preload: [0, 1] // Will preload 0 - before current, and 1 after the current image
    },
    image: {
      tError: '<a href="%url%">The image #%curr%</a> could not be loaded.',
      titleSrc: function(item) {
        return item.el.attr('title') + '<small>by Marsel Van Oosten</small>';
      }
    }
  });
});
/*
To enhance the visual presentation, images are set to display: block with a fixed width value of 500px;
*/
.gallery-item {
  width: 500px;
}
.gallery-item img {
  display: block;
  width: 100%;
}

.gallery-item a {
  /*Position the icon and overlay relative to each linked image*/
  position: relative;
}

.gallery-item a::before {
  /*Utilize the icon specifications from https://fontawesome.com/v5/docs/web/advanced/css-pseudo-elements */
  font-style: normal;
  font-variant: normal;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
  /*Define the unicode value of the icon (e.g., eye icon: \f06e)*/
  content: "\f06e";
  /*Adjust the size of the icon*/
  font-size: 2em;
  /*Specify the color of the icon*/
  color: #FFF;
  /*Center the icon and apply a gray overlay*/
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(0, 0, 0, 0.2);
  /*Smooth transition from 0 opacity to full opacity upon hover*/
  transition: opacity 0.3s linear;
  /*Initially invisible until hovered over*/
  opacity: 0;
}

.gallery-item a:hover::before {
  /*Visible when hovering over the linked image*/
  opacity: 1;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.min.js"></script>
<div class="seller-gallery gallery-item">
  <a href="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80">
    <img src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80" alt="">
  </a>
  <a href="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80">
    <img src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1173&q=80" alt="">
  </a>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Modify the behavior of the tab key using JavaScript

I'm currently working on a text editor embedded within a contenteditable div. My goal is to modify the [TAB] functionality so that instead of shifting focus to the next element (as is done by default in browsers), it will either insert spaces or a &b ...

sophisticated HTML navigation bar

I am looking for a way to create a menu where the drop-down items overlay the rest of the menu when the screen width is small. Here is my current code: nav{ line-height:100%; opacity:.9; }nav ul{ background: #999; padding: 0px; border-radius: 20px; ...

Determine which division is currently at the top of the scroll

I am having trouble retrieving the data attribute of each div with the class ".section" that has scrolled to the top. Currently, only the first div is being recognized, while the others at the top are not registering. Take a look at the example provided b ...

Adjust iFrame size if the width of the screen is lower than x

My website includes an iFrame showcasing a 990x90 advertisement. I am looking for a solution to ensure that mobile viewers can also see the ad on their devices. I need the iframe to resize proportionately based on the screen width; for instance, if the sc ...

Ways to safeguard your API endpoint

Just starting out with Node.js/Express, I'm looking to have my front end retrieve data from an endpoint ('/1') without displaying the JSON data to users when they access that specific endpoint. Any guidance on how to accomplish this would be ...

Parsing JSON data using multilevel iteration in JavaScript is a complex yet

{ "id":0, "item":[ { "id":"0-", "text":"BlueWing", "userdata":[ { "name":"cid", "content":"10377" } ], "item":[ { "id" ...

Leveraging jQuery template for JSON visualization

I've been struggling for days to understand how to render JSON data using jQuery templates with no luck. I was hoping someone could help me figure out where I'm making a mistake. The JSON data I am working with looks something like this: [{"pk" ...

How to make text dynamically shrink with TailwindCSS class 'flex-shrink-0'

I've designed an 'Album' (React) component to showcase album artwork, name, and release date in a card-like format. This component consists of two divs - one for the photo and the other for text. Each artist's discography displays multi ...

How can you identify when a Vuetify radio button is re-selected?

Currently, I am developing a wizard that involves triggering navigation when a radio button is selected. Users should also be able to go back and change their previous choices. However, one issue I have encountered is the difficulty in detecting a re-selec ...

HTML Elements for Displaying Undefined JSON Information

Hey there, I'm new to programming and I'm looking to display JSON data in an HTML table using jQuery. The issue I'm facing is that the output from the server shows up as 'undefined'. My goal is to have a constantly updated list of ...

Develop a JSON object with a unique format by combining elements from two separate arrays using JavaScript

I've searched extensively on stack for a solution but couldn't find one, so I'm reaching out here for help: Let's consider two arrays: one with "keys" and the other with "values" For example: keys = [CO2, Blood, General, AnotherKey, . ...

Utilize identical animations across various elements

I have a canvas animation in JavaScript that is currently limited to one canvas element with the id "stars". I want to be able to use this animation multiple times without repeating the code. Is there a way to add a class for the canvas elements instead of ...

How can I manipulate image resolution and export images of varying sizes using Javascript?

I am new to using three js. I have successfully exported an image in png format using the WebGL renderer. However, when attempting to export the image in a different custom size resolution, the resolution does not change. How can I set the image resoluti ...

Issues with GTM web tracking due to conflicts with the jQuery submit function when used in an AngularJS form

I am having trouble getting the Google Tag Manager jQuery script to fire when tracking form submissions. I have removed any AngularJS expressions for privacy reasons. Can anyone provide assistance with this issue? <div id="login_signIn" class=""> ...

Guide on transforming Color to HTML color with .NET Standard 2.0

How can I convert a color to HTML color in .NET Standard 2.0? Thank you. Is there a way to achieve the same functionality in .NET Core? System.Drawing.ColorTranslator.ToHtml(color); Or is this only available in DotNet Framework? ...

Tips on obtaining standardized values for an array with ng-repeat

My goal is to retrieve the normalized value of an array associated with different groups without altering the original array items. Instead, I am creating new objects for each group's normalized items. http://jsfiddle.net/k5Dvj/5/ $scope.nomalizedIt ...

Struggling to create a responsive navbar for a landing page using Next.js and TailwindCSS

I'm currently working on a landing page using nextjs, tailwind css, and shadcnui. The design looks great on desktop with a logo and two links, but it's not responsive on smartphones. https://i.stack.imgur.com/HVQsa.png On mobile devices, the lay ...

Display the AJAX loading indicator with a slight delay rather than instantly

For my latest web app project, I have incorporated numerous ajax calls. While the majority of these calls are quick and provide immediate responses, I am interested in implementing an ajax loader to display when calls take longer than 250ms. This will pr ...

Laravel route does not receive a parameter sent via Ajax

I am currently using Laravel 5.8 and implementing a discount code system on my website. To achieve this, I attempted to send data via Ajax in the following manner: $.ajax({ type: 'POST', url: baseurl + 'discount/register', ...

Learning how to implement the selection tag to upload data to a SQL database using PHP

As a coding beginner, I've been tackling a project involving data insertion into an SQL server with PHP. My current struggle lies in the process of inserting data and capturing select tag objects as variables. I keep encountering Undefined Index error ...