object-fit:contain on child prevents parent event from triggering

510 views Asked by At

let parent = document.getElementById("parent");
let img = document.getElementById("img");

parent.addEventListener("click", function() {
  parent.style.display = "none";
});

img.addEventListener("click", function(e) {
  e.stopPropagation();
})
#parent {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  background-color: blue;
}

#img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
<div id="parent">
  <img src="https://dummyimage.com/600x400/000/fff" id="img">
</div>

Basically, what I want to achieve is a pop-up that covers the whole window and has a centered image that stretches to the maximum height or width (depending on image dimension) and preserves aspect ratio.The full image should still be visible. When you click on the remaining visible parent blue background, both the parent and the image should disappear.

The parent event is not triggering. But if I remove the CSS code, the event triggers. What is happening here?

3

There are 3 answers

1
atan On BEST ANSWER

Since I couldn't find a simple solution using CSS (considering that the problem isn't that complicated), I have decided to use a quick fix using JavaScript by dynamically adjusting image sizing.

I'm leaving my answer here for anyone who needs this. But I'm still hoping for a CSS solution for this one.

let parent = document.getElementById("parent");
let img = document.getElementById("img");

parent.addEventListener("click", function() {
  parent.style.display = "none";
});

img.addEventListener("click", function(e) {
  e.stopPropagation();
})

function stretchImage(){
    let w = this.innerWidth;
    let h = this.innerHeight;

    if(w < h){
        img.style.width = "100%";
        img.style.height = "auto";
    }else{
        img.style.width = "auto";
        img.style.height = "100%";
    }
}

window.onresize = stretchImage;
window.onload = stretchImage;
#parent {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    background-color: blue;
    display: flex;
    justify-content: center;
    align-items: center;
}
<div id="parent">
  <img src="https://dummyimage.com/400x400/000/fff" id="img">
</div>

The script dynamically changes the image sizing depending on the width and height of the window using onload and onresize. This way, I don't even need to know the dimensions of the image.

7
yunzen On

An Image in HTML is a replaced element

If you inspect the img in your developer tools, you might recognize that the image element itself covers all of the parent (that's by means of width: 100%; height: 100%;).

The representation of the image on screen is altered by object-fit: contain;. But this does not change the dimensions of the image element itself. You can see that if I add a yellow background to the image element. This covers all of the blue parent

let parent = document.getElementById("parent");
let img = document.getElementById("img");

parent.addEventListener("click", function() {
  parent.style.display = "none";
});

img.addEventListener("click", function(e) {
  e.stopPropagation();
})
#parent {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  background-color: blue;
}

#img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: yellow;
}
<div id="parent">
  <img src="https://dummyimage.com/600x400/000/fff" id="img">
</div>

You need to try something different for your code to work as intended

Edit: changed the implementation

Example with image size 500 x 500

let parent = document.getElementById("parent");
let img = document.getElementById("img");

parent.addEventListener("click", function() {
  parent.style.display = "none";
});

img.addEventListener("click", function(e) {
  e.stopPropagation();
})
#parent {
  width: 100%;
  height: 100%;
  
  position: fixed;
  top: 0;
  left: 0;
  background-color: blue;
  
}

#img {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  max-width: 100%;
  max-height: 100%;
  margin: auto;
}
<div id="parent">
  <img src="https://dummyimage.com/500x500/f0f/000" id="img">
</div>

Example with image size 1000 x 600

let parent = document.getElementById("parent");
let img = document.getElementById("img");

parent.addEventListener("click", function() {
  parent.style.display = "none";
});

img.addEventListener("click", function(e) {
  e.stopPropagation();
})
#parent {
  width: 100%;
  height: 100%;
  
  position: fixed;
  top: 0;
  left: 0;
  background-color: blue;
  
}

#img {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  max-width: 100%;
  max-height: 100%;
  margin: auto;
}
<div id="parent">
  <img src="https://dummyimage.com/1000x600/f0f/000" id="img">
</div>

Example with image size 600 x 1000

let parent = document.getElementById("parent");
let img = document.getElementById("img");

parent.addEventListener("click", function() {
  parent.style.display = "none";
});

img.addEventListener("click", function(e) {
  e.stopPropagation();
})
#parent {
  width: 100%;
  height: 100%;
  
  position: fixed;
  top: 0;
  left: 0;
  background-color: blue;
  
}

#img {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  max-width: 100%;
  max-height: 100%;
  margin: auto;
}
<div id="parent">
  <img src="https://dummyimage.com/600x1000/f0f/000" id="img">
</div>

6
Deepu Reghunath On

child overlap the parent. child element takes full available space and it fully covers its parent element. so there no clickable area available for the parent element.

If you adjust the height and width of the child element then you can achieve this.

let parent = document.getElementById("parent");
let img = document.getElementById("img");

parent.addEventListener("click", function() {
  parent.style.display = "none";
});

img.addEventListener("click", function(e) {
  e.stopPropagation();
})
#parent {
  width: 100%;
  height: 100%;
  position:fixed;
  top: 0;
  left: 0;
  background-color: blue;
  display: flex;
    align-items: center;
    justify-content: center;
}

#img {
 overflow:hidden;
}
<div id="parent">
  <img src="https://dummyimage.com/400x400/000/fff" id="img">
</div>