伪元素上的 CSS Mix-Blend-Mode

问题描述

我想为元素提供混合模式,但我不希望它影响它包含的文本。 我的想法是为此使用伪元素,以便文本不受影响。但是,mix-blend-mode 效果根本不生效。

效果应该应用到 .blue-column(100% 高度的列) 为了更好地理解这里是一个片段:

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,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>

我不明白这里有什么问题。

解决方法

问题是应用于创建堆叠上下文的 blue-column 的 z-index。您需要将其删除并更新其中一张图片以确保其保持在下方:

: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,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>