Dr. O. Hoffmann
Der Fehler begleitet den Menschen.
Platon
Wer einen Fehler gemacht hat und nicht korrigiert,
begeht einen zweiten.
Konfuzius
Erstellt oder aktualisiert: 2005-02-14/20; 2005-06-07/10-25; 2007-12-13; 2010-10-05; 2013-03-12
Ich habe festgestellt, daß es vielen Seitenerstellern schwerfällt, bei
eigenen Projekten Fehler zu suchen oder noch wichtiger zu finden.
Generell ist es natürlich immer einfacher, sie von vorne herein zu vermeiden.
Dabei helfen erst einmal Editoren mit farblicher Strukturhervorhebung
(Syntax-Highlightning, zum Beispiel Kate und Kwrite
bei KDE und viele andere
mehr - die Editoren sollen dann natürlich das Format und seine Syntax kennen, um
die Struktur sinnvoll hervorheben zu können). Anhand der Hervorhebung ist meist
gleich beim Schreiben zu erkennen, wenn noch etwas fehlt oder anders formuliert werden
muß. Dieses Vorgehen ist bei einfachen Schreib- und Flüchtigkeitsfehlern meist
bereits erfolgreich. Allerdings untersuchen solche Editoren nur die Syntax an sich und
kümmern sich nicht um den Inhalt - falsche Reihenfolge von Parametern und
inhaltliche Fehler werden sie in der Regel nicht aufdecken. Auch welche Elemente in
welchen verschachtelt werden dürfen oder eben auch nicht, werden solche Programme
oft nicht komplett untersuchen.
Eine andere hilfreiche Vorgehensweise ist es, Strukturen wie Klammern oder
XHTML-auf- und zu-Markierungen (tags)
erst komplett zu notieren und dann erst mit Inhalt zu füllen, so
vergißt man seltener das Schließen von solchen Strukturen. Ferner kann
es bei verschachtelten Strukturen sinnvoll sein, die auf- und zu-Markierungen mit eindeutigen
Kommentaren zu versehen, um sie sich jederzeit gegenseitig zuordnen zu können.
Um zügig hartnäckigen Fehlern auf die Spur zu kommen, hat sich eine Methode bewährt, die darauf beruht, nach Herstellung einer Sicherheitskopie das Problemdokument schrittweise so weit zu reduzieren, bis der Fehler nicht mehr auftaucht und dann den zuletzt entfernten Abschnitt genauer zu untersuchen. Bleibt der Fehler immer noch rätselhaft, so sollte ein minimales, aber voll funktionsfähiges Modelldokument erstellt werden, in dem der Fehler noch auftaucht, welches aber nicht mehr Struktur und Inhalt enthält, als unbedingt notwendig, um den Fehler zu erzeugen. Solche Dokumente eignen sich, um sie in Foren anderen zur Diskussion zu stellen oder aber auch, um Fehler zu dokumentieren, die man nicht selbst verursacht hat, sondern zum Beispiel ein Fehler eines Darstellungsprogrammes ist oder des PHP-parsers oder sonst eines Programmes. Solche Modelldokumente eignen sich ebenfalls, um per Diskussion zu klären, ob es sich wirklich um einen Fehler solcher Programme handelt oder vielleicht doch um einen eigenen. Ferner können solche Modelldokumente dann gegebenenfalls auch mit Listen bereits bekannter Fehler von Programmen verglichen werden oder aber an die Entwickler zur Information eingesendet werden. Letzteres hat aber nur Sinn, wenn der Fehler wirklich auf seinen Kern reduziert ist und kein Raum für nicht relevante andere Dinge gelassen wird. Das hilft seinerseits den Entwicklern, Fehler zu lokalisieren und zügig zu beseitigen.
Eine weitere häufig erfolgreiche Strategie ist, Fehler groß zu machen. Das ist immer dann gut realisierbar, wenn das Auftreten, die Häufigkeit oder das Erscheinungsbild von Fehlern manipuliert werden kann. Statt den Fehler also zu verbergen, zu vertuschen oder zu minimieren, erweist es sich im Gegenteil als vorteilhaft, den Fehler unübersehbar zu machen, bis ins Absurde aufzublähen. Schließlich fällt es Elefanten auch deutlich schwerer, sich Jägern zu entziehen als es den Mücken möglich ist. Auch bei der Dokumentation von Fehlern ist ein offensichtlicher Fehler immer besser und eindrucksvoller für Helfer oder die dafür Verantwortlichen als etwas, was man mühsam suchen muß. Ein auffälliger Fehler in einem Testdokument ist für einen Entwickler psychologisch deutlich relevanter als ein winziger Schönheitsfleck, den nur Experten mit einer Lupe erkennen können.
Sofern Fehlerlisten auf irgendeine Weise zur Verfügung stehen, sollten die bei Unklarheiten von vorne nach hinten abgearbeitet werden. Gerade bei Syntaxfehlern, die von Programmen analysiert werden, verschwinden oft so Fehlinterpretationen von selbst oder es treten weitere Fehler erst für das Programm zu Tage.
Zur Fehleranalyse ist es meist hilfreich, die Fehleranzeige von PHP komplett anzuschalten. PHP gibt hier eine sehr schöne Hilfe mit Fehlermeldungen, Warnungen und Notizen, die ein schnelles Auffinden von Fehlern stark erleichtern. Am Anfang eines PHP-Dokumentes sollte daher immer notiert werden:
error_reporting(E_ALL);
Eine relevante Frage ist auch, ob die genutzte Funktion überhaupt in der genutzten PHP-Version vorhanden ist oder genau so genutzt wird, wie es im Handbuch steht. Die genutzte PHP-Version und zahlreiche Voreinstellungen, installierte Module können über die PHP-Information eingesehen werden, dazu dient ein PHP-Dokument mit folgendem Inhalt:
<?php phpinfo(); ?>
Besonders zu achten ist auch auf Einstellungen von:
Im PHP-Handbuch - siehe den Menüpunkt Verweise - ist dokumentiert, welche Funktion wie bei welcher Version in welcher Form zur Verfügung steht.
Ein Problem, welches öfter auftritt, wenn die
header
-Funktion genutzt
wird, möchte ich noch kurz genauer erläutern, weil dem Fehler von
Unerfahrenen nur schwer auf die Schliche zu kommen ist. Manches Mal kommt die
Fehlermeldung, daß bereits ein header
gesendet wurde.
Das liegt fast immer
daran, daß vor dem header
bereits eine Textausgabe erfolgt, entweder absichtlich
oder versehentlich. Das wird in der Regel nicht sinnvoll funktionieren. header
und
auch damit zusammenhängende cookies sind zu senden, bevor
jeglicher sonstiger Inhalt ausgegeben wird.
Auch Leerzeichen und Zeilenumbrüche außerhalb der PHP-Elementes vor dem
header
führen dazu, daß der server bereits einen header
für Textausgabe
sendet. Das ist daher zu vermeiden. Typisch ist etwa eine solche Konstruktion als Fehlerursache:
<!-- Kommentar, Leerzeichen, Zeilenumbruch etc --> <?php Header("Content-type: image/png"); # etc php-Quelltext ... ?>
Was als Kommentar sichtbar angegeben ist, kann auch ein schlichtes Leerzeichen oder
ein Zeilenumbruch sein. Zeilenumbrüche sind auch von Betriebssystem zu
Betriebssystem verschieden, in der Hinsicht auch die Empfindlichkeit der
parser.
Auf dem lokalen Test-server kann daher manchmal funktionieren, was auf dem
richtigen unix- oder linux-server dann zu Fehlern führt. Eine andere
Fehlerquelle sind Dateien, die per include
eingebunden werden, etwa so, erst
die einbindende Datei, dann die eingebundene:
<?php include('initialisierung.php'); Header("Content-type: image/png"); # etc php-Quelltext ... ?>
<?php # Datei initialisierung.php # etc php-Quelltext ... ?> <!-- Kommentar, Leerzeichen, Zeilenumbruch etc -->
Zeilenumbrüche und Leerzeichen am Ende der eingebundenen
Datei werden also ebenfalls zum Senden eines unerwünschten headers
führen und sind nur schwer zu finden.
Sollen wirklich mehrere header gesendet werden, so stellt PHP dafür
bei der header
-Funktion übrigens eine besondere Option zur
Verfügung.
Eine weitere etwas kniffligere Fehlerquelle, nach der man lange suchen kann,
sind Variablen, die versehentlich
doppelt auftauchen. Das passiert etwa, wenn
recht kurze oder typische Variablennamen in verschiedenen PHP-Dateien
genutzt werden, die zum Beispiel per include
miteinander verbunden werden.
Das jüngste Beispiel aus dem eigenen Gruselkabinett: eine Variable namens
$flag, die ich in zwei Dateien verwendet habe, die ich per
include
miteinander
verbunden habe. Entgegenwirken kann man solchen unangenehmen Fehlern,
indem man sich möglichst dateispezifische und funktionsbezeichnende
Variablennamen ausdenkt, besonders dann, wenn diese vor einem include
definiert werden und danach noch genutzt. Hier zeigt sich einer der Nachteile
der recht lockeren Variablenverwaltung in PHP - welches ja wohl eigentlich
für größere Vorhaben gar nicht gedacht war.
Ein Quell weiterer Freude kann das Vergleichen von Variablen
werden - was
scheinbar gleich ist, will in PHP bei einem Vergleich einfach nicht identisch
sein. Als Tip hier: Die beiden zu vergleichenden Variablen per echo
ausgeben
und zwar durch ein markantes Anfangs- und Endzeichen verziert - etwa ein *.
Innerhalb von XHTML empfiehlt sich um die Ausgabe herum auch die
Anwendung des pre
-Elementes, denn Grund für
derartige Probleme ist
oft unsichtbarer sogenannter whitespace -
die englische Bezeichnung für Leerzeichen, Zeilenumbrüche und ähnliches.
Dieses muß dann letztlich vor einem Vergleich mit
geeigneten PHP-Funktionen entfernt werden (etwa trim
) - oder der
Vergleich muß anders vorgenommen werden, zum Beispiel die
Suche nach Zeichenfolgen.
Auch wenn irgendwie unklar geworden ist, was Variablen für
Werte beinhalten oder warum nicht genau das passiert, was man aufgrund
des Wertes einer Variable vermutet, empfiehlt es sich immer, den Wert
der Variable an der fraglichen Stelle per echo
auszugeben.
Ist in der Konfiguration von PHP noch short_open_tag aktiviert, so kommt es
häufig bei XML-Ausgaben zu einer Fehlermeldung, weil XML-Verarbeitungsanweisungen dann von
PHP als eigene Verarbeitungsanweisungen interpretiert werden. Die beste Lösung liegt
darin, diese mangelhafte und auch überflüssige Funktion von PHP zu deaktivieren.
Ist das aus irgendwelchen Gründen nicht möglich oder nicht erwünscht, so können stattdessen auch
die XML-Verarbeitungsanweisungen per echo
innerhalb des PHP-Bereiches
ausgegeben werden, statt sie außerhalb zu notieren.
Voneinander abzugrenzen sind zunächst mal eigene
Syntaxfehler des Autors,
die fehlerhafte Verwendung von Elementen und Attributen, die eine andere Funktion haben oder von
div
- und span
-Elementen für Funktionen, für die es
andere spezifische Elemente
gibt. Weiterhin gibt es auch falsche Erwartungen des Autors
an die Anzeige von Elementen, aber auch echte Anzeigefehler,
die auf der Seite des Darstellungsprogrammes liegen.
Bei der Fehleranalyse kommt es nun darauf an, diese Möglichkeiten
auseinanderzuhalten und an der richtigen Stelle nach Ursachen zu suchen.
Einfaches und bewährtes Mittel, um Syntaxfehler zu finden, ist erst einmal
die Nutzung von Validatoren oder von
Fehlerlisten, die Anzeigeprogramme
anbieten. Einige Validatoren habe ich unter dem Menüpunkt Verweise
angegeben, ein schönes Anzeigeprogramm, welches für XML,
XHTML, MathML, SVG etc
Fehlerlisten liefert, ist das Darstellungsprogramm Amaya von W3C.
Andere Darstellungsprogramme können oftmals zur Offenlegung von Fehlern bewegt werden,
die sie oft sonst vertuschen, indem entweder die Dateiendung .xml gewählt wird
oder aber etwa per PHP ein XML-header
gesendet wird, etwa so:
<?php $content="Content-type: text/xml"; header($content); ?> <!-- weiterer SVG- oder XHTML-Quelltext -->
Das sollte zumindest bei groben Syntaxfehlern zum Abbruch der Anzeige führen und zur Ausgabe einer Fehlermeldung.
Andersherum ist es mir zunehmend besonders bei einem XML wie
SVG begegnet,
daß Dateien mit der Endung .svg oder .svgz
(komprimierte Version) nicht angezeigt werden können. Häufig stellt
sich dann heraus, daß der server schlecht konfiguriert ist, er kenne den
MIME-Typ
für .svgz nicht oder gar noch nicht mal für .svg
und sendet stattdessen dann text/svg oder text/svgz,
was das Darstellungsprogramm zum Anlaß nehmen kann,
solch ein Format nicht zu kennen. Einige Autoren verwenden statt image/svg+xml
auch image/svg-xml, was aber auch Unfug ist. Der einzig korrekte MIME-Typ für SVG ist image/svg+xml. Alles andere kann bei einem korrekt
funktionierenden Darstellungsprogramm dazu führen, daß das Bild nicht angezeigt
wird. Ähnlich kann es anderen speziellen XML passieren, deren
MIME-Typ der server nicht kennt. Vorrangig sind solche Fehler vom Betreiber
des servers zu beseitigen. Ist dieser unwillig, so kann der Autor immer noch selbst per
PHP den richtigen MIME-Typ senden, eventuell dann
mit readfile
die Datei hinterherschicken, wenn es nicht selbst eine
PHP-Datei ist. Andere Fehlerquellen
sind natürlich parser-Fehler oder Syntaxfehler im
XML-Format. Mit dem
entsprechenden Validator ist das zu überprüfen. Für SVG
kann der gleiche wie für HTML und XHTML von
W3C verwendet werden.
Auch fehlerhafte Angaben zum Dokumenttyp können dazu führen,
daß nichts angezeigt wird. Hier empfiehlt sich immer der Dokumenttyp
wie in der aktuellen Spezifikation angegeben und nicht irgendwelche
Phantasie-Namen.
Bei XHTML ist der komplett richtige MIME-Typ übrigens application/xhtml+xml.
Übergangsweise ist aber auch noch text/html für solche Programme akzeptabel, die kein XHTML
interpretieren können. Letztlich ist es
auch Aufgabe des Betreibers des servers, dies korrekt ablaufen zu lassen, notfalls
muß dazu eben der Dokumentkopf untersucht werden, bevor ein falscher
MIME-Typ gesendet wird. Wird text/html gesendet,
handelt es sich formal allerdings nicht um XHTML.
Eher suboptimal ist bei gemischten XMLs auch, eine Dokumenttypdeklaration
anzugeben, die nur zu einem Format paßt, etwa jene für XHTML wenn das
Dokument auch SVG enthält. Für den Fall gibt es sogar einen vom W3C abgesegneten Dokumenttyp, wenn es den nicht gibt, sollte die Angabe der
jeweiligen Namensräume hinreichend sein, wenn ein XML-MIME-Typ gesendet wurde. Für den Autor ergibt sich
offenbar das Problem, daß er schlecht einschätzen kann, ob die verwendeten Formate
vom Darstellungsprogramm interpretiert werden und das Darstellungsprogramm kann wiederum
schlecht anhand des gesendeten MIME-Typs beurteilen, ob es das Dokument
darstellen kann. Dies muß gegebenfalls genauer untersucht werden. In SVG
gibt es dazu Attribute zur bedingten Verarbeitung und das Element switch
,
allgemein bietet das Darstellungsprogramm oft Hilfen an, die mit PHP
ausgelesen werden können, um passenden Inhalt zusammenzustellen.
Der wichtigste Schritt bei Einzelformaten ist die Angabe der XML-Deklaration und des Namensraumes, soweit vorhanden des doctypes beziehungsweise der verwendeten Sprachvariante, sonst ist die Syntax im Grunde gar nicht definiert und Fehler im engeren Sinne können auch nicht angegeben und aufgefunden werden. Fehlende oder unvollständige Angaben nehmen zahlreiche Darstellungsprogramme zum Anlaß, sich aus der Anzeige einen Spaß zu machen und von den gut dokumentierten Standards nach Gutdünken abzuweichen. Die Programm-Entwickler nennen diese Anzeigeart auch Quirks-Modus - ich denke, die Bezeichnung spricht für sich - sie klingt nicht zufällig nach Unfug, Schabernack und Blödsinn.
Wenn zudem vergessen wird, sowohl die verwendete
Kodierung (englisch: encoding) anzugeben,
als auch Sonderzeichen zu maskieren, werden einige spätere
Nutzer sicher über bizarre Zeichen staunen, weil ihr Darstellungsprogramm
zufällig eine andere Kodierung verwendet als der Editor des
Seitenerstellers. Relevant ist übrigens die Angabe des servers bei einer
HTTP-Verbindung, nicht die Angaben in der Datei selbst. Gegebenenfalls ist
dafür zu sorgen, daß entweder die Angabe des servers korrigiert
wird oder das Dokument an die Angaben des servers angepaßt wird.
Zudem - pro Dokument gibt es exakt eine korrekte Angabe der Kodierung - auch wenn die
Ausgabe etwa per PHP aus mehreren Dokumenten oder Datenbankeinträgen zusammengesetzt wird,
hat diese Ausgabe immer exakt eine Kodierung - gegebenenfalls ist es also notwendig, nicht passende
Teile umzukodieren, bevor sie zu einem neuen Dokument zusammengestellt werden.
Eine Maskierung von Sonderzeichen funktioniert in der Praxis auch nur bei HTML und einigen Versionen von XHTML. Obgleich sie bei allen Varianten von XHTML und wenigen anderen Formaten definiert sein mögen, verweigern die meisten Darstellungsprogramme meist die Kenntnis der Maskierungen, es führen dann nur die numerischen Angaben zum Erfolg, die man sich allerdings deutlich schwerer merken kann als die Abkürzungen etwa für HTML.
Beliebt ist auch bei der Verwendung von PHP das Vergessen der
Maskierung des Sonderzeichens & im
href
-Attribut des
a
-Elementes - in Kombination mit anderen Zeichen kann das bei einigen
Darstellungsprogrammen mächtig in die Hose gehen - natürlich niemals
bei ausgerechnet dem Darstellungsprogramm, das der Autor benutzt, um seine
Seite zu testen.
Nur weil ich gesehen habe, daß das dies bereits einige auf dieser
Seite gesucht haben - in SVG sind
Umlaute und die ß-Ligatur
nicht in einer speziellen maskierten Form wie bei HTML verfügbar.
Nutzt man Umlaute, muß man je nach Kodierung vorgehen.
Bei ISO-8859-1 oder UTF-8 etc müssen Umlaute
eigentlich nicht maskiert werden und können direkt benutzt werden.
Mit PHP kann auch explizit der Zeichensatz mit dem
MIME-Typ gesendet werden:
header("Content-type: image/svg+xml; charset=ISO-8859-1");
Ohne Angaben zur Kodierung oder mit Angabe
von UTF-8 ist keine Maskierung notwendig, wenn der Editor die
Datei wirklich als UTF-8 abspeichert. Probleme kann es dann
natürlich immer noch geben, wenn der Rechner des Nutzers
keine UTF-Zeichenkodierung kennt, was allerdings nur noch bei
antiken Betriebssystemen vorkommen sollte. Die Glyphen selbst müssen dann in den
verfügbaren Zeichensätzen allerdings noch lange nicht vorhanden sein, zumindest
Umlaute und die ß-Ligatur sollten aber inzwischen immer verfügbar sein.
Will man ganz sicher gehen, was die Kodierung anbelangt, nicht die Verfügbarkeit der
Glyphen, kann man die Maskierung per Hand vornehmen, etwa so:
ä ö ü Ä Ö Ü ß
ä ö ü Ä Ö Ü ß
Beispiel mit obiger Maskierung und mit ISO-Zeichensatz.
Wenn es bei eigenen Dateien zu Fehlern kommt, ist vermutlich also
die Datei mit der falschen Kodierung abgespeichert worden oder
aber es ist vergessen worden, in der ersten Zeile das richtige
encoding anzugeben - in jedem Falle soll beides zusammenpassen.
Genau das gleiche Verfahren gilt übrigens auch für alle
anderen XML-Formate. Spezielle Maskierungen wie ß sind so
nur in der XHTML-Dokumenttypdeklaration vorgesehen. Bei eigenen
Formaten kann das natürlich genauso definiert werden, eine
Erweiterung der Dokumenttypdefinition im Rahmen von XML kann formal einfach
vorgenommen werden. Persönlich habe ich dabei keine Probleme beobachtet.
Wenn man ganz sicher gehen will, sollte man das aber vermeiden, weil noch
nicht davon ausgegangen werden kann, daß dies alle Darstellungsprogramme
berücksichtigen werden. Wie es genau geht, ist dem Quelltext des obigen
Beispiels zu entnehmen.
Ein weiterer Stolperstein besonders für Anfänger ist die korrekte Angaben von Verzeichnissen und Dateinamen innerhalb von Verweisen oder der URI-Angabe von Bildern. Die Markierung von Verzeichnissen ist immer / und nichts anderes, Leer- und Sonderzeichen müssen maskiert oder vermieden werden. Es wird zwischen Groß- und Kleinschreibung jedes einzelnen Buchstabens unterschieden, Ausnahme dabei ist der Rechnername (domain, subdomain).
Bei den (X)HTML-strict-Varianten oder bei der Neuformulierung
XHTML1.1 fehlen zahlreiche
überflüssige Elemente und Attribute gegenüber HTML3.2 und
der transitional-Variante von HTML4. Das ist Absicht. All diese
fehlenden Elemente und Attribute haben sich als
Fehlentwicklungen
oder eben als überflüssig
erwiesen. Attribute und Elemente, die der visuellen Anzeige dienten, können
einfach und elegant durch CSS ersetzt werden. So konzentriert
sich XHTML wieder auf seine eigentliche Aufgabe, die Auszeichnung von Text gemäß seiner Funktion. Im Sinne einer strikten Trennung von Inhalt und Layout dient
CSS der Art der Darstellung.
Als XML-Format erfordert in XHTML in jedem Falle jede Elementmarkierung einen Elementendemarkierung.
Bei der fehlerhaften Verwendung von XHTML-Elementen und
den falschen Erwartungen,
die an Elemente gestellt werden, geht es meist darum, daß der Seitenersteller eine
gewisse Erwartungshaltung hat, wie ein XHTML-Element dargestellt wird.
Nun ist XHTML gar nicht dazu da, um festzulegen, wie etwas angezeigt wird,
es gibt vielmehr an, was für ein Inhalt drinsteckt. Typisches Beispiel sind die
Tabellen-Elemente, die von vielen Leuten (immer noch) genutzt werden, um beliebigen Inhalt
anzuordnen oder zu positionieren. Nun, Tabellen-Elemente kennzeichnen Inhalt
als tabellenartig - was heißt das nun? Mittels Tabellen werden
Mengen miteinander korreliert. Aufgabe des Darstellungsprogrammes ist somit die systematische
Anordung der Tabellenzellen, um die Art der Korrelation hervorzuheben.
Diese Anforderung kann komplexe Algorithmen zur Folge haben, wie der
Inhalt der Tabellen relativ zueinander genau angeordnet wird. Verschiedene
Drstellungsprogramme können dies Problem zudem ganz verschieden lösen.
Die Erwartung einer einheitlichen Anordnung oder Positionierung von Inhalt
mit Tabellen wird somit oft enttäuscht, insbesondere wenn es noch
Syntaxfehler in der komplexen Tabellenstruktur gibt oder Anzeigekonflikte
zwischen verschiedenen Größenvorgaben des Autors oder der
Größe des Inhalts. Auch hier gilt:
Positionierung und Anordnung
von Inhalt ist eine Aufgabe von CSS und nicht von
XHTML.
Hierbei handelt es sich also nicht um einen Fehler des jeweiligen Programmes,
der etwas anderes anzeigt als der Seitenautor erwartet, sondern immer
eine falsche Erwartung und ein mangelndes Verständnis der
Aufgaben von XHTML. Ein Blick in die jeweilige Spezifikation des Elementes
hätte hier eine Menge Ärger und Aufregung erspart.
Darstellungsprogramme
können natürlich auch selbst
Fehler und Lücken haben. Als Lücke in der
Interpretation eines Dateiformates würde man interpretieren, wenn
das Programm ein Element oder ein Attribut komplett ignoriert.
Bei HTML oder XHTML ist das besonders bei
älteren Darstellungsprogrammen auffällig.
Neben einigem anderen ignoriert netscape4 zum Beispiel das Elemente iframe
aus dem Bereich der transitional-Varianten. Der microsoft internet explorer 6
(msie 6) ignoriert das Element abbr
. Beim
XHTML-Modul ruby
dürften auch einige neuere Programme noch Probleme haben. Diese Elemente werden allerdings
eher im asiatischen Raum gebraucht, weswegen diese Lücken nicht
so schnell auffallen werden. Probleme können auch noch beim
object
-Element auftreten. Man muß hier aber zwischen der eigentlichen
Interpretation des object
-Elementes unterscheiden und der
Darstellung des referenzierten Objektes, welches ein ganz anderes
Problem ist, welches nichts mit XHTML zu tun hat, sondern mit der
Methode, mit dem das Format des Objektes interpretiert wird.
Bei msie etwa scheint seit einem Aktualisierungspaket die Interpretation des
object
-Elementes selbst schwer gestört zu sein.
Gravierender ist das Problem, daß in XHTML das id
-Attribut statt des
name
-Attributes verwendet wird, um Ziele von
Ankern zu definieren. Da kann es ebenfalls bei einigen alten Darstellungsprogrammen
Probleme geben.
Spektakulär oder fast schon legendär ist die weit verbreitete
Lücke beim link
-Element (immerhin schon seit
HTML2 eingeführt).
Bekannt ist mir, daß das originale Mozilla-Programm (und seine Nachfolger SeaMonkey und
Iceape) das link
-Element komplett
interpretiert, wenn man dieses so voreinstellt. Für dessen
Sparversionen firefox oder iceweasel gibt es hingegen nur eine Erweiterung, mit der Ähnliches
erreicht werden kann. Opera7-12 interpretieren das link
-Element zu
einem größeren Teil, Konqueror3 und msie6 ignorieren das Element nahezu
komplett mit Ausnahme der
Angaben zu Stilvorlagen und zum favicon.ico - der msie interpretiert selbst die
Angaben zu Stilvorlagen nur teilweise. Der text-browser lynx hingegen hat keine
Probleme mit dem link
-Element. Lange Zeit war wohl auch nicht klar, wie dieses
Element interpretiert werden soll, die Mozilla-Methode spiegelt die eigentliche Funktion
des Elementes aber korrekt und sinnvoll wider. Andere Probleme ergeben sich etwa bei
Attributen, die Information enthalten, also etwa cite
und datetime
,
die meist entweder komplett ignoriert werden oder für den Nutzer nicht weiter
hilfreich irgendwie oder nur sehr versteckt zugänglich sind.
Bei SVG ist die Situation viel kritischer. Soweit mir bekannt ist, gibt es kein Darstellungsprogramm, welches dieses Format komplett lückenlos darstellen kann - und die Lücken umfassen oft ganze Bereiche der Spezifikation.
Ein Fehler bei einem Darstellungsprogramm liegt hingegen vor, wenn Elemente falsch verglichen mit der Beschreibung in der jeweiligen Spezifikation interpretiert werden. Ein Fehler liegt auch vor, wenn ungültige Elemente interpretiert werden - das ist der Fehler, der bei weitem am häufigsten bei der Interpretation von XHTML auftritt. Um Fehler von Darstellungsprogrammen leichter herauszufinden, stellt W3C sogenannte Test-Suiten zur Verfügung, wo Beispiele erläutert angeboten werden.
Noch komplizierter wird es, wenn die Spezifikationen selbst Fehler oder Widersprüche enthalten, was leider auch vorkommt. In solch einem Falle sind natürlich die Autoren der jeweiligen Spezifiaktion oder die zuständige Arbeitsgruppe Ansprechpartner - in der Spezifikation ist angegeben, wie Rückmeldungen gegeben werden können, meist über eine öffentliche Liste. In neuen Versionen eines Formates werden bekannte alte Fehler meist behoben. Es gibt allerdings auch Formate wie CSS, wo es keine Möglichkeit für den Autor gibt, die verwendete Version festzulegen. Widersprüche und Fehler in solchen Formaten sind natürlich formal nicht mehr zu beheben. Als Autor ist es dann ratsam, auf die fehlerhaften Strukturen zu verzichten.
Voraussetzung für eine nachvollziehbare Anzeige
von CSS ist erst einmal fehlerfreies (X)HTML.
Nachdem das erreicht ist, kann auch ein Validator für
CSS verwendet werden, um CSS-Fehler aufzufinden.
Auch bei CSS gibt es oft falsche Erwartungen des Autors,
die meist darin begründet
liegen, dass er davon ausgeht, daß die Stilvorlagen von Darstellungsprogrammen alle gleich
sind und er sie mit seiner eigenen Stilvorlage nur modifizieren muß. Das
ist schlichtweg falsch. Besonders was an Randabständen
(padding, margin
),
Schriftgrößen und Farben aller Art vorgegeben ist, hängt am
jeweiligen Programm und dessen Voreinstellungen durch den
Nutzer. Eigenschaften,
die für das Layout wesentlich sind, muß der Autor
komplett vorgeben,
wenn er ihrer sicher sein will. Ein anderes Mißverständnis ergibt
sich oft bei der Schriftgröße und damit
korrelierten Eigenschaften - etwa
der Höhe und Breite von Elementen, die Text enthalten. Der Nutzer kann die
Schriftgröße nicht nur vorgeben, sondern auch eine minimale
Schriftgröße festlegen, um die Anzeige für seine Ausrüstung
(Auflösung des Monitors in Pixeln pro Millimeter) und seine
Sehgewohnheiten
optimal einzustellen. Absolute Angaben in Millimetern oder in Pixeln oder in
typographischen Einheiten wie pt sind sind somit für ein Layout von
internet-Seiten ungeeignet. Geeignet sind relative Angaben in Prozent, em
oder ex, oder xx-small, x-small,
small, medium, large, x-large,
xx-large, beziehungsweise larger, smaller.
Ein typischer Fehler, der aus der Angabe von ungeeigneten Maßeinheiten resultiert ist,
daß Inhalt beim Nutzer
nicht mehr in den vorgesehenen Bereich hineinpaßt oder Schrift zu
groß oder schlimmer zu klein erscheint, als daß sie gut lesbar
wäre. Solche Hinweise von Nutzern sollten unbedingt ernst genommen
werden und können dazu führen, daß das Layout einer Seite
mit höchster Dringlichkeit geändert werden muß.
Sollte einem einmal die Übersicht
oder das Verständnis verloren
gehen über die Abmessungen von gekennzeichneten Bereichen, so
empfiehlt es sich, diese Bereich provisorisch
mit dünnen Rahmen zu
versehen. Das führt zwar zu einer kleinen Veränderung der
Abmessungen, was aber meist einen recht kleinen Unterschied ausmacht.
Dafür ist aber eindeutig zu erkennen, von wo bis wo sich der
jeweilige Bereich erstreckt.
Dünner roter Rahmen mit outline
oder border
um ein div
-Element der
Klasse 'beispiel':
div.beispiel { border 1px solid #ff0000; }
Man beachte dabei aber, daß der margin
-Bereich
außerhalb des
border
-Bereichs liegt und erst sichtbar gemacht wird,
wenn ein umgebender,
ansonsten leerer Container mit einem solchen Rahmen ausgestattet wird.
Zu beachten bei (X)HTML ist, daß Blockelemente
wie div
, Überschriften,
Absätze etc ohne weitere Angaben die volle Breite des Elternelementes annehmen.
Ohne weitere Angabe richtet sich die Höhe hingegen nach dem Inhalt des
Elementes. Bei inzeiligen Elementen wie span, a, img
richtet sich die Breite ebenfalls
nach dem Inhalt.
Demgegenüber wird bei SVG davon ausgegangen, daß Elemente immer
eine definierte Höhe und Breite haben, die durch die Eigenschaften des
Elementes bestimmt sind beziehungsweise bestimmt werden. Das eigentliche
SVG-Element ist ebenfalls immer mit entsprechenden Angaben zu versehen.
Die Algorithmen zur Darstellung von (X)HTML-Tabellen sind sehr komplex. Hier entstehen in Zusammenhang mit CSS oft falsche Erwartungen, oft auch, weil wie oben beschrieben, Tabellen nicht funktionsgemäß eingesetzt werden. Also nochmals: (X)HTML dient der Auszeichnung des Inhalts gemäß seiner Funktion, CSS dem Design oder Layout.
Besonders bei Listen (ul, ol, li, dl, dt, dd
) ist es wichtig,
im Hinterkopf zu behalten,
daß die Einrückungen und Symbole innerhalb von (X)HTML von
verschiedenen Programmen per Voreinstellung anders realisiert werden. Um
eine einheitliche Erscheinung zu erreichen, sind bei Listen besonders
Abstände wie margin-left, padding-left
etc
explizit zu definieren.
Die Korrelation von Abmessungen innerhalb des Box-Modells ist so zu
verstehen, daß die Box-Breite die Summe der Rahmen (border
)
und Polsterung (padding
) sowie der Breite des Inhaltes ist.
Linke und rechte Außenabstände (margin
) liegen außerhalb, können aber dazu beitragen,
besonders die effektiv verfügbare Breite eines Elementes zu bestimmen, sofern nicht explizit festgelegt,
sondern automatisch berechnet.
Die Höhe ergibt sich aus dem
Rahmen und Polsterung sowie der Höhe des Inhaltes.
Je nach Struktur können untere und obere Außenabstände von aufeinanderfolgenden Boxen zusammenfallen - also jeweils der größere von beiden wird zur Darstellung gebracht.
Kurz gilt für Blockelemente (Höhe entsprechend):
'margin-left
' + 'border-left-width
' +
'padding-left
' + 'width
' +
'padding-right
' + 'border-right-width'
+
'margin-right
' = benötigte Breite der gesamten Box samt Außenabstand.
Positionierung mit top
, bottom
, left
, right
bezieht sich also auf die
Ecken beziehungsweise Kanten des von margin
umschlossenen Rechtecks.
Werden CSS-Eigenschaften scheinbar nicht angezeigt, kann es an der Spezifität der Angaben liegen. Laut Spezifikation wird diese für eine CSS2-Angabe wie folgt berechnet:
id
-Attribute in einem Selektor (=a)
Zusammenfügen der drei Zahlen a-b-c ergibt die Spezifität.
Die Angaben mit der höchsten Spezifität werden bei mehreren
Angaben interpretiert.
Angaben innerhalb des style
-Attributes sind laut CSS2.0 so zu behandeln,
als wären sie mit einem id
-Attribut angegeben.
Bei gleicher Spezifität geht allerdings die Angabe im
style
-Attribut vor. Um die Werte eines
style-Attributes
mit
Angaben innerhalb des style
-Elementes oder in einer externen Datei zu
überschreiben, muß das Element also ein id
-Attribut
haben und sinngemäß ist dann zum Beispiel eine Notation wie folgende anzuwenden:
div#id0815 { border 1px solid #ff0000; }
Spezifität hiervon ist 1-1-0, vom style
-Attribut
lediglich 1-0-0, was der
Angabe #id0815 entspricht.
Weitere Details sind in der Spezifikation nachzulesen.
Gemäß CSS2.1 entfällt diese Möglichkeit allerdings, dort ist die Angabe im style
-Attribut immer von höherer Spezifität und kann praktisch nicht mehr überschrieben werden.
Da Autoren wiederum bei CSS-Dokumenten nicht angeben können, welche Version sie verwenden, ist
das Verhalten formal undefiniert. In der Praxis werden neuere Programmversionen eher den Angaben von CSS2.1
folgen. Man sollte hier also Angaben vermeiden, die gemäß den beiden Versionen zu unterschiedlichen Ergebnissen
führen können. Ähnliches gilt für anderen Angaben, die zwischen verschiedenen Versionen von CSS
widersprüchlich sind, etwa die Notation der Eigenschaft clip
. Auch sollte man sich
niemals auf eine korrekte Darstellung absoluter Größen und von Pixeln verlassen, weil es da in CSS2.1
Widersprüche gibt, die wiederum Fehler in den gängigen Darstellungsprogrammen widerspiegeln.
Da derzeit (März 2013) kein Darstellungsprogramm CSS2 lückenlos interpretiert,
kann es trotz aller Bemühungen zu Problemen kommen, die dann
wirklich auf Lücken oder gar Fehler des Darstellungsprogrammes
zurückzuführen sind. Um das zu verifizieren, bietet W3C
eine Testsuite an, in der Darstellungsprogramm-Fehler anhand von beschriebenen
Beispielen identifiziert werden können. Fehler von bekannteren
Programmen sind meist so weit bekannt, daß sie bereits an vielen
Orten im internet dokumentiert sind.
Ein Fehler liegt vor, wenn CSS falsch interpretiert wird oder aber
ungültige Eigenschaftsangaben Folgen für die
Darstellung haben. Lücken haben hingegen zur Folge, daß
korrekte Angaben ignoriert werden.