0

I am trying to achieve an effect, where I will have div with background image with content inside. This content should be flex-positioned div with the same image but blurred (while keeping its relative position to parent).

In search for salvation, I have discovered that certain combination of CSS rules make this exact effect, but only in Chrome.

.container {
  width: 320px;
  height: 240px;
  position: relative; /* it is required */
  display: flex; /* it is required */
  background: url(https://loremflickr.com/cache/resized/4848_46406748211_5572c760e0_320_240_nofilter.jpg);
}

.mask {
  z-index: 1; /* it is required */
  overflow: hidden; /* it is required */
  width: 150px;
  height: 150px;
  border-radius: 1px; /* it is required */
}

.element {
  background: url(https://loremflickr.com/cache/resized/4848_46406748211_5572c760e0_320_240_nofilter.jpg);
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  filter: blur(5px);
}


<div class="container">
  <div class="mask">
    <div class="element"></div>
  </div>
</div>

https://jsfiddle.net/39um580g/16/

Chrome / Chrome Mobile: enter image description here

Firefox: enter image description here

Safari: enter image description here

This is ridiculous. Is there a way I can make this solution cross-browser?

Answer to Moorthy G:

Let's suppose my block is placed on the right side. Current behavior of Chrome version is as I desire: enter image description here

Adding any kind of transform will make .mask relative, so it will destroy desired effect: enter image description here

Community
  • 1
  • 1
Łukasz Szcześniak
  • 1,417
  • 11
  • 23
  • I would say chrome is wrong here. The element is positionned relatively to an upper element thus overflow shouldn't apply to it – Temani Afif Mar 17 '19 at 10:55

2 Answers2

0

Adding clip-path: polygon(0px 0px, 0px 100%, 100% 100%, 100% 0); clips your mask.

.mask {
  z-index: 1; /* it is required */
  overflow: hidden; /* it is required */
  width: 150px;
  height: 150px;
  border-radius: 1px; /* it is required */      
  clip-path: polygon(0px 0px, 0px 100%, 100% 100%, 100% 0); /* Fix for Firefox*/
}
Moorthy G
  • 1,441
  • 8
  • 9
0

One solution is to make the mask element position:absolute so that the overflow will work as expected then you consider adjusting the background-position while adjust the position of the element to rectify the image position.

I used CSS variable to make it easy to adjust:

.container {
  width: 320px;
  height: 240px;
  position: relative;
  display: flex;
  --img:url(https://loremflickr.com/cache/resized/4848_46406748211_5572c760e0_320_240_nofilter.jpg);
  background:var(--img);
}

.mask {
  z-index: 1;
  overflow: hidden;
  width: 150px;
  height: 150px;
  top:var(--t,0);
  left:var(--l,0);
  position:absolute;
  border-radius: 50px;
}

.mask::before {
  content:"";
  display:block;
  background:var(--img) calc(-1*var(--l)) calc(-1*var(--t)); 
  width:100%;
  height:100%;
  filter: blur(5px);
}
<div class="container" style="--t:20px;--l:80px">
  <div class="mask">
  </div>
</div>

<div class="container" style="--t:90px;--l:0px">
  <div class="mask">
  </div>
</div>
<div class="container" style="--t:50px;--l:50px;--img:url(https://picsum.photos/320/240?image=1069)">
  <div class="mask">
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • I have tried this solution but it is problematic if I want to use `background-size: cover;` – Łukasz Szcześniak Mar 17 '19 at 15:57
  • @ŁukaszSzcześniak ok will try to find another way, but I saw you already accepted the clip-path solution. I guess that one is fine for you? – Temani Afif Mar 17 '19 at 18:35
  • @TermaniAfif I accepted clip-path but it is not a perfect solution (its just okay for now). If you find anything else worth trying, (if I am correct) I should be able to change accepted answer. I think this problem is worth giving a though. – Łukasz Szcześniak Mar 17 '19 at 20:48