5

I'm using Keith Clark's CSS-only method to create a two-layer parallax effect so that the background image scrolls at a slower speed than the rest of the site's content. Just to be clear, the image covers the entire page and the content sits on top of it.

My site is divided into two main div elements (and a container div) - one for the background image, and the other for the page's content. Below is the code I was using for the different div elements.

.container {
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  perspective: 1px;
  position: absolute;
  left: 0;
  right: 0;
}

.background {
  background-image: url(images/background.jpg);
  background-size: cover;
  position: absolute;
  /* margin-bottom: -200em;
     overflow: hidden; */
  height: 200em;
  left: 0;
  right: 0;
  transform: translateZ(-2px) scale(3);
}

.page-content {
  transform: translateZ(0);
}

Without the margin-bottom and overflow properties added, the background div element would end up having vertical white space left over once it was set to a height high enough to cover all the page's content.

After adding the negative margin, the problem was fixed in Chrome and sort of in Firefox*, and I increased the height and negative margin of the div element to be much more than was required to ensure it would work for different page lengths.

IE 11 still has has the white space there though. Normally the background-size: cover; property removes any white space, but this doesn't work with the parallax effect.

Do you know of any ways to remove the white space that would work for IE9+ and other major browsers, or am I out of luck?

Here's a JSFiddle with pretty much exactly the same code as the site I'm creating.

*Firefox doesn't have white space, but the negative margin isn't working properly for all page lengths. For shorter pages you can scroll way passed the end of the page's content. I could remedy this by changing the height and margin for each page, but a global solution would be appreciated if possible.

  • why you're using `height: 100%` instead of `height: 100vh` like the article mentioned? – Joe RR Apr 21 '15 at 02:57
  • 1
    @LeandroRuel, since percentages are better supported and they seemed to have the same effect, I decided to use them instead of vh units. I just tested changing the units to vh right now, but it didn't fix the problem in IE 11. – Andrew Hansen Apr 21 '15 at 03:03
  • 1
    yep, but, if you set with percentages, you need set `html,body` as `height: 100%` too, to the element achieve 100% of his height. or you can wrap the elements with a parent element using a fixed height – Joe RR Apr 21 '15 at 03:06
  • @LeandroRuel, I think that's how it is by default. Plus, vh isn't as supported. – Andrew Hansen Apr 21 '15 at 03:09
  • @LeandroRuel, Notice the `overflow: hidden;` in the code above. Also, the div element does have a fixed height, but there's still a white space. It also doesn't work if I put an image inside the div tags instead of using the `background-image` tags. – Andrew Hansen Apr 21 '15 at 03:17
  • 2
    @AndrewHansen the problem is that for `.back` you have specified the height as 50em which roughly translates to 50*16=800px but your `line-height: 300px;` translates to 900px as you three text elements hence whitspace. check this fiddle http://jsfiddle.net/Lawrg9mv/15/ i have removed the image as it was not loading, url was showing white background and changed height to `60em` – Raunak Kathuria Apr 21 '15 at 04:30
  • hard question, i tryed solve here, but no sucess, i'll try again later – Joe RR Apr 21 '15 at 04:56
  • @Raunak, Thanks for pointing that out. I fixed that issue in the fiddle, but the whitespace is being caused by something else (your fiddle still shows whitespace in IE). On my page I've set `height: 200em;` which is way too big for it, but by setting an equally large `margin-bottom: -200em;` I hope to make the background stop at the end of the page, as long as its less than 200em. – Andrew Hansen Apr 21 '15 at 12:44
  • @AndrewHansen `html, body` does **not** have `height: 100%` by default. You need to set this yourself. – Praxis Ashelin Apr 21 '15 at 13:48

2 Answers2

1

I think you have a few problems if your goal is to make this work on IE9. This works for me, but not without increasing the size height of the .back div.

This works for me in IE9 and Chrome, but you may just want some IE conditionals.

http://jsfiddle.net/Lawrg9mv/21/

Additions:

.back {
    height: 80em; 
    -ms-transform: translateZ(-2px) scale(3);
}

.front {
    -ms-transform: translateZ(0);
    z-index: 10;
    position: relative;
}
user1477388
  • 20,790
  • 32
  • 144
  • 264
  • Hmm... it's strange that this isn't working for me. Perhaps there's something messed up with my IE11 install. I think I also noticed something more fundamentally wrong with how my page is displaying in IE - there's no parallax! You stated that this didn't work without increasing the height. That's true, and it's part of the problem. The negative margin should get rid of the added height, but it's not. By adding more height, the "end of the page" no longer is the end of the page, at least when I've tried it. Anyway, I'm wondering if anyone else is getting the no parallax problem in IE too. – Andrew Hansen Apr 21 '15 at 14:47
  • The demo for that does work OK in IE, but it's a bit different because the background image is fixed rather than scrolling at a slower speed. If the parallax system I'm trying to implement fails, I'll probably revert to a fixed background image. – Andrew Hansen Apr 21 '15 at 16:03
0

There isn't any way to get CSS parallax to work in IE, yet. But since Webkit-based browsers like Chrome and Opera (I haven't tested Safari) work well with parallax, it's possible to target Webkit browsers and display the parallax background for them, and display different code - without parallax - for other browsers.

First, I put the parallax code inside @media queries, like this:

@media screen and (-webkit-min-device-pixel-ratio:0) and (min-resolution: .001dpcm) {
  .container {
    [rule contents]
  }

  .background {
    [rule contents]
  }

  .page-content {
    [rule contents]
  }
}

The first attribute (-webkit-min-device-pixel-ratio:0) targets all Webkit-based browsers, but since I assume not all versions of Webkit browsers will support this parallax effect, I also added the second attribute, which limits the browsers to Chrome 29+ and Opera 16+ (I excluded Safari just to be safe, but you can choose another hack that targets Safari too if you find out it works).

It would probably be a much better idea to use feature detection, but I haven't yet learned JavaScript, and the above is a CSS-only solution.

After putting the parallax rules in a @media query, I set up an alternative default rule for the back div element.

(Though dividing up the site into front and back div elements isn't necessary without parallax, setting the back div element with a background image rather than body or html eliminates a ton of lag.)

To retain as much similarity to the parallax version as possible, I set the background image to position: fixed.

Because browsers read through the CSS file top-down and apply styles in that order, it's important to have the parallax .back rule (and its surrounding @media query) coming after the standard, non-parallax .back rule in the file.

And of course, I made sure that all the attributes which applied to both the standard and parallax .back rules were only present in the default one to save space (they would be applied by Webkit browsers along with additional rules in the parallax version).