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

Tips for integrating a vertical menu with button icons and subcategories

Currently working on a project with Twitter Bootstrap and looking to create a specific sidebar setup. My goal is to include subcategories using an accordion and a collapsible menu for mobile devices. I came across a similar implementation at http://jsfiddl ...

How to Extract an Object from an Array using React

I have a situation where I am fetching data from an API using axios. Specifically, on my invoice details page, I am trying to retrieve data for only one invoice using the following code: const id = props.match.params.id; const invoice = useSelecto ...

Error: Unable to locate font in the VueJS build

Within my config/index.js file, I have the following setup: ... build: { index: path.resolve(__dirname, 'dist/client.html'), assetsRoot: path.resolve(__dirname, 'dist'), assetsSubDirectory: 'static', assetsPub ...

Determining the best CSS based on the user's preferred color scheme using media queries

Is it possible to separate my CSS into two files, one for dark mode and one for light mode, and conditionally load them using only HTML without the need for JavaScript? I haven't been able to find any examples on https://developer.mozilla.org. Could ...

What are the steps to modify the text color in WKWebView?

I've customized my ViewController to include a WKWebView, where I load my content from both .html and .css files. The result resembles a controller for reading books within the Apple Books app. do { guard let filePath = Bundle.main.path(fo ...

What is causing the Unhandled Rejection (TypeError) error after I move the object in my Redux application and receive the message "Cannot read property 'filter' of undefined"?

I've been working on a Redux application. I've made modifications to a couple of files, and here are the changes in the two files: index.js: const store = createStore( reducer, { propReducer: { day: 1, data: [], filte ...

Tips on enhancing an array by separating values with vertical bars instead of commas

I am trying to store checked values in an array and separate them with vertical bars instead of commas. Is there a way to achieve this using the jQuery map .get() function? Any suggestions or links you can provide would be greatly appreciated. Thank you in ...

How can multiple buttons be added to each row in Jquery datatables and how can events be applied to them?

I currently have one button, but I am in need of two buttons. These buttons will trigger MySql commands when clicked to retrieve data from the database. How can I set up an event handler for these buttons? $(document).ready(function () { var table= ...

.load() not triggering for images that are not in the cache - jquery

In Safari and Opera, the callback function of .load doesn't wait for uncached images to be fully loaded. With cached images, it works perfectly fine. The code may seem a little complicated, but I'll do my best to simplify it... So, here is my J ...

Creating a Seamless Bond Between JavaScript and HTML

I've been struggling to find a helpful and straightforward solution to a simple problem. On my web page, I have five image placeholders that should be filled with one of nine random pictures. To achieve this, I wrote a JavaScript code that generates r ...

What is the proper way to update data in reactjs?

I previously had code that successfully updated interval data in the browser and locale without any issues. class Main extends Component { constructor(props) { super(props); this.state = {data: []} } componentWillMount() { fetch('fi ...

Is it necessary to only override the monospaced font?

Can the monospace font in Angular Material be customized for just the <code>foo</code> blocks? I want to use a font where the number zero 0 looks distinct from the letter oh O. ...

Headerbar overlapping Div when scrolling

I'm currently trying to create a fixed header bar that allows the content of the page to scroll beneath it rather than displaying above it. This functionality is working on multiple pages, but I'm experiencing issues with my calendar page. When ...

The website's navigation system effectively directs content within the initial 100% viewport

I have encountered a slight issue. I created a Sidebar Navigation with some added "hey's" to demonstrate the problem: * { margin: 0; padding: 0; font-family: 'Roboto', sans-serif; } nav { height: 100vh; width: 250px; borde ...

Combine javascript and css sequentially

I have a few tasks that involve combining CSS and JavaScript together. Here is an example of how I accomplish this: gulp.task('javascript', function() { return gulp.src([ libPath + 'jquery-2.1.4.min.js', libPath + '*.js& ...

Using Javascript, populate an array with Enum variable values

Hey there! I've got this code that creates an array from an enum variable in JavaScript, but it's looking a bit old and clunky. I'm curious if any JavaScript or jQuery experts out there have a cleaner (best practice) approach for achieving ...

Swap out the image for a div element if the image is not found

Is there a way to accurately display an image if it's available, and use a div as a replacement if the image is not present? // How can I determine `imageExists` without encountering cross-origin issues? (imageExists) ? (<img class="avatar-img" sr ...

The Infinite Scroll feature is malfunctioning when the $(window).scrollTop() is greater than or equal to $(document).height() - $(window).height() - 10

JavaScript: $.ajax({ type: 'POST', url: 'getcontent.php', data: 'lastid=' + 0, dataType: "html", success: function (data) { console.log(data); $("#content").appe ...

React Native - The size of the placeholder dictates the height of a multiline input box

Issue: I am facing a problem with my text input. The placeholder can hold a maximum of 2000 characters, but when the user starts typing, the height of the text input does not automatically shrink back down. It seems like the height of the multiline text ...

Update the text input field from a different webpage

I am working with two PHP pages, let's call them page1.php and page2.php. On page1.php, there is a textbox with a default value of 0, while on page2.php, there is a button. I have these two pages open in different tabs in a browser. My goal is to have ...