【问题标题】:CSS3 opacity gradient?CSS3不透明度渐变?
【发布时间】:2013-03-13 21:26:00
【问题描述】:

我希望创建一个效果like this,但我的网站有一个动态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 不透明度渐变。 This 有点工作,但代码太乱了。看看第二个例子,我可以用 jQuery 来实现它,但是有没有办法完全用 CSS 来实现呢?

【问题讨论】:

  • 我的用例没有动态背景,所以谢谢谢谢谢谢你的“喜欢这个”链接。这正是我所需要的! (垂直除外:))

标签: css


【解决方案1】:

我认为从another question here 链接的“混乱”第二种方法可能是唯一的纯 CSS 解决方案。

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

demo: using a canvas element to fade text against an animated background

这个想法是你的元素与文本和canvas 元素 是一个在另一个之上。您将文本保留在元素中(在 为了允许文本选择,canvas 无法做到这一点 文本),但使其完全透明(使用rgba(0,0,0,0),在 为了让文本在 IE8 和更早版本中可见 - 那是因为你 在 IE8 和更早版本中不支持 RGBa 和不支持 canvas)。

然后您读取元素内的文本并将其写在画布上 具有相同的字体属性,这样你写的每个字母 画布是在元素中对应的字母与文本。

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);
};

【讨论】:

  • 非常感谢您提供的信息。你的例子很酷。但这比我的项目需要付出更多的努力;-) 我希望有一些我不知道的内置 CSS 技巧。我试图做 jquery 实现,但我需要知道背景颜色。我在我的网站中使用 jquery themeroller 有许多可切换的主题,所以我不知道文本的前景色或背景色。所以您的示例将文本设置为黑色。
  • 我注意到了一个有趣的错误(功能?);当您突出显示小的描述文本时,它会调整大小。
【解决方案2】:

您可以在 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 值)

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

DEMO

还要注意,所有常用的 image 属性都可用于 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;
}
&lt;div&gt;&lt;p&gt;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 &lt;/p&gt;&lt;/div&gt;

现在,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;
}
&lt;div&gt;&lt;p&gt;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 &lt;/p&gt;&lt;/div&gt;

【讨论】:

  • Firefox 的 -webkit-mask-image 是否有等价物?
  • @suga_shane 为大多数现代浏览器添加了等效性。
  • 我在 Firefox 中遇到了第二种方法的问题 - 它显示了一些故障。最后我只是使用 :after 与线性渐变(从透明到白色)作为背景。
  • 原来的答案是2013年的。有没有关于浏览器支持的更新?
  • @MikhailKhazov 最简单的解决方案是为渐变设置初始步骤。 - 保持它不透明直到非 0 百分比。一个更困难的方法,但有更多不同的可能性,是设置多个掩码,我添加了一个 sn-p 显示这种可能性
【解决方案3】:

除了使用@vals回答的css mask外,您还可以使用透明渐变背景并将background-clip设置为text

创建适当的渐变:

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 下测试。

支持的平台:

【讨论】:

    【解决方案4】:

    我们可以通过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%);
      
    }
    

    【讨论】:

    • 我认为您误解了这个问题。作者想要在文本上进行渐变。
    猜你喜欢
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 2015-09-20
    • 1970-01-01
    • 2011-02-07
    • 2020-04-27
    • 2016-04-25
    相关资源
    最近更新 更多