That's because absolutely positioned elements are positioned relatively to their containing block, which is established by their nearest positioned ancestor, or the initial containing block if there is no such ancestor.
Then, if you don't use filter
, the containing block will be the initial one, which has the same dimensions as the viewport.
However, if you use filter
on body
, that will establish a containing block, even for absolutely positioned descendants. It will be like if you used position: relative
.
body {
position: relative;
}
div {
background: blue;
margin: auto;
position: absolute;
right: 0;
top: 50%;
left: 0;
height: 200px;
width: 200px;
transform: translateY(-50%);
}
<div></div>
Instead, I recommend setting the filter
on html
, and use height: 100%
to make it as tall as the viewport.
html {
height: 100%;
-webkit-filter: blur(2px);
filter: blur(2px);
}
div {
background: blue;
margin: auto;
position: absolute;
right: 0;
top: 50%;
left: 0;
height: 200px;
width: 200px;
transform: translateY(-50%);
}
<div></div>