4

I am trying to apply a simple blur to most of the page while another element sits on top, unblurred

<div class="stufftobeblurred">
   <header>
     ...
   </head>
   ... most of page is here ...
</div>
<div class="stuffontop">
  ... this isn't blurred ...
</div>

(with CSS such as below)

.stufftobeblurred {
  filter: blur(2px);
}
header {
  position: absolute;
  ...
}

This works ok except that the positioned header gets moved while the blur is active. See this fiddle where I've broken it down to the minimum possible replication.

https://jsfiddle.net/8hr72gs3/

Uncomment the blur and observe the blue rectangle moves.

I've tried applying z-index:0; and transform:translateZ(0) as suggested by search hits but this appears to have no effect.

The element still moves even if blur radius is 0.

N.B. In the fiddle if I apply margin:0; padding:0 to the body it seems to fix the problem, however in my real-world scenario this doesn't work. I don't know what the semantic difference is between the fiddle and my realword scenario, so if anyone can tell me why this padding/margin should works on the fiddle it may help with further diagnosis.

Also, if the fiddle is modified to have an outer div then the trick no longer works (if applied to the outer div instead of body, with or without a position:relative added)

DJL
  • 2,060
  • 3
  • 20
  • 39

1 Answers1

0

Seems weird to me. But apparently adding:

margin-left: -8px;
margin-top: -8px;

remove that move on filter: blur.

Tested in 66.0.1 (64-bit) and Chrome Version 73.0.3683.86 (Official Build) (64-bit)

It should've been fixed https://bugzilla.mozilla.org/show_bug.cgi?id=1125767

.blurme {
  filter: blur(1px);
  margin-left: -8px;
  margin-top: -8px;
}

.blurme:hover{
  filter: blur(0);
}

.positionme {
  position: absolute;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  background-color: blue;
}
<div class="blurme">

  <div class="positionme">


  </div>
</div>

Alternatively by adding:

position: absolute;
left: 0px;
top: 0px;

could fix them to top-left.

.blurme {
  filter: blur(1px);
  position: absolute;
  left: 0px;
  top: 0px;
}

.blurme:hover{
  filter: blur(0);
}

.positionme {
  position: absolute;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  background-color: blue;
}
<div class="blurme">

  <div class="positionme">


  </div>
</div>
Mukyuu
  • 6,436
  • 8
  • 40
  • 59
  • hmm. TBH I assumed that this was _not_ a browser bug since it happened in both FF and chrome when I tried it on my real-world scenario. I guess your margin just undoes whatever the browser is doing here. Not really a fix if the browser is going to be fixed as the margin would (presumably) start over-correcting – DJL Apr 01 '19 at 07:11
  • You can add another class in the meantime to prevent too much work only for this issue e.g `blur-move`. – Mukyuu Apr 01 '19 at 07:13
  • I've add possible alternative, mind to check if it's viable with your condition? – Mukyuu Apr 01 '19 at 07:58
  • Adding the position to what? – DJL Apr 01 '19 at 08:05
  • `.blurme` ? wasn't that the question? – Mukyuu Apr 01 '19 at 08:06
  • That does actually seem to work (with an additional right:0 being required in my real-world scenario). I'd still like to know what is really going on here though. Such positions won't necassarily be so easy to apply in all circumstances. – DJL Apr 01 '19 at 08:09
  • @DJL it's not a bug, it's by design (check the duplicate) – Temani Afif Apr 01 '19 at 09:39
  • @Temani Afif - thanks. But If I'm understanding correctly I still don't see how this causes the behviour seen in my fiddle, where the containing element is already at 0,0 anyway, so whether its contents are positioned relative to the element with filter, or one of its parents is not really relevant? (Though I can see how it would be a problem if any of the elements are not at 0,0) – DJL Apr 01 '19 at 09:47
  • @DJL without filter your element is positionned relatively to the viewport since there is no positionned ancestor .. when you add filter the element will be positionned relatively to the element where you applied the filter and this element is inside the body where you have a default margin ... add border to your filtred element to better see the issue. – Temani Afif Apr 01 '19 at 09:49
  • That being the case, should this not have worked? > N.B. In the fiddle if I apply margin:0; padding:0 to the body it seems to fix the problem, however in my real-world scenario this doesn't work – DJL Apr 01 '19 at 09:51
  • 1
    @DJL adding maring:0 won't fix the issue, it will simply fix it visually since the filtred element is placed at the same position of the viewport ... and you can do nothing to avoid this, your element will be placed relatively to the filtred element (this is a fact) now if you don't want this you need to re-think your code and apply the filter somewhere else or adjust the position to achieve what you want but you cannot prevent this behavior – Temani Afif Apr 01 '19 at 10:01