skip to Main Content

I’m trying to create a flex layout where each of the flex items "cut through" the flex box, revealing the image that’s beneath the flex box. I’ve managed to achieve this by using mix-blend-mode property.

However, I also want the flex items to have a backdrop-filter: blur, so that the background they reveal is blurry only for those flex items.

The following snippet illustrates what I’m trying to achieve, however the backdrop-filter does not seem to work.

How can I update this snippet to achieve the desired effect?

body {
  margin: 0
}
.background {
  background-image: url("https://upload.wikimedia.org/wikipedia/commons/3/3d/Fesoj_-_Papilio_machaon_%28by%29.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}
.flex {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 20px;
  width: 100%;
  height: 50px;
  background-color: black;
  
  /* Used to make the flex items "cut through" the flex box */
  mix-blend-mode: hard-light;
}
.box {
  width: 100%;
  height: 100%;
  /* Ased to make the flex items "cut through" the flex box */
  background-color: grey;
  
  /* *** This doesnt seem to work *** */
  backdrop-filter: blur(20px);
}
<div class="background">
    <div class="flex">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
</div>

Edit

I’ve been able to achieve something similar by not having the flex items "cut through" the flex box, but rather use a transparent flex box and add extra elements above and below the flex box, and extra flex items serving as the gap/separators. It’s not ideal since it makes applying a border-radius to the flex items almost impossible, but it does the job.

body {
  margin: 0
}
.background {
  background-image: url("https://upload.wikimedia.org/wikipedia/commons/3/3d/Fesoj_-_Papilio_machaon_%28by%29.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.horizontal {
  height: 20px;
  width: 100%;
  background-color: black;
}
.flex {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 50px;
  backdrop-filter: blur(10px);
}
.box {
  width: 100%;
  height: 100%;
}
.separator {
  flex: 0 0 20px;
  background-color: black;
}
<div class="background">
  <div class='horizontal'></div>
    <div class="flex">
      <div class="box separator"></div>
      <div class="box"></div>
      <div class="box separator"></div>
      <div class="box"></div>
      <div class="box separator"></div>
      <div class="box"></div>
      <div class="box separator"></div>
      <div class="box"></div>
      <div class="box separator"></div>
    </div>
  <div class='horizontal'></div>
</div>

2

Answers


  1. body {
                margin: 0
            }
            .background {
                background: url("https://upload.wikimedia.org/wikipedia/commons/3/3d/Fesoj_-_Papilio_machaon_%28by%29.jpg");
                background-repeat: no-repeat;
                background-size: cover;
                width: 100vw;
                height: 100vh;
            }   
            .layer{
                width: 100%;
                height: 100vh;
                background: rgba(255, 255, 255, 0.3);
                backdrop-filter: blur(20px);
                display: flex;
                justify-content: center;
                align-items: center;
            }
            .flex {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 20px;
                padding: 20px;
                width: 100%;
                height: 50px;
                background-color: black;
                
                /* Used to make the flex items "cut through" the flex box */
                mix-blend-mode: hard-light;
            }
            .box {
                width: 100%;
                height: 100%;
                /* Ased to make the flex items "cut through" the flex box */
                background-color: grey;
                
                /* *** This doesnt seem to work *** */
            }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div class="background">
            <div class="layer">
                <div class="flex">
                    <div class="box"></div>
                    <div class="box"></div>
                    <div class="box"></div>
                    <div class="box"></div>
                  </div>
            </div>
        </div>
    </body>
    </html>
    Login or Signup to reply.
  2. No mix-blend-mode required. Make .flex transparent, and fill the gaps with box-shadow on .box. Less and simpler code:

    body {
      margin: 0
    }
    .background {
      background-image: url("https://upload.wikimedia.org/wikipedia/commons/3/3d/Fesoj_-_Papilio_machaon_%28by%29.jpg");
      background-repeat: no-repeat;
      background-size: cover;
      width: 100vw;
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .flex {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 20px;
      padding: 20px;
      width: 100%;
      height: 50px;
    }
    .box {
      width: 100%;
      height: 100%;
      box-shadow:0 0 0 20px #000;
      backdrop-filter: blur(20px);
    }
    <div class="background">
        <div class="flex">
          <div class="box"></div>
          <div class="box"></div>
          <div class="box"></div>
          <div class="box"></div>
        </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search