Transparenter Text aus dem Hintergrund ausgeschnitten

90

Gibt es eine Möglichkeit , mit CSS einen transparenten Text aus einem Hintergrundeffekt wie dem im folgenden Bild herauszuschneiden ?
Es wäre traurig, alle wertvollen SEOs zu verlieren, weil Bilder Text ersetzen.

Transparenter Text aus dem Hintergrund ausgeschnitten

Ich habe zuerst an Schatten gedacht, aber ich kann nichts herausfinden ...

Das Bild ist der Site-Hintergrund, ein absolut positioniertes <img>Tag

Liebes-Dager
quelle
"Verlieren Sie alle wertvollen SEOs, weil Bilder Text ersetzen." Es gibt auch Bildersatztechniken, die immer noch SO freundlich sind. Übrigens: Eigentlich muss auch der Hintergrund hinter den Briefen transparent bleiben, was hier das Problem ist…
Feeela
Ja, das wäre eine großartige Übung, wenn möglich mit CSS ...
Jessica Lingmn
Ich sehe keinen Grund, warum <h1><img alt="Some Text" /></h1>es weniger SEO-freundlich ist als <h1>Some Text</h1>. Traditionell bestand das Problem bei Bildern darin, dass sie gerade ohne unterstützendes Markup auf der Seite abgelegt wurden.
Cimmanon
@ Cimmanon Ja, du hast recht. Ich könnte wahrscheinlich Bilder verwenden, ohne SEO-Punkte zu verlieren, aber Sie können immer noch keinen Text auswählen, auf einer Seite suchen, das Verknüpfen wird komplizierter und es wird viel mehr Arbeit sein, den Text zu aktualisieren ...: /
Love Dager
2
Nur damit Sie wissen, ist Google mit CSS- Bildersatztechniken
cimmanon

Antworten:

46

Es ist mit CSS3 möglich, wird aber nicht in allen Browsern unterstützt

Mit Hintergrundclip: Text; Sie können einen Hintergrund für den Text verwenden, müssen ihn jedoch am Hintergrund der Seite ausrichten

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/


Automatische Ausrichtung

Mit ein wenig Javascript können Sie den Hintergrund automatisch ausrichten:

$(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>
Wenn Sie

http://jsfiddle.net/JGPuZ/1336/

Gijs
quelle
A Sie Leute sind zu schnell: D
Gijs
Oh toll! Ich werde die automatische Ausrichtung testen, sobald ich nach Hause komme! Danke dir! : D
Love Dager
Sie müssen möglicherweise den Code ein wenig ändern, hängt von der Situation ab, jetzt kann es zu Konflikten mit anderen Elementen kommen, und dieser wurde sehr schnell geschrieben. Wenn Sie Fragen haben, werde ich sie hören
Gijs
3
Die Antwort nicht außer Acht zu lassen, was eine wirklich nette Lösung ist, sondern background-clip:texteine reine Webkit-Option, die nicht dem Standard entspricht. CSS3 lässt den textWert für dieses Attribut nicht zu ( siehe ).
Tanius
1
Mit dieser Technik können Sie den Hintergrund des Elements sehen, in dem sich der Text normalerweise befindet. Ich suche nach einer Möglichkeit, um zu sehen, was sich mit dem Text unter dem Element befindet, und zwar an der Stelle, an der sich der Text normalerweise befindet.
Vince
49

Obwohl dies mit CSS möglich ist, wäre ein besserer Ansatz die Verwendung eines Inline-SVG mit SVG-Maskierung . Dieser Ansatz hat einige Vorteile gegenüber CSS:

CodePen Demo: SVG- Textmaske

transparenter Textausschnitthintergrund

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>

Wenn Sie den Text auswählbar und durchsuchbar machen möchten, müssen Sie ihn außerhalb des <defs>Tags einfügen. Das folgende Beispiel zeigt eine Möglichkeit, den transparenten Text mit dem <use>Tag beizubehalten:

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>

Web-Tiki
quelle
2
Dies scheint die einzige Lösung zu sein, die heute browserübergreifend funktioniert: IE11, FF, Chrome, Safari. Und benötigt kein Bild als Hintergrund, wie viele andere Lösungen für das Problem im gesamten Web.
Timo Kähkönen
1
Inspiriert von dieser Antwort habe ich eine Keyframes-Animation erstellt, bei der sich transparenter SVG-Text auf einem weißen, abgerundeten Rechteck dreht. Der Hintergrund hat Text und Bilder. Gehen Sie und sehen Sie: jsbin.com/nipuqu/3 (Die Weltmeisterschaft kommt :))
Timo Kähkönen
2
Gute Lösung, aber da "Text auswählen und auf Seite suchen" in den Anforderungen von OP zu stehen scheint, möchten Sie möglicherweise die <text>Außenseite des <defs>Teils einbeziehen. (Übrigens bin ich mir nicht sicher, wie SE-Crawler mit SVG-Inhalten in Defs umgehen). Hier ist ein Weg, um zu halten, was OP will, mit einem schrecklichen FF-Bug-Exploit: jsfiddle.net/tfneqxxb
Kaiido
Was ist, wenn der Text dynamisch ist? Die Breite wird nicht automatisch angepasst.
Imran Bughio
1
@ ImranBughio nein, tut es nicht. SVG-Text verhält sich nicht wie einfacher HTML-Text. Sie müssen es positionieren. Weitere Informationen finden Sie hier
Web-Tiki
16

