Testo trasparente tagliato fuori dallo sfondo


90

C'è un modo per rendere un testo trasparente ritagliato da un effetto di sfondo come quello nell'immagine seguente, con CSS?
Sarebbe triste perdere tutto il prezioso SEO a causa delle immagini che sostituiscono il testo.

Testo trasparente tagliato fuori dallo sfondo

Ho pensato prima alle ombre ma non riesco a capire niente ...

L'immagine è lo sfondo del sito, un <img>tag posizionato in modo assoluto


"perdere tutto il prezioso SEO a causa delle immagini che sostituiscono il testo." Esistono anche tecniche di sostituzione delle immagini esistenti, che sono ancora così amichevoli. BTW: in realtà anche lo sfondo dietro le lettere deve rimanere trasparente, che è il problema qui ...
feeela

sì, questa sarebbe un'ottima pratica, se possibile con CSS ...
Jessica Lingmn

Non vedo un motivo per cui <h1><img alt="Some Text" /></h1>sia meno SEO friendly di <h1>Some Text</h1>. Tradizionalmente, il problema con le immagini era che venivano semplicemente scaricate sulla pagina senza markup di supporto.
cimmanon

@cimmanon Sì, hai ragione. Probabilmente potrei usare le immagini senza perdere punti SEO, ma non puoi ancora selezionare il testo, cercare sulla pagina, il collegamento sarà più complicato e sarà molto più lavoro per aggiornare il testo ...: /
Love Dager

2
Solo così sai, Google è assolutamente fantastico con le tecniche di sostituzione delle immagini CSS: mezzoblue.com/archives/2008/05/05/image_replac
cimmanon

Risposte:


46

È possibile con css3 ma non è supportato in tutti i browser

Con clip di sfondo: testo; puoi usare uno sfondo per il testo, ma dovrai allinearlo con lo sfondo della pagina

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/


Allineamento automatico

Con un po 'di javascript puoi allineare lo sfondo automaticamente:

$(document).ready(function(){
  //Position of the header in the webpage
  var position = $("h1").position();
  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/


A voi persone siete TROPPO veloci: D
Gijs

Oh grande! Proverò l'allineamento automatico non appena arrivo a casa! Grazie! : D
Love Dager

devi modificare un po 'il codice, dipende dalla situazione, ora potrebbe entrare in conflitto con altri elementi e questo è stato scritto molto velocemente, se hai domande le ascolterò
Gijs

3
Per non ignorare la risposta, che è davvero una bella soluzione, ma background-clip:textè un'opzione solo Webkit, non standard. CSS3 non consente il textvalore per questo attributo ( vedi ).
tanius

1
Questa tecnica ti consente di vedere lo sfondo dell'elemento dove sarebbe normalmente il testo. Sto cercando un modo per vedere cosa c'è sotto l'elemento con il testo attraverso il punto in cui sarebbe normalmente il testo.
Vince

49

Sebbene ciò sia possibile con i CSS, un approccio migliore sarebbe quello di utilizzare un SVG in linea con mascheramento SVG . Questo approccio presenta alcuni vantaggi rispetto ai CSS:

  • Supporto browser molto migliore : IE10 +, chrome, Firefox, safari ...
  • Ciò non influisce sulla SEO poiché gli spider possono eseguire la scansione dei contenuti SVG ( Google indicizza i contenuti SVG dal 2010 )

CodePen Demo: maschera di testo SVG

sfondo di ritaglio di testo trasparente

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>

Se miri a rendere il testo selezionabile e ricercabile, devi includerlo al di fuori del <defs>tag. L'esempio seguente mostra un modo per farlo mantenendo il testo trasparente con il <use>tag:

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>


2
Questa sembra essere l'unica soluzione che oggi funziona su tutti i browser: IE11, FF, Chrome, Safari. E non ha bisogno dell'immagine come sfondo come molte altre soluzioni fornite al problema in tutto il web.
Timo Kähkönen

1
Ispirato da questa risposta, ho creato un'animazione dei fotogrammi chiave, in cui ruota il testo SVG trasparente su un rettangolo arrotondato bianco. Lo sfondo ha testo e immagini. Vai a vedere: jsbin.com/nipuqu/3 (Il campionato del mondo sta arrivando :))
Timo Kähkönen

2
Bella soluzione, ma poiché "seleziona il testo e cerca nella pagina" sembra essere nei requisiti dell'OP, potresti voler includere l' <text>esterno della <defs>parte. (btw non sono sicuro di come i crawler SE gestiscono i contenuti SVG nelle definizioni). Ecco un modo per mantenere ciò che vuole OP, con un orribile exploit di bug FF: jsfiddle.net/tfneqxxb
Kaiido

E se il testo fosse dinamico? Il dosaggio non regola automaticamente la larghezza.
Imran Bughio

1
@ImranBughio no, non lo fa. Il testo SVG non si comporta come un semplice testo HTML. Devi posizionarlo. Per ulteriori informazioni vedere qui
web-tiki

16

Un modo che funziona sulla maggior parte dei browser moderni (eccetto cioè edge), sebbene solo con uno sfondo nero, è quello di utilizzare

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

nel tuo elemento di testo e poi metti lo sfondo che vuoi dietro. Moltiplica fondamentalmente mappa il codice colore 0-255 su 0-1 e poi lo moltiplica per tutto ciò che c'è dietro, quindi il nero rimane nero e il bianco si moltiplica per 1 e diventa effettivamente trasparente. http://codepen.io/nic_klaassen/full/adKqWX/


3
Per sfondo bianco con colore nero utilizzare color-dodge, lighteno screensumix-blend-mode
Imran Bughio

3

Si è possibile, ma finora solo con i browser Webkit base (Chrome, Safari, RockMelt, nulla sulla base del progetto Chromium.)

Il trucco è avere un elemento all'interno di quello bianco che ha lo stesso sfondo del corpo, quindi utilizzare -webkit- background-clip: text;sull'elemento interno che in pratica significa "non estendere lo sfondo oltre il testo" e utilizzare testo trasparente.

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/


Fantastico trucco! Ma ora per allineare tutto correttamente sarà una cagna .. -.-
Love Dager

Sì, questo è un altro problema con esso. È ancora in fase di sviluppo e spero sinceramente che presto vedremo qualcosa di simile! :)
Kyle

Inoltre, puoi sempre sovrapporre il testo trasparente dell'immagine, in modo che sia ancora selezionabile. Ma sono sicuro che sia una cattiva pratica per il SEO .. Messaggi / parole chiave nascosti e simili.
Kyle

Sono sicuro che sia molto carino nei browser Webkit, ma per tutti gli altri è una scatola bianca semitrasparente sopra un po 'di erba.
cimmanon

1
Ah, andiamo ragazzi ... Sì, ho intenzione di usarlo in produzione. Ma ovviamente non senza un ripiego! @cimmanon
Love Dager


2

Ho appena scoperto un nuovo modo per farlo mentre scherzavo, non sono del tutto sicuro di come funzioni (se qualcun altro vuole spiegare per favore fallo).

Sembra funzionare molto bene e non richiede doppi sfondi o JavaScript.

Ecco il codice: 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>


1

Puoi utilizzare un carattere invertito / negativo / inverso e applicarlo con la font-face="…"regola CSS. Potrebbe essere necessario giocare con la spaziatura delle lettere per evitare piccoli spazi bianchi tra le lettere.

Se non hai bisogno di un font specifico, è semplice. Scarica uno simpatico, ad esempio da questa raccolta di caratteri invertiti .

Se hai bisogno di un carattere specifico (ad esempio, "Open Sans"), è difficile. Devi convertire il tuo font esistente in una versione invertita. Questo è possibile manualmente con Font Creator, FontForge ecc., Ma ovviamente vogliamo una soluzione automatizzata. Non sono ancora riuscito a trovare le istruzioni per questo, ma alcuni suggerimenti:


1

È possibile utilizzare il plug-in jQuery Patternizer di myadzel per ottenere questo effetto su tutti i browser. Al momento, non esiste un modo cross-browser per farlo con solo CSS.

Puoi utilizzare Patternizer aggiungendo class="background-clip"agli elementi HTML in cui desideri che il testo venga dipinto come un motivo di immagine e specificare l'immagine in un data-pattern="…"attributo aggiuntivo . Vedi la fonte della demo . Patternizer creerà un'immagine SVG con testo pieno di pattern e la sovrapporrà all'elemento HTML renderizzato in modo trasparente.

Se, come nell'immagine di esempio della domanda, il motivo di riempimento del testo dovesse far parte di un'immagine di sfondo che si estende oltre l'elemento "modellato", vedo due opzioni (non testata, la mia preferita per prima):

  • Usa il mascheramento invece di un'immagine di sfondo nell'SVG. Come nella risposta di web-tiki , a cui l'utilizzo di Patternizer aggiungerà comunque la generazione automatica dell'SVG e un elemento HTML invisibile in cima che consente la selezione e la copia del testo.
  • Oppure usa l'allineamento automatico dell'immagine del motivo. Può essere fatto con codice JavaScript simile a quello nella risposta di Gijs .

1

metti solo quel 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;

    }

