Why does applying a CSS-Filter on the parent break the child positioning?

If we refer to the specification we can read:

A value other than none for the filter property results in the
creation of a containing block for absolute and fixed positioned
descendants unless the element it applies to is a document root
element in the current browsing context. The list of functions are
applied in the order provided.

This means that your position:fixed element will be positioned relatively to the filtered container and no more the viewport. In other words, it’s still fixed but inside its new containing block (the filtered container)

Here is a simplified version to illustrate the issue:

.container {
  display: inline-block;
  width: 200px;
  height: 200vh;
  border: 1px solid;
}

.container>div {
  position: fixed;
  width: 100px;
  height: 100px;
  background: red;
  color: #fff;
}
<div class="container">
  <div>I am fixed on scroll</div>
</div>

<div class="container" style="filter:grayscale(1);">
  <div>I move with the scroll</div>
</div>

To fix the issue try to move the filter to the fixed element instead of its container:

.container {
  display: inline-block;
  width: 200px;
  height: 200vh;
  border: 1px solid;
}

.container>div {
  position: fixed;
  width: 100px;
  height: 100px;
  background: red;
  color: #fff;
  filter: grayscale(1);
}
<div class="container">
  <div>I am fixed on scroll</div>
</div>

Here is a non-exhaustive1 list of the properties that results in the creation of a containing block for absolute and fixed positioned descendants

  • filter
  • transform ref
  • backdrop-filter ref
  • perspective ref
  • contain ref
  • transform-style ref
  • content-visibility ref
  • will-change when used with one of the above values

If any non-initial value of a property would cause the element to generate a containing block for absolutely positioned elements, specifying that property in will-change must cause the element to generate a containing block for absolutely positioned elements. ref

1: I will try to keep this list up to date.

Leave a Comment