Search code examples
htmlcsscss-transitionsbackground-size

CSS transition: background-size not working


I am working on a website that when you hover over an image, it zooms out to so that you can see the whole image, without zooming out too much to see the background of the div.

This is what my HTML looks like:

<div id="wrapper">
 <div id="imgDiv">
  <div id="transitionDiv" style="background-image: url("../resources/models/HA-SJX.JPG");"></div>
 </div>
 <p id="title">MALEV Cessna c172 HA-SJX (G1000)</p>
 <a href="../downloads/TP172-MALEV PS_P4exw.zip" download="MALEV Cessna c172 HA-SJX (G1000)">Download</a>
</div>

And my CSS:

:root {
  --img-size: 350px;
  --button-margin: 20px;

  --dark-blue: #070b21;
  --blue: #10184a;
  --light-blue: #00d1ff;
}

div#wrapper {
  position: relative;
  margin: auto;
  margin-bottom: 100px;
  background-color: var(--dark-blue);
  width: var(--img-size);
}

div#imgDiv {
  position: relative;
  text-align: center;
  color: red;
  padding: 0;
  margin: 0;
  background-color: var(--dark-blue);
  overflow: hidden;
  height: var(--img-size);
}

div#imgDiv div#transitionDiv {
  background-position-x: 50%;
  height: 100%;
  width: 100%;
  background-size: auto var(--img-size);
  background-repeat: no-repeat;

  -webkit-transition: background-size 1500ms ease;
  -moz-transition: background-size 1500 ease;
  -o-transition: background-size 1500 ease;
  -ms-transition: background-size 1500ms ease;
  transition: background-size 1500ms ease;
}

div#imgDiv:hover div#transitionDiv {
  background-position-y: 50%;
  background-size: var(--img-size) auto;
}

p#title {
  overflow: hidden;
  height: 38px;
  margin: 30px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

div#designs div a {
  display: block;
  text-align: center;
  text-decoration: none;
  background-color: var(--light-blue);
  color: white;
  font-size: 40px;
  font-family: "Montserrat", sans-serif;
  margin: var(--button-margin);
  padding: 0px;
  width: calc(100% - 2 * var(--button-margin));
  border-radius: 15px;
  transition: 0.5s;
}

div#designs div a#no-link {
  background-color: grey;
}

div#designs div a:hover {
  background-color: dodgerblue; /* using random color for now */
}

div#designs div a:active {
  background-color: blue; /* using random color for now */
}

I tried looking for a solution, and they all said to do it the way I have it done. This zooms the background image to the correct size, but the transitions aren't working.

I've also tried changing the div so that it has an image tag inside the div, but this also didn't work.


Solution

  • It turned out that transitions don't work with auto and some other properties (cover, contain, inherit, initial, unset). The solution that I found was using JavaScript using this code:

    img.onload = function () {
        let height = img.naturalHeight;
        let width = img.naturalWidth;
        let ratio = height / width;
        img.surroundingDiv.bgSize = "" + ((1 / ratio) * 100) + "%";
        img.surroundingDiv.style.backgroundSize = this.surroundingDiv.bgSize;
    };
    
    transitionDiv.style.backgroundImage = "url(" + img.src + ")";
    transitionDiv.onmouseenter = function () {
        this.style.backgroundSize = 100 + "%";
    };
        
    transitionDiv.onmouseleave = function () {
        this.style.backgroundSize = this.bgSize;
    };
    

    First I calculate the ratio, to figure out how much to zoom the image when it's not being hovered over. I had to store this value to be used in the onmouseleave event, by creating a new property bgSize in the div and storing it there.

    Then I used the onmouseenter and onmouseleave events to change the size of the image when it's being hovered over.

    I also removed the :hover selector in the css file, because it was now obsolete.