1

Screenshot demo

Avevo bisogno di creare un testo che fosse esattamente come nel post originale, ma non potevo semplicemente simularlo allineando gli sfondi, perché c'è un'animazione dietro l'elemento. Nessuno sembra averlo suggerito ancora, quindi ecco cosa ho fatto: (Ho cercato di renderlo il più facile da leggere possibile.)

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

Mettilo nella tua finestra, scarica, imposta lo sfondo del corpo sulla tua immagine e guarda la magia accadere!


0

Non è possibile con i CSS solo ora, temo.

La soluzione migliore è usare semplicemente un'immagine (probabilmente un PNG) e inserire un buon testo alt / titolo su di essa.

In alternativa puoi usare uno SPAN o un DIV e avere l'immagine come sfondo di quello con il tuo testo che desideri per scopi SEO al suo interno ma con un rientro del testo fuori dallo schermo.


Si hai ragione. Probabilmente potrei usare le immagini senza perdere punti SEO, ma non puoi ancora selezionare il testo, cercare sulla pagina, il collegamento sarà più complicato e sarà molto più lavoro per aggiornare il testo ...: /
Love Dager

0

mix-blend-mode è anche una possibilità per quel tipo di effetto.

La mix-blend-modeproprietà CSS imposta il modo in cui il contenuto di un elemento deve fondersi con il contenuto del genitore dell'elemento e con lo sfondo dell'elemento.

h1 {
background:white;
mix-blend-mode:screen;

/* demo purpose from here */
padding:0.25em;
mix-blend-mode:screen;
}


html {
background:url(https://i.picsum.photos/id/1069/367/267.jpg?hmac=w5sk7UQ6HGlaOVQ494mSfIe902cxlel1BfGUBpEYoRw)center / cover ;
min-height:100vh;
display:flex;
}
body {margin:auto;}
h1:hover {border:dashed 10px white;background-clip:content-box;box-shadow:inset 0 0 0 2px #fff, 0 0 0 2px #fff}
<h1>ABCDEFGHIJKLMNOPQRSTUVWXYZ</h1>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.