Eine Möglichkeit, die in den meisten modernen Browsern (außer Edge) funktioniert, obwohl nur mit schwarzem Hintergrund, ist die Verwendung

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

in Ihr Textelement und setzen Sie dann den gewünschten Hintergrund dahinter. Multiplizieren ordnet den 0-255-Farbcode grundsätzlich 0-1 zu und multipliziert diesen dann mit dem dahinter stehenden Wert. Schwarz bleibt also schwarz und Weiß multipliziert mit 1 und wird effektiv transparent. http://codepen.io/nic_klaassen/full/adKqWX/

Nic
quelle
3
Für weißen Hintergrund mit schwarzer Farbe verwenden color-dodge, lightenoder screenaufmix-blend-mode
Imran Bughio
3

Es ist möglich, aber bisher nur mit Webkit-basierten Browsern (Chrome, Safari, Rockmelt, alles, was auf dem Chromium-Projekt basiert.)

Der Trick besteht darin, ein Element innerhalb des weißen Elements zu haben, das denselben Hintergrund wie der Körper hat, und es dann -webkit- background-clip: text;für das innere Element zu verwenden, was im Grunde bedeutet, dass der Hintergrund nicht über den Text hinaus erweitert wird, und transparenten Text zu verwenden.

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/

Kyle
quelle
Cooler Trick! Aber jetzt, um alles richtig auszurichten, wird eine Hündin sein .. -.-
Love Dager
Ja, das ist ein weiteres Problem. Es befindet sich noch in der Entwicklung und ich hoffe aufrichtig, dass wir so etwas bald sehen! :)
Kyle
Sie können das Bild auch jederzeit über transparenten Text legen, sodass er weiterhin ausgewählt werden kann. Aber ich bin sicher, dass es eine schlechte Praxis für SEO ist. Versteckte Nachrichten / Schlüsselwörter und so.
Kyle
Ich bin sicher, dass es in Webkit-Browsern sehr gut aussieht, aber für alle anderen ist es eine halbtransparente weiße Box auf etwas Gras.
Cimmanon
1
Ah, komm schon Leute ... Ja, ich habe vor, es in der Produktion einzusetzen. Aber natürlich nicht ohne Fallback! @ Cimmanon
Love Dager
2

Ich habe gerade einen neuen Weg gefunden, dies zu tun, während ich herumgespielt habe. Ich bin mir nicht ganz sicher, wie es funktioniert (wenn jemand anderes es erklären möchte, bitte tun Sie es).

Es scheint sehr gut zu funktionieren und erfordert keine doppelten Hintergründe oder JavaScript.

