Home > OS >  modal is constrained to parent when backdrop-filter is applied
modal is constrained to parent when backdrop-filter is applied

Time:12-31

I made a modal (inspired by Daisy UI) and would like to give a backdrop filter to the container. To open the modal click the checkbox.

body {
  margin: 0px;
}

#container {
  background: red;
  {% comment %} backdrop-filter: blur(16px); {% endcomment %}
}

.modal {
    pointer-events: none;
    visibility: hidden;
    position: fixed;
    top: 0px;
    right: 0px;
    bottom: 0px;
    left: 0px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.modal-toggle:checked   .modal {
    pointer-events: auto;
    visibility: visible;
}

.modal-box {
    background-color: blue
}
<div id="container">
  <input id="modal"    type="checkbox" value="off"/>
  <label  for="modal">
    <label  for=""> 
      modal-box
    </label>
  </label>
</div>
 

However, when I uncomment the backdrop-filter, the modal gets constrained to the container element. I don't want this. I would like the modal to fill the whole page, even with a backdrop filter on the parent.

CodePudding user response:

it will add a black transparent shadow at the full body but will not add the backdrop filter.

.modal-box {
    background-color: blue;
    box-shadow: 0 0 0 5000px rgb(0 0 0 / 50%);
}

CodePudding user response:

Update

This example shows when backdrop is set as position: absolute to have it contained in the container, hopefully closer to the desired result.

Try scroll to see the elements behind the container blurred (only when the modal is visible).

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#container {
  background-color: rgba(220, 20, 60, 0.25);
  position: sticky;
  top: 0;
  padding: 30px 10px;
  isolation: isolate;
}

.modal {
  pointer-events: none;
  visibility: hidden;
  position: fixed;
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.modal-toggle:checked ~ .modal {
  pointer-events: auto;
  visibility: visible;
}

.modal-box {
  padding: 25px;
  background-color: blue;
  color: #fff;
}

.backdrop {
  position: absolute;
  inset: 0;
  pointer-events: none;
  visibility: hidden;
  backdrop-filter: blur(5px);
}

.modal-toggle:checked ~ .backdrop {
  pointer-events: auto;
  visibility: visible;
}

.modal-toggle {
  position: relative;
  z-index: 50;
}

section {
  display: flex;
  width: 400px;
  height: 400px;
  background-color: lightgreen;
  border-radius: 20px;
  padding: 12px;
  overflow: hidden;
}

section:nth-of-type(1) {
  background: url(https://picsum.photos/200?random=1);
  background-size: cover;
}
section:nth-of-type(2) {
  background: url(https://picsum.photos/200?random=2);
  background-size: cover;
}
section:nth-of-type(3) {
  background: url(https://picsum.photos/200?random=3);
  background-size: cover;
}
section:nth-of-type(4) {
  background: url(https://picsum.photos/200?random=4);
  background-size: cover;
}
section:nth-of-type(5) {
  background: url(https://picsum.photos/200?random=5);
  background-size: cover;
}
<div id="container">
  <input id="modal"  type="checkbox" value="off" />
  <figure ></figure>
  <label  for="modal">
    <label  for="">
      modal-box
    </label>
  </label>
</div>
<section></section>
<section></section>
<section></section>
<section></section>
<section></section>

Original

It seems that this is because parent with backdrop-filter will make fixed element placed relative to the parent element instead of the viewport. Accoding to MDN:

If the position property is absolute or fixed, the containing block may also be formed by the edge of the padding box of the nearest ancestor element that has the following: ...

... A backdrop-filter other than none (e.g. backdrop-filter: blur(10px);)

Not sure if it would work in the use case, but a possible work around could be to have a separate element for the backdrop, perhaps such the following example.

Although not ideal, the separate backdrop here could still be further styled to be contained or offset from the container if needed.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#container {
  background: red;
  position: relative;
  padding: 10px;
}

.modal {
  pointer-events: none;
  visibility: hidden;
  position: fixed;
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.modal-toggle:checked ~ .modal {
  pointer-events: auto;
  visibility: visible;
}

.modal-box {
  padding: 12px;
  background-color: blue;
  color: #fff;
}

.backdrop {
  /*            
  • Related