Search code examples
csspseudo-element

before pseudo element came in front of div when using backdrop filter


I am trying to create master card and i want a vertical line behind it. When i use backdrop filter on master card it works fine. But when i put it on its parent element ::before pseudo element come in front of master card. I can't even fix this with z-index.

I tried this on firefox but i have to add backdrop-filter to both parent and child then this works

Here's the code:-

:root {
        --white: #fff;
        --gold: rgb(255, 215, 0);
        --bg-color: rgba(255, 0, 255, 0.2);
      }
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      html {
        font-size: 62.5%;
      }
      body {
        background-image: linear-gradient(
            rgba(0, 0, 0, 0.3),
            rgba(0, 0, 0, 0.3)
          ),
          url("https://images.pexels.com/photos/460635/pexels-photo-460635.jpeg?auto=compress&cs=tinysrgb&dpr=1");
        background-attachment: fixed;
        background-repeat: no-repeat;
        background-position: center center;
        background-size: cover;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100vh;
        padding: 1rem;
      }

      .container {
        display:flex;
        justify-content:center;
        align-items:center;
        width: 50%;
        height:90vh;
        margin:2rem;
        padding: 5rem;
        box-shadow: 0px 0px 3px var(--gold), 0px 0px 3px var(--gold);
        border: 0.1rem solid var(--gold);
        border-radius: 3rem;
        position: relative;
        backdrop-filter: blur(1rem);
        &::before {
          content: "";
          position: absolute;
          top: 0;
          left: 50%;
          translate: -50% 0%;
          width: 0.2rem;
          height: 100%;
          background-color: var(--gold);
        }
        .master-card {
          text-transform: capitalize;
          color: var(--white);
          width: 100%;
          aspect-ratio: 2/1;
          /*backdrop-filter: blur(1rem);*/
          background-color: var(--bg-color);
          border: none;
          border-radius: inherit;
          padding: 2.5rem;
          box-shadow: inherit;

          display: flex;
          & .brand-bg {
            width: 10%;
            aspect-ratio: 1;
            border-radius: 50%;
          }
        }
      }
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Master card</title>
  </head>
  <body>
    <div class="container">
      <div class="master-card">
        <div class="left-side">
          <div class="brand">
            <span class="brand-bg"></span><span class="brand-bg"></span>
            <h2>master card</h2>
          </div>
          <div class="info">
            <p>card number</p>
            <p>8050 5040 2030 3020</p>
          </div>
          <p>prem kumar shahi</p>
        </div>
        <div class="right-side"></div>
      </div>
    </div>
  </body>
</html>

I think should use a hr tag then rotate it but because of padding it could touch the borders of the container div.

Here's an image of the design. "This image is from firefox since its somehow working on it"

enter image description here


Solution

  • It seems to be a Chromium and Edge bug that nested backdrop-filter blurring is not working correctly. (If the backdrop-filter on the parent is removed, the backdrop-filter on the child will work as expect.) Many similar issues have being reported on Chromium.

    The vertical line should be blurred since it is included in the backdrop root image (backdrop-filter’s filter operations will applied to) as per spec:

    The Backdrop Root Image for an element E is the final image that would be produced by the following steps:

    1. Start at the Backdrop Root element that is the nearest ancestor of E.
    2. Paint all content, in painting order, between (and including) the ancestor Backdrop Root element and element E.

    — Here, the Backdrop Root element of master-card is container, and the vertical line element is indeed between them.

    One way achieve the effect is to apply the backdrop-filter on a sibling element of the child to blur the background. The example below uses ::after with negative z-index, but you can also add another div if ::after is being used as well.

    :root {
      --white: #fff;
      --gold: rgb(255, 215, 0);
      --bg-color: rgba(255, 0, 255, 0.2);
    }
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    html {
      font-size: 62.5%;
    }
    
    body {
      background-image: linear-gradient( rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url("https://images.pexels.com/photos/460635/pexels-photo-460635.jpeg?auto=compress&cs=tinysrgb&dpr=1");
      background-attachment: fixed;
      background-repeat: no-repeat;
      background-position: center center;
      background-size: cover;
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100vh;
      padding: 1rem;
    }
    
    .container {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 50%;
      height: 90vh;
      margin: 2rem;
      padding: 5rem;
      box-shadow: 0px 0px 3px var(--gold), 0px 0px 3px var(--gold);
      border: 0.1rem solid var(--gold);
      border-radius: 3rem;
      position: relative;
      &::after {
        z-index: -1;
        position: absolute;
        content: "";
        width: 100%;
        height: 100%;
        border-radius: inherit;
        backdrop-filter: blur(10px);
      }
      &::before {
        content: "";
        position: absolute;
        top: 0;
        left: 50%;
        translate: -50% 0%;
        width: 0.2rem;
        height: 100%;
        background-color: var(--gold);
      }
      .master-card {
        text-transform: capitalize;
        color: var(--white);
        width: 100%;
        aspect-ratio: 2/1;
        backdrop-filter: blur(10px);
        background-color: var(--bg-color);
        border: none;
        border-radius: inherit;
        padding: 2.5rem;
        box-shadow: inherit;
        display: flex;
        & .brand-bg {
          width: 10%;
          aspect-ratio: 1;
          border-radius: 50%;
        }
      }
    }
    <body>
      <div class="container">
        <div class="master-card">
          <div class="left-side">
            <div class="brand">
              <span class="brand-bg"></span><span class="brand-bg"></span>
              <h2>master card</h2>
            </div>
            <div class="info">
              <p>card number</p>
              <p>8050 5040 2030 3020</p>
            </div>
            <p>prem kumar shahi</p>
          </div>
          <div class="right-side"></div>
        </div>
      </div>
    </body>