1

How is my question different from the proposed duplicate:

I want only the part of the div.background-pic (the div with the background image) which is behind div.lower (the div with the translucent blue color), to just appear to be blurred.

Explained:

As you can see, the div.background-pic is position:fixed (which means it is out of the flow, and does not scroll), while the rest of the page scrolls vertically, which implies that there are different parts of div.background-pic behind the div.lower at different times (while the page is being scrolled).

So it is obvious that we don't want to do anything to the div with the image itself, but do something (apply some kind of filter if there is one, etc.) on the div.lower such that it causes the part of the background-image of the div which is behind it, to appear blurred.


QUESTION:

JSFiddle

In the following SSCCE, I want the part of the (background-image of) .background-pic which is behind .lower (and is partially visible because .lower is translucent) to appear blurred out. Is that possible?

.background-pic {
  background-image: url(http://khongthe.com/wallpapers/nature/beautiful-valley-45851.jpg);
  background-size: cover;
  position: fixed;
  z-index: -1;
  height: 400px;
  width: 400px;
}
.top-blur {
  height: 400px;
  width: 400px;
  overflow: auto;
}
.upper {
  height: 300px;
  width: 100%;
  background-color: rgba(255, 127, 80, 0.5);
}
.lower {
  height: 200px;
  width: 100%;
  background-color: rgba(0, 255, 255, 0.51);
}
<div class="background-pic">

  <div class="top-blur">
    <div class="upper"></div>
    <div class="lower"></div>
  </div>

</div>

NOTE: CSS only solution is preferred.


Solace
  • 8,612
  • 22
  • 95
  • 183
  • @TinyGiant I added an edit to the top of the question, explaining how my question is different from that question. Can the "This question may already have an answer here:" label be removed if my edit is satisfactory? – Solace Jul 09 '15 at 00:14
  • 1
    I don't believe it would be possible because you're blurring the overlaying element, even a opacity wouldn't do what you intend. I can't answer, but I believe it's not possible. You may want to edit with photoshop? – Billy Purvis Jul 09 '15 at 00:21
  • 2
    I agree with @BillyPurvis, this is not possible with CSS, I doubt you could even do this with JavaScript. But, you're right, this is not a duplicate. –  Jul 09 '15 at 00:27
  • 1
    However, it does look like this can be done with HTML5's `` http://stackoverflow.com/a/17134789/4639281, which offers a new duplicate. If this solves the problem, @ping me and I'll get another user to suggest that as a duplicate (as I've retracted my close vote and can't vote again) –  Jul 09 '15 at 00:32

1 Answers1

1

There's a way with some js to get this result, using clipping path and some repositioning on scroll. Like this:

HTML:

<div class="background-pic-top"></div>
<div class="background-pic-bottom"></div>
<div class="top-blur" id="scrollingDiv">
    <div class="upper">
        <svg class="clip-svg" width="400" height="500" style="position: relative">
            <defs>
                <clipPath id="uppersvg" clipPathUnits="userSpaceOnUse">
                    <rect x="0" y="0" width="400" height="300" />
                </clipPath>
            </defs>
        </svg>
    </div>
    <div class="lower">
        <svg>
            <defs>
                <clipPath id="lowersvg" clipPathUnits="userSpaceOnUse" width="200" height="200">
                    <rect x="0" y="300" width="400" height="200" />
                </clipPath>
            </defs>
        </svg>
    </div>
</div>

JS:

    var elem = document.getElementById('scrollingDiv');
    var clipUp = document.getElementById('uppersvg');
    var clipDown = document.getElementById('lowersvg');

    elem.onscroll = function (e) {
        clipDown.getElementsByTagName('rect')[0].setAttribute('y', 300 - elem.scrollTop);
        clipUp.getElementsByTagName('rect')[0].setAttribute('y', 0 - elem.scrollTop);
    }

CSS:

   body {
            margin: 0px;
        }
        .background-pic-top {
            background-image:url(http://khongthe.com/wallpapers/nature/beautiful-valley-45851.jpg);
            background-size:cover;
            position:fixed;
            z-index:-1;
            height:400px;
            width:400px;
            clip-path: url(#uppersvg);
            -webkit-clip-path: url(#uppersvg);
        }
        .background-pic-bottom {
            background-image:url(http://khongthe.com/wallpapers/nature/beautiful-valley-45851.jpg);
            background-size:cover;
            position:fixed;
            z-index:-1;
            height:400px;
            width:400px;
            clip-path: url(#lowersvg);
            -webkit-clip-path: url(#lowersvg);
            -webkit-filter: blur(5px);
            filter: blur(5px);
        }
        .top-blur {
            height:400px;
            width:400px;
            overflow: auto;
        }
        .upper {
            height:300px;
            width:100%;
            background-color: rgba(255, 127, 80, 0.5);
        }
        .lower {
            top: 200px;
            height:200px;
            width:100%;
            background-color: rgba(0, 255, 255, 0.51);
        }

http://jsfiddle.net/4f601tt7/7/

Won't be cross-browser but it seems to work on Chrome and Firefox.

Julien Grégoire
  • 16,864
  • 4
  • 32
  • 57