66

我正在寻找创建这样的效果但我的网站有一个动态的background-color。请注意,此示例使用白色叠加层,它不适用于不同的背景。

p {
    width: 300px;
    overflow: hidden;
    height: 50px;
    line-height: 50px;
    position: relative;
}
p:after {
    content: "";
    width: 100px;
    height: 50px;
    position: absolute;
    top: 0;
    right: 0;
    background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,1));
}

我希望做的是设置 CSS 不透明度渐变。这种工作,但代码太乱了。看看第二个例子,我可以在 jQuery 中实现它,但是有没有办法完全在 CSS 中做到这一点?

4

4 回答 4

105

你可以在 CSS 中做到这一点,但目前除了现代版本的 Chrome、Safari 和 Opera 之外的浏览器支持不多。Firefox 目前仅支持 SVG 蒙版。有关更多信息,请参阅Caniuse结果。

CSS:

p {
    color: red;
    -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, 
    from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
}

诀窍是指定一个掩码,该掩码本身就是一个以不可见结尾的渐变(通过 alpha 值)

查看具有纯色背景的演示,但您可以将其更改为您想要的任何内容。

演示

另请注意,所有常用的图像属性都可用于 mask-image

p  {
  color: red;
  font-size: 30px;
  -webkit-mask-image: linear-gradient(to left, rgba(0,0,0,1), rgba(0,0,0,0)), linear-gradient(to right, rgba(0,0,0,1), rgba(0,0,0,0));
  -webkit-mask-size: 100% 50%;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: left top, left bottom;
  }

div {
    background-color: lightblue;
}
<div><p>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text </p></div>

现在,Chrome、Firefox、Safari 和 Opera 支持另一种方法。

这个想法是使用

mix-blend-mode: hard-light;

如果颜色为灰色,则提供透明度。然后,元素上的灰色叠加层创建透明度

div {
  background-color: lightblue;
}

p {
  color: red;
  overflow: hidden;
  position: relative;
  width: 200px;
  mix-blend-mode: hard-light;
}

p::after {
  position: absolute;
  content: "";
  left: 0px;
  top: 0px;
  height: 100%;
  width: 100%;
  background: linear-gradient(transparent, gray);
  pointer-events: none;
}
<div><p>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text </p></div>

于 2013-03-25T21:02:34.680 回答
5

我认为从另一个问题链接到此处的“混乱”第二种方法可能是唯一的纯 CSS 解决方案。

如果您正在考虑使用 JavaScript,那么这是我对问题的解决方案:

演示:使用canvas元素淡化动画背景上的文本

这个想法是你的元素与文本和canvas元素是一个在另一个之上。您将文本保留在元素中(以便允许文本选择,这对于文本来说是不可能的canvas ),但使其完全透明(使用rgba(0,0,0,0), 以使文本在 IE8 和更早版本中可见 - 那是因为您没有RGBa支持并且不canvas支持 IE8 及更早版本)。

然后,您读取元素内的文本并使用相同的字体属性将其写在画布上,这样您在画布上写的每个字母都会覆盖元素中带有文本的相应字母。

canvas元素不支持多行文本,因此您必须将文本分解为单词,然后继续在测试行上添加单词,然后进行测量。如果测试线的宽度大于一条线的最大允许宽度(通过读取计算出的带有文本的元素的宽度来获得最大允许宽度),那么你将它写在画布上而不用添加最后一个单词,您将测试行重置为最后一个单词,并将写入下一行的 y 坐标增加一个行高(您也可以从元素与文本的计算样式中获得)。对于您编写的每一行,您还可以通过适当的步骤降低文本的不透明度(此步骤与每行的平均字符数成反比)。

在这种情况下,你不能轻易做的是证明文本的合理性。它可以完成,但它变得有点复杂,这意味着您必须计算每个步骤的宽度并逐字而不是逐行编写文本。

另外,请记住,如果您的文本容器在调整窗口大小时改变了宽度,那么您必须在每次调整大小时清除画布并在其上重新绘制文本。

好的,代码:

HTML

<article>
  <h1>Interacting Spiral Galaxies NGC 2207/ IC 2163</h1>
  <em class='timestamp'>February 4, 2004 09:00 AM</em>
  <section class='article-content' id='art-cntnt'>
    <canvas id='c' class='c'></canvas>In the direction of <!--and so on-->  
  </section>
</article>

CSS

html {
  background: url(moving.jpg) 0 0;
  background-size: 200%;
  font: 100%/1.3 Verdana, sans-serif;
  animation: ani 4s infinite linear;
}
article {
  width: 50em; /* tweak this ;) */
  padding: .5em;
  margin: 0 auto;
}
.article-content {
  position: relative;
  color: rgba(0,0,0,0);
  /* add slash at the end to check they superimpose *
  color: rgba(255,0,0,.5);/**/
}
.c {
  position: absolute;
  z-index: -1;
  top: 0; left: 0;
}
@keyframes ani { to { background-position: 100% 0; } }

JavaScript

var wrapText = function(ctxt, s, x, y, maxWidth, lineHeight) {
  var words = s.split(' '), line = '', 
      testLine, metrics, testWidth, alpha = 1, 
      step = .8*maxWidth/ctxt.measureText(s).width;

  for(var n = 0; n < words.length; n++) {
    testLine = line + words[n] + ' ';
    metrics = ctxt.measureText(testLine);
    testWidth = metrics.width;
    if(testWidth > maxWidth) {
      ctxt.fillStyle = 'rgba(0,0,0,'+alpha+')';
      alpha  -= step;
      ctxt.fillText(line, x, y);
      line = words[n] + ' ';
      y += lineHeight;
    }
    else line = testLine;
  }
  ctxt.fillStyle = 'rgba(0,0,0,'+alpha+')';
  alpha  -= step;
  ctxt.fillText(line, x, y);
  return y + lineHeight;
}

window.onload = function() {
  var c = document.getElementById('c'), 
      ac = document.getElementById('art-cntnt'), 
      /* use currentStyle for IE9 */
      styles = window.getComputedStyle(ac),
      ctxt = c.getContext('2d'), 
      w = parseInt(styles.width.split('px')[0], 10),
      h = parseInt(styles.height.split('px')[0], 10),
      maxWidth = w, 
      lineHeight = parseInt(styles.lineHeight.split('px')[0], 10), 
      x = 0, 
      y = parseInt(styles.fontSize.split('px')[0], 10), 
      text = ac.innerHTML.split('</canvas>')[1];

  c.width = w;
  c.height = h;
  ctxt.font = '1em Verdana, sans-serif';
  wrapText(ctxt, text, x, y, maxWidth, lineHeight);
};
于 2013-03-24T11:36:35.740 回答
4

除了使用@vals回答的css 掩码外,您还可以使用透明渐变背景并设置为.background-cliptext

创建适当的渐变:

background: linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 100%);

然后用文本剪辑背景:

background-clip: text;
color: transparent;

演示

https://jsfiddle.net/simonmysun/2h61Ljbn/4/

在 Windows 10 下的 Chrome 75 下测试。

支持的平台:

于 2020-09-14T09:23:15.090 回答
1

我们可以通过css来做到这一点。

body {
  background: #000;
  background-image: linear-gradient(90deg, rgba(255, 255, 255, .3) 0%, rgba(231, 231, 231, .3) 22.39%, rgba(209, 209, 209,  .3) 42.6%, rgba(182, 182, 182, .3) 79.19%, rgba(156, 156, 156, .3) 104.86%);
  
}
于 2020-09-23T06:57:52.000 回答