Bild unter Text anzeigen (mit akzeptablem Fallback)

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Aktualisiert im April 2014 mit moderneren Informationen.

WebKit unterstützt die coole CSS3-Eigenschaft background-clip, mit der Sie einige ziemlich nette Dinge tun können. Das erste Mal, als wir uns damit beschäftigten, war die Idee des iPhone Slide-to-unlock, bei der wir einen Gradienten animierten, der durch den Hintergrund des Textes lief. Dann haben wir uns damit für die Idee der transparenten Ränder beschäftigt.

Schauen wir uns an, wie wir damit ein Bild nur durch die Buchstaben des Textes sichtbar machen können. Eine weitere coole Sache, deren Fähigkeit von Druckdesignern wir nicht mehr beneiden müssen.

Demo ansehen

Die Grundidee

h1 {
   color: white;  /* Fallback: assume this color ON TOP of image */
   background: url(images/fire.jpg) no-repeat;
   -webkit-background-clip: text;
   -webkit-text-fill-color: transparent;
}

Das ist alles, was dazu gehört. Setzen Sie ein Hintergrundbild auf das Element, schneiden Sie es aus und setzen Sie die Textfüllfarbe auf transparent.

Das Problem

Wie ich sicher bin, ist jedem schmerzlich bewusst, dass dies nicht in allen Browsern funktioniert. Die aktuelle Unterstützung beschränkt sich auf WebKit. Was passiert also als Fallback? Wie Sie im obigen Code sehen können, deklarieren Sie auch einen color-Wert. Dieser Wert wird in Browsern, die ihn unterstützen, durch -webkit-text-fill-color überschrieben, so dass wir damit klarkommen. In Browsern, die -webkit-background-clip: text nicht unterstützen, sehen wir das Hintergrundbild vollständig, sodass wir Text über diesem Hintergrundbild sehen. Wenn Sie also nicht weiterlesen, setzen Sie einen Farbwert, der auf diesem Hintergrundbild gut sichtbar ist.

Also, wir bekommen das hin

Nicht das absolute Ende der Welt, zumindest haben wir den Text einigermaßen lesbar gemacht. Aber das ist noch ein weiter Weg von dem, was wir uns vorstellen und was WebKit-Benutzer erleben werden. Grundsätzlich gilt: Dieser Fallback ist schlecht, machen wir es besser.

Ein besserer Fallback

Das ultimative Werkzeug für bessere Fallbacks ist Modernizr. Fügen Sie einfach die (recht kleine) JavaScript-Datei auf Ihre Seite ein, und sie fügt dem html-Tag Ihrer Seite Klassen hinzu, die anzeigen, wozu der aktuelle Browser in der Lage ist. Sie bietet auch eine API zum Testen von Funktionen in JavaScript, aber die werden wir heute nicht brauchen.

Leider hat Modernizr keinen direkten Test für background-clip. Ich habe einen der Entwickler, Paul Irish, gefragt, der mir diesen schnellen Weg gezeigt hat, diesen Test hinzuzufügen. Der ganze Teil

<script src="modernizr-1.6.min.js"></script>
<script>
  Modernizr.addTest('backgroundclip',function() {

    var div = document.createElement('div');

    if ('backgroundClip' in div.style)
      return true;

    'Webkit Moz O ms Khtml'.replace(/([A-Za-z]*)/g,function(val) { 
      if (val+'BackgroundClip' in div.style) return true;
    });

  });
</script>

Jetzt wissen wir, ob der aktuelle Browser background-clip unterstützt oder nicht. Wenn ja, hat das html-Tag eine Klasse backgroundclip, wenn nicht, hat es eine Klasse no-backgroundclip.

Jetzt wenden wir das Hintergrundbild nur an, wenn wir sicher sind, dass der Browser background-clip unterstützt.

.backgroundclip h1 {
  background: url(images/west.jpg) -100px -40px no-repeat;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

h1 {
  color: orangered;
}

Badda Bing, jetzt ist der Fallback eine gerade durchgezogene Volltonfarbe anstelle eines unordentlich aussehenden Bild-Ausschnitts.

Demo ansehen

Aber… es gibt kein perfektes System dafür.

Es gibt ein Problem mit Android (bis einschließlich 4.2), wo es -webkit-background-clip tatsächlich nicht unterstützt – obwohl jeder Test zurückgibt, dass es das tut. Die Eigenschaft und jeder Wert, den sie haben mag, einschließlich text. Selbst Modernizr's testAllProps() kann es nicht erfassen. Aber -webkit-text-fill-color funktioniert, sodass Sie im Grunde ein Bild ohne Text erhalten. Ziemlich schlecht.

Wenn Sie dies unbedingt verwenden müssen, müssen Sie möglicherweise UA-Tests für Android durchführen

var NastyBrowserSniffing = {

  ua: navigator.userAgent.toLowerCase(),

  init: function() {
    var isAndroid = NastyBrowserSniffing.ua.indexOf("android") > -1;
    if (isAndroid) {
      $("html").addClass("android");
    }
  }

};

NastyBrowserSniffing.init();

Dann den Effekt rückgängig machen, wenn es Android ist

html.android .gradient-text {
  color: white;
  background: none;
  -webkit-text-fill-color: white;
  -webkit-background-clip: border-box;
}
.gradient-text {
  background: -webkit-linear-gradient(gray, black);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

Stephen Morley beschreibt wie man es für IE mit Filtern macht.