Dr. O. Hoffmann
Einfach auch mal hinter die Dinge sehen und das Staunen nicht vergessen...
Olaf Hoffmann
Ein prinzipielles Problem sowohl von (X)HTML als auch CSS ist es, die Größe des Anzeigebereiches des Darstellungsprogrammes in Erfahrung zu bringen, zumal diese vom Nutzer in weiten Bereichen jederzeit variiert werden kann. java-script, sofern überhaupt aktiviert, gibt auch nur die gesamte Größe des Bildschirms in Pixeln an, ist also auch nicht weiter hilfreich. Nun, eigentlich werden die Abmessungen des Anzeigebereiches gar nicht explizit gebraucht, wenn alles richtig durchdacht wird.
Implizit sind jedoch viele Abmessungen über CSS verfügbar. Insbesondere bietet das Modul für Medienanfragen von CSS 3 Möglichkeiten, die Abmessungen des Darstellungsbereiches in den üblichen Einheiten, also insbesondere auch em und ex zu verwenden, um geeignete Stile anzubieten, ohne die Abmessungen zu kennen - bei dem Verfahren wird also umgekehrt vorgegangen, es wird festgelegt, daß eine bestimmte Stilvorlage nur für bestimmte Abmessungsbereiche des Anzeigebereiches verwendet werden soll. Prinzipiell sieht hier CSS auch entsprechende Anfragen hinsichtlich der Bildschirmgröße vor, was aber nur sehr selten relevant sein dürfte, weil der Anzeigebereich meist anders, kleiner als die Größe des Bildschirms ist.
Um bei einem Bild allerdings die gleichen Maßeinheiten verwenden zu können, wie in der Stilvorlage, also etwa em, ex oder Prozent, wäre Vektorgraphik im Format SVG (skalierbare Vektorgraphik) zu verwenden. Mit dem Format sollte es kein Problem sein, ein Bild an die Größe des Anzeigebereiches fließend anzupassen. Mit Bildern in diesem Format treten sogar nicht einmal Qualitätsverluste beim Skalieren auf. Zwar wird das Format bereits etwa seit 2006 von technisch aktuellen Darstellungsprogrammen wie den Geckos (ab Version 1.7/1.8, Firefox, SeaMonkey etc), von Opera 8 und 9 und vom Konqueror 3.3 interpretiert, zunächst allerdings nicht jedoch als CSS-Hintergrundbild, was ein bekannter Fehler all dieser Programme war. Dieser Fehler ist zuerst bei Opera mit der Version 9.50 alpha beseitigt worden - diese Version ist damit die erste, mit der SVG sinnvoll für ein CSS-Layout eingesetzt werden kann. In den folgenden Jahren wurde das Problem dann auch bei anderen gängigen Darstellungsprogrammen behoben. SVG als Hintergrundbild kann heute also verwendet werden. Allerdings haben einige Programme immer noch massive Probleme, zentrale CSS-Einheiten für Längen korrekt zu interpretieren, etwa Prozentangaben oder die besonders relevanten Angaben in em und ex, was es komplizierter macht, in solchen Programmen keine gute Präsentation zu erreichen, weil die eigentlich vorgesehene und notierte korrekte Präsentation der Größe des Hintergrundbildes aufgrund solcher Fehler bei der Interpretation von CSS-Einheiten für Längen nicht erreicht wird, stattdessen wird das Hintergrundbild dann oft in der falschen Größe dargestellt.
Anwendungsbeispiel: SVG-Hintergrundbild an die Größe des
Anzeigebereiches fließend anpassen.
Die Bildgröße wird auf 100% gesetzt und das Aspektverhältnis preserveAspectRatio
auf 'none'.
Das Bild wird dann per CSS als Hintergrundbild des Elementes html
angegeben
(bei XHTML, bei HTML alternativ auch für body
).
Zudem wird eine passende Hintergrundfarbe angegeben, für den Fall, daß das
Programm das Bild nicht darstellen kann.
Das Hintergrundbild wird aufgrund des Attributwertes 'none' von
preserveAspectRatio
in der Regel verzerrt. Läßt man die
Angabe weg oder wählt eine andere vom Typ 'meet', so bleibt zwar das Aspektverhältnis
erhalten, es entstehen aber Ränder, vermeidbar ist das mit dem Typ 'slice', besonders geeignet
für ein Muster als Hintergrund, da es da nicht darauf ankommt, wenn in einer Richtung ein Stück vom
Bild nicht sichtbar ist, wenn das Aspektverhältnis nicht stimmt. Folgendes Beispiel nutzt ein
aperiodisches Penrose-Muster mit komplett asymmetrischen Grundformen als Hintergrundbild. Das ist aufgrund der
fehlenden Periodizität und der fehlenden Skalierbarkeit von Pixelgraphik als Hintergrundbild mit einem
Pixelgraphikformat gar nicht umsetzbar:
SVG-Hintergrundbild mit
Muster an die Größe des Anzeigebereiches fließend anpassen.
Hier wurde preserveAspectRatio
= xMidYMid slice'
verwendet, um die Struktur zu zentrieren, auch um die fünfzählige Rotationssymmetrie mit
dem Zentrum als Rotationszentrum deutlich sichtbar zu machen. Mit den anderen möglichen
Werten kann man auch sicherstellen, daß die jeweils ausgewählte Ecke auf jeden Fall sichtbar
bleibt.
Tatsächlich funktionierte die Darstellung eines SVG-Hintergrundbildes wie gesagt
2009 bei anderen Darstellungsprogrammen als Opera ab Version 9.50 alpha/beta noch nicht,
in späteren Jahren wurde der Fehler bei den anderen gängigen Programmen allerdings in aktuellen
Versionen beseitigt. Bei Mozilla/Gecko (Firefox) oder WebKit (Chromium, Safari etc) scheint wie bereits angedeutet
die Implementierung auf niedrigem Niveau zu stagnieren und es können diverse Fehler insbesondere bei der korrekten
Dimensionierung des Hintergrundbildes auftreten. Je nachdem, ob width
und height
explizit gesetzt sind oder auf welchen Wert, insbesondere in
welcher Einheit, was für preserveAspectRatio
angegeben wird, kann es
da zu verschieden unsinnigen Dimensionierungen kommen oder zum Abschneiden des Bildrandes
abhängig von viewBox
, was die Nutzbarkeit von SVG-Hintergrundbildern
bei diesen Darstellungsprogrammen immer noch stark einschränkt - teilweise gilt das auch
für eingebettete SVGs.
Prinzipiell, wenn man einmal von den noch zu beseitigenden Fehlern einiger Darstellungsprogramme absieht, ist es einfach, ebenfalls bei anderen Elementen das Hintergrundbild passend zu skalieren, was bei diversen Layouts recht nützlich sein kann, wo etwa in Navigationsmenüs die Verweise oft als Knöpfe ausgebildet sind. Die Knöpfe sind oft als Hintergrundgraphik umgesetzt, was eine Skalierung oder Anpassung der Größe des Hintergrundbildes an die aktuelle Schriftgröße des Lesers notwendig macht, um die optimale Lesbarkeit des Verweistextes bei gleichzeitigem Erhalt der Layoutidee zu realisieren.
Da mit SVG auch Pixelgraphik eingebunden und transformiert werden kann, gilt das dann auch
für Pixelgraphik. Da allerdings bei CSS dringend zu empfehlen ist, eine Hintergrundfarbe
anzugeben, die zur Schriftfarbe passend ist, ergeben sich durch die fehlende Darstellung von
SVG-Hintergrundbildern auch für Nutzer alter Programme bei der Seite keine Probleme, weswegen die Methode
somit problemlos einsetzbar ist. Was leider nicht nachvollziehbar ist, ist eine alternative Angabe eines
Pixelgraphikhintergrundbildes vor dem SVG-Hintergrundbild als zusätzliche
Eigenschaft. Dies ist erst für CSS 3 vorgesehen.
Bleibt also nur die Angabe der Hintergrundfarbe als Alternative oder der Einsatz von einem
zusätzlichen Element div
, welches den ganzen Anzeigebereich abdeckt. Dann wird
die Pixelgraphik für das Element html
verwendet und die Vektorgraphik für
das div
, welches html
komplett verdeckt. Die Vektorgraphik sollte
dann keine teiltransparenten Stellen aufweisen und html
bekommt dann eine Angabe zur
Hintergrundfarbe, nicht das div
.
Wenn das SVG-Hintergrundbild auch mit alten, fehlerhaften Programmversionen angezeigt werden soll,
bleibt also die (allerdings inhaltlich schlechte) Möglichkeit,
SVG als object
einzubinden oder Pixelgraphik als Bild.
Pixelgraphik verfügt nur über Pixel als Maßangabe, die
zum Skalieren nur schlecht geeignet ist, ein entscheidender Nachteil gegenüber SVG,
der Vorteil liegt darin, daß auch alte Programme besonders JPEG/JFIF richtig darstellen
können, die meisten auch PNG (selbst Netscape 4 und der MSIE
bis Version 6 können das bis auf Teiltransparenz). Aufgrund der verwendeten Kompressionsmethode
kann ein JPEG/JFIF sogar in gewissen Grenzen skalierbar sein, ohne daß die Qualitätsverluste
zu arg auffallen.
Trotzdem gibt es bei den Formaten JPEG oder PNG keine Möglichkeit, eine Größe von hundert Prozent anzugeben, so daß sich Bilder in dieses Formaten nicht allein als Hintergrundgraphilk mit CSS 2 an den Anzeigebereich anpassen lassen. Somit gibt es für dieses Problem keine Lösung bei der Verwendung von Pixelgraphik, die nicht in ein SVG eingebunden ist. Es ist nicht möglich, allein mit XHTML und CSS2 eine Pixelgraphik als Hintergrundbild an die Größe des aktuellen Anzeigebereiches des Darstellungsprogrammes anzupassen.
Allerdings ist es mit CSS möglich, ein Bild auf die Größe des Anzeigebereiches zu skalieren, ohne diese überhaupt absolut zu kennen. Dies kann als Ersatzlösung des Problems verwendet werden. Fraglich bleibt es allerdings, ob es wirklich Situationen gibt, wo es sinnvoll ist, ein Vordergrundbild derart zu skalieren. Als kleine CSS-Übung ist die Aufgabenstellung allerdings ideal. Was wichtiger und relevant für eine eigene Seite ist, ist Bilder allgemein relativ zu ihrem umgebenden Kasten skalieren zu können, damit sie nicht seitlich aus einem CSS-Bereich definierter Breite herausragen. Etwa kann angegeben werden in XHTML:
<p> Sonstiger Inhalt<br /> <img class="skaliere" ... /><br /> Weiterer Inhalt </p>
und dann in der CSS-Datei:
img.skaliere { max-width: 100%; height: auto; }
Nachdem damit die korrekte Lösung mit SVG und CSS und das allgemein Nützliche abgehandelt ist, kommen wir nun zu dem Teil, der in meinen Augen für die Praxis nicht nützlich ist, aber Spaß beim Basteln macht - jedenfalls würde ich das nie ernsthaft auf einer Seite einsetzen: Ein Bild als XHTML-Element als 'Hintergrundbild' nutzen und an die Größe des Anzeigebereiches anpassen.
Um dieses zu bewerkstelligen, ist es erst einmal notwendig, das Element body
über den
gesamten Anzeigebereich erstrecken zu lassen. Dies ist ebenfalls mit CSS möglich, indem
margin
und padding
auf 0
gesetzt werden, Höhe und Breite aber jeweils auf hundert Prozent gesetzt werden. Vorsorglich sollte dann auch
overflow: hidden
gesetzt werden.
Das spätere Bild, welches als Hintergrund verwendet werden soll, ist nun
als normales Bild mit dem Element img
oder object
in den
body
-Bereich einzufügen.
Da img
oder object
selbst inzeilige Elemente sind, muß man es
zusätzlich in ein Blockelement setzen. Da das keine spezifische Bedeutung hat,
wird dafür ein div
-Element verwendet. Wenn dies direkt hinter dem
Element body
erfolgt, sind später nicht die
Schichtpositionen mit z-index
festzulegen.
Nachteil dieser Position im XHTML-Quelltext ist allerdings die Anzeige des
Bildes an dieser Stelle, wenn das Darstellungsprogramm kein CSS aktiviert
hat.
Dem kann mit eimem Trick entgegengewirkt werden, indem die
XHTML-Attribute für Höhe und Breite auf 1 Pixel gesetzt werden.
Anschließend sind Höhe und Breite des Bildes mit einer direkten
CSS-Formatierung auf hundert Prozent zu setzen.
Der eigentliche Inhalt der Seite wird anschließend in einem weiteren div
-Element eingefügt.
Dieses div
-Element wird absolut positioniert und zwar mit
top, bottom, left
und right
jeweils auf
0.
Um gegebenenfalls notwendige Rollbalken zu bekommen, muß
dieses div
-Element mit overflow: auto
ausgestattet werden.
Damit der eigentliche Inhalt noch einen Randabstand bekommt, ist dieser mit padding
anzugeben.
Beispiel: Hintergrundbild an die Größe des Anzeigebereiches fließend anpassen
Zu sehen ist, daß das normale Seitenverhältnis des Bildes in der Regel nicht
erhalten bleibt. Ist dies erwünscht, sollte nur die Breite des Bildes auf hundert Prozent
festgelegt werden. Auch die Höhenangabe im XHTML-Attribut muß dann wegfallen,
beziehungsweise wird die Höhenangaben per CSS auf 'auto' gesetzt.
Dann bleibt das Seitenverhältnis des Bildes erhalten. Das Bild
wird aber je nach dem Seitenverhältnis des Anzeigebereiches nur teilweise sichtbar sein oder
es wird den Anzeigebereich nur teilweise abdecken - man kann eben nicht alles haben.
Nun kann das gleiche Prinzip verwendet werden, um mittels object
statt img
eine SVG einzubinden:
SVG-Hintergrundbild an die Größe
des Anzeigebereiches fließend anpassen.
Da die oben beschriebene Methode besser ist, sollte diese Möglichkeit nur als Spielerei verstanden werden.
Bei einer ernsthaften Anwendung sollte auch eine Möglichkeit vorgesehen werden,
CSS explizit abzuschalten oder Nutzer älterer Programme zur Darstellung von
SVG und XHTML vorzuwarnen.
Mit Opera 9 funktioniert es bereits, erweist sich aber als unnötig in diesem Zusammenhang, weil ab
Opera 9.50 alpha/beta auch die Einbindung als SVG-Hintergrundbild bereits funktioniert.
Konqueror+KSVG1, Konqueror+Adobe-plugin,
MSIE+Adobe-plugin und Opera 8 haben einen Fehler, daß das
SVG immer im Vordergrund zeigt, weswegen da der eigentliche Inhalt nicht mehr sichtbar ist.
Gecko 1.8 (SeaMonkey 1, Firefox 2) stellt es nach lägerer Wartezeit ebenfalls dar, friert aber nahezu ein und
ist kaum noch nutzbar. Amaya 9.5 stellt das Bild nicht dar. Programme, die gar kein SVG darstellen
können, werden die leere Alternative des verwendeten Elementes object
verwenden und keine
Probleme haben.
Beispiel 2: Hintergrundbild an die Größe des Anzeigebereiches
fließend anpassen
Hier wird der gleiche Effekt mit etwas anderen Mitteln erreicht. Die Positionierung und Skalierung
erfolgt hier komplett mit einer CSS-Angabe im Stilbereich, nicht durch Direktformatierung.
Die SVG-Version:
SVG-Hintergrundbild an die Größe des Anzeigebereiches fließend anpassen.
Nun, 2009 ergab auch das nur mit Opera 9 das gewünschte korrekte
Ergebnis, was wohl einmal mehr zeigt, daß Opera technologisch eine Spitzenposition einnimmt, was
die Unterstützung von SVG oder gemischten Formaten
SVG+XHTML anbelangt.
Eine weitere Variante wäre, SVG und XHTML direkt in einem
Dokument zu mischen.
1. Netscape 4 beherrscht das Skalieren der Bilder nicht richtig. Da wir aber das Bild per XHTML auf einen Pixel gesetzt haben, ist praktisch gar kein Bild statt des Hintergrundbildes zu sehen. Man sollte sowieso immer eine passende Hintergrundfarbe angeben.
2. Microsoft internet explorer (msie, Version 6 getestet) hatte kleinere Probleme mit dem
Rollbalken für den eigentlichen Inhalt. Daher wird overflow: hidden
für das Element body
mit dem üblichen Trick vor ihm versteckt:
das Element body
bekommt eine id
und die
CSS-Zuweisung
nutzt einfach 'body
[id
]'.
Nun wird das Bild korrekt skaliert, wird aber fälschlich mitgerollt. Im Bedarfsfalle sollte
man eine passende Hintergrundfarbe angeben. Im zweiten Falle beherrscht der msie natürlich
auch position
: fixed nicht, was aber hier nicht
so gravierend ist, da er dafür fälschlich
position
: static
interpretiert, was auch dazu führt, daß das Bild mitrollt.
3. Konqueror (Version 3.2 getestet) zeigt bei derartig positionierten Elementen
für den body
(?) immer einen Rollbalken an, egal was man
für CSS-Anweisungen gibt.
Aber damit kann man leben. Spätere Versionen (3.3.2 getestet) sind hingegen
komplett in Ordnung.
Der ältere Konqueror (Version 2.2 getestet) skaliert hingegen nur die Breite
des Bildes und rollt ebenso verkehrt wie der msie.
4. Geckos wie Mozilla, SeaMonkey oder Firefox funktionieren problemlos (getestet mit rev 1.5 - 1.8), ebenso Opera (getestet mit 7, 8, 9)