在背景重叠部分将文本颜色从黑色改为白色

13

我有一个使用背景渐变颜色定位为absolute的div。我想要在滚动文字时将其更改为白色。

我目前正在使用'mix-blend-mode'属性来实现这一点,但我找不到任何能将文本从黑色变成白色的设置。有人做过这个吗?或者你有什么诀窍可以做到吗?

滚动时更改图片文字

.bg-container {
  position: fixed;
  top: -30px;
  left: 0;
  width: 100px;
  height: 100px;
}

.gradient-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  height: 200px;
  background-image: linear-gradient(to bottom, rgb(100, 182, 240) 15%, rgb(81, 155, 244));
  transform: skewY(-15deg);
}

.scroll-content {
  position: absolute;
  top: 50px;
}

.scroll-content p {
  color: #000;
  mix-blend-mode: overlay;
}

/*hack for iOS*/
.scroll-content p:after{
    content: '\200c'
}
<div class="bg-container">
  <div class="gradient-background">
    &nbsp;
  </div>
</div>
<div class="scroll-content">
  <p> abc 1 </p>
  <p> abc 2 </p>
  <p> abc 3 </p>
  <p> abc 4 </p>
  <p> abc 5 </p>
  <p> abc 6 </p>
  <p> abc 7 </p>
  <p> abc 8 </p>
  <p> abc 9 </p>
  <p> abc 10 </p>
  <p> abc 11 </p>
  <p> abc 12 </p>
  <p> abc 13 </p>
  <p> abc 14 </p>
  <p> abc 15 </p>
  <p> abc 16 </p>
  <p> abc 17 </p>
  <p> abc 18 </p>
  <p> abc 19 </p>
</div>

*编辑1:更改了我的代码示例。背景渐变不仅是矩形div。它有点倾斜,这就是使它如此困难的原因。 因此,在边界处,文本变成了两种颜色。

