Search code examples
htmlcsspositionz-indexclip-path

How to fix clip-path altering the z-index stacking order of page?


https://jsfiddle.net/9gqbne6j/1/

<div class="row">
  <div class="row-inner">
    <div class="row-background"><div class="row-background-inner">
    
    </div></div>
    <div class="row-content">
    <section class="first-section">
          <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Circle-icons-flame.svg/1024px-Circle-icons-flame.svg.png" class="icon">
      <h2 class="section-heading">
      Some Heading
      </h2>
      <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ullamcorper justo a neque mollis iaculis.
      </p>
      <button class="read-more">Read More</button>
      </section>
    </div>
  </div>
</div>
html,
body {
  background-color: grey;
  color: white;
  position: relative;
}

*, *::before, *::after {
  box-sizing: border-box;
}

body::after {
  content: "";
  position: absolute;
  background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMjAuNSA2MDQwLjEiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDojMjMxZjIwO29wYWNpdHk6MC43O308L3N0eWxlPjwvZGVmcz48cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iMzIwLjUgMjQ0OC45MiAwIDYwNDAuMSAwIDYwNDAuMSAwIDAgMzIwLjUgMjQ0OC45MiIvPjwvc3ZnPg==);
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-repeat: no-repeat;
  background-size: 29.66%;
  background-position: right 3% top 40%;
}

.row-inner {
  position: relative;
  clip-path: polygon(-38% 50%,128% 110%,128% -10%)
}

.row-background-inner {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: url(https://i0.wp.com/www.wagpets.com/wp-content/uploads/2020/04/pembroke-welsh-corgi-appearance-and-vital-stats.jpeg?resize=1429%2C956&ssl=1);
  background-size: cover;
  background-repeat: no-repeat;
}

.row-content {
  position: relative;
  display: flex;
  justify-content: flex-end;
}

.first-section {
    padding: 2em 1em;
   display: flex;
   flex-flow: column;
   align-items: center;
   max-width: 33%;
   z-index: 9;
}

.section-heading {
  margin-bottom: 0.5em;
}

.icon {
  width: 50px;
  height: 50px;
}

.read-more {
  padding: 0.5em 1em;
  background-color: steelblue;
  color: white;
  border: 0;
}

Above is a minimal example of the issue I'm trying to fix. It's pulled from a much larger page, so I was hoping it'd be possible to fix via CSS rather than completely reorganising the DOM.

So, the .row-inner element has a clip-path on it. If the clip-path is enabled, then the .first-section text appears underneath the body::after background, but if the clip-path is disabled, then the text appears above the body::after background.

Is there a way to get the .first-section to appear above the body::after background with clip-path still enabled?

I've read from previous questions that it has something to do with clip-path altering the render order of the elements, but I couldn't find a solution for the issue in this case that I haven't tried already.

If it's not possible to fix via CSS alone, what would be the most minimal way to re-order the DOM to fix it?

Thanks


Solution

  • Rule clip-path needs to be assigned to more child element.

    Specify this rule for .row-background-inner by removing it from .row-inner.

    html,
    body {
        background-color: grey;
        color: white;
        position: relative;
    }
    
    *,
    *::before,
    *::after {
        box-sizing: border-box;
    }
    
    body::after {
        content: "";
        position: absolute;
        background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMjAuNSA2MDQwLjEiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDojMjMxZjIwO29wYWNpdHk6MC43O308L3N0eWxlPjwvZGVmcz48cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iMzIwLjUgMjQ0OC45MiAwIDYwNDAuMSAwIDYwNDAuMSAwIDAgMzIwLjUgMjQ0OC45MiIvPjwvc3ZnPg==);
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-repeat: no-repeat;
        background-size: 29.66%;
        background-position: right 3% top 40%;
    }
    
    .row-inner {
        position: relative;
        /*clip-path: polygon(-38% 50%,128% 110%,128% -10%);*/
    }
    
    .row-background-inner {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-image: url(https://i0.wp.com/www.wagpets.com/wp-content/uploads/2020/04/pembroke-welsh-corgi-appearance-and-vital-stats.jpeg?resize=1429%2C956&ssl=1);
        background-size: cover;
        background-repeat: no-repeat;
        clip-path: polygon(-38% 50%, 128% 110%, 128% -10%);
    }
    
    .row-content {
        position: relative;
        display: flex;
        justify-content: flex-end;
    }
    
    .first-section {
        padding: 2em 1em;
        display: flex;
        flex-flow: column;
        align-items: center;
        max-width: 33%;
        z-index: 9;
    }
    
    .section-heading {
        margin-bottom: 0.5em;
    }
    
    .icon {
        width: 50px;
        height: 50px;
    }
    
    .read-more {
        padding: 0.5em 1em;
        background-color: steelblue;
        color: white;
        border: 0;
    }
    <div class="row">
        <div class="row-inner">
            <div class="row-background"><div class="row-background-inner"></div></div>
            <div class="row-content">
                <section class="first-section">
                    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Circle-icons-flame.svg/1024px-Circle-icons-flame.svg.png" class="icon" />
                    <h2 class="section-heading">
                        Some Heading
                    </h2>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ullamcorper justo a neque mollis iaculis.
                    </p>
                    <button class="read-more">Read More</button>
                </section>
            </div>
        </div>
    </div>