XHTML SVG CSS PHP

Dr. O. Hoffmann

Fehler suchen und finden
bei XHTML, SVG, CSS und PHP

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

Allgemeine Hinweise

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.

PHP-Fehler finden

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:

  • register_globals
  • safe_mode
  • short_open_tag
  • disable_functions
  • allow_url_fopen

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.

Fehler in XML, XHTML oder SVG finden

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:
&#228; &#246; &#252; &#196; &#214; &#220; &#223;
ä ö ü Ä Ö Ü ß

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 &szlig; 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.

Fehler in CSS finden

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:

  • Zählen der id-Attribute in einem Selektor (=a)
  • Zählen anderer Attribute und Pseudo-Klassen in einem Selektor (=b)
  • Zählen der Elementnamen in einem Selektor (=c)
  • Ignorieren von Pseudoelementen

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.