htmlcsscss-animationskeyframeobject-fit

Animation when hovering object-fit: contain <img>


On mouse hover, animated span tags beneath an img work fine when the img isn't using object-fit: contain like below:

body {
  height: 100%;
  width: 100%;
  margin: 0
}

.container {
  max-width: 600px;
  position: relative;
  text-align: center;
  width: 100%;
}

.product {
  position: relative;
  width: 150px;

}

img.content {
  background: white;
  height: auto;
  margin: 8%;
  position: relative;
  width: 84%;
  vertical-align: middle;
  z-index: 5000;
}

.product:hover .effect-1,
.product:hover .effect-2 {
  display: block;
}

.effect-1,
.effect-2 {
  border-radius: 30%;
  display: none;
  mix-blend-mode: multiply;
  height: 84%;
  opacity: 1;
  position: absolute;
  width: 84%;
  z-index: 3000;
}

.effect-1 {
  animation: rotate 1.8s linear infinite;
  background: cyan;
}

.effect-2 {
  animation: rotate 1.2s linear reverse infinite;
  background: #e7a9ff;
}

.placeholder {
  width: 84%;
  height: auto;
  visibility: hidden;
}

@keyframes rotate {
  0% {
    top: 0;
    left: 8%;
  }
  25% {
    top: 8%;
    left: 0%;
  }
  50% {
    top: 16%;
    left: 8%;
  }
  75% {
    top: 8%;
    left: 16%;
  }
  100% {
    top: 0;
    left: 8%;
  }
}
<body>
    <div class="container">
      <p>Hover image please</p>
      <div class="product">
          <img class="content" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg">
          <span class="effect-1"><img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg"></span>
          <span class="effect-2"><img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg"></span>
      </div>
    </div>
</body>

But when the img is using object-fit: contain the animated spans take up the entire area:

body {
  height: 100%;
  margin: 0;
}

.container {
  max-width: 600px;
  position: relative;
  text-align: center;
  width: 100%;
  height: 100%;
  min-height: 700px;
}

.product {
  height: 100%;
  position: absolute;
}
.content {
  background: white;
  margin: 8%;
  position: relative;
  width: 84%;
  height: 100%;
  vertical-align: middle;
  z-index: 5000;
  object-fit: contain;
}

.product:hover .effect-1,
.product:hover .effect-2 {
  display: block;
}

.effect-1,
.effect-2 {
  border-radius: 30%;
  display: none;
  mix-blend-mode: multiply;
  height: 84%;
  opacity: 1;
  position: absolute;
  width: 84%;
  z-index: 3000;
}

.effect-1 {
  animation: rotate 1.8s linear infinite;
  background: cyan;
}

.effect-2 {
  animation: rotate 1.2s linear reverse infinite;
  background: #e7a9ff;
}

.placeholder {
  width: 84%;
  height: auto;
  visibility: hidden;
}

@keyframes rotate {
  0% {
    top: 0;
    left: 8%;
  }
  25% {
    top: 8%;
    left: 0%;
  }
  50% {
    top: 16%;
    left: 8%;
  }
  75% {
    top: 8%;
    left: 16%;
  }
  100% {
    top: 0;
    left: 8%;
  }
}
<body>
    <div class="container">
      <div class="product">
        <span class="effect-1"><img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg"></span>
        <span class="effect-2"><img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg"></span>
          <img class="content" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg">
      </div>
    </div>
</body>

How do you make these hover effects apply only to the area around the image (not the entire area) when using object-fit: contain? The image must remain vertically centered using object-fit.


Solution

  • Is this what you wanted? The image is centered between the animated divs.

    The reason why your image is larger in the second example you've given is because you've changed your CSS there. You've changed the height/width values of .container, .product etc, so the children elements are showing up larger, because they inherit these values.

    I've changed max-width and min-height in .container to reduce the overall size. And the width of .content should be less than the width of the effect divs

    html {
      width: 100%;
      height: 100%;
    }
    
    body {
      width: 100%;
      height: 100%;
      margin: 0;
    }
    
    .container {
      max-width: 300px;
      /* This is new */
      position: relative;
      text-align: center;
      width: 100%;
      height: 100%;
      min-height: 300px;
      /* This is new */
    }
    
    .product {
      height: 100%;
      position: absolute;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
    
    .content {
      display: flex;
      align-self: center;
      background: white;
      margin: 0 auto;
      position: relative;
      width: 65%;
      /* This is new */
      object-fit: contain;
      /* This is new */
    }
    
    .product:hover .effect-1,
    .product:hover .effect-2 {
      display: flex;
    }
    
    .effects {
      position: absolute;
    }
    
    .effect-1,
    .effect-2 {
      border-radius: 30%;
      display: flex;
      mix-blend-mode: multiply;
      height: 84%;
      opacity: 1;
      position: absolute;
      width: 84%;
      z-index: 3000;
      visibility: visible;
    }
    
    .effect-1 {
      animation: rotate 1.8s linear infinite;
      background: cyan;
    }
    
    .effect-2 {
      animation: rotate 1.2s linear reverse infinite;
      background: #e7a9ff;
    }
    
    .placeholder {
      width: 84%;
      height: auto;
      visibility: hidden;
      object-fit: contain;
      display: flex;
      margin: 0 auto;
      align-self: center;
      position: relative;
    }
    
    @keyframes rotate {
      0% {
        top: 0;
        left: 8%;
      }
      25% {
        top: 8%;
        left: 0%;
      }
      50% {
        top: 16%;
        left: 8%;
      }
      75% {
        top: 8%;
        left: 16%;
      }
      100% {
        top: 0;
        left: 8%;
      }
    }
    <body>
      <div class="container">
        <div class="product">
          <span class="effects">
                <img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg">
                <span class="effect-1"></span>
          <span class="effect-2"></span>
          </span>
          <img class="content" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg">
        </div>
      </div>
    </body>