CSS3-dekkingsgradiënt?

Ik wil een effect creëren zoals dit, maar mijn website heeft een dynamische background-color. Merk op dat dit voorbeeld een witte overlay gebruikt, die niet werkt met verschillende achtergronden.

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

Wat ik hoopte te doen, was een CSS-dekkingsgradiënt instellen. Ditwerkt wel, maar de code is te rommelig. Als ik naar dit tweede voorbeeld kijk, zou ik het in jQuery kunnen implementeren, maar is er een manier om dit volledig in CSS te doen?


Antwoord 1, autoriteit 100%

Je kunt het in CSS doen, maar er is momenteel niet veel ondersteuning in andere browsers dan moderne versies van Chrome, Safari en Opera. Firefox ondersteunt momenteel alleen SVG-maskers. Bekijk de Caniuseresultaten voor meer informatie.

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

De truc is om een masker op te geven dat zelf een verloop is dat eindigt als onzichtbaar (door de alfawaarde)

Bekijk een demo met een solide achtergrond, maar je kunt dit veranderen in wat je maar wilt.

DEMO

Merk ook op dat alle gebruikelijke -afbeeldingen -eigenschappen beschikbaar zijn voor MASK-afbeelding

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>

Antwoord 2, Autoriteit 5%

Ik denk dat de “rommelige” tweede methode, die is gekoppeld aan een andere vraag hier kan de enige pure CSS-oplossing zijn.

Als u denkt aan het gebruik van JavaScript, dan was dit mijn oplossing voor het probleem:

Demo: met behulp van een canvaselement om tekst te vervagen tegen een Geanimeerde achtergrond

Het idee is dat uw element met de tekst en de canvaselement
zijn er een op de top van de andere. Je houdt de tekst in je element (in
om tekstselectie toe te staan, wat niet mogelijk is met canvas
tekst), maar maak het volledig transparant (met rgba(0,0,0,0), in
om de tekst zichtbaar te maken in IE8 en ouder – dat komt omdat u
geen RGBa-ondersteuning en geen canvas-ondersteuning hebben in IE8 en ouder).

Je leest dan de tekst in je element en schrijft deze op het canvas
met dezelfde lettertype-eigenschappen, zodat elke letter die u op de schrijft
canvas staat boven de corresponderende letter in het element met de tekst.

Het canvaselement ondersteunt geen tekst met meerdere regels, dus u moet
om de tekst in woorden op te splitsen en vervolgens woorden op een testregel toe te voegen
die je dan meet. Als de breedte van de testlijn groter is
dan de maximaal toegestane breedte die je voor een lijn kunt hebben (je snapt dat
maximaal toegestane breedte door de berekende breedte van het element te lezen
met de tekst), dan schrijf je het op het canvas zonder het laatste woord
toegevoegd, stelt u de testregel opnieuw in als dat laatste woord en verhoogt u
de y-coördinaat waarop de volgende regel met één regelhoogte moet worden geschreven
(die je ook krijgt van de berekende stijlen van je element met de
tekst). Met elke regel die u schrijft, verlaagt u ook de dekking van
de tekst met een passende stap (deze stap is omgekeerd)
evenredig met het gemiddelde aantal tekens per regel).

Wat u in dit geval niet gemakkelijk kunt doen, is tekst uitvullen. Het kan zijn
gedaan, maar het wordt een beetje ingewikkelder, wat betekent dat je zou hebben
om te berekenen hoe breed elke stap moet zijn en het tekstwoord te schrijven met
woord in plaats van regel voor regel.

Houd er ook rekening mee dat als uw tekstcontainer van breedte verandert terwijl u
verander het formaat van het venster, dan moet je het canvas leegmaken en de . opnieuw tekenen
tekst erop bij elke formaatwijziging.

OK, de code:

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

Antwoord 3, autoriteit 4%

Behalve het gebruik van css-maskerbeantwoord door @vals, u kunt ook een achtergrond met een transparant verloop gebruiken en background-clipinstellen op text.

Maak het juiste verloop:

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

Knip dan het achtergrondgeluid met tekst:

background-clip: text;
color: transparent;

Demo

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

Getest onder Chrome 75 onder Windows 10.

Ondersteunde platforms:


Antwoord 4

We kunnen het doen door css like.

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

Other episodes