DeadApe
DeadApe

Reputation: 505

CSS Mix-Blend-Mode on pseudo element

I want to give a mix blend mode to an element, but I don't want it to affect the text it contains. My idea was to use a pseudo element for this, so that the text is not affected. However, the mix-blend-mode effect does not take effect at all.

The effect should be applied to the .blue-column (the 100% height column) For better understanding here is a snippet:

https://codepen.io/ChickenCat/pen/YzGmaqx

:root {
  --col-width: 200px;
  --border-offset: 20px;
  --document-height: calc(933px - (var(--border-offset) * 2));
  --document-width: calc(595px - (var(--border-offset) * 2));
  --blue: rgb(0, 86, 164);
}

div.blue-column::before {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  content: '';
  background: linear-gradient(rgba(17, 64, 114, 1), rgba(22, 98, 173, 1));
  mix-blend-mode: multiply;
  z-index: -1;
}

.blue-column {
  --left-offset: 50px;
  color: white;
  position: absolute;
  left: var(--left-offset);
  top: var(--border-offset);
  right: calc(100% - (var(--left-offset) + 200px));
  bottom: -1px;
  padding-left: 15px;
  padding-right: 15px;
  z-index: 224;
}

div.header::after {
  position: absolute;
  top: 20px;
  left: 20px;
  height: 268px;
  width: 300px;
  content: '';
  background: linear-gradient(90deg, rgba(0, 52, 102, 1), rgba(0, 86, 164, 1));
  mix-blend-mode: multiply;
}

.container {
  position: relative;
  padding: var(--border-offset);
  border: 1px solid var(--blue);
  min-width: var(--document-width);
  max-width: var(--document-width);
  min-height: var(--document-height);
}

.header {
  width: 100%;
  height: 268px;
  margin: 0;
}

.header img {
  width: 100%;
  height: auto;
}

.body {
  padding-top: 20px;
  padding-left: 243px;
  padding-right: 20px;
  min-width: 276px;
  min-height: 608px;
}
<body>
  <div class="container">
    <div class="header">
      <img src="https://www.fillmurray.com/640/360">
    </div>
    <div class="body">
    </div>
    <div class="blue-column">
      <div class="logo">
      </div>
      <div class="column-content">
        This text should be white and not affected by the mix-blend-mode.
      </div>
    </div>
  </div>
</body>

I don't understand what the problem is here.

Upvotes: 1

Views: 3227

Answers (1)

Temani Afif
Temani Afif

Reputation: 273914

The issue is the z-index applied to blue-column that create a stacking context. You need to remove it and update the one of the image to make sure it stays below:

:root {
  --col-width: 200px;
  --border-offset: 20px;
  --document-height: calc(933px - (var(--border-offset) * 2));
  --document-width: calc(595px - (var(--border-offset) * 2));
  --blue: rgb(0, 86, 164);
}

div.blue-column::before {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  content: '';
  background: linear-gradient(rgba(17, 64, 114, 1), rgba(22, 98, 173, 1));
  mix-blend-mode: multiply;
  z-index: -1;
}

.blue-column {
  --left-offset: 50px;
  color: white;
  position: absolute;
  left: var(--left-offset);
  top: var(--border-offset);
  right: calc(100% - (var(--left-offset) + 200px));
  bottom: -1px;
  padding-left: 15px;
  padding-right: 15px;
}

div.header::after {
  position: absolute;
  top: 20px;
  left: 20px;
  height: 268px;
  width: 300px;
  content: '';
  background: linear-gradient(90deg, rgba(0, 52, 102, 1), rgba(0, 86, 164, 1));
  mix-blend-mode: multiply;
}

.container {
  position: relative;
  z-index:0;
  padding: var(--border-offset);
  border: 1px solid var(--blue);
  min-width: var(--document-width);
  max-width: var(--document-width);
  min-height: var(--document-height);
}

.header {
  width: 100%;
  height: 268px;
  margin: 0;
  position: relative;
  z-index: -1; /* HERE */
}

.header img {
  width: 100%;
  height: auto;
}

.body {
  padding-top: 20px;
  padding-left: 243px;
  padding-right: 20px;
  min-width: 276px;
  min-height: 608px;
}
<body>
  <div class="container">
    <div class="header">
      <img src="https://www.fillmurray.com/640/360">
    </div>
    <div class="body">
    </div>
    <div class="blue-column">
      <div class="logo">
      </div>
      <div class="column-content">
        This text should be white and not affected by the mix-blend-mode.
      </div>
    </div>
  </div>
</body>

Upvotes: 2

Related Questions