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 不透明度グラデーションを設定することでした。この種の動作はしますが、コードが乱雑すぎます。この 2 番目の例を見ると、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)));
}

秘訣は、それ自体が非表示として終了するグラデーションであるマスクを指定することです(アルファ値を介して)

背景がはっきりしているデモをご覧ください。ただし、これは好きなように変更できます。

デモ

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

ここで別の質問からリンクされている「乱雑な」2番目の方法が、唯一の純粋なCSSソリューションである可能性があると思います。

JavaScript の使用を検討している場合、これが問題に対する私の解決策でした。

デモ:canvas要素を使用して、アニメーション化された背景に対してテキストをフェードする

アイデアは、テキストを含む要素とcanvas要素が重なり合っているということです。要素にテキストを保持します (テキストでは不可能なテキスト選択を可能にするためcanvas ) が、完全に透明にしrgba(0,0,0,0)ます (IE8 以前でテキストを表示できるようにするため、RGBaサポートがないためです)。 canvasIE8 以前ではサポートされていません)。

次に、要素内のテキストを読み取り、同じフォント プロパティを使用してキャンバスに書き込みます。これにより、キャンバスに書き込む各文字が、テキストを含む要素内の対応する文字の上に表示されます。

このcanvas要素は複数行のテキストをサポートしていないため、テキストを単語に分割し、テスト行に単語を追加し続けて測定する必要があります。テスト行の幅が行の最大許容幅よりも大きい場合 (要素の計算された幅をテキストで読み取ることにより、その最大許容幅を取得します)、それをキャンバスに書き込みます。最後の単語が追加されたら、テスト行をその最後の単語になるようにリセットし、次の行を書き込む y 座標を 1 行の高さで増やします (これは、テキストを含む要素の計算されたスタイルからも得られます)。書く行ごとに、適切なステップでテキストの不透明度も減らします (このステップは、1 行あたりの平均文字数に反比例します)。

この場合簡単にできないことは、テキストを正当化することです。それは可能ですが、もう少し複雑になります。つまり、各ステップの幅を計算し、行ごとではなく単語ごとにテキストを記述する必要があります。

また、ウィンドウのサイズを変更するときにテキスト コンテナの幅が変わる場合は、キャンバスをクリアして、サイズを変更するたびにテキストを再描画する必要があることに注意してください。

OK、コード:

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 に答える