How can I emulate the behaviour of a css background image, instead using a div with absolute positioning which scales within it's relative container?

Viewed 29

I am trying to build a card that has a background image, that when clicked, darkens that background image and then displays a lighter, transparent div with text on top of it. Both the darkening of the background card, and the appearance of the text div need to have transitions.

I have managed to create this functionality, including transitions, using a container with relative positioning, that contains an image with absolute positioning: https://jsfiddle.net/marcuslv/kmbvxt14/

The issue with this solution is that I can't work out how to scale the image inside the container such that when it grows and shrinks, it adapts its size to the container.

I want it to behave like a css background-image if it had these properties:

  background-image: url('https://www.fillmurray.com/300/300');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center top;

I have implemented a near equivalent solution using a css background-image instead of an img element as in the first fiddle: https://jsfiddle.net/marcuslv/knq3e7dg/

The issue with this solution is that I can't get the background image to transition to its darkened state - it transitions immediately which is a bit jarring - and more importantly, I will be using b64 images for this project, which are finicky to set as a css background-image and I would much prefer to use an img element.

1 Answers

You can overlay a transparent area using the ::before psuedo element then use the opacity which is animatable. To use an img tag rather than a background image, absolutely position the info box like the example below. I've also tweaked your JS

window.onload = () => {
  const container = document.querySelector('.container');
  container.addEventListener('click', () => {
    document.querySelector('.movieCard').classList.toggle('movieCardActive');
    document.querySelector('.info').classList.toggle('infoActive');
  });
}
* {
  font-family: Arial;
  font-size: 14px;
}

.container {
  position: relative;
  max-width: 400px;
  min-width: 200px;
  height: 400px;
  margin: auto;
  border: 1px solid red;
  box-sizing: border-box;
  padding: 1rem;
}

.movieCard {
  cursor: pointer;
  background-color: #242424;
  height: 100%;
  padding: 0;
  box-sizing: border-box;
}

.movieCard img {
  width: 100%;
}

.movieCard::before {
  content: '';
  position: absolute;
  inset: 0;
  background-color: #000;
  opacity: 0;
  margin: 1rem;
  transition: opacity 1s;
}

.movieCardActive.movieCard::before {
  opacity: 0.8;
}

.info {
  position: absolute;
  top: 2rem;
  left: 2rem;
  right: 2rem;
  padding: 1rem;
  color: white;
  background: rgba(204, 204, 204, 0.4);
  opacity: 0;
  transition: opacity 0.1s;
}

.infoActive {
  color: #e8e6e6;
  background: rgba(204, 204, 204, 0.4);
  opacity: 1;
  transition: opacity 0.1s;
}
<div class="container">
  <div class="movieCard">
    <img src='https://www.fillmurray.com/300/300'>
    <div class="info">
      <div id="Title">Harry Potter, 2000</div>
      <div id="Genre">Fantasy, Adventure</div>
      <div id="Plot">A young wizard discovers a world of adventure.</div>
      <div id="Rated">PG</div>
      <div id="imdbRating">7.1</div>
      <div id="imdbVotes">9090</div>
      <div id="Runtime">127 mins</div>
    </div>
  </div>
</div>

Related