CSS 2.1 ::Tutorials
Text dynamisch ersetzen
Das Original dieses Textes wurde zuerst am 15. Juni 2004 unter dem Titel Dynamic Text Replacement im Online-Magazin A List Apart veröffentlicht. Der Autor ist Stewart Rosenberger. Die Übersetzung erfolgte mit Genehmigung von A List Apart und dem Autor.
Translated with the permission of A List Apart Magazine and the author.
Die Gestaltung von Text ist eins der mehr stumpfsinnigen Probleme des Webdesigns. Nur wenige Fonts sind allgemein verfügbar und hochentwickelte graphische Effekte sind mit standardsgemäßem CSS und HTML fast unmöglich. Für unsere Texte halten wir uns deshalb sinnvollerweise an die herkömmlichen Fonts, nur für unsere Überschriften, für kurze aufmerksamkeitsheischende Titelzeilen, hätten wir oft gern etwas mehr Auswahl. Inzwischen haben wir uns an das Problem gewöhnt und kommen damit zurecht, entweder indem wir aus den paar Fonts, die wir haben, das beste machen oder indem wir unsere Überschriften alle durch Grafiken ersetzen.
In den meisten Websites, wo Text durch Grafiken ersetzt wird, sind diese Grafiken von Hand erstellt. Solange die Anzahl der Titelzeilen überschaubar ist, kann man damit leben. Wenn eine Website aber mehrmals täglich aktualisiert wird, führt dies schnell zu einem unübersehbaren Aufwand. Denn wie auch immer man so eine Ersetzung realisiert, letztlich muss jede Grafik eine Verbindung zu dem Text haben, den sie ersetzt. Diese Bindung besteht meistens aus einem Element img
, einem eingebetteten Stylesheet oder einem speziellen Attribut id
. Dies alles muss von irgendwem über alle Änderungen ind Redesigns hinweg laufend gehalten werden.
Jetzt können wir all diesen Nonsens vergessen. Keine img
oder span
mehr, keine ID
-Attribute, keine vertane Zeit mit Photoshop und keine vertrackten CSS-Hacks mehr. Mit JavaScript und PHP können wir grafische Titelzeilen generieren, die für alle zugänglich sind. Und das mit jedem beliebigen Font. Und die Struktur unseres CSS und HTML bleibt völlig unberührt.
Sehen Sie sich jetzt den dynamischen Texteinsatz in einem Funktionsbeispiel an. Wenn Sie dann weiterlesen, finden Sie heraus, wie Sie diese Funktionalität in Ihren eigenen Seiten ergänzen können.
Das PHP-Script
Ein kurzes PHP-Script (hier herunterladbar) erzeugt bei jedem Aufruf eine dynamische PNG-Grafik. Vor der ersten Anwendung müssen wir es an das Aussehen unserer Website anpassen. Dazu dienen die ersten sieben Zeilen:
$font_file = 'font.ttf' ; $font_size = 56 ; $text_color = '#ffffff' ; $background_color = '#000000' ; $transparent = true ; $cache_images = true ; $cache_folder = 'cache' ;
Die Variablen haben folgende Bedeutung:
$font-file
enthält den lokalen Pfad zu einem True-Type-Font (TTF) oder Open-Type-Font (OTF) auf Ihrem Webserver. In dieser Schriftart werden Ihre Graphiken erzeugt. Sie laden ihn einfach von Ihrem PC aus hoch.$font_size
gibt die Größe der Schrift in Pixel an.$text_color
und$background_color
sind die hexadezimalen Farbwerte für den Text und seinen Hintergrund.$transparent
kann den Werttrue
oderfalse
annehmen,true
bewirkt die Glättung der Kanten zwischen der Textgrafik und dem Hintergrund. Die eigentliche Hintergrundfarbe wird dadurch vollkommen unsichtbar.- Wenn
$cache_images
den Werttrue
und$cache_folder
den lokalen Pfad zu einem Verzeichnis auf Ihrem Server enthält, dann wird das Script jede Graphik, die es erzeugt, zur späteren Verwendung speichern. Dadurch lassen sich die Ladezeiten der Graphiken erheblich verkürzen. Das ist besonders wichtig bei Servern mit hohem Verkehrsaufkommen. Der angegebene Pfad muss mit Schreibrechten versehen sein.
Zur Installation laden Sie das Script einfach auf Ihren Server hoch. Stellen Sie sicher, das er für PHP-Nutzung konfiguriert ist. Es sollte mindestens die PHP-Version 4.3 mit eingebundener Unterstützung der GD-Grafikbibliothek, Version 1.6, verfügbar sein. Diese Bezeichnungen sagen Ihnen nichts? Dann mailen Sie sie einfach an Ihren Webhoster. Die Serviceleute schreiben Ihnen dann, ob das geht oder nicht.
Ihre Website muss nicht mit PHP erstellt worden sein, um die hier vorgestellte Technik zu nutzen. Egal, wie Sie Ihre Seiten erstellen und ob Sie sie per Hand oder mit einem CMS aktualisieren: solange Sie ein Element script
im Kopf Ihrer Seiten einfügen können, können Sie auch diese Technik nutzen. Etwas weiter unten wird das noch deutlicher.
Auch der Hinweis auf andere serverseitige Techniken soll hier nicht vergessen werden. Was man mit PHP erreichen kann, lässt sich oft auch mit Perl, ASP, Java Servlets oder anderen Programmiersprachen machen. Aufgrund seiner weiten Verbreitung, Systemunabhängigkeit und leichten Erlernbarkeit ist PHP in diesem Fall erste Wahl.
Bedenken Sie die Alternativen dann, wenn Sie etwas brauchen, das PHP nicht bietet oder wenn Sie Ihre eigene Image-Generierung programmieren wollen.
Weiter oben haben wir das Script mit ein paar Variablen an unsere Seiten angepasst. Was jetzt noch fehlt, ist der individuelle Text und den erhält das Script über seine URL. So generieren wir beispielsweise durch den Aufruf der URL heading.php?text=URLs%20sind%20einfach
eine Graphik, die sich wie der Text 'URLs sind einfach' liest. Und das stimmt auch. Aber wir brauchen unsere URLs nie von Hand einzutragen, denn dazu haben wir JavaScript.
Das JavaScript
Sie können hier die Scriptdatei herunterladen.
Die Technik, die wir hier verwenden, lehnt sich stark an die JIR-Methode (=JavaScript Image Replacement) von Peter-Paul Koch an. Ihm war aufgefallen, dass viele Webdesigner ihre Stylesheets vor bestimmten Browsern verstecken, indem sie die browsereigenen Fehler ausnutzen. Diese CSS-Hacks sind etwas ähnliches wie bedingte Anweisungen eingeschränkter Art und machen aus CSS eine primitive Programmiersprache. Genau genommen ist so etwas aber eher eine Fehlersprache. Der Gedanke von PPK und anderen war nun, dass eine richtige Scriptsprache wie JavaScript dieselbe Aufgabe besser und unter Einhaltung der Webzugänglichkeit ausführen kann. Das ist für unsere Zwecke hervorragend, denn JavaScript gibt uns eine höhere Flexibilität. Insbesondere, da wir Text durch Images ersetzen wollen, die bis dato noch gar nicht existieren.
Ganz am Beginn des Seitenaufbaus versucht das Script zuerst, eine kleine 1×1 Pixel große Testgrafik herunterzuladen. Wenn dieser Test erfolgreich verläuft, bedeutet das, dass der Browser Grafiken darstellt. Anderenfalls würde er keine DÜ-Kapazität dafür aufgewendet haben. Dies ist der springende Punkt des JIR: Indem wir testen, ob die Darstellung von Grafiken unterstützt wird, können wir gleichzeitig herausfinden, ob die Besucher unserer Seite überhaupt etwas mit unseren stilvollen Titelzeilen anfangen können.
Falls der Browser die Darstellung von Grafiken unterstützt, wartet das Script, bis die Seite komplett geladen ist, denn nur herunter geladener Text kann auch replaziert werden. Sobald das HTML dann vollständig vorliegt, wird es vom Script nach den spezifizierten Elementen, z. B. h1
, h2
oder span
, durchsucht. Das Script ersetzt den Text innerhalb dieser Elemente durch ein Element img
. Das Attribut alt
dieses dynamischen Elementes img
enthält den Originaltext und das Attribut src
enthält die URL unseres soeben installierten PHP-Scripts. Das PHP-Script schickt dann ein maßgeschneidertes PNG-Image an den Browser und fertig ist die Laube.
Acht Kilobyte sind für ein einfaches Script natürlich ein bisschen heftig, aber es passiert an dieser Stelle auch eine ganze Menge. Dennoch müssen wir nur zwei Zeilen anpassen, damit das Script läuft:
replaceSelector("h2","heading.php",true); var testURL = "test.png";
Die Funktion replaceSelector
benötigt drei Parameter:
- zuerst den Selektor, der angibt, welche Elemente ersetzt werden sollen. Das kann fast jeder gültige CSS-Selektor sein, einschließlich ID-, Klassen-, Element- und Attributselektoren.
- Der zweite Parameter ist die URL unseres PHP-Scriptes.
- Der dritte Parameter ist eine Variable, die vorgibt, ob ein Zeilenumbruch möglich sein soll. Wenn wir hier den Wert true einsetzen, erstellt das Script für jedes Wort eine eigene Grafik, sodass die Worte auf mehrere Zeilen verteilt werden können. Setzen wir false ein, wird nur ein Image in der notwendigen Größe erzeugt, das nicht umgebrochen werden kann.
Die Funktion replaceSelektor
sollte für jede Gruppe von Elementen aufgerufen werden, die wir durch eine Grafik ersetzen wollen. Die URL kann ein absoluter Pfad (http://...) oder der relative Pfad zu unserer HTML-Datei sein.
Die Variable testURL
muss die URL unseres kleinen Testimages enthalten.
Sobald diese Zeilen korrekt eingegeben sind, können Sie das JavaScript auf Ihren Webserver hochladen. Mit der folgenden Zeile, die im Kopfbereich Ihrer Seiten stehen muss, aktivieren Sie das Script:
<script type="text/JavaScript" src="replacement.js"> </script>
Stellen Sie sicher, dass das Attribut src
den korrekten Pfad zur JavaScript-Datei enthält.
Mehr ist nicht nötig, um unseren dynamischen Textersatz zum Laufen zu bringen, deshalb könnten wir an dieser Stelle aufhören. Es sind aber noch einige Verbesserungen möglich, die wir vorher noch anbringen wollen.
Druckversionen
Viele Websites enthalten heute spezielle Druck-Stylesheets, um die Ausdrucke ihrer Inhalte besser zu gestalten. (Siehe dazu das Tutorial Druck-Layouts mit CSS, d. Ü.) In vielen Fällen bedeutet dies aber auch, dass wir den Prozess der Textersetzung umkehren müssen, da Graphiken nach der Ausgabe durch hochauflösende Drucker oft nicht ganz so gut aussehen. Die Druckausgabe erfolgt daher wieder mit den eigentlichen Schriftfonts. Leider ist dieses Problem nicht mit JavaScript lösbar. Wenn wir unseren Text einmal durch Grafiken ersetzt haben, können wir diesen Vorgang nicht speziell für den Druck wieder rückgängig machen. Wir müssen uns also nach einer anderen Lösung umsehen.
Anstatt nun den Rückwärtsgang einzulegen und unseren Textersatz wieder umzukehren, können wir ein wenig im Voraus planen. Gemeinsam mit dem Element img
, das unseren Text als Grafik enthält, können wir auch ein Element span
einfügen, das den Originaltext enthält. Für dieses Element span
deklarieren wir im Stylesheet für den Bildschirm display:none
. Jetzt haben wir zwei Versionen unseres Textes: eine ist die sichtbare Grafik, die andere ist die innerhalb des unsichtbaren (weil nicht dargestellten) Elements span
. Wenn wir jetzt noch beiden Versionen unterschiedliche Klassenattribute geben, z. B. 'grafik
' und 'druck-text
', und ein Druck-Stylesheet einfügen, können wir die Darstellung zum Druck austauschen.
Für diesen Teil unserer Seite brauchen wir nur wenige CSS-Deklarationen, wie im folgenden Beispiel:
span.print-text { display: inline !important; } img.replacement { display: none; }
Nachdem wir dieses Stylesheet hochgeladen haben, müssen wir in unserem JavaScript noch zwei Zeilen anpassen:
var doNotPrintImages = false; var printerCSS = "replacement-print.css";
Wenn wir der Variablen doNotPrintImages
den Wert true
geben und der Variablen printerCSS
den Namen des Druck-Stylesheets, dann wird das Script automatisch das passende Element link im Kopf unserer Seiten einfügen.
Flimmerfreie Ausgabe
Das Script kann mit seiner Arbeit erst beginnen, nachdem das gesamte Dokument geladen ist. Deshalb wird oft für einen kurzen Moment der ungestaltete Text sichtbar, während der Browser darauf wartet, dass der Ersetzungsprozess abläuft. Dies ist eigentlich kein Problem, es bleibt aber lästig, und da es vermeidbar ist, können wir es ebenso gut in Ordnung bringen. Das ist ganz einfach mit einem weiteren kurzen Stylesheet.
Dieses Stylesheet fügen wir dynamisch ein, bevor das Element body
unseres Webdokuments geladen wird. Wir verwenden es dazu, unsere ungestalteten Elemente insgesamt zu verbergen. CSS-Dateien, die durch das Element link
angebunden sind, werden bereits beim Aufbau der Seite angebracht. Daher wird nichts von den Inhalten, die durch das Script ersetzt werden sollen, vorher sichtbar sein. Sobald der Ersetzungsprozess abgelaufen ist, wird auch unser temporäres Stylesheet durch ein anderes ersetzt. Dadurch werden unsere grafischen Überschriften sichtbar.
Ein Beispiel: wenn Sie auf Ihrer Seite alle Elemente h2
ersetzen wollen, dann würden Sie sie durch das folgende Stylesheet verbergen, bis das Script abgelaufen ist:
h2 { visibility: hidden; }
Auch wenn wir die Sache so angehen, bleibt aber dennoch ein kleines Problem. Unsere Technik hängt ganz davon ab, ob eine kleine Testgrafik geladen wird oder nicht und dadurch anzeigt, ob der Browser Grafiken ausgibt oder nicht. Wenn die Testgrafik nicht lädt, wird unser Script nicht aktiviert. Das wiederum bedeutet, dass das Stylesheet, das unsere unformatierten Überschriften unterdrückt, nicht deaktiviert wird. Das heißt, dass Besucher, welche die Grafikausgabe in ihrem Browser deaktiviert haben, anstelle der Titelzeilen nichts sehen, auch wenn ihre Browser CSS und JavaScript korrekt behandeln.
Dieser armen Minderheit, für die das Surfen ohnehin schon schwer genug ist, können wir es etwas leichter machen, indem wir eine kleine Verzögerung in das Script einbauen. Sie bewirkt, dass das Script automatisch das kurze temporäre Stylesheet deaktiviert, wenn die Testgrafik nach einer oder zwei Sekunden noch nicht geladen wurde. Dadurch werden die Überschriften wieder sichtbar. Die zwei Sekunden Zeitverlust sind zwar für unsere kleine Minderheit etwas unbequem, aber für die anderen 99,99% unserer Besucher haben wir das Problem der flimmerfreien Ausgabe gelöst. Wichtig ist, dass wir die Zugänglichkeit für alle aufrecht erhalten.
Um diese Anpassung zu aktivieren und die Anzeige der ungestylten Titelzeilen zu vermeiden, müssen wir im JavaScript diese drei Zeilen ändern:
var hideFlicker = false; var hideFlickerCSS = "replacement-screen.css"; var hideFlickerTimeout = 1000;
Die Variable hideFlicker
erhält den Wert true
und die Variable hideFlickerCSS
enthält den Namen der kurzen CSS-Datei, die nur dem Verbergen der Überschriften dient. Mit der dritten Variablen, hideFlickerTimeout
, definieren wir die Länge der Verzögerung in 1/1000 Sekunden.
Anmerkungen und weiterführende Ideen
Ältere Versionen der Gecko-Engine, bis Netscape 6.2 und Mozilla 1.3, enthielten einen Bug, der bewirkte, dass Grafiken in jedem Fall herunter geladen wurden. In diesen Versionen wird die hier vorgestellte Technik auch dann Unterstützung von Grafiken feststellen, wenn die Ausgabe von Grafiken deaktiviert ist. Dies kommt aber äußerst selten vor und ich sehe es nicht als einen ernsthaften Nachteil an. Das Problem wird hier nur der Vollständigkeit halber genannt und es gibt auch momentan keinen Weg, es zu umgehen.
Diese Technik funktioniert auch, wenn Seiten online übersetzt werden, z. B. durch Google oder Altavistas Babelfish. Solange der Font die Zeichen der fremden Sprachen enthält, werden die dynamisch erzeugten Grafiken diese Zeichen auch enthalten.
Der ersetzte Text muss nicht unbedingt innerhalb der Elemente h1
, h2
usw. für Titelzeilen liegen. Das Script arbeitet mit jedem beliebigen Element auf der Seite. Mit der Hilfe einiger einfacher Änderungen und floatierten Elementen erlaubt diese Technik, große Initialen (engl. drop-caps) dynamisch für jeden Artikel zu erzeugen.
Wir können auch alle Elemente a
durch Grafiken ersetzen und unsere Seiten mit besonders formatierten Hyperlinks versehen. Nur die Rollovers würden dann noch mehr Anpassungen verlangen.
Eine andere Möglichkeit wäre, das PHP-Script ganz fallen zu lassen und dynamische Flash-Animationen anstelle der dynamisch erzeugten Elemente img zu verwenden.
TOP
Dank und Anerkennung
An Peter-Paul Koch, für seine JIR-Technik.
An Simon Willison, für seine Funktion getElementsBySelector
.
An Stuart Langridge, für seine unauffälligen JavaScript-Techniken.
Das Original dieses Textes wurde zuerst am 15. Juni 2004 unter dem Titel Dynamic Text Replacement im Online-Magazin A List Apart veröffentlicht. Der Autor ist Stewart Rosenberger. Die Übersetzung erfolgte mit Genehmigung von A List Apart und dem Autor.
Translated with the permission of A List Apart Magazine and the author.