*编辑2以获得更清晰表达:当文本位于白色背景上方时,我希望其为黑色(#000实心),当文本位于渐变/图像上方时,我希望其为白色(#FFF实心)。 我的内容是可滚动文本,如代码示例所示。

*编辑3:iOS Safari不兼容,除非您执行以下技巧。将零宽度空格&#8203;添加到每个文本元素中,以使其正常工作。 这可以通过CSS属性轻松完成,如我所示,已在CSS标记中添加。


你应该能够将纯色转换为渐变色(例如这个例子:https://dev59.com/aFQJ5IYBdhLWcg3wuob7#53232693)...如果遇到问题,请告诉我。 - Temani Afif
嘿,Temani,如果我想要达到这个效果,我可以做到,但我不想要。当文本在白色背景上方时,我希望它是黑色(#000 solid),而当文本在渐变/图像上方时,我希望它是白色(#FFF solid)。我的内容也是可滚动的,因此任何假定绝对位置的解决方案都行不通。 - playingwithnumbers
3个回答

6

您可以使用渐变色来给文本上色。诀窍是让这个渐变色与您的形状相似(在形状边缘具有相同的程度和颜色变化)。由于您的倾斜元素是固定的,因此您需要使渐变色也固定以创建文本滚动的 神奇 效果:

.gradient-background {
  position: fixed;
  top: 0;
  left: 0;
  width: 100px;
  height: 200px;
  background-image: linear-gradient(to bottom, rgb(100, 182, 240) 15%, rgb(81, 155, 244));
  transform: skewY(-15deg);
  transform-origin:left;
}

.scroll-content {
  position: absolute;
  top: 50px;
  /* 165deg = 180deg - 15deg   */
  background: linear-gradient(165deg, #fff 195px,#000 195px) fixed;
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
<div class="gradient-background">
</div>
<div class="scroll-content">
  <p> abc 1 </p>
  <p> abc 2 </p>
  <p> abc 3 </p>
  <p> abc 4 </p>
  <p> abc 5 </p>
  <p> abc 6 </p>
  <p> abc 7 </p>
  <p> abc 8 </p>
  <p> abc 9 </p>
  <p> abc 10 </p>
  <p> abc 11 </p>
  <p> abc 12 </p>
  <p> abc 13 </p>
  <p> abc 14 </p>
  <p> abc 15 </p>
  <p> abc 16 </p>
  <p> abc 17 </p>
  <p> abc 18 </p>
  <p> abc 19 </p>
</div>


啊,当你说在评论中给文本渐变上色时,我以为你是指像我的背景渐变一样,然后使用反转混合模式属性,这将得到白色,但使黑色文本成为我的渐变颜色。这是一个很好的解决方案!谢谢!现在你这么说,听起来很明显。 - playingwithnumbers
@playingwithnumbers 是的,完全正确;)但我承认这并不是很简单,特别是因为还有固定功能,所以我重新打开并添加了一个答案。 - Temani Afif
你真是救星啊。这个问题让我快疯了!我差点就要改变页面的样式了。 - playingwithnumbers
@playingwithnumbers 顺便提醒一下,注意支持情况:https://developer.mozilla.org/en-US/docs/Web/CSS/background-clip#Browser_compatibility .. 我可能稍后会添加另一种方式 ;) - Temani Afif
哇,太棒了,我的朋友。 - doğukan
只是额外的一点说明。这在IOS Safari上不起作用。除非您查看此线程:https://dev59.com/IFcP5IYBdhLWcg3wAmKy 您必须向所有p元素添加一个零宽度空格'​',以使其适用于iOS Safari... - playingwithnumbers

2
你可以使用一些JavaScript来实现这个功能:

最初的回答:

$(document).ready(function() {
  $(window).scroll(function() {
    var bgHeight = $('.bg-container').height();
    var scroll = $(window).scrollTop();
    $('.scroll-content p').each((i, el) => {
      var pPos = $(el).offset().top;
      var pHeight = $(el).height();

      if (pPos < (scroll - pHeight + bgHeight)) {
        $(el).removeClass('black');
        $(el).addClass('white');
      } else {
        $(el).addClass('black');
        $(el).removeClass('white');
      }
    });
  })
})
.bg-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100px;
  height: 100px;
}

.gradient-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  height: 100px;
  background-image: linear-gradient(to bottom, rgb(1, 55, 124) 15%, rgb(81, 155, 244));
}

.scroll-content {
  position: relative;
  z-index: 99999;
  font-family: neuzeit-grotesk, sans-serif;
  font-weight: 700;
}

.white {
  color: #fff;
}

.black {
  color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bg-container">
  <div class="gradient-background">
    &nbsp;
  </div>
</div>
<br/><br/><br/><br/><br/><br/>
<div class="scroll-content menu_black">
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
  <p>asdf</p>
</div>


抱歉,我重新制作了我的示例以匹配我的图片。边界不是水平的,实际上是对角线的,因此在边界处文本变成了两种颜色。如果它是水平的,这肯定会起作用。 - playingwithnumbers
请问您能解释一下这段代码的作用吗?(pPos < (scroll - pHeight + bgHeight)) - Nithya Rajan
@BearNithi <p/> 的位置小于(当前滚动值减去 <p/> 高度加上渐变高度)。 - Miroslav Glamuzina

1
你可以使用JavaScript进行测量,并对落在你想要的范围内的标签应用样式,但你也可以做一些非常简单的事情来使文本易读(这属于“我能做的一些其他技巧”):
.scroll-content {
  text-shadow: 0 0 3px white;
}

这只会在蓝色背景上显示,并在白色背景上消失。不过,这取决于您想要实现的效果。即使使用JavaScript实现,您可能仍然考虑为无JS用户提供渐进增强

文本不会变成白色,这是OP要求的。它只会在渐变下变得可见。 - Sayan J. Das
1
没错,这就是我为什么说它只是一个相关技巧的广泛类别下的一部分——如果他主要担心可读性等问题。 - user241244
已添加JS实现,但在移动设备上效果未知。将尽快进行测试。 - user241244
没时间测试JS,而且它几乎只是伪代码,所以删除了那部分--但如果有人想尝试或使用它作为起点,它在编辑历史记录中。 - user241244
欣赏这个想法,但不是我想要实现的效果。我不介意使用JS解决方案,但我不认为会有这样的解决方案存在。我认为解决方案将是一系列滤镜和混合背景模式。也许我需要复制文本内容并进行叠加。也许我需要对某些div应用isolation: isolate属性。仍然没有弄清楚 :( - playingwithnumbers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接