Search code examples
cssanimationbackgroundresponsiveviewport

Responsive Background Image (animated fade loop) that will span full height of page content?


ITERATION 1 :

I've got a quite pleasant animation going on in the background. It is responsive, filling the viewport on the fly (you can resize the window and it adjusts). However, if the content on the page exceeds the height of the viewport, I get a scrollbar (as expected); but when I scroll down I see the black background of the site (and not the background image).

If you go to the page and resize your window so that the viewport is shorter than the content, then scroll, you'll see what I mean : https://www.vortex42studios.com

Is it not possible to have the background image scale to the height of the page OR the viewport height, whichever of the two happens to be the longest in px at any given moment?

IE : If the page content is 1000px and the viewport is 700px, then the background spans 1000px in height.

And, if the page content is 500px, and the viewport is 750px, then the background image spans to the 750px height of the viewport.

So that it looks good both when there are, and are not scrollbars? Preferably responsively, as it is now, where you can resize the window and the background image adjusts accordingly on the fly. I would very much like to keep this to a CSS-only solution if at all possible.

Surely this is possible. I'm obviously missing something, but can't figure it out. Help would be massively appreciated.

@charset "utf-8";

/* CSS Document */

* {
  margin: 0;
}

html {
  background-color: #000000;
  color: #FFFFFF;
  font-family: Constantia, "Lucida Bright", "DejaVu Serif", Georgia, "serif";
  font-size: 3vw;
}

html,
body {
  height: 100%;
}

.wrapper {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.header {}

.content {
  font-size: 2vw;
  flex: 1;
}

.footer {}

plateBG {
  animation-name: imageAnimation;
  animation-iteration-count: infinite;
  animation-duration: 25s;
  height: 100%;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  background-attachment: scroll;
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  opacity: 0%;
  z-index: -1;
  overflow: visible;
}

plateBG:nth-child(1) {
  background-image: url(https://www.vortex42studios.com/source/img/BG01_1080P.JPG);
}

plateBG:nth-child(2) {
  animation-delay: 5s;
  background-image: url(https://www.vortex42studios.com/source/img/BG02_1080P.JPG);
}

plateBG:nth-child(3) {
  animation-delay: 10s;
  background-image: url(https://www.vortex42studios.com/source/img/BG03_1080P.JPG);
}

plateBG:nth-child(4) {
  animation-delay: 15s;
  background-image: url(https://www.vortex42studios.com/source/img/BG04_1080P.JPG);
}

plateBG:nth-child(5) {
  animation-delay: 20s;
  background-image: url(https://www.vortex42studios.com/source/img/BG05_1080P.JPG);
}

@keyframes imageAnimation {
  0% {
    opacity: 0;
  }
  20% {
    opacity: 1;
  }
  40% {
    opacity: 0;
  }
  60% {
    opacity: 0;
  }
  80% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}


}
<plateBG></plateBG>
<plateBG></plateBG>
<plateBG></plateBG>
<plateBG></plateBG>
<plateBG></plateBG>

<div class="wrapper">

  <div class="header">
    <p>vortex42studios</p>
    <p>Film and Animation Effects Studios</p>
  </div>

  <div class="content">
    <p>This is content</p>
    <p>This is content</p>
    <p>This is content</p>
    <p>This is content</p>
    <p>This is content</p>
    <p>This is content</p>
    <p>This is content</p>
    <p>This is content</p>
  </div>

  <div class="footer">
    <p>Relaunching soon</p>
    <p>Facilities in Scotland and Denmark</p>
  </div>

</div>


Solution

  • ITERATION 2 :

    I couldn't make any of the methods found on SO to force an absolute div to take on the height of its parent (when that element's height is auto) work.

    So, turning to putting the images as backgrounds on the the body itself, using a pseudo before element for images fading in and after for fading out it works. Body height is set to auto, but with min-height: 100vh.

    BUT, it takes a lot of GPU, even more than (current at time of writing this) https://www.vortex42studios.com, so let's hope someone can come up with something better. Otherwise we are in danger of draining the user's mobile battery or their laptop scorching their knees.

    * {
      margin: 0;
      padding: 0;
    }
        body {
          height: auto;
          min-height: 100vh;
          width: auto;
          overflow: visible;
          position: relative;
        }
        body::before, body::after {
            display: inline-block;
            top: 0;
            left: 0;
            position: relative;
            position: absolute;
            content: '';
            animation: none 25s infinite ease;
            animation-fill-mode: forwards;
            width: 100%;
            height: 100%;
            min-height: 100vh;
            z-index: -1;
            overflow: visible;
            background-size: cover;
            background-position: center center;
        }
        body::before {
          animation-name: fadein;
        }
        body::after {
            animation-name: fadeout;
        }
        @keyframes fadein {
          0% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG01_1080P.JPG);
          }
          20% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG01_1080P.JPG);
            }
          20.001% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG02_1080P.JPG);
            }
          40% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG02_1080P.JPG);
            }
          40.001% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG03_1080P.JPG);
            }
          60% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG03_1080P.JPG);
            }
          60.001% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG04_1080P.JPG);
            }
          80% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG04_1080P.JPG);
          }
          80.001% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG05_1080P.JPG);
            }  
          100% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG05_1080P.JPG);
            }
        }
        @keyframes fadeout {
          0% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG05_1080P.JPG);
          }
          20% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG05_1080P.JPG);
            }
          20.001% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG01_1080P.JPG);
            }
          40% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG01_1080P.JPG);
            }
          40.001% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG02_1080P.JPG);
            }
          60% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG02_1080P.JPG);
            }
          60.001% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG03_1080P.JPG);
            }
          80% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG03_1080P.JPG);
          }
          80.001% {
            opacity: 1;
            background-image: url(https://www.vortex42studios.com/source/img/BG04_1080P.JPG);
            }  
          100% {
            opacity: 0;
            background-image: url(https://www.vortex42studios.com/source/img/BG04_1080P.JPG);
            }
        }
        .wrap {
          height: auto;
          width: 100%;;
        }
    <div class="wrap">some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br></div>