Hier ist der 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>

ChrisBrownie55
quelle
1

Sie können eine invertierte / negative / umgekehrte Schriftart verwenden und diese mit der font-face="…"CSS-Regel anwenden . Möglicherweise müssen Sie mit dem Buchstabenabstand spielen, um kleine weiße Lücken zwischen den Buchstaben zu vermeiden.

Wenn Sie keine bestimmte Schriftart benötigen, ist dies einfach. Laden Sie eine sympathische Schrift herunter, zum Beispiel aus dieser Sammlung invertierter Schriftarten .

Wenn Sie eine bestimmte Schriftart benötigen (z. B. "Open Sans"), ist dies schwierig. Sie müssen Ihre vorhandene Schriftart in eine invertierte Version konvertieren. Dies ist manuell mit Font Creator, FontForge usw. möglich, aber wir wollen natürlich eine automatisierte Lösung. Ich konnte noch keine Anleitung dafür finden, aber einige Hinweise:

Tanius
quelle
1

Sie können das jQuery-Plugin Patternizer von myadzel verwenden , um diesen Effekt in allen Browsern zu erzielen. Derzeit gibt es keine browserübergreifende Möglichkeit, dies nur mit CSS zu tun.

Sie verwenden Patternizer, indem Sie class="background-clip"HTML-Elemente hinzufügen, in denen der Text als Bildmuster gezeichnet werden soll, und das Bild in einem zusätzlichen data-pattern="…"Attribut angeben . Siehe die Quelle der Demo . Patternizer erstellt ein SVG-Bild mit mustergefülltem Text und legt es dem transparent gerenderten HTML-Element unter.

Wenn das Textfüllmuster wie im Beispielbild der Frage Teil eines Hintergrundbilds sein sollte, das über das "gemusterte" Element hinausgeht, sehe ich zwei Optionen (ungetestet, mein Favorit zuerst):

  • Verwenden Sie im SVG die Maskierung anstelle eines Hintergrundbilds. Wie in der Antwort von Web-Tiki , zu der mit Patternizer weiterhin die automatische Generierung des SVG und ein unsichtbares HTML-Element hinzugefügt werden, das die Auswahl und das Kopieren von Text ermöglicht.
  • Oder verwenden Sie die automatische Ausrichtung des Musterbilds. Kann mit JavaScript-Code ausgeführt werden, der dem in Gijs Antwort ähnelt .
Tanius
quelle
1

Setzen Sie einfach das 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;

    }
Ausgeschlagen
quelle
1

Demo-Screenshot

Ich musste Text erstellen, der genau so aussah wie im ursprünglichen Beitrag, aber ich konnte ihn nicht einfach vortäuschen, indem ich Hintergründe ausrichtete, da sich hinter dem Element eine Animation befindet. Bisher scheint dies noch niemand vorgeschlagen zu haben. Deshalb habe ich Folgendes getan: (Ich habe versucht, das Lesen so einfach wie möglich zu gestalten.)

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

Werfen Sie das einfach in Ihr Fenster. Laden Sie es ein, stellen Sie den Hintergrund des Körpers auf Ihr Bild ein und beobachten Sie, wie die Magie geschieht!

Pecacheu
quelle
0

Mit CSS momentan leider nicht möglich.

Am besten verwenden Sie einfach ein Bild (wahrscheinlich ein PNG) und platzieren einen guten Alt- / Titeltext darauf.

Alternativ können Sie ein SPAN oder ein DIV verwenden und das Bild als Hintergrund für Ihren Text verwenden, den Sie für SEO-Zwecke verwenden möchten, aber außerhalb des Bildschirms einrücken.

Billy Moat
quelle
Ja, du hast recht. Ich könnte wahrscheinlich Bilder verwenden, ohne SEO-Punkte zu verlieren, aber Sie können immer noch keinen Text auswählen, auf einer Seite suchen, das Verknüpfen wird komplizierter und es wird viel mehr Arbeit sein, den Text zu aktualisieren ...: /
Love Dager