Texte Transparent découpé en arrière-plan

est-il possible de faire un texte transparent découpé sur un fond effet comme celui de l'image suivante, avec CSS?

Il serait triste de perdre tout précieux SEO en raison d'images remplaçant le texte.

Transparent text cut out of background

j'ai d'abord pensé aux ombres mais je n'arrive pas à comprendre quoi que ce soit...

l'image est le fond du site, un absolu positionné <img> tag

75
demandé sur web-tiki 2012-12-18 16:24:09

11 réponses

C'est possible avec css3 mais il n'est pas supporté par tous les navigateurs

avec background-clip: text; vous pouvez utiliser un background pour le texte, mais vous devrez l'aligner avec le background de la page

body {
    background: url(http://www.color-hex.com/palettes/26323.png) repeat;
    margin:10px;
}
h1 { 
    background-color:#fff;
    overflow:hidden;
    display:inline-block; 
    padding:10px; 
    font-weight:bold;
    font-family:arial;
    color:transparent;
    font-size:200px;
}span { 
    background: url(http://www.color-hex.com/palettes/26323.png) -20px -20px repeat;
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text;
    display:block;
}
<h1><span>ABCDEFGHIKJ</span></h1>

http://jsfiddle.net/JGPuZ/1337 /

alignement automatique

avec un petit javascript vous pouvez aligner l'arrière-plan automatique:

$(document).ready(function(){
  var position = $("h1").position(); //Position of the header in the webpage
  var padding = 10; //Padding set to the header
  var left = position.left + padding;
  var top = position.top + padding;
  $("h1").find("span").css("background-position","-"+left+"px -"+top+"px"); 
});
body {
    background: url(http://www.color-hex.com/palettes/26323.png) repeat;
    margin:10px;
}
h1 { 
    background-color:#fff;
    overflow:hidden;
    display:inline-block; 
    padding:10px; 
    font-weight:bold;
    font-family:arial;
    color:transparent;
    font-size:200px;
}span { 
    background: url(http://www.color-hex.com/palettes/26323.png) -20px -20px repeat;
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text;
    display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1><span>ABCDEFGHIKJ</span></h1>
http://jsfiddle.net/JGPuZ/1336 /
40
répondu Gijs 2018-10-03 06:56:08

bien que cela soit possible avec CSS, une meilleure approche serait d'utiliser un SVG en ligne avec SVG masking . Cette approche présente certains avantages par rapport aux NSC :

  • Beaucoup une meilleure prise en charge du navigateur : IE10+, chrome, Firefox, safari...
  • cela n'a pas d'impact SEO que les araignées peuvent ramper contenu SVG ( Google indexes contenu SVG depuis 2010 )

CodePen Démo : SVG texte masque

transparent text clipping background

body,html{height:100%;margin:0;padding:0;}
body{
  background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg');
  background-size:cover;
  background-attachment:fixed;
}
svg{width:100%;}
<svg viewbox="0 0 100 60">
  <defs>
    <mask id="mask" x="0" y="0" width="100" height="50">
      <rect x="0" y="0" width="100" height="40" fill="#fff"/>
      <text text-anchor="middle" x="50" y="18" dy="1">SVG</text>
      <text text-anchor="middle" x="50" y="30" dy="1">Text mask</text>
    </mask>
  </defs>
  <rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill-opacity="0.5"/>    
</svg>

si vous visez à rendre le texte sélectionnable et consultable, vous devez l'inclure en dehors de la balise <defs> . L'exemple suivant montre une façon de faire que le maintien du texte transparent avec le <use> étiquette:

body,html{height:100%;margin:0;padding:0;}
body{
  background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg');
  background-size:cover;
  background-attachment:fixed;
}
svg{width:100%;}
<svg viewbox="0 0 100 60">
  <defs>
    <g id="text">
      <text text-anchor="middle" x="50" y="18" dy="1">SVG</text>
      <text text-anchor="middle" x="50" y="30" dy="1">Text mask</text>
    </g>
    <mask id="mask" x="0" y="0" width="100" height="50">
      <rect x="0" y="0" width="100" height="40" fill="#fff"/>
      <use xlink:href="#text" />
    </mask>
  </defs>
  <rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill-opacity="0.5"/>
  <use xlink:href="#text" mask="url(#mask)" />
</svg>
43
répondu web-tiki 2016-10-14 12:28:50

une façon qui fonctionne sur la plupart des navigateurs modernes (sauf ie, edge), bien que seulement avec un fond noir, est d'utiliser

background: black;
color: white;
mix-blend-mode: multiply;

dans votre élément de texte, puis mettre ce fond que vous voulez. Multiplier essentiellement les cartes du code de couleur 0-255 à 0-1 et multiplie ensuite que par ce qui est derrière elle, de sorte que le noir reste noir et blanc multiplie par 1 et devient effectivement transparent. http://codepen.io/nic_klaassen/full/adKqWX /

15
répondu Nic 2016-01-30 22:34:38

It is possible, mais jusqu'à présent uniquement avec les navigateurs Webkit (Chrome, Safari, Rockmelt, tout ce qui est basé sur le projet Chromium.)

le truc est d'avoir un élément dans le blanc qui a le même arrière-plan que le corps, puis utiliser -webkit- background-clip: text; sur l'élément intérieur qui signifie essentiellement" ne pas étendre l'arrière-plan au-delà du texte " et utiliser du texte transparent.

section
{
    background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg);
    width: 100%;
    height: 300px;
}

div
{
    background: rgba(255, 255, 255, 1);
    color: rgba(255, 255, 255, 0);

    width: 60%;
    heighT: 80%;
    margin: 0 auto;
    font-size: 60px;
    text-align: center;
}

p
{
    background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg);
    -webkit-background-clip: text;
}
​

http://jsfiddle.net/BWRsA/

3
répondu Kyle 2012-12-18 12:37:43

je suppose que vous pourriez obtenir quelque chose comme ça en utilisant background-clip , mais je ne l'ai pas encore testé.

voir cet exemple:

http://www.css3.info/wp-content/uploads/2008/03/webkit-backgroundcliptext_color.html

(Webkit seulement, je ne sais pas encore comment changer le fond noir en blanc)

2
répondu feeela 2012-12-18 12:37:08

vous pouvez utiliser une police inversée / négative / inversée et l'appliquer avec la règle font-face="…" CSS. Vous pourriez avoir à jouer avec l'espacement des lettres pour éviter de petits écarts blancs entre les lettres.

Si vous n'avez pas besoin d'une police spécifique, c'est simple. Téléchargez un sympathique, par exemple à partir de cette collection de polices inversées .

si vous avez besoin d'une police spécifique (par exemple," ouvrir Sans"), c'est difficile. Vous devez convertir votre police existante en une version inversée. Cela est possible manuellement avec le créateur de police, FontForge etc. mais bien sûr, nous voulons une solution automatisée. Je n'ai pas encore trouvé d'instructions pour cela, mais quelques conseils:

1
répondu tanius 2017-05-23 12:02:48

vous pouvez utiliser le Patternizer jQuery plugin de myadzel pour obtenir cet effet à travers les navigateurs. À l'heure actuelle, il n'y a pas de moyen de faire cela avec CSS.

vous utilisez Patternizer en ajoutant class="background-clip" aux éléments HTML où vous voulez que le texte soit peint comme un motif d'image, et spécifiez l'image dans un attribut supplémentaire data-pattern="…" . Voir la source de la Démo . Patternizer va créer une image SVG avec du texte rempli de motifs et le sous-tendre à L'élément HTML rendu transparent.

si, comme dans l'exemple d'image de la question, le motif de remplissage de texte devrait faire partie d'une image de fond qui s'étend au-delà de l'élément "modifié", je vois deux options (non testées, ma première préférée):

  • utilisez masquage au lieu d'une image de fond dans le SVG. comme dans web-tiki's réponse , à laquelle L'utilisation de Patternizer ajoutera encore la génération automatique de la SVG et un élément HTML invisible sur le dessus qui permet la sélection de texte et la copie.
  • ou utiliser l'alignement automatique de l'image de motif. peut être fait avec un code JavaScript similaire à celui de réponse de Gijs .
1
répondu tanius 2017-05-23 12:26:35

Demo Screenshot

j'avais besoin de faire un texte qui ressemble exactement à celui du post original, mais je ne pouvais pas le simuler en alignant les arrière-plans, parce qu'il y a de l'animation derrière l'élément. Personne ne semble avoir suggéré cela encore, alors voici ce que j'ai fait: (essayé de le rendre aussi facile à lire que possible.)

var el = document.body; //Parent Element. Text is centered inside.
var mainText = "THIS IS THE FIRST LINE"; //Header Text.
var subText = "THIS TEXT HAS A KNOCKOUT EFFECT"; //Knockout Text.
var fontF = "Roboto, Arial"; //Font to use.
var mSize = 42; //Text size.

//Centered text display:
var tBox = centeredDiv(el), txtMain = mkDiv(tBox, mainText), txtSub = mkDiv(tBox),
ts = tBox.style, stLen = textWidth(subText, fontF, mSize)+5; ts.color = "#fff";
ts.font = mSize+"pt "+fontF; ts.fontWeight = 100; txtSub.style.fontWeight = 400;

//Generate subtext SVG for knockout effect:
txtSub.innerHTML =
"<svg xmlns='http://www.w3.org/2000/svg' width='"+stLen+"px' height='"+(mSize+11)+"px' viewBox='0 0 "+stLen+" "+(mSize+11)+"'>"+
    "<rect x='0' y='0' width='100%' height='100%' fill='#fff' rx='4px' ry='4px' mask='url(#txtSubMask)'></rect>"+
    "<mask id='txtSubMask'>"+
        "<rect x='0' y='0' width='100%' height='100%' fill='#fff'></rect>"+
        "<text x='"+(stLen/2)+"' y='"+(mSize+6)+"' font='"+mSize+"pt "+fontF+"' text-anchor='middle' fill='#000'>"+subText+"</text>"+
    "</mask>"+
"</svg>";

//Relevant Helper Functions:
function centeredDiv(parent) {
    //Container:
    var d = document.createElement('div'), s = d.style;
    s.display = "table"; s.position = "relative"; s.zIndex = 999;
    s.top = s.left = 0; s.width = s.height = "100%";
    //Content Box:
    var k = document.createElement('div'), j = k.style;
    j.display = "table-cell"; j.verticalAlign = "middle";
    j.textAlign = "center"; d.appendChild(k);
    parent.appendChild(d); return k;
}
function mkDiv(parent, tCont) {
    var d = document.createElement('div');
    if(tCont) d.textContent = tCont;
    parent.appendChild(d); return d;
}
function textWidth(text, font, size) {
    var canvas = window.textWidthCanvas || (window.textWidthCanvas = document.createElement("canvas")),
    context = canvas.getContext("2d"); context.font = size+(typeof size=="string"?" ":"pt ")+font;
    return context.measureText(text).width;
}

jetez ça à votre fenêtre.chargez, réglez le fond du corps à ton image, et regarde la magie arriver!

1
répondu Pecacheu 2018-03-23 02:19:57

impossible avec CSS.

votre meilleur pari est simplement d'utiliser une image (probablement un PNG) et de placer un bon texte alt/titre dessus.

alternativement vous pouvez utiliser une portée ou un DIV et avoir l'image comme arrière-plan à cela avec votre texte que vous voulez à des fins de référencement à l'intérieur mais texte-l'indenter hors de l'écran.

0
répondu Billy Moat 2012-12-18 12:27:11

vient de mettre ce css

    .banner-sale-1 .title-box .title-overlay {
      font-weight: 900;
      overflow: hidden;
      margin: 0;
      padding-right: 10%;
      padding-left: 10%;
      text-transform: uppercase;
      color: #080404;
      background-color: rgba(255, 255, 255, .85);

      /* that css is the main think (mix-blend-mode: lighten;)*/
      mix-blend-mode: lighten;

    }
0
répondu Rashed 2017-09-22 06:29:32

je viens de découvrir une nouvelle façon de le faire tout en jouant, Je ne suis pas entièrement sûr comment cela fonctionne ( si quelqu'un d'autre veut expliquer s'il vous plaît faire ).

il semble fonctionner très bien, et ne nécessite pas de double fond ou JavaScript.

voici le code: JSFIDDLE

body {
  padding: 0;
  margin: 0;
}

div {
  background: url(http://www.color-hex.com/palettes/26323.png) repeat;
  width: 100vw;
  height: 100vh;
}

body::before {
  content: '$ALPHABET';
  left: 0;
  top: 0;
  position: absolute;
  color: #222;
  background-color: #fff;
  padding: 1rem;
  font-family: Arial;
  z-index: 1;
  mix-blend-mode: screen;
  font-weight: 800;
  font-size: 3rem;
  letter-spacing: 1rem;
}
<div></div>
0
répondu chbchb55 2018-01-10 06:30:44