CSS für alle Browser
Kristof Lipfert
Dipl.-Des.(FH)

Viele CSS-Features neuerer Browser, die bisher aus Rücksichtnahme auf Browser wie den Netscape Communicator 4, oder auch oft im Intranet den Microsoft Internet Explorer 4, brachlagen, können bereits zur Umsetzung von Website-Layouts genutzt werden, ohne die Zugänglichkeit einzuschränken. Und nicht nur bei CSS, auch zu HTML und JavaScript gibt es neue Cross-Browser-Strategien.

 

top  

Alle genannten Marken- und Produktbezeichnungen sind Warenzeichen der entsprechenden Inhaber. Keine Haftung für hier vorgestellte Verfahren. Hier wiedergegebene Verfahren und Methoden werden ohne Rücksicht auf die Patentlage dargestellt. Trotz sorgfältiger Arbeit können Fehler nicht ausgeschlossen werden. Scripte sind teilweise verkürzt. Es gilt ausschließlich deutsches Recht. Copyright © 10/2002 Kristof Lipfert, Lipfert & Malik GbR Düsseldorf Web-Design, Alle Rechte vorbehalten einschließlich Vervielfältigung, Übersetzung, elektronische Speicherung und Verarbeitung. Veröffentlichung, auch auszugsweise, nur mit schriftlicher Genehmigung des Autors Kontakt. (Arbeitsumgebung:) Scripte und Methoden wurden i.d.R. um auch ältere Browser zu berücksichtigen u.a. mit dem Microsoft Internet Explorer 4, Netscape Communicator 4.08, 4.70 und 4.80 unter Windows 98/95, sowie Netscape Communicator 4.77 unter Linux getestet.

top Einführung

Wie werden die Forderungen nach Zugänglichkeit, Barrierefreiheit und Layoutumsetzung ohne exzessive Verwendung von Tabellen angesichts der rund 10% Netscape 4 Nutzer in Deutschland [1]nach unten Ende 2002 bzw. zu Anfang des Jahres 2003 von Webdesignern umgesetzt? Ausgehend von einer veränderten Gewichtung der Anforderungen an Webdesign und HTML-Code mit beispielsweise einer höheren Bedeutung der Validität nach den Vorstellungen des W3C -Web Consortium gilt es neue Verfahren und Strategien zu entwickeln. Die gelegentlich propagierten drastischen Browserweichen im CSS, die vielen Browsern kein CSS anzeigen, sind ebensowenig der Weisheit letzter Schluss, wie die Verwendung veralteter oder proprietärer Tags im HTML. Wünschenswert ist HTML und CSS valide nach W3C, dabei möglichst die Verwendung der neueren CSS2 Eigenschaften auch für die Browser Netscape 4 [30]nach unten und Internet Explorer 4 [33]nach unten, so z.B. die Styleangaben right, bottom. Aber auch innerHTML, getElementById, oder Iframe sind letztendlich für die Viererbande NC4 und IE4 zu berücksichtigen, wenn man zu einer homogeneren einheitlicheren Codierung kommen möchte.

top Sollanforderungen

CSS für alle Browser, dieser Anspruch ergibt sich aus den veränderten Sollanforderungen an Webdesign. Zu den Fähigkeiten neuerer Browser kommen grundsätzliche Forderungen. Man möchte Websites barrierefreier aufbauen, die HTML-Tags möglichst in ihrem eigentlichen Sinn einsetzen, und relativ zukunftssicher die Normen des W3C berücksichtigen. Auch der Gesetzgeber kann sich ausser an üblicher Praxis wohl nur an den Vorgaben des W3C orientieren, und neuere Browser zeigen ja auch dass viele dieser Normen anwendbar sind.

Nun ist zunächst Zugänglichkeit für möglichst alle Browser, womit im Moment erstmal Software auf PCs gemeint ist, die wichtigste Forderung. Gefragt ist also trotz zunehmender Vereinheitlichung beim W3C erstmal eine Crossbrowserlösung, wenn man sich die unterschiedlichen Fähigkeiten der gebräuchlichen Browser anschaut. Dabei wünscht man sich natürlich möglichst einheitlichen Code für alle Browser. Hier zeigt sich denn auch, dass Browserkenntnisse, praktische Erfahrung und Kenntnisse der Standards idealerweise beim Web-Designer zusammentreffen. Arbeitsteilungen in die Bereiche Wysiwyg-Layout und Web-Programmierung sind oft nicht effizient genug und können zu unnötig aufgeblähtem Quelltext führen. Welche Browser sind zu beachten, welche Auswirkungen ergeben sich?

top Browserverbreitung

Auffällig bei der Analyse ist besonders der Netscape 4. Er ist noch weit verbreitet, ob man nun von rund 10 % Anfang des Jahres 2003 in Deutschland ausgeht, oder je nach Zielgruppe oder bei internationalen Statistiken [2] nach unten andere Zahlen zugrundelegt, die dann auch noch auf eine Zunahme des Anteils an Internet Explorer 4 hinweisen oder den steigenden Anteil an Surfern aus China belegen. Beim Vergleich der CSS Fähigkeiten sieht der Netscape 4 auch im Vergleich zum betagten IE4 erstmal recht schlecht aus. Bekanntlich hatte ja Netscape mit JSSS auf das falsche Pferd gesetzt, und auch beim dynamischen Aufbau der Seiten, dynamisch im Sinne der wechselseitigen Beziehungen zwischen den Elementen oder Vererbung von Eigenschaften, einen potenziell sehr leistungsfähigen, aber proprietären Weg mit Inline-Scripten bei Layern eingeschlagen, der wohl noch unbekannter ist als JSSS.

Es sind offenbar zu viele Anwender mit älteren Browsern unterwegs, als dass man diese Gruppe der Besucher ignorieren oder schlecht bedienen könnte, andererseits fehlen den älteren Browsern verschiedene Fähigkeiten die zunehmend nachgefragt werden. Und auch andere ältere CSS-fähige Browser wie beispielsweise von Opera [44]nach unten können berücksichtigt werden oder sollten zumindest keine fehlerhafte Darstellung erhalten.

Wenn man weiter die Besonderheiten des Netscape 4 im Vergleich zu moderneren Browsern anschaut, fallen auch andere Defizite als beim CSS auf, so kann er kein HTML Tag "Iframe", und beim JavaScript nervt das verschachtelte Layermodell, und da schon zu vermuten ist dass Nachhilfe für den Netscape 4 per JavaScript und dynamischen HTML erfolgen kann, ist schon erkennbar dass eine Erfassung der Layer und sonstigen Elemente in einer handlichen Form per Array nötig ist, bis hin zu einer Ansprechbarkeit a la DOM, schließlich sind die JavaScript-Fähigkeiten recht ordentlich.

top Crossbrowserstrategien

Die einfachste Cross-Browser-Lösung ist hinsichtlich CSS und HTML zum Erzeugen der Seitenstruktur bzw. Umsetzen des Layout erstmal ganz klar die Tabelle. Und die Praxis zeigt letztendlich auch dass bei allen Vorbehalten diese Lösung gar nicht so schlecht ist. Aber es gibt viele Vorteile ohne Tabellen eine Seitenstruktur zu beschreiben, und auch das W3C hat entsprechende Vorschläge und Beispielseiten für "tableless layout" [6] nach unten.

Dabei wird seitens des W3C eine ebenfalls überschaubare Crossbrowserlösung vorgestellt, die statt des kleinsten gemeinsamen Nenner die Browser in zwei Gruppen unterteilt, welche die CSS erhalten und andere die kein oder nur ein minimales CSS vorgesetzt bekommen. Wenn der Seitenaufbau so angelegt ist, dass die Reihenfolge der Elemente auch ohne CSS sinnvoll angezeigt wird, immerhin eine Notlösung.

Nun ist es oft so dass bei dieser Notlösung letztendlich doch recht viele Besucher einen wenig strukturierten Inhalt vorgesetzt bekommen würden, oder je nach Betrachtung eben nicht den Inhalt, weil ja der strukturierte Seitenaufbau auch Inhalt sein kann, oder zum Verständnis usw. doch nötig ist.

Schließlich sind beim Thema Cross-Browser-Strategien auch die altbekannten Möglichkeiten, browserspezifische HTML-Tags ergänzend zu verschachteln, zu nennen. Hier können durchaus stabile Lösungen gelingen, die aber den genannten Sollanforderungen nicht mehr gerecht werden. Da aber die Verwendung unbekannter, oder laut W3C zu vermeidenden, Tags oder CSS-Anweisungen bei richtiger Syntax einen Browser eigentlich nicht stören dürfen, mag eine differenziertere Betrachtung im Einzelfall sinnvoll sein. So "erkennt" und ignoriert ein Browser unbekannte Tags anhand der SGML Formalismen bzw. anhand der Begrenzungen in Form von Kleiner- und Größerzeichen ohne Probleme. Beispielsweise könnte die Verwendung des Alt-Attribut beim Image-Tag als Ersatz für "Title" dann zu Sinnverfälschungen führen wenn das Image mal nicht geladen werden kann, hingegen scheint eine nicht interpretierbare weil unbekannte Styleanweisung harmloser. Popup-Seite

<div
 onMouseOver="alert('test')">
<ilayer><layer
 onMouseOver="alert('test')">
Test
</layer></ilayer>
</div>

Mouseover für Divs auch bei Netscape 4, aber mittels zusätzlicher Layer-Tags. Schon der Umstand dass Netscape 4 Divs doch recht gut unterstützt, spricht gegen eine zusätzliche Verwendung solcher Layer, und da "onMouseOver" sowieso per JavaScript erfolgt, ist es hier natürlich naheliegend das Verhalten des Netscape 4 ebenfalls mittels JavaScript anzupassen. Immerhin wird bereits deutlich, dass Netscape 4 nicht nur beim a-Tag onMouseOver beherrscht.

top Browserweichen

Browserweichen PHP

Daraus ergibt sich die nächste Vorgehensweise, die individuelle Anpassung. Dass jeder Browser seine eigene Seite erhält wäre vielleicht mittels serverseitiger Browsererkennung machbar, wenn so etwas wirklich sauber funktionieren würde. Eine einfache serverseitige Browserweiche, z.B. per PHP, kann zwar geschrieben werden, basiert aber mit der Abfrage des Useragent auf eher unsicheren Erkennungsversuchen:

$ch_HTTP_USER_AGENT = strip_tags($HTTP_USER_AGENT);
if(substr_count($ch_HTTP_USER_AGENT,'MSIE')<1)
if(substr_count($ch_HTTP_USER_AGENT,'Gecko')<1)
if(substr_count($ch_HTTP_USER_AGENT,'Opera')<1)

Aus Sicherheitsgründen wird zunächst der ja clientseitig manipulierbare Useragent gefiltert, anschliessend wird nur noch die Variable abgefragt. Bei einem Projekt mit sowieso serverseitig generierten Seiten ist diese Weiche in Kombination mit einer zusätzlichen Kontrolle im augegebenen HTML- oder Scriptcode, wie später noch ausführlich dargelegt, sehr sinnvoll um z.B. der Mehrzahl der Browser einen für spezielle Browser wie Netscape 4 optimierten zusätzlichen Code gar nicht erst anzubieten.

Auch wenn es mit PHP, oder besser gesagt mit dem Useragent, allein nicht zuverlässig funktioniert, Anpassung, Erkennung und doch eine Art von Unterscheidung der Browser und unterschiedliche Bedienung sind nötig um etwas mehr als nur die schnelle Aufteilung in zwei Gruppen, etwa in Browser die CSS erkennen und solche welche nicht. Notwendig ist dabei aber eine pflegeleichte Seite, bei der Struktur und die Abfolge der Elemente einer Seite nicht nur aus Rücksicht auf bestimmte Browser festgelegt sind, und nach den genannten Anforderungen sind jegliche HTML-Tricksereien erstmal verpönt.

Browserweichen SSI

Ähnlich eine SSI Browserweiche, vgl. [61] nach unten, wieder auf der Abfrage des problematischen Useragent basierend:

<!--#if expr="${HTTP_USER_AGENT} = /Opera/">
  Opera
<!--#elif expr="${HTTP_USER_AGENT} = /MSIE/">
  Internet Explorer
<!--#elif expr="${HTTP_USER_AGENT} = /Mozilla/">
  Mozilla
<!--#else -->
  Sonstige
<!--#endif -->

Browserweichen mod_rewrite

Und dazu passend eine serverseitige Weiche per mod_rewrite:

RewriteEngine  on
RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/4.*
RewriteRule ^yxz\.html$         xyz.NC4.html         

Browserweichen HTML

Doch erstmal zurück zu den Browserweichen. Nachdem es serverseitig schwierig ist, gibt es clientseitig zuverlässigere Wege. Zuerst eine HTML-Methode zur Unterscheidung des Netscape 4 gegenüber Browser mit Unterstützung iframe, welche vielen Forderungen an Webdesign deutlich widerspricht, und bei der eine mögliche Fehlinterpretation oder ein "worstcase" auch hinsichtlich zukünftiger Browser schwer abschätzbar ist:

<iframe src="" style="display:none">
 ... nc4
  <script>if(document.layers)document.write('<noscript>');</script>
 </iframe>
 ... andere Browser
<iframe src="" style="display:none">
</noscript>
</iframe>

Auch eher der Vollständigkeit halber denn als Empfehlung eine Browserweiche mit Netscapes proprietärem nolayer-Tag im Head um Styleangaben von Netscape 4 nicht ausgewerten zu lassen:

<nolayer>
  <style>
    ...
  </style>
</nolayer>

Browserweichen JavaScript

Dann gibt es natürlich Browserweichen oder -filter per JavaScript; eine solche CSS-Weiche funktioniert allerdings bei Netscape 4 nicht verläßlich, zudem ist es unvorteilhaft Styleanpassungen von JavaScript abhängig zu machen:

if(document.all&&!window.opera)
   document.write('<style> ...  ');

Einige per JavaScript abfragbare browserspezifische Objekte:

NC4 IE4IE5-6Op6,7M1x  
layers*
all**!
getElementById***
documentElement *
window.opera *
window.clipboardData *
createElement ****

Natürlich könnte per JavaScript auch wie eingangs als PHP-Skript gezeigt der Useragent des Browsers abgefragt werden [59] nach unten, hier werden jedoch Browserfähigkeiten abgefragt (vgl. f. ältere Browser [58] nach unten), die so eng mit dem Konzept des Browsers verflochten sind, dass man diese Variante als sehr viel zuverlässiger betrachten kann als die Abfrage des bei vielen Browsern auch noch editierbaren oder umschaltbaren Useragent, vgl. dazu auch [62] nach unten, "The Ultimate JavaScript Client Sniffer". Eine Übersicht über abfragbare Eigenschaften und meine Lösung zu Popup-Seite Browsererkennung per JavaScript

Browserweichen CSS

Nachteilig bei der Abfrage browserspezifischer Objekte als CSS-Browserweiche ist dass auch da aktiviertes JavaScript vorausgesetzt wird wo es um CSS-Korrekturen geht. Zulässig ist es dennoch wenn die Konsequenzen folgerichtig sind, etwa wenn ohne JavaScript sowieso kein CSS möglich ist oder gar nicht eingebunden wird, wie bei Netscape 4. Schließlich die scheinbar eleganteste Möglichkeit einer Browserweiche direkt per CSS:

NC4IE4IE5-6Op6,7M1x  
*****
*   ****
@media all !***
@import ***
div[id] **
html:root !

Mehr auf der Testseite Popup-Seite CSS Filter: Browserweichen per CSS. Zunächst muss man bei der beliebten CSS-Weiche per @media all berücksichtigen, dass die so vor älteren Browsern versteckten Anweisungen teilweise auch dem Internet Explorer 4 zugänglich sein können, diese Browserweiche sollte nicht oder nur mit Berücksichtigung dieses Problems eingesetzt werden. Unterschieden werden muss dabei nicht nur die Art des Mediums, als CSS-Weiche wären u.U. screen und all denkbar, sondern auch der Ort der Medienangabe, also ob als HTML-Attribut, oder als Styleangabe:

 <style type="text/css" media="all">
                @media all{ ....

Und html:root, das letzte Beispiel, ist bis zur Verabschiedung von CSS 3 ebensowenig valid wie z.B. die JSSS-Schreibweisen ohne Bindestrich. Es gibt noch einige weitere Möglichkeiten wie z.B. div > oder div#id, um mittels einigen Browsern unbekannter logischer Operatoren bzw. Selektoren CSS-Weichen zu realisieren. Trotzdem mag mitunter html:root erstmal hilfreich sein um Opera 7 per CSS-Weiche auszuschliessen.

Der * Selektor eignet sich als einfachster Filter für (vor) Netscape 4, und ist geeigneter und kompakter als die problematischen @media all Konstrukte:

<style type="text/css">
 div  {
      font-size: 14px;
      }
* div {
      font-size: 13px;
      }

Die folgende Browserweiche ergibt bei Mozilla grün, beim IE rot und Netscape 4 wird offenbar ganz an der Interpretation des Styles gehindert.

style="color:green;{color:red;}"

Soweit eine solche Browserweiche auf den Unfähigkeiten älterer und nicht mehr weiterentwickelter Browserversionen beruht, mag sie auch relativ verlässlich sein.

<link rel="stylesheet" media="screen" href="NC4.css">
<link rel="stylesheet" media="all" type="text/css" href="IE4.css">
<style>
@import url( "IE6.css" );
@import url( 'MOZ.css' ) all;
</style>

Browserweichen CSS class

Da ältere Browser nur einen Wert im class-Attribut unterstützen, lässt sich mittels verschiedener Klassenangaben auch eine Browserweiche erstellen, allerdings wird vom Netscape 4 dann gar keine, also auch nicht die erste, Klasse angewandt, daher hat eine doppelte Angabe hier den gleichen Effekt wie zwei verschiedene Klassen:

 <style type="text/css">
div  {      font-size: 14px;      }
div.neu {      font-size: 13px;      }
 </style>
 ....

 <div class=" neu neu ">
 ....

So lässt sich der Umstand nutzen dass die neueren Browser das erste Attribut class= interpretieren, und z.B. der Netscape 4 das zweite Attribut anwendet:

 <style type="text/css">
.n4c  {      font-size: 14px;      }
.neu {      font-size: 13px;      }
 </style>
 ....

 <div
 class=" neu "
 class=" n4c ">
 ....

Browserweichen IE 4

Aus den bei einem crossbrowser-Projekt auffälligen Eigenheiten des IE4, bei @media nur den Anfang zu ignorieren, konnte ich auch eine neue Browserweiche, besonders für den Internet Explorer 4, ableiten, dabei ist mit handheld ein Medientyp nach CSS 2.0 genannt, die möglichen Auswirkungen auf zukünftige Handheld-Browser sind natürlich zu berücksichtigen. tty käme hier auch in Frage, oder einfach ungeachtet der Validität none:

/* 2001-2002 Kristof lipfert Düsseldorf */
 <style type="text/css">
             div.rechts{ right:5px; position:absolute;}

 @media handheld {
               #dummy{left:0px}
             div.rechts{ left: 80%; }
              }

Auch die folgende Schreibweise, Ergebnis meiner gezielten Suche nach Eigenheiten des Browsers, wird vom IE 4 angewandt, allerdings versuchen sich auch Opera bis Version 6 an der Anweisung, solange nicht die zweite nicht valide Variante eingesetzt wird:

html * body { color:red }

html * body { color=red }

* html body{color:red}

Daraus habe ich noch weitere valide und auch hinsichtlich Opera verlässliche Browserweichen für den IE 4 abgeleitet Popup-SeiteIE 4 CSS Weiche

/* 2002-2003 Kristof Lipfert Duesseldorf */
 <style type="text/css">

 * html * body  #test { color:red }
/* 2002-2003 Kristof Lipfert Duesseldorf */
 <style type="text/css">

 html.dummy * body #test { color:red }

Browserweichen IE 5 / 4

Neue von mir entwickelte valide Browserweichen für IE 4 Popup-SeiteIE 4 CSS Weiche und IE 5.0 Popup-SeiteIE 5 CSS Weiche:

/* 2002-2003 Kristof Lipfert Duesseldorf  */

/*   ie 5 + ie 4 */

html + body #test { color:green;  }

/* ie 4 */

* html body #test { color:blue;  }

Browserweiche für IE 5.5 - 6

/* 2002-2003 Kristof Lipfert Duesseldorf  */

html.*  #test { color:red; }

Browserweiche nur für IE 5.5

/* 2002-2003 Kristof Lipfert Duesseldorf  */

html.*  #test {content:"\"; color:red; }

Valide CSS-Weiche nur für IE bis 6 Popup-SeiteCSS Weiche :

/* 2001-2002 Kristof Lipfert Duesseldorf  */

* html  #test { color:red; }

Valide CSS-Weiche nur für IE bis 5.5 Popup-SeiteCSS Weiche :

/* 2002-2003 Kristof Lipfert Duesseldorf  */

* html  #test {content:"\"; color:red; }

Noch eine -nicht valide- Weiche für die IE 4 bis 5.5 Popup-SeiteCSS Weiche :

 <style type="text/css">
/* 2002-2003 Kristof Lipfert Duesseldorf  */

@media tty {
   @import url(IE40-55.css);
  }

Weiche IE 4 bis IE6 und Opera 5 versus Mozilla und Opera 6-7:

 <style type="text/css">
/* 2002-2003 Kristof Lipfert Duesseldorf  */

@import url(nicht-IE.css) screen;
@media screen {   @import url(IE6.css);  }

Nur Opera 5

 <style type="text/css">
/* 2002-2003 Kristof Lipfert Duesseldorf  */

@media screen { @import url(Opera5.css) screen; }

Nur Opera 5 II

 <style type="text/css">
/* Autor 2002-2003 Kristof Lipfert Duesseldorf  */

 @import url('opera5.css""') screen;

Dabei bleibt aber meist ein nicht abschätzbares Risiko, weil Bedingungen abfragt werden, die mit dem jeweiligen Problem eigentlich nichts zu tun haben. So kann man versuchen auf Nummer sicher zu gehen und statt dessen alternative Möglichkeiten, etwa verschachtelte Divs zu Korrektur von Abständen, verwenden. Eine gemischte Strategie um die unterschiedliche Behandlung des Body, falls er z.B. grösser als das Browserfenster ist, auszugleichen, wird später noch im Abschnitt HTML und CSS nach unten gezeigt.

Auch browserspezifische Schreibweisen und Eigenheiten lassen sich als Browserweiche einsetzen, etwa die Scriptsprache JScript statt JavaScript oder EcmaScript oder diese unbekannte Variante:

<script language="mocha">

Da das Attribut language nicht mehr vom W3C empfohlen wird, ist diese neue Weiche für Netscape/Mozilla Browser auf HTML-4 Seiten nicht "validierbar".

Browserweiche IE 6

Valide ist folgende Möglichkeit nur den IE 6 anzusprechen Popup-SeiteIE 6 CSS Weiche :

<style type="text/css">
 /*  Autor, Entwickler 2001 2002 Kristof Lipfert Duesseldorf  */

@media All{

 * html b\ody #test {
         color:lime;
         font-size:1.6em;
                   }

          }

 </style>

Browserweiche Mozilla

Hinlänglich bekannt dürfte folgende Weiche I. Explorer vs. Mozilla und andere sein:

@import url(IE-alle.css);
@import url(nicht-IE.css) screen;

Eine umfassende Lösung zur Einbindung externer Stylesheets wird im folgenden Kapitel Browserweiche Neue Browsernach unten noch ausgeführt, jetzt erstmal eine bislang unbekannte Weiche um mittels der CSS 3 Fähigkeiten der Mozilla-Browser Code vor anderen Browsern zu versteckenPopup-SeiteMozilla CSS Weiche :

 <style type="text/css">
/* Autor 2002-2003 Kristof Lipfert Duesseldorf  */

  *:not(hr) #test {
        color:lime;
        font-size:1.6em;
                   }

Browserweichen Opera 6

Noch eine Neuentwicklung für Opera 6 Popup-SeiteOpera 6 CSS Weiche :

 <style type="text/css">
/* Autor 2003 Kristof Lipfert Duesseldorf  */

 html *>b\ody #test {

           color:lime;
           font-size:1.6em;

                    }

Und noch eine Alternative für Opera 6 Popup-SeiteOpera 6 CSS Weiche B :

 <style type="text/css">
/* Autor 2003 Kristof Lipfert Duesseldorf  */

html * body #test, [xfilter] {

           color:lime;

                    }

Und auch um nur Opera 6 von einer Anweisung auszuschliessen habe ich eine valide Möglichkeit entwickelt Popup-SeiteOpera 6 CSS Filter :

 <style type="text/css">
/* Autor 2004 Kristof Lipfert Duesseldorf  */

 @media all and (color){ i{}}

     #test { color:lime }


Browserweiche Opera 4 bis 6

Nützlich sind auch diese Browser-Weichen für Opera 4 bis 6 Popup-SeiteOpera 4 - 6 CSS Weiche:

 <style type="text/css">
/* Autor 2003-2004 Kristof Lipfert Duesseldorf  */

html * body #test[id] { color:lime }

@media screen{ html * body #test { font-size:1.6em; }
                              }

Browserweiche Opera 7

Und auch Opera 7 läßt sich einzeln ansprechen Popup-SeiteOpera 7 CSS Weiche:

 <style type="text/css">
/* Autor 2003-2004 Kristof Lipfert Duesseldorf  */

 html:first-child>b\ody #test {

                    color:lime;
               font-size:1.6em;

                              }

Browserweiche Konqueror

Noch neue Entwicklungen für Konqueror, getestet bislang mit Konqueror 3.1 Popup-SeiteKonqueror CSS Weiche:

 <style type="text/css">
/* Autor 2004 Kristof Lipfert Duesseldorf  */

 h/**/tml:first-child>*:first-child+body #test {

                    color:lime;
               font-size:1.6em;

                                               }

Entsprechende Weiche für eine externe Datei Popup-SeiteKonqueror import Weiche:

<style type="text\/css">
/* Autor 2003 Kristof Lipfert Duesseldorf  */

 /*/*/
  @import (" '\'") screen;
  @import url(Konqueror.css) screen;
 /* */
</style>

Browserweichen JSSS

An dieser Stelle wird JSSS nur kurz als Möglichkeit einer JavaScript-Weiche gezeigt, da das Thema JSSS noch ausfühlich behandelt wird. Zunächst wird hier nur die Kombination des Style-Tags mit dem Attribut type=text/javascript gezeigt. Die so eingebundenen Anweisungen werden nur vom Netscape 4 befolgt, die Vorgehensweise eignet sich aber nur bedingt zur Ausführung von normalem JavaScript.

<style type="text/javascript">
 alert('Ihr Browser ist Netscape 4');
</style>

Browserweichen Entity

Da Netscape 4 Schriftgrössen oft abweichend, 1 Pixel zu klein, darstellt, gibt es auch einen konkreten Anlass für die weiteren Beispiele mit der font-size. Sogar die JavaScript Entities oder Inlinescripte von Netscape (vgl. [10][32] nach unten) lassen sich als CSS-Weiche für den Netscape Communicator 4 verwenden, und der folgende von mir entwicklete Code wird dabei sogar als valides HTML 4.01 vom W3C Validation Service abgesegnet, auch der W3C CSS-Validator hat nichts zu bemängeln:

<body style=" font-size: 13px;  &{'font-size:14px;'}; ">

Oder die Methode wird zur Einbindung spezifischer Dateien verwandt, wie auch im Kapitel Im Kopf nach unten thematisiert wobei je nach Browser allerdings auch eine meist harmlose, aber unnötige Serveranfrage entstehen kann:

<link type="text/css" rel="stylesheet" href="&{'nc4.css'};">

<script src="&{'nc4.js'};" type="text/javascript"> </script>

Eine solche unnötige Serveranfrage, bei der vergeblich nach &{'nc4.css'}; oder &%7B'nc4.css'%7D; gesucht wird, lässt sich aber einfach für die meisten Browser (ausser z.B. Mac IE 5x) vermeiden, indem weitere Attribute entsprechend in Entities erfolgen:

<link type="&{'text/css'};" rel="&{'stylesheet'};" href="&{'beispiel.css'};">

Das wird übrigens immer noch vom W3C-Validator z.B. als HTML 4.01 Transitional validiert, 404-Anfragen auf dem Server entstehen offenbar nicht, und so scheint mir diese Vorgehensweise durchaus geeignet um für den NC4 Styledateien einzubinden.

Bei der Verwendung dieser interessanten Methode in Inlinestyles ist zu berücksichtigen, dass der IE 4 bei mehreren Anweisungen u.U. nach dem ersten ; mitliest. Eine Lösung kann wieder die Netscape-Schreibweise der Styleangaben sein:

<body style="&{'width:130%;margintop:-12px;'};">

oder:

<p style=" color:blue; &{'color:green;'}; &{'color:red;'}; //color:orange; ">
<!--          Moz/Op.          IE4               NC4          IE6      -->

Eigenheiten JSSS

Ähnliches wie bei den browserspezifischen Tags wie Layer gilt für unterschiedliche Schreibweisen oder Begriffe bei Styles. Immerhin gibt es verschiedene nicht valide Möglichkeiten, die bereits wie eine Browserweiche funktionieren, aber doch nicht erwünscht sind. Da kommt nicht nur das Netscape-4 spezifische layer-background-color in Frage, sondern auch eine spezifische Schreibweise ähnlich JSSS im normalen CSS:

<style>
body {
      font-size: 13px;
      fontsize:  14px;
      }

Valider scheint font-size:13.4px, hier wird das unterschiedliche Rundungsverhalten der Browser benutzt um letztlich eine gleiche Schriftgrösse zu erhalten. Es gibt aber kaum weitere Beispiele mit anderen Grössen bei denen es so zuverlässig klappt wie bei 13.4, dann bleiben Unsicherheiten hinsichtlich möglicher Nebeneffekte oder auch zukünftiger Browser, und die Kombination von Nachkommastellen mit der Einheit Pixel könnte auch irgendwann als nicht valide beurteilt werden.

<style>
body {
      font-size: 13.4px;
      }

important

Ebenfalls valide und als Methode offenbar unbekannt ist die Zweckentfremdung von important:

<style>
body {
      font-size: 13px!important;
      }
body {
      font-size: 14px;
      }

Das folgende Beispiel zeigt bei den IEs bis 6 rot an, Browser wie Mozilla grün:

 h1 { color:green!important; color:red; }

Auch in Hinblick auf die weitere Flexibilität, Userstylesheets und Barrierefreiheit ist es besser diese valide Weiche nicht anzuwenden.

Browserweichen IE expression

Nicht W3C-valide, und abhängig von der Scriptaktivierung bzw. eigentlich eine Script-Weiche ist die Möglichkeit, beim Internet Explorer JScript in Styles einzubinden. Verfolgt einen ahnlichen leistungfähigen Ansatz wie die dynamischen Attribute (s.o., Entities) etwa bei Layern unter Netscape 4, mehr zu diesem Aspekt im Abschnitt IE expression dhtml.

<style>
body {
      font-size: 13px;
      }
body {
      font-size: expression("14px");
      }

Natürlich lassen sich die Internet Explorer 5, 5.5 und 6 innerhalb der Expressions auch per JavaScript unterscheiden, vgl. den Abschnitt Browserweichen JavaScript. Expressions sind nicht validierbar und können Instabilitäten begünstigen.

body {
      font-size: expression(document.createEventObject?"13px":"13.5px");
      }

Browserweichen invalid; IE, Opera

Ebenfalls nicht konform ist die Nutzung der Fehlertoleranz des Internet Explorers als CSS-Weiche:

<style>
body {
      font-size : 13px;
      }
body {
      font-size = 14px;
      }

Auch verlässlich, aber nicht validierbar ist diese Schreibweise:

<style>
body {
      font-size : 13px;
      }
body {
      font-size :"14px";
      }

Bei Opera 7 hängt die Toleranz vom Doctype bzw. dem resultierendem Quirks Mode oder weniger nachsichtigem Standards Mode ab.

<style>
body {
      font-size: 13px;
      }
body {
      font-size: 14 px;
      }

Ein extra Stylesheet für den IE5-Mac, statt @import "./IE5Mac.css"; oder @import url("./IE5Mac.css"); versteht der Mac-IE5 auch [49] nach unten :

@import("./IE5Mac.css");

Ein Backlash kann ebenfalls eingesetzt werden, Mozilla, IE 6, und Opera führen die Anweisung aus:

<style>
* p{c\olor:red;}

Und das unpassede abschliessende ! akzeptieren Netscape 4 sowie Opera nicht, während IE sogar die letzten Anweisungen akzeptiert:

p{color:red;}
p{color:green!}
p{!color:blue}
p{color=silver}

Auch p{color!important:red} führt beim IE zur Farbgebung, allerdings wird important nicht umgesetzt.

Der Internet-Explorer (-6) befolgt das disabled-Attribut, und Mozilla opder Opera lasssen sich durch den anführenden Slash fernhalten, Netscape 4 liest beide:

<link rel="stylesheet" type="text/css" href="nicht_IE.css" disabled> 
<link rel="stylesheet" type="text/css" href="/nur_IE.css"> 

Browserweichen Comments

Eine weitere Möglichkeit sind die unterschiedlichen Eigenheiten bei Kommentaren, der erste Kommentar /*/*/ wird einmal als /* /* und sonst als /* */ verstanden, der zweite Kommentarblock wird im ersten Fall als Kommentarende benötigt, eine Verwendung dieses Verhaltens als einfache Weiche ist zunächst von Caio Chassot beschrieben worden[27] nach unten. Da Opera 5 und Netscape 4 bei der ersten Variante ähnlich reagieren, empfiehlt sich aber ggf. eine entsprechende Ergänzung, hier etwa * body {font-size:13px} für Opera 5. Solche Kommentare werden übrigens vom Amaya-Browser nochmals etwas anders interpretiert und z.b. als nicht unterstützter */ Selector betrachtet, da aber die CSS-Unterstützung dieses Web Editors noch nicht umfassend ist eignet sich Amaya sowieso nur bedingt als Referenz.

<style>
body {
      font-size: 14px;
      }
/*/*/
body {
      font-size: 13px;
      }
/* */

* body {
      font-size: 13px
       }

oder:

<style>
body {
      font-size: 13px;
      }
/*/*//*/
body {
      font-size: 14px;
      }
/* */

Daraus entwickelte ich eine nach W3C valide neue Variante einer CSS-Weiche für NC4, die die Validität der auskommentierten Bereiche mit der Sicherheit verbindet, dass möglicherweise existierende Browser mit einer gleichen Fehlinterpretation der Kommentare wie teilweise Opera 5 die CSS-Anweisungen für den NC4 trotzdem nicht ausführen würden:

<style type="text/css">
/* 2002 Kristof Lipfert Duesseldorf  */

body {
      font-size: 13px;
      }
/*/*//*/
body {
      fontsize: 14px;
      }
/* */

Nachtrag: die einfache Anwendung der JavaScript und JSSS-Syntax funktioniert sehr zuverlässig, eine Ausnahme besteht aber beir den border- Angaben, welche ohne Bindestrich offenbar nicht richtig von Netscape 4 interpretiert werden.

Netscape 4

Zu vermeiden ist in den Styleanweisungen z.B. hinsichtlich Opera 5 ein Slash, also kann eine Anweisung a la font: 13px/19px durch fontsize und lineheight ersetzt werden.

Die folgende Weiterentwicklung der Weiche schließt nun auch Opera 5 vom Kommentarblock aus und ist immer noch valides CSS: Popup-SeiteBrowserweiche Netscape 4 CSS crossover

<style type="text/css">
/* 2002-2003 Kristof Lipfert Duesseldorf - V4.3 */

body {
      font-size: 13px;
      }
/*/*//*/\{! i{}
body {
      fontsize: 14px;
      }

*}{}/* */

Nachtrag: Bei der Entwicklung hatte ich die Auswirkungen und Seiteneffekte auf die Umsetzung von nachfolgenden CSS-Code unter verschiedenen Browsern getestet, und sehe hier einen Vorteil meiner Opera-Ergänzung gegenüber anderen ähnlichen mittlerweile im Web anzutreffenden Lösungen.

Passend auch ein CSS Filter für Netscape 4, statt einer Kommentarlösung empfehle ich für kleine CSS-Passagen * einzusetzen. Für grössere Blöcke ist eine auch für den Internet Explorer 4 angepasste Anwendung von @media all geeignet: Popup-SeiteCSS Filter Netscape 4

Weitere Weichen für Netscape 4 sind noch in verschiedenen Kapiteln beschrieben, vorweg möchte ich hier kurz zwei Varianten zur Einbindung externer CSS-Dateien vorstellen, die ich entwickelt hatte um Probleme beim ersten Seitenaufbau und Einbindung per JavaScript zu vermeiden:

<!-- 2001 Kristof Lipfert Duesseldorf -->

<link href="./linktest.css" rel="&{'stylesheet'};"
                type="text/css" media="&{'screen'};" />

<!-- 2001 Kristof Lipfert Duesseldorf -->

<style type="text/css" style="include-source:url('css.htm')"></style>

Mehr dazu im Text Popup-SeiteExternes CSS für Netscape 4 ; eine validierbare Variante ist auch so möglich:

<!-- 2002 Kristof Lipfert Duesseldorf -->

<style type="text/css"> /*/*//*/
style{includesource:url('css.htm')}body{position:absolute}
                             /* */</style>
<style type="text/css"></style>

Opera 5

Verstecken vor Opera 5:

/*/*/{/*/
/*  */

p { color:red; }

/*/*/}/*/
/* (c) */

Code nur für Opera 5

<style type="text/css">
/* 2002-2003 Kristof Lipfert Duesseldorf  */

/*/*//*/
&{'//*'};
 font-size: 13px;
/* */

Aufpassen muss man bei solchen Konstruktionen natürlich auch mit im Stylesheet eingefügten echten Kommentaren, da sind Lösungen mit Selektoren vorteilhafter. Die Schreibweise des Kommentar-Endes als /* */ mit Lücke ist auch bedeutsam, mit /**/ liesse sich in der Kombination schon wieder eine neue Weiche realisieren, der Internet Explorer 4 zeigt hier blau, NC4, Mozilla rot:

div{color:blue}
 /*/*//*/ 
 /**/
div{color:red} 

Wichtig ist in dem Zusammenhang, dass diese Weiche ja nach Position und Seitenaufbau gerade bei Inlinestyles nicht zuverlässig funktioniert. Und auch im Stylesheet könnte es wegen Opera 5 Einschränkungen geben, die aber bei der Kombination mit der JSSS-Schreibweise wenig Anlass zur Sorge geben solten. Falls bei Inlinestyles "nur" JavaScriptfehler vom NC4 bemängelt werden, kann bei Positionsangaben in Pixeln als Notlösung die Einheit weggelassen werden.

 style="/*/*/position:absolute;left:150;bottom:50;">

Als CSS-Weiche zwischen IE und Mozilla lässt sich ebenfalls eine Auskommentierung verwenden, die aber für Inlinestyles bei verschiedenen Browsern nur bedingt geeignet ist, teilweise auch Opera bedient und dazu bei Verwendung im Stylesheet vom W3C als invalid erkannt wird. Wichtig ist die umständliche Schreibweise mit zwei vollständigen Zeilen, und die Slashes müssen innerhalb der geschweiften Klammern stehen, damit der IE, ab 4, die Styleanweisung trotzdem befolgt, auch wegen möglicher Probleme beim IE 5 ist die Methode weniger empfehlenswert:

<style>
 div {    color:red; }
 div { // color:blue;}

Oder auch als Inlinestyle, etwa um bei border den Box-Bug zu korrigieren (die unterschiedliche Rahmenbreite müsste hier noch mit weiteren Breitenangaben angepasst werden):

 style="width:130px; height:160px; border-size:1px;
         border-style:solid;// width:180px; // height:210px;"

So ähnlich wie diese neue IE-Weiche ist denn mitunter doch ein, falls gewünscht auch nur teilweises, Auskommentieren von Inlinestyles für Netscape 4 möglich, allerdings beinflusst der Eintrag auch das Verhalten beim IE4. Auch mit weiteren Varianten lässt sich das das Browserverhalten differenzieren:

<p style="&{'//'}; font-size:13px">

<p style=" ... ; @media all{ ... }; &{ ... }; ">

<p style="//; font-size:13px">

Browserweiche IE3?

Nein, der Internet Explorer 3 steht hier nicht auf der Liste der umfassend unterstützbaren Browser. Da er dazu bei Grafiken das PNG-Format nicht anzeigt gibt es noch andere Einschränkungen als der geringe Umfang der CSS-Interpretation. Dass er in einigen Versionen überhaupt Styleanweisungen auswertet ist ein Grund für den Einsatz sehr gründlicher CSS-Weichen per import, die ja auch für den Nestcape Communicator 4 ergänzt und auch bei NC4-Unterstützung weiterhin genutzt werden können.

Dennoch ist auch eine andere Strategie möglich, denn angesichts der vielen möglichen CSS-Weichen innerhalb von Stylesheets wäre ein einziges und allen Browsern zugängliches Stylesheet auch vorstellbar. Deshalb noch ein Beispiel einer CSS-Weiche für den IE 3.02. Die folgende Weiche für den IE 3.02 nutzt den Umstand, dass dieser Browser immer nur die erste Styleanweisung bei gleichen Adressaten interpretiert.

 
         div {  color:red;     }    /* IE 3 */
         div {  color:blue;    }    /* NC 4 */
  * html div {  color:orange;  }    /* IE 5 */
  * html div {  col\or:lime;   }    /* IE 6 */
       *>div {  color:silver;  }    /* Opera */
html:root div{   color:wheat;  }    /* Mozilla */
  @media tty { #dummy { top:0;}  
   * html div { color:green; } }    /* IE 4 */

Es gibt natürlich viele mögliche Kombinationen von Selektoren, so könnte beispielsweise auch @ media all{ div, mit Berücksichtigung der Eigenheiten gerade beim hier auszuschließenden IE 4, eingesetzt werden. Geeignet zur Unterscheidung von IE und älteren Opera-Browsern ist auch //, das aber nicht validierbar ist. Immerhin gibt es für die meisten Situationen hinreichend Möglichkeiten, um Browser nicht nur per JavaScript, sondern auch in Stylesheets selbst zu differenzieren, wenn es auch bei komplexen mehrfachen CSS-Weichen schwierig wird die unterschiedlichen Hierarchien der Selektoren und Bedingungen zu berücksichtigen Popup-Seite . Da der IE 3 display:none nicht umsetzt, gäbe es für ihn zur Not noch eine weitere Möglichkeit der Unterstützung:

     .ie3d {    display:none }    /* IE 3 zeigts doch */

Browserweichen Conditional Comment

Dann gibt es noch Microsoftspezifische Tags im HTML-Code [21][22] nach unten , mit denen neuere Internet-Explorer, d.h. ab Version 5, unterschieden werden können: <!--[if ... endif]-->, aber als crossbrowser-Strategie scheint es erstmal unvorteilhaft überhaupt in den HTML-Code einzugreifen. Trotzdem könnte diese Möglichkeit gerade zur Korrektur von Styleangaben in Kombination mit dem Doctype "strict" sinnvoll sein, um bei den älteren Microsoft-Browsern einzugreifen, wobei der bei CSS leistungsfähigere Mac-IE5 nicht angesprochen wird:

<!--[if IE 5]>
 <STYLE>
  ....
 </STYLE>
<![endif]-->

So lassen sich per auskommentiertem Tag alle in Frage kommenden heutigen (Win )Internet Explorer erfassen, dabei gibt es gt "greater than" oder "less" lt kleiner als und "-or equal" gte bzw. lte, und eine weitere valide Möglichkeit browserabhängig externe Dateien zu laden ist verfügbar:

<!--[if lt IE 7]>
     <link type='text/css' rel='stylesheet' href='demo4e56.css'>
<![endif]-->

Natürlich kann auch im Head auf eine andere Datei umgeleitet werden:

<!--[if !gt IE 5.1]>
-->
<meta http-equiv="refresh" content="0; 
     URL=alle-anderen-ausser-IE-groesser-als-5.htm">
<!--
<![endif]-->

Oder ein IE vom CSS ausgeschlossen werden:

<!--[if !lt IE 5.1]><!--
               -->
  <link type="text/css" rel="stylesheet" href="alleausser5ie.css">  
               <!--
               <![endif]-->

Vorweg ein Beispiel aus einem folgenden Abschnitt: Popup-Seite

Auch Netscape 4 verfügt zumindest in den früheren Versionen über Conditional Comments, die eine ähnliche Syntax wie die schon erwähnten Entities aufweisen. Da diese Technik auch bei den älteren Browsern nicht zuverlässig anwendbar ist, so führt bereits das Vorhandensein einer Seite im Browsercache zu Fehlfunktionen, gibt es wenig sinnvolle Anwendungsmöglichkeiten, anwendbar ist folgende Methode um anspruchsvolleres CSS nur Netscape 4 Versionen ab 4.70 anzubieten:

<!-- 2002-2003 Kristof Lipfert Duesseldorf  -->

<!--&{true}; <!--   -->
<link type="text/css" rel="stylesheet" href="alle_aber_netscape_erst_ab_47.css">
<!--&{true};  -->

Browserweiche Entities Netscape 4

Um Unterversionen des Netscape 4 mit exklusiven Stylesheets zu versorgen sind die Entities mit JavaScript Syntax geeignet Popup-Seite Filter Link Netscape 4 Unterversionen:

<!--  Autor, Entwicklung 2002 Kristof Lipfert Dueseldorf -->

<link type="&{'text/css'};" rel="&{'stylesheet'};" 
href="&{'./nnx/nn4'+navigator.appVersion.substring(2,3)+'.css'};" disabled >

Browserweiche neue Browser

Noch ein Beispiel einer Weichenkombination um ein externes Stylesheet nur für neue Browser, IE ab 5, Opera ab 5, Mozilla zu laden:

<!-- 2002-2003 Kristof Lipfert Duesseldorf  -->

<style type="text/css">
 @import url(neueBrowser.css) screen;
</style>
<!--[if IE]> 
 <link type='text/css' rel='stylesheet' href='neueBrowser.css'>
<![endif]-->

Um bestimmte Browser auszuschliessen kann die Weiche weiter ergänzt werden, separate Stylesheets für ältere Browser sind auch möglich: Meine Lösung CSS Browserweiche für 9 verschiedene Browser mit exklusiv geladenen externen Syteldateien Popup-Seite CSS Filter Import / Link

<!-- 2002-2003 Kristof Lipfert Duesseldorf  -->

<link type='text/css' rel='stylesheet' href='\NBnetscape4.css' disabled>
<!--[if IE 6]>
  <link type='text/css' rel='stylesheet' href='NBIE6.css'>
<![endif]-->
<!--[if IE 5]>
  <link type='text/css' rel='stylesheet' href='NBIE5.css'>
<![endif]-->
<style type="text/css">
/*/*/
  @import url(NBOperaMozilla.css) screen;
/* */
</style>
<style type="text/css">
 @media screen { @import url(NBOpera5.css) screen; }
</style>
<style type="text/css">
 @import("./NBIEMac.css");
</style>

Doctype

Der doctype der HTML-Datei kann wie eben schon erwähnt ebenfalls das Browserverhalten ändern und auch wie eine Weiche wirken. Einfachste pauschale Empfehlung z.Zt. ist angesichts der enormen Verbreitung der IE5-5.5 der Doctype "transitional", denn damit befindet sich auch der IE6 im standard-compliant-mode bzw. "BackCompat" javascript-alert Mode , verhält sich also ähnlich wie seine Vorläufer. Auch die kurze Schreibweise ohne Angabe der URI zur DTD hat Vorteile, weil die Browser, besonders bei HTML 4.0, eher in den Back- oder Quirks-Modus schalten:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

Die Angabe der URL zur DTD lässt den Internet Explorer 6 in den "standards-compliant mode" bzw. "CSS1 compliant" schalten, er rendert dann -vgl. folgender Abschnitt über den Box-Bug- ähnlicher wie andere moderne Browser.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
           "http://www.w3.org/TR/html4/loose.dtd">

Der vielzitierte Boxbug kann mit diesem Doctype oft für IE 4-6, NN 4-7 /Mozilla und Opera 7 ähnlich behandelt werden; mit einem zusätzlichem Element, z.B. ein p in einem div, sogar ohne Browserweichen.

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">

<!--  -->
<!DOCTYPE ..

Dieser Doctype XHTML ermöglicht mit der anfänglichen XML-Deklaration den IE 6 ebenso im Quirks-Modus rendern zu lassen wie auch ein Kommentar am Dateianfang; eine gleiche Behandlung derIE 5 bis 6 mit ähnlichem Box-Bug ist dann möglich.

Box-Bug

Die umgekehrte Strategie ist aber auch möglich, beim Doctype "strict" sollen sich alle neueren Browser möglichst ähnlich und natürlich normgerechter verhalten. Hier als Beispiel eine vom Autoren aus der bereits vorgestellten IE-4 Weiche weiterentwickelte Kombination unter Ausnutzung der Besonderheiten von content, so mögliche Anführungszeichen, Interpretation durch IE erst ab Version 6 zur Korrektur des Box-Bug, die allerdings nicht valide ist und Opera zwar richtig, aber per Parsingefehler etwas unelegant behandelt:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
       "http://www.w3.org/TR/html4/strict.dtd">
 ...
<style type="text/css">
/* 2002 Kristof Lipfert Duesseldorf  */

#beispiel{ width:200px;height:200px;
           margin:50px;padding:50px;
           border:10px solid silver;                }

@media video {
b{content:"\";/*" "*/}!}

#beispiel { width:320px;height:320px; } 

/*"}}/* */

Um Probleme mit ungetesteten Browsern vorsorglich auszuschliessen kann bei diesem Beispiel einfach per > Selektor nochmals der Wert für moderne Browser gesetzt werden. Dann ist auch per b{content:"\";/*" "*/}} eine valide Variante möglich. Der Doctype wird von den neueren Browsern richtig umgesetzt, und die angepasste Weiche versorgt die korrekturbedürftigen IE4, IE5, IE5.5, Netscape 4 mit den nötigen größeren Werten, Opera 5, 6, 7, und Mozilla interpretieren den Korrekturblock nicht.

Der bekannteste und vmtl. wichtigste CSS-Hack zum Thema Box-Bug von Tantek Çelik [28] nach unten, übrigens Entwickler des Internet Explorer für Mac, hat bereits bei voice-family: "\"}\""; einen Backslash in Anführungszeichen eingesetzt, sodass meine Lösung auch als eine Weiterentwicklung dieses Hacks betrachtet werden kann.

Grundsätzlich ist meine Empfehlung die Einbindung geeigneter Styledateien für die besonders zu behandelnden IEs per Conditional Comment, eine eigentlich sehr zuverlässige Weiche. Auch da ist allerdings ein Fehlverhalten nicht völlig auszuschliessen, denn unter Microsoft Windows 9x bezieht der Browser m.E. seine Information über die eigene Versionsnummer aus der Registry und nicht vom Browser selbst. Da aber in diesem Fall eine Deinstallation eines Browserupdates oder ähnliche Szenarien kaum möglich sind dürfte eine Fehlinterpretation der Versionsnummer kaum auftreten.

Der > Selektor eignet sich natürlich auch als einfache Lösung mit einer Ergänzung per Comment, hier mit anschliessender IE 4-5 Weiche zur Nachkorrektur:

<style type="text/css">
/* 2002-2003 Kristof Lipfert Duesseldorf  */

#beispiel    { width:320px; height:320px; } 
*>#beispiel { width:200px; height:200px;}
html + body #beispiel { width:320px; height:320px; }
</style>
<!--[if IE 6]><STYLE>
 #beispiel { width:200px; height:200px; } 
</STYLE><![endif]-->

Zum Vergleich die Verwendung von [id]:

<style type="text/css">
#beispiel    { width:320px; height:320px; } 
#beispiel[id] { width:200px; height:200px; }

Hier eine Variante für XHTML strict, IE 6 rendert hier "CSS1"-kompatibel: Popup-Seite

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<title>Doctype test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<style type="text/css">
/*  2002-2003 Kristof Lipfert Duesseldorf  */

div {padding:50px;border:50px solid silver;width:100px;height:100px;}

* html div {content:"\";}
* html div { width:300px; height:300px;}

</style>

Nun XHTML strict mit gleicher Behandlung der IE 4 bis 6, der IE 6 bleibt hier im "Back Compat" oder "quirks" Render-Modus: Popup-Seite

<?xml version="1.0" encoding="iso-8859-15"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<title>Doctype test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<style type="text/css">
/* 2002-2003 Kristof Lipfert Duesseldorf  */

div {padding:50px;border:50px solid silver;width:100px;height:100px;}

* html div { width:300px; height:300px;}

</style>

Nachtrag zum Thema Box-Bug: In der CSS3 Spezifikation ist eine Syntax zur Steuerung des Browserverhaltens vorgesehen, box-sizing: kann border-box oder als content-box festgelegt werden, damit können Mozilla (Syntax ggf. mit -moz-) und InternetExplorer Mac gezielt angesprochen werden.
[http://www.w3.org/TR/2003/WD-css3-ui-20030703/#box-sizing]
Eigentlich auf DHTML basierende Ersatzmethoden für den Windows-IE würde ich nach meinen Erfahrungen mit Expressions eher vermeiden.

top Index: neue CSS Weichen

Zum Abschluss des Kapitels Browser-Weichen oder "crossover" bzw. Filter eine Übersicht über die ergänzenden Beispieldateien zu den vorgestellten von mir weiter bzw. meist neu entwickelten Weichen und Konzepte:

  1. Ergänzung der CSS Weiche für Netscape 4 (z.B. Caio) mit zusätzlichen Filtern oder CSS-Hacks für andere Browser und Opera 5
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-nc4-crossover.html
  2. CSS Crossover für Opera 5, Filter sperrt auch Netscape 4
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-op5-crossover.html
  3. CSS-Weiche für den Internet Explorer 4
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-ie4-b-crossover.html
  4. Noch ein CSS crossover für den Internet Explorer 4
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-ie4-crossover.html
  5. Ein CSS Filter für die Internet Explorer 4 bis 6
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-IE-4-6-crossover.html
  6. CSS Bandpass für Internet Explorer 4 bis 5.5
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-IE-4-55-crossover.html
  7. CSS Filter für Internet Explorer 5
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-ie5-crossover.html
  8. Nochmal CSS Hack Internet Explorer 4 bis 5.5
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-ie40-55-crossover.html
  9. Mozilla CSS Filter
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-xhtml-b-crossover.html
  10. XHTML Box Bug und CSS Filter
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-xhtml-b-crossover.html
  11. XHTML Box-Bug Testbox und CSS-Filter
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/kristof-lipfert-xhtml-crossover.html
  12. CSS-Weiche bei Import und Link, diese CSS-Weiche lädt externe Stylesheets exklusiv für bis zu neun Browser bzw. Browsergruppen
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/NBdemo.html

Nachtrag: Schwerpunkt meiner in diesem Tutorial dargestellten Arbeiten war wie schon in der Einführung erklärt nicht eine Einführung in CSS, sondern neue, unbekannte oder vernachlässigte Lösungen zu entwerfen und vorzustellen, auch grundlegende Strategien zu cross-browser geeignetem Code darzulegen. Ziel war dabei auch für mögliche viele Browser Layoutvorgaben umsetzen zu können, und das soweit möglich bei validem Code. Entsprechend basieren dieses Tutorial und die Codebeispiele im Wesentlichen auf eigenen Entwicklungen. Beim Box-Bug zeigte zudem einer der zu Beginn meiner Arbeit schon existierenden Hacks bei meinen Tests Probleme mit einer 5er Version des Internet Explorer, oder beim Caio Filter als Weiche für Netscape 4 gab es Effekte mit Opera 5. So habe ich 2002, auch mit der Überlegung einer Veröffentlichung in einem Printmedium, eigene Lösungen entwickelt und auch bereits vorher von mir entwickelte Techniken aus meiner Praxis als Web-Designer eingebracht, und natürlich mögen Ähnlichkeiten oder Parallelentwicklungen existieren.

top CSS als Crossbrowser-Werkzeug

Auch hier bei der Frage der Browseranpassung zeigt sich wieder der grosse Vorteil von CSS. Wenn es gelingt überwiegend per unterschiedlicher CSS-Abschnitte an verschiedene Browser anzupassen, bleibt immerhin der HTML-Code homogen, und die Anpassungen sind kompakt und an einer Stelle im Head oder in einer externen Datei festgelegt. Wenn es da wo sinnvoll gelingt Anpassungen per CSS-Fähigkeiten der Browser selbst ohne Weiche oder per CSS-Weiche durchzuführen, ist es gerade bei neueren Browsern ein erheblicher Vorteil. Erstes Fazit einer weitergehenden Crossbrowserlösung ist also differenziertes CSS einzusetzen, und erfahrungsgemäß ist diese Vorgehensweise sowieso wegen der doch vorhandenen Unterschiede der neueren Browser oft nötig, oder es wird wie beim "BoxBug" doch etwas mehr HTML in Form zusätzlicher Divs eingesetzt.

Nun gibt es ausser der Möglichkeit des kleinsten gemeinsamen Nenners oder der speziellen Anpassungen noch eine andere Strategie um crossbrowser zu coden. Fehlende Fähigkeiten eines Browsers werden wenn möglich ersetzt oder simuliert, entsprechende Workarounds oder "Hacks" sind allerdings oft mit vielen Mängeln behaftet, etwa dass sie nicht kompatibel sind, zu umfangreiche Bibliotheken benötigen, oder eigentlich in der Praxis doch nicht funktionieren, und bei der nächsten Version eines Browsers erheblich stören.

top Ersatzmethode

Ein Beispiel für solch eine Vorgehensweise, nämlich fehlende Fähigkeiten eines Browsers zu ersetzen, ist das Nachrüsten von JavaScript-Fähigkeiten bei Netscape 2. Dieser Browser unterstützt JavaScript 1.0, Netscape 2 kennt weder die Methode Array, noch den Eventhandler onMouseOut, noch substr. Man kann nun eine Funktion Array() o.ä. erstellen, sodass entsprechende Scripte gleichermassen unter Netscape 4, 3 oder 2 laufen:

function Array(){
 this.length=Array.arguments.length;
 for(var i=0; i<99; i++)this[i]=Array.arguments[i]
}
 var Ti=new Array('Start','Ziel 1','Ziel 2');

Beim fehlenden onMouseOut ist es das einfachste, per setTimeout zu überprüfen ob eine neuer onMouseOver erfolgt, was in diesem speziellen Fall auch noch die unsaubere Arbeitsweise des onMouseOut beim Netscape 3 korrigiert. Und substr wird einfach vermieden, da man mit substring ähnlich ohne nennenswerte Einbußen im Funktionsumfang zum Ziel kommen kann.

Das grundlegende Instrumentarium für crossbrowser kann also aus Nachbildung, Ersatz, indirekte Workarounds oder Vermeidung bestehen.

top Sonderfall NC4

Zunächst, welche Browser sind hier überhaupt mit Netscape Communicator 4 gemeint? Ich beziehe mich aus verschiedenen Gründen auf die Windowsversionen des NC4, und damit sind vermutlich auch um die 98% erfasst. Bekanntlich sind, das gilt besonders für ältere Browser, die Varianten für verschiedene Betriebssysteme ganz unterschiedliche Software mit unterschiedlichen Bugs, dazu noch abweichendem Leistungsumfang. Beim NC4 für Linux ist denn auch das Verhalten deutlich anders, während sich der NC4 für Mac nach meinen Erfahrungen meist ähnlich wie die Windowsversion verhält, aber einige Abstände ein paar Pixel anders anlegt, besonders bei Rändern des Body. Vom NC4 gibt es dann noch Unterversionen, sodass man für optimale Ergebnisse auch noch mit einer älteren Version kontrollieren kann. Häufigster NC4 mit über 80% ist der 4.7x, der weniger verbreitete 4.8 verhält sich ähnlich wie der 4.79, mit einem 4.5 sind vielleicht 10% unterwegs, und ca. 5% mit einem 4.0.

Wer besonders gründlich sein möchte kann berücksichtigen dass ein Teil der Netscape 4 Nutzer wenig updatefreudig ist, und z.B. die Version 4.7 statt einer bugfreieren 4.79 testen.

Nachdem der NC4 eine Sonderstellung einnimmt, gilt es sich nochmals unter anderen Aspekten mit seinen Fähigkeiten auseinanderzusetzen. So ist eine Liste mit Sollanforderungen und Defiziten zu erstellen und ihre Abhängigkeiten voneinander zu bewerten, denn was nützt schließlich eine Lösung für ein ganz bestimmtes Problem falls unterm Strich zuviele andere Hindernisse bleiben. Und da gerade über Netscape 4 Halbwahrheiten kursieren, muss manchmal auch genau hingeschaut werden, welche CSS-Fähigkeiten dieser Browser doch hat. Popup-Seite

Dann muss die JavaScript Unterstützung beim Netscape 4 betrachtet werden. Anders als etwa Opera 6 vermag der Netscape schon etwas mehr an dynamischem HTML, das JavaScript ist bei CSS bzw. um CSS zu ermöglichen bei diesem Browser sowieso immer aktiviert, dazu ist das Sicherheitsrisiko von JavaScript bekanntlich beim NC4 relativ gering. Der Netscape 4 ist in seiner Entwicklung trotz der noch Ende 2002 erschienen Version 4.80 [31] nach unten abgeschlossen, also hinsichtlich seines Verhaltens berechenbar und verlässlich, und per if(document.layers) ist er eindeutig indentifizierbar.

Ein Ziel als Ergebnis der Überlegungen ist also erstmal zu überprüfen ob per JavaScript beim Netscape 4 hinreichend so weitgehend nachgebessert werden kann, dass durch ordentlich im Head der HTML-Datei zusätzlich eingebundene Scripte nahezu alle modernen Möglichkeiten offenstehen.

NN 6?

Da bei der Frage, warum der NC4 überhaupt noch genutzt wird, die Versionsnummern der neueren Netscape Browser Navigator 6 oder seit Herbst 2002 N 7 den NC4 als besonders veraltet erscheinen lassen, kurz etwas zum Netscape 6 (der eigentlich die übersprungene Versionsnummer 5 erhalten sollte). Netscape 6 basiert auf Mozilla 0.6, was zwar die allgemein als gut beurteile Gecko Rendering-Engine beinhaltet, aber anhand der Versionsnummer auch eine Einschätzung der Software als im Alphastatus befindlich nahelegt.

NetscapeN.MozillaVerfügbar  
6.00.6.0 / m18 1/2001
6.10.9.2 8/2001
6.20.9.410/2001
7.01.0.1 9/2002

Bestand bei ersten Tests von veröffentlichten Vorabversionen, z.B. "M13" im Frühjahr 2000 [37]nach unten, noch die Hoffnung auf Verbesserungen und Performancesteigerung des endgültigen Browsers, folgte später, etwa angesichts des auf Mozilla M18/0.6 basierenden Netscape 6, eher Ernüchterung. So fand sich Anfang 2001 in einer Zeitschrift [38]nach unten die Überschrift "Kalte Dusche", und im Vergleich eines anderen Magazins [39]nach unten wurde deutlich, wie schnell und durchaus competitive der Netscape 4.75 beim Seitenaufbau ist. Um den neuen Browser zu unterstützen, wurden übrigens noch Methoden veröffentlicht um mit NN6 auf Layer zuzugreifen[25]nach unten.

Die grundsätzliche Methode zur weitergehenden Unterstützung der Performance ist beim Communicator 4 übrigens immer noch die Cacheeinstellung, wie auch bereits 6/1997 beim Hersteller eigentlich bekannt oder veröffentlicht [29]nach unten. Die letzten Versionen des NC4 sind nach meinen Erfahrungen auch äusserst stabil. Instabilitäten wurden interessanterweise in Newsgroups auch auf den wohl unnötigen talkback oder Quality Feedback Agent zurückgeführt, mit verschiedenen Lösungsvorschlägen etwa Ändern der Voreinstellungen (Bearbeiten von prefs.js bzw. ini wäre vmtl. auch möglich)[40][42][43]nach unten.

top Beispiel HTML zu CSS

Hier möchte ich auch gleich ein Beispiel zeigen, bei dem sich der Netscape 4 anders verhält als andere Browser. Die Bezeichnung "Bug" ist in solchen Situationen nicht besonders hilfreich, wenn infolge dieser Einschätzung womöglich eher übersehen wird, dass vielleicht eine anwendbare Logik hinter diesem Verhalten steckt.

Konkret also jetzt schonmal etwas zu Hintergrundgrafiken bei Tabellen, Netscape 4 vererbt Hintergünde von Tabelle zu Untertabelle oder Zelle usw.. Dabei wird eine Hintergrundgrafik in jeder Zelle wieder neu als Hintergrund angefangen, auch bei Hintergrundfarben sind übrigens solche Effekte möglich, diese Vererbung kann aber einfach abgestellt werden: Popup-Seite

<style>
#bg{
   background-image:url(logo.png);
   background-repeat:no-repeat;
   }
</style>
<body>
<table>
 <tr>
  <td id=bg>
     <table border="0" cellpadding="0" cellspacing="0" background="">
       <tr>
        <td>1
        </td>
        <td>2
        </td>
       </tr>
       <tr>
        <td>3
        </td>
        <td>4
        </td>
       </tr>
     </table>
  </td>
 </tr>
</table>

Hier wird per background="" die Vererbung für das Element aufgehoben, der jeweilige Hintergrund der Tabelle oder der Zelle bleibt transparent. Allerdings muss bei dieser einfachen und zuverlässigen Lösung gesehen werden, dass der zusätzliche Eintrag im Table-Tag nicht vom W3C abgesegnet ist.

top Tabellen-Hintergund CSS

Es gibt aber eine konformere Lösung per CSS, die sich aus den bisherigen Überlegungen als Übertragung der Beschreibung der Eigenschaften in CSS entwickeln lässt: Popup-Seite

<style>
#bg{
   background-image:url(logo.png);
   background-repeat:no-repeat;
   }
td{
  background-image:url();
  }
</style>
<body>
<table>
 <tr>
  <td id=bg>
     <table border="0" cellpadding="0" cellspacing="0">
           ....

Diese Lösung nur per CSS zeigte bei verschiedenen Browsern keine unerwünschten Effekte, ist also offenbar so ohne zusätzliche CSS-Weiche o.ä. bereits crossbwrowserfähig. Für den NC4 empfiehlt sich hier als Hintergrund übrigens ein Gif mit Transparenz, um unerwünschte Effekte beim Fensterwechsel zu vermeiden.

top Tableless nur per CSS

Beim Netscape 4 zeigt sich auch dass dieser Browser schon ohne DHTML sehr einfach ein "tableless layout" ähnlich dem Beispiel des W3C per CSS umsetzen kann, zumindest eine einfach zweispaltige Lösung ist ohne weitere Klimmzüge möglich. Auch das Beispiel des W3C mit drei Spalten funktioniert mit kleinen Änderungen, so muss ein unnötiger Inlinestyle, der einzige übrigens auf der Seite, in die normale CSS-Datei gesetzt werden -vgl. auch den Absatz Voraussetzungen nach unten -, und etwas JavaScript wird noch benötigt.

<style>
 #main{ margin-left:12em }
 #left{ position:absolute;
        top:0; left:0;
        width:11em; }
</style>

Schon dieses einfache Beispiel zeigt dass CSS beim Netscape 4 den Seitenaufbau bewerkstelligen kann. Es geht sogar noch einfacher und ohne absolute Positionierung:

<style>
 #left{ width:11em; float:left; }
</style>

Bei der zweiten Variante muss das Div id=left dann im HTML-Code zuerst aufgeführt werden. Schwierig wird diese Zweckentfremdung der Eigenschaft float dann, wenn crossbrowser das Div eine Höhe von 100%, also height:100% erhalten soll. Jetzt zeigt sich die Schwierigkeit bei verschiedenen Browsern ob die Höhe überhaupt umgesetzt wird, und ob sich die Höhe wenn es funktioniert sich nur auf die Höhe des Window auswirken. Speziell bei Netscape 4 zeigt sich dann dass verschiedene Tricks die wechselseitigen Abhängigkeiten nur mit Aufwand korrigieren können, so padding oder margin oder clip-height, die u.U. eine Änderung per negativer Angabe für top erfordern würden.

Um grundsätzlich zu zeigen dass selbst diese für Netscape 4 besonders schwierige Situation erstmal ganz einfach und ohne Browserweiche oder JavaScript beherrschbar ist, habe ich einfach die für den sogenannten Box-Bug bekannte Strategie abgewandelt und den Inhalt der linken Spalte id=left in ein <div id=ileft> mit der Eigenschaft padding-bottom:100% gesetzt.

<style>
 #left{ width:11em; float:left; }
 #ileft{ padding-bottom:100%; }
</style>

Popup-Seite

<body>
<div id=left><div id=ileft>...
</div></div>
<div id=main>...
</div>

top Drei Spalten Layout nur per CSS

Nachdem ein Layout mit zwei Spalten so gut geklappt hat, jetzt noch ein Beispiel für drei Spalten welches auch für die Browser InternetExplorer 4 oder Netscape 4 geeignet ist, und immer noch ohne irgendeine Browserweiche und ohne JavaScripte funktioniert: Popup-Seite

<style>
 #rechts { width:11em; float:right; height:100%}
 #mitte  { margin-left:12em; }
 #links  { position:absolute; width:11em; top:0.8em; }
</style>
<body>
<div id=rechts>
 ....
</div>
<div id=mitte>
 ....
</div>
<div id=links>
 ....
</div>

oder auch so: Popup-Seite

<style>
 body{width:auto}
 #links{ width:10em; float:left; height:100%; }
 #mitte{ margin-left:0.2em; margin-top:0.2em; float:none; }
 #rechts{width:10em; float:right; height:100%;}

top Drei Spalten plus

Und es klappt auch mit zwei zusätzlichen Divs, "oben" und "unten", allerdings in der hier gezeigten sehr einfachen Form ist vorsorglich noch ein zusätzliches leeres Div eingefügt um die nötige Anweisung clear:both sicherer auszuführen, und um den Höhenunterschied/Zeilensprung beim NC4 ausgleichen zu können. Das Layout eignet sich für übliche Seiten, bei denen ein grösserer Textblock in der Mittte über das Window hinausgeht. Zugleich ist mittels clear:both und dem Div für NC4 sichergestellt, dass auch bei einem kurzen mittlerem Textblock der abschliessende Block "unten" sich nicht mit "rechts" oder "links" überschneidet. Eine Variante für kurze Textblöcke und einem Div "unten" am Windowrand würde zunächst Angaben zum Body erfordern, ggf. Containerdivs u.a. falls der Body grösser sein sollte als das Window, und natürlich eine Angabe bottom:0px. In der jetzigen Form soll es aber besonders zeigen wie bereits mit den vorhandenen Mitteln im Rahmen einer Layoutumsetzung durch CSS ältere Browser berücksichtigt werden können. Der Aufbau mit einer mittleren Spalte, die für neuere Browser im Wesentlichen mittels margin-left: und margin-right: beschrieben wird, entspricht den Empfehlungen des W3C für Tableless Layout. Das Beispiel ist auch für Opera 3.6 geeignet. Popup-Seite

Die je nach Bildschirmauflösung beim NC4 manchmal etwas unstimmigen Breiten der Elemente "oben" und "unten", z.B. bei 800 x 600, können ähnlich einem später bei Korrekturen Body/Tabelle nach unten noch beschriebenen Verfahren ordentlich abgeglichen werden, oder mittels body{width:100%} gleichmäßig zum rechten Rand des Window gehalten werden.

Man kann sich auch das Verhalten des Netscape 4 zunutze machen und anders vorgehen, nämlich einfach mittels #oben,#unten{width:110%;} sicherstellen dass Netscape 4 den verfügbaren Platz voll nutzt, zumindest bis zur Scrollleiste plus Sicherheitsabstand, und dabei, auch bei noch grösseren Werten, nicht überschreitet, und auch bei 800 x 600 sieht es jetzt richtig aus, und funktioniert z.B. auch mit Opera 3.60. Popup-Seite

Dann wäre noch @media all{#unten,#oben{width:auto}} und für den IE4 u.U. document.write('<style>#oben2,#unten{width:100%} sinnvoll. Interessant ist auch das Verhalten der anderen drei Spalten, hier liesse sich auch gleich eine neue Lösung des 100% Breitenproblems für den NC4 ableiten.

<style>
 #oben, #unten { width:100%; text-align:justify;
                        border: 1px solid black; }
 #links       { width:10em; height:100%; float:left;
                        border: 1px solid black; }
 #mitte {float:none; text-align:justify;
          margin-right:.1em; /* NC 4.70 Bug */
                       border: 1px solid black; }
 #rechts {width:10em; height:100%; float:right;
         text-align:right; border: 1px solid black; }
 #vunten{ clear:both; margin-top:-1em; }
 @media all{
  body{min-width:30em;}
  #links,#rechts,#mitte{height:auto;}
  #mitte{margin-left:10.2em;margin-right:10.2em;}
  #unten{clear:both;}
  #vunten{display:none}
 }
</style>
<script>
 if(document.all&&!document.getElementById)
  document.write('<style>#mitte{margin-left:0!important;}'+
               '#vunten{margin-top:0!important;}<\/style>')
</script>

<body>
<div id=oben>    ....  </div>
<div id=links>   ....  </div>
<div id=rechts>  ....  </div>
<div id=mitte>   ....  </div>
<div id=vunten></div>
<div id=unten>   ....  </div>

Es ist also sehr wohl schon mit einfachsten Mitteln möglich, eine Seite in Dreispalten-Layout mit einem einzigen kurzen validen CSS-Abschnitt zu realisieren, auch für Netscape 4 oder IE4. Dazu in einer nichtstatischen Umsetzung ohne Pixelangaben. Die bislang gezeigten Beispiele haben dazu noch den Vorteil, dass ein Reload wegen des Resizebug beim NC4 vorerst entfallen kann, und das vorher eingesetzte zusätzliche Schachtel-Div ist hier auch nicht nötig. Und das gezeigte Beispiel ist ausbaufähig und kann auch auf andere Anforderungen angepasst werden, z.B.:

#rechts { width:20%; float:right; height:100%}
#mitte  { margin-left:22%;}
#links  { width:20%; position:absolute; top:0.8em; }

Das nachfolgende Beispiel scheitert übrigens am Internet Explorer. Mozilla 1, Opera und Netscape 4 setzen Abstand rechts und margin-right hier prinzipiell gleich um, bei Netscape 4 muss allerdings der Resizebug beachtet werden: Popup-Seite (Fehler bei IE)

 #rechts { position:relative; width:20%;top:3.4em;float:right; }
 #mitte  { position:absolute;left:22%;top:4em;margin-right:20% }
 #links  { position:absolute; width:20%;top:4em; }
 #oben   { position:absolute;top:0;
           height:4em;width:100%;margin-right:0;
          }
</style></head><body>
<div id=oben>oben</div>

Erst die notdürftige Unterstützung des Internet Explorer, der das margin-right nicht befolgt, mittels width:58%, führt dann zu weiteren Problemen die eine Browserweiche erfordern würden, statt dessen könnte das margin-right:20% u.U. auch durch padding-right:25% ersetzt werden.

Aber zurück zu Netscape und IE 4. Die Beispiele sollten erstmal die konservativeren Möglichkeiten aufzeigen und lassen bereits erkennen, dass die Potenziale sowohl von CSS selbst als auch der CSS-Fähigkeiten älterer Browser nicht zu unterschätzen sind.

Die grundlegenden Fähigkeiten, Elemente absolut oder per margin zu positionieren beherrschen die älteren Browser hinreichend. Statt right ist bei den dreispaltigen Beispielen float, z. Teil in Verbindung mit browserspezifisch wirkenden Angaben von height oder width, zur Definition der rechten Spalte eingesetzt.

Mit den noch weitergehenden Möglichkeiten per JavaScript erweitert sich die verfügbare Bandbreite noch erheblich, und dann ist nochmals weniger Rücksichtnahme auf den ursprünglichen Leistungsumfang der Browser nötig. Weitergehende später noch gezeigte Möglichkeiten ermöglichen dabei auch noch eine freie Festlegung der Reihenfolge der Divs im HTML-Code, was erhebliche Vorteile bei der Berücksichtigung CSS-unfähiger Browser hat, bis hin zum Ziel der weitestgehenden Barrierefreiheit (u.a. Kapitel CSS right bottom, Layout a la W3C).

top Konzept

Der konkrete Nutzen soll ja z.B. darin bestehen, dass trotz einer noch recht grossen Verbreitung des Netscape 4 eine Website mit modernerem und validem Code ausgestattet wird, bei vielen Projekten sollen ja möglichst 99% der Besucher optimal bedient werden. Also eine frühere Entscheidung für CSS und "tableless layout", bei der die nötigen Scripte ordentlich getrennt sind.

Ziel dieser Arbeit ist aber nicht für jede Eigenheit alter Browser die richtige Antwort parat zu haben, sondern eine stabile Grundstruktur, ein Konzept um eine vernünftige und zeitgemäße Darstellung zu ermöglichen. Teil des Konzeptes ist einmal die grundlegende Lösung zweier Defizite, nämlich das einfache Adressieren von Objekten, besonders natürlich "Layern", beim NC4, sowie die möglichst bequeme Korrektur von CSS mittels JavaScript. Dann geht es in der Praxis darum, möglichst alle wichtigen Mängel ersetzen zu können, aber ebenfalls nicht als lückenlos abgearbeitete Bugliste, sondern um mit der Anwendung an einen Punkt zu kommen ab welchem wegen der besseren Darstellung und der zeitgemässen Möglichkeiten die Mühe lohnt, bei stabiler Funktion der Website. So ist es vorrangig keine Sammlung von Workarounds, sondern ein funktionsfähiges Gesamtpaket oder -konzept mit sehr gut zusammen funktionierenden Beispielen, aber auch möglichen Widersprüchen und Lücken.

Dabei geht es nicht nur darum dass bei einem alten Browser per JavaScript der eine oder andere Effekt simuliert werden kann, sondern es geht darum auf den Ebenen CSS und HTML möglichst alle Browser gleich und dabei richtig, also auch W3C konform, zu bedienen. Proprietäre Tags wie Layer oder Spacer sollen im HTML-Code bzw. im Body ebensowenig auftauchen wie Browserweichen, Scripte oder veraltete Angaben, etwa margin-Angaben im Body-Tag.

Der hohe Anspruch, alten Browsern prinzipiell alles zu ermöglichen, ist vorteilhaft solange die Umsetzung im Gesamtkonzept möglich und nötig ist, und der damit verbundene Aufwand wirtschaftlich noch vertretbar ist. Spätestens zu dem Zeitpunkt einer Entscheidung, entweder viel zu umfangreiche unübersichtliche Bibliotheken zu erhalten, oder aber permanente Korrekturen und aufwändige Detaillösungen immer wieder nachzubessern, gilt es sowieso aufzuhören. Nun hier eine Liste der möglichen Punkte:

top Katalog der Probleme

Der Code soll valides CSS und HTML 4 transitional oder strict oder XHTML bleiben. Es muss erreicht werden, dass auch für Netscape 4 eigentlich alle HTML-Tags trotz einiger Browser-Bugs gemäss ihrer eigentlichen Bedeutung eingesetzt werden. Ein ganz wesentlicher Punkt, zunächst wird die Verwendung von HTML-Tags einfacher, richtiger.

Wenn man analysiert wo und wie in der Praxis auf Netscape 4 beim Code Rücksicht genommen wird, stellt man fest dass oft auf Listen und Überschriften, also Tags wie <ul> oder <h1> verzichtet wird, um die viel zu großen Seitenabstände zu umgehen. Hier gilt es zu korrigieren, damit es eher möglich wird diese Tags richtig einzusetzen ohne dass z.B. Netscape 4 das Layout zerlegt, neben dem Ersatz der fehlenden Möglichkeiten wie right erstmal ein wichtiger Punkt.

  1. CSS
    • right, bottom,
    • overflow: auto
    • position: fixed
    • a:hover
    • mouseover/hover für div
    • width, height, background-color, margin, padding
    • h1-h6 {margin, padding
    • ol, ul {list-style-type:none; margin-left:
    • td {height:
    • background: repeat-x
  2. JavaScript
    • getElementById (left, top, src, ..)
    • innerHTML
  3. HTML
    • <iframe>
    • <object>

Die Forderung einer einheitlichen und richtigen sowie W3C-konformen Codierung führt so zur Forderung nicht nur CSS, sondern HTML und JavaScript soweit möglich anzupassen und zumindest im eigentlichen Seitencode zu vereinheitlichen.

top Richtige Verwendung der Tags

Mit der richtigen Verwendung der HTML-Tags macht man gleichzeitig auch einen Schritt hin zu barrierefreiem Webdesign, und in diesem Zusammenhang kann denn auch der Verzicht auf Tabellen als Layoutwerkzeug nochmals Sinn machen. Auch die Darstellung bei deaktivierter oder fehlender CSS-Unterstützung wird stimmiger. Es sind zwar den meisten Statistiken zufolge kaum Surfer ohne CSS unterwegs, trotzdem gilt es auch ohne CSS eine Präsentation mit möglichst geringem Verlust der logischen Strukturen zu erreichen. Wenn farbliche oder räumliche Differenzierungen fehlen, bleiben wenigstens noch grundlegende HTML-Tags und deren Formatierungen erhalten, z.B.: a, b, i, tt, pre, ul, ol, table, h1-6.

Wenn also diese Tags sinnvoll und ihrer eigentlichen Bedeutung entsprechend verwendet werden, zudem die Reihenfolge der Elemente auch ohne CSS stimmig bleibt, kann auch ohne CSS oder mit rein textbasierten Browsern wie Lynx der Besuch einer Website noch funktionieren. Und wenn in der CSS Version beispielsweise bestimmte Inhalte wie etwa Quellcode nur durch die Farbgebung vom übrigen Text unterschieden werden sollen, kann man den HTML-Tags Style-Classes zuweisen und die übrigen Schriftformatierungen dem sonstigen Text angleichen. Bei Darstellung ohne CSS unterscheidet sich der Abschnitt dann durch Schriftformat statt Farbe, das Grundprinzip der Differenzierung bleibt erhalten, die bestimmungsgemäße Zuordnung der HTML-Tags ebenfalls.

Barrierefreiheit

Barrierrefreies Webdesign ist mit der erwähnten richtigen Verwendung von HTML möglich, und mit den hier angesprochenen oder später noch dargelegten Methoden ist es auch so möglich dass die Zugänglichkeit nicht darunter leiden muss. Dazu muss gesehen werden, dass Layoutvorgaben meist inhaltliche Strukturen erzeugen, oder solche Strukturen zumindest unterstützen.

Die Darstellung einer Website ohne solche Strukturen oder mit falschen Strukturen muss also vermieden werden, dass gilt beim barrierrefreien Internet-Design wie auch beim Zugang mit älteren Browsern. Nach einer Verordnung zum Behindertengleichstellungsgesetz müssen Behörden der Bundesverwaltung bis 2005 Vorkehrungen treffen, damit auch Behinderte das Informationsangebot nutzen können.

Der anfängliche Mehraufwand sich auch mit den älteren Browsern zu beschäftigen erlaubt die frühere Umsetzung eines zukunftstauglicheren Konzeptes, ohne gleich Kunden oder Besucher zu verprellen, und kann wegen der grösseren Zugänglichkeit und des geringeren Pflegeaufwandes letztendlich auch die kostengünstigste Lösung sein.

alt Attribut

Nicht ohne Grund ist bei Bildern im img-Tag das alt-Attribut vom W3C zwingend vorgeschrieben, das aber je nach Bildbedeutung auch leer sein darf. Wichtig um das auf manchen Seiten störende Aufklappen zu verhindern ist das title-Attribut, weil es bei vorhandenem Bild bei den neueren Internet Explorern statt des alt angezeigt wird oder bei title="" die Anzeige verhindert, einige andere Browser würden den alternativen Text nur bei fehlendem Bild anzeigen.

Für wen wird nun eine alternative Beschreibung bereitgestellt? Abgesehen von Screenreadern und speziellen Lesegeräten geht es auch um fehlende oder nicht anzeigbare Bilder, und bei älteren Browsern wie dem NC4 wurde es wie ein title-Attribut eingesetzt. Mit der Einführung des title-Attributes und seinen Möglichkeiten ist die Bedeutung des alternativen Textes eindeutiger, die richtige Verwendung auch möglicher und nötiger geworden. Gerade wenn alternative Beschreibungen bereitgestellt werden ist es natürlich sinnvoll zu beachten wo und wann diese Texte angezeigt werden.

Es gibt aber auch Situationen, bei denen diese Texte eher unbeabsichtigt unterdrückt werden. Falls im Text Navigationssymbole als PNG-Grafiken bereitgestellt werden, gibt es viele ältere grafikfähige Browser die nun die Ersatzbeschreibung ausgeben, wie natürlich auch die meisten Browser bei fehlenden Bilddateien. Ist nun solch eine Grafik im laufenden Text mit Höhen- und Breitenangaben eingebunden, wird der alternative Text gar nicht angezeigt bzw. angeschnitten. Bei den IE Browsern wird der Text beim mouseover sichtbar, und natürlich sieht das Layout mit den Grössenangaben stimmiger aus, die Notlaufeigenschaften der Seite dürften aber ohne solche Angaben oft besser sein. Popup-Seite

Die bisher getesteten Browser auf Gecko-Basis haben anscheinend auch ein ungünstiges Verhalten beim Alt-Attribut und Img-Tag mit konventionellen Grössenangaben, und zeigen die Alt-Texte beim mouseover auch bei fehlendem Bild nicht an. Die Unterstützung für diese Browser beim vorliegenden Beispiel kann hier auch per egänzendem oder überschreibendem Style erfolgen:

*>img{width:auto;height:auto;color:blue}

Da bei Bildern seit HTML 4 auch noch das longdesc Attribut verfügbar ist, können auch umfangreichere Beschreibungen untergebracht werden, damit wird auch das alt Attribut etwas entlastet. Allerdings wird beim Gecko-Browser zwar longdesc unterstützt, ist jedoch bei nicht gefundenem Bild und angezeigtem Alt-Text nicht mehr aufrufbar, und auch nur in neueren Versionen als Link über das Menu rechte Maustaste/Properties abrufbar.

top Usability

Auch die bekannte Forderung nach Usability, oder um einen im Produkt- und Industrialdesign etablierten Begriff zu verwenden, Ergonomie, erfordert natürlich den Zugang zu einer Seite und zu den Strukturen. Zum einen also die Forderung nach richtigem HTML, auch um die "Notlaufeigenschaften" zu optimieren, zum anderen aber die Notwendigkeit das geplante Layout möglichst umfassend umzusetzen.

Jakob Nielsen sagte in einem Interview "Das Interface ist nur eine Komponente von Usability. Eine weitere ist der Content." und "Die vielleicht wichtigsten Komponenten sind Workflow, Funktionalität und Support. Wie ist die Website strukturiert?" [41]nach unten,

top Quelltextkontrolle

Weitere Erfahrungswerte beim Netscape 4 zeigen, dass übliche Workarounds für Iframe entweder bei der Verwendung von Divs instabil sind, oder das Layer Tag verwenden:

<ilayer>
<layer src=ins-iframe.html>
<iframe src=ins-iframe.html>   </iframe>
</layer>
</ilayer>

Hier ist ganz konkret die Entwicklung einer neuen Lösung sinnvoll, so gilt es notfalls festzustellen dass man besser auf Konstruktionen wie <div src=xy.html> verichtet, oder eben doch eine stabile Lösung ohne Layer und ohne Einfluss auf die Position eines Div im HTML-Code zu finden, wobei, soviel vorweg, schonmal eine stabile Lösung gelungen ist.

Immer interessant: die Quelltextanzeige des Netscape 4 gibt Hinweise auf Fehler. Hier erscheinen im Iframe-Div von Netscape 4 bei einer komplexen Seite zwei von Netscape selbst erzeugte Divs mit fehlerhaften Styleangaben und ohne Endtag, ein solcher Iframe-Ersatz mag zwar am Seitenende noch funktionieren, aber die Festlegung an bestimmte Stellen im Code und die möglichen Instabilitäten fordern eine bessere Lösung. Andere Auswirkung solcher Fehler kann auch das doppelte Auftauchen des Ersatz-Iframe in der Seite sein.


<DIV id="iframe">
<DIVstyle='display:none'<DIVTtyle='display:none'>
</DIV>

So sind generell Einträge wie "Ttyle" statt "Style", oder unstimmige farbliche Zuordnungen oder blinkende Bereiche im Code ein Indiz für problematische Stellen, oder grossgeschriebene Tags zeigen u.U. dass und wie der Browser eine Seite intern z.B. um Styleangaben zu realisieren "übersetzt" oder nach Einsatz von JavaScript (document.write) aufgebaut hat. Popup-Seite (nur für NC 4 sinnvoll)

top Voraussetzungen

Die Voraussetzungen um mit NC4 gut klarzukommen sind erstmal überschaubar. So die Forderung nach fehlerfreiem HTML, dieser Punkt ist ja sowieso erstrebenswert. Und als einfache Maßnahme der grundsätzliche Verzicht auf Inlinestyles, ein Punkt der zwar für den NC4 nicht immer nötig, aber ebenfalls grundsätzlich richtig ist, so er der Vorstellung von CSS als Trennung der Formatierung vom Inhalt entspricht. Selbst die Vorgabe keine Tabellen als Positionierungswerkzeug einzusetzen ist vorteilhaft, denn stark verschachtelte Tabellen in der Kombination mit Absätzen und Divs, dazu Styleangaben, sind viel problematischer als ein Aufbau überwiegend mit Tabellen oder auch als eine Struktur nur durch Divs.

Manche Styleangaben müssen wiederholt werden, weil beim NC4 die Vererbung von Eigenschaften oft nicht funktioniert, oder Vererbung nur per Inline-JavaScript und Layern möglich wäre. Wesentlich bei dem hier vorgestellten Konzept ist der Einsatz einer CSS-Datei mit möglichst umfassenden Angaben für alle Browser. Lediglich Angaben die Netscape 4 hängenlassen würden müssten vor ihm versteckt werden oder in eine extra Datei kommen. Die Browser sollen also alle eine möglichst einheitliche und vollständige CSS-Datei erhalten. Eine Einbindung könnte grundsätzlich früh im Head für alle Browser erfolgen. Man kann aber auch, da beim I.E.4 die Korrekturen per JavaScript erfolgen, für die älteren Browser die Einbindung auch in die JavaScript-Sektion stellen, damit bei deaktiviertem Script kein dann unkorrigierbares CSS eingelesen wird.

top Image als Link

ohne Border

Hier kurz ein bekanntes Netscape 4 Problem mit einer vormals unbekannten sauberen Lösung per CSS. Der blaue Rahmen verlinkter Bilder unter Netscape 4 lässt sich zwar einfach per border=0 unterdrücken. Aber auch per CSS gibt es Wege, HTML 4.01 Strict usw. ist also auch möglich. Die von mir entwickelten Lösungen ergeben sich aus dem durchaus logischen Verhalten des Browsers, und sind beispielhaft für viele kleinere Workarounds.

Wichtig ist die Überlegung, dass Netscape hier offenbar vom a-Tag ausgeht. Der Rahmen um das Bild ist nicht nur Eigenschaft des img, kann also per CSS beim a-Tag unterbunden werden, z.B. über border-width. Direkt ansprechbar ist auch die Farbe des Rahmens be4i A-Tag oder bei IMG, es muss also ggf. die Hintergrundfarbe bekannt sein, hilfreich als Alternative wenn durch die Zuweisung einer Border der A-Tag nicht mehr funktioniert.

a   { border-width:.1px;
      text-decoration:none; }

img { color:999; }

a   { color:999; }

Auch border:1px solid 'none'; kann eine Möglichkeit sein um Rahmen wieder zu entfernen. Mit dem zusätzlichen text-decoration:none; lässt sich denn auch die Markierung von Leerzeichen uhnd Zwischenräumen unterdrücken. Im Absatz Image border nach unten ist dazu nochmals eine JSSS-Lösung dargestellt. Auch so kann der Rahmen verändert werden ohne den Link zu deaktivieren wie es bei einer Beschreibung des a-tag als Blockelement passieren könnte:

 a img { margin-left: -1px; }
 a     { text-decoration:none; color:999; }

Schließlich bleibt noch den Rahmen einfach beim umgebenden Element abzuschneiden, dazu müssen die Masse der Grafik bekannt sein:

#umE {clip:rect(1px, 50px, 20px, 1px);}

line-height

Ähnliches passiert, wenn sich bei Netscape 4 in einem Div die gesetzte line-height auf den verfügbaren Platz auswirkt und Text nicht angezeigt oder verdeckt wird. Hier wird als schnelle Methode einfach paddingbottom, in Netscape 4 spezifischer Schreibweise als Browserweiche, zur Korrektur der Bildhöhe abzgl. Zeilenhöhe eingesetzt. Alternativ kann z.B. per <a class=.. und einer Weiche im CSS a la /*/*//*/ gearbeitetet werden.

<div style="font-size: 8pt; line-height: 9pt;">
<a href="#" style="paddingbottom:80px"><img width=100 height=100 src=xy.gif></a>
text text
</div>

Form

Bei Grössenproblemen, etwa durch Zeilenumbrüche nach form, kann umgekehrt lineheight, oder fontsize:smaller, eingesetzt werden, um die zusätzliche Zeilenhöhe zu korrigieren wenn negativer margin oder andere Angaben nicht möglich sind.

<form>
<span style="lineheight:.5em">
<select>
<option>

noscript

Ein lästiger Netscape 4 Bug ist der Verlust von Formatierungen nach noscript. Wenn ein script benachbart ist, kann dort z.B. durch einen neuen body-Tag nachgebessert werden:

if(document.ids)document.write('<body>');

top Frameset

Eine eigentlich unsinnige Maßnahme ist die Verschleierung der URI bzw. Adresse im Browser durch ein Frameset, dennoch der Hinweis wie ein solches Konstrukt für möglichst viele Browser zugänglich bleibt:

<frameset cols="0,100%">
<frame src="about:blank" scrolling="no" frameborder="0">
<frame src="inhalt.htm" frameborder="0">
</frameset>

top rechts platzieren per JavaScript

Schonmal ein einfaches Beispiel zur Positionierung per JavaScript am rechten Rand, und eine einfache Korrektur von Abständen: Popup-Seite (nicht für IE4 geeignet)

<style>
 #rDiv{position:absolute;right:10px}
</style>
<script>
 if(document.layers)
  document.write('<style>#rDiv{left:'+
   (innerWidth-100) +'} ul{margin-left:-20px}</style>');
</script>

Hier werden bereits mehrere für Netscape 4 geeignete Methoden deutlich, die Erkennung per document.layer, das nachträgliche Ergänzen oder Ändern von Styleeigenschaften, das Abfragen von Parametern, hier die Fensterbreite, als Grundlage zur Erstellung spezifischer Styleangaben. Da für Netscape 4 sowieso der Resizebug berücksichtigt werden muss, ist die Vorgehensweise auch hinsichtlich möglicher Veränderungen der Fenstergröße nach dem Laden der Seite legitim.

top Aspekt IE4

Nun hat Netscape 4 einiges mehr zu bieten, und es sind ja auch weitere Ziele zu erreichen um in einem Gesamtpaket eine Strategie zu erhalten welche erlaubt Netscape 4 mit ins Boot der CSS-fahigen Browser zu nehmen. Dazu zeigt sich bereits, dass der wenig gebräuchliche Internet Explorer 4 ebenfalls berücksichtigt werden kann, denn auch wenn einige Probleme anders sein mögen, die grundlegenden Strategien sind auch für ihn anwendbar, sofern man berücksichtigt dass aktiviertes JScript bzw. aktive Inhalte bei ihm nicht unmittelbar an die Nutzung von CSS gekoppelt sind. Die meist recht guten CSS-Fähigkeiten des IE4 und das größere Gesamtpaket sind jedenfalls erstmal gute Argumente den IE4 ähnlich zu bedienen, wenn auch die eben gezeigte Methode der Positionsbestimmung von right: vor dem Aufbau der Seite beim IE4 schwieriger ist.

Statt innerWidth gibt es beim IE4 erstmal nur zur Beurteilung der Fenstergröße weniger geeignete Daten. Daher empfiehlt es sich nach dem Laden der Seite Eigenschaften des Body oder eines Container-Div abzufragen. Auch die Abfrage der gesetzten CSS-Werte gelingt beim IE4 nicht, aber dafür sind ja weniger Korrekturen nötig als beim NC4. Im späteren Abschnitt Nachkorrektur per JS nach unten mehr zu dem Thema.

top Im Kopf

Die Einbindung der zusätzlichen Scripte findet im Head der HTML-Datei statt. Damit gibt es keine Vermischung mit dem eigentlichen Inhalt der HTML-Datei, andere Browser werden nicht beeinträchtigt und die spätere Pflege einer Seite wird einfacher. Zugleich ist der Aufbau zukunftsorientierter, ein späterer Relaunch etwa wegen veränderter Anforderungen bei der Barrierefreiheit wird womöglich überflüssig oder wesentlich einfacher, als wenn sich Korrekturen per JavaScript durch den eigentlichen Inhalt ziehen würden.

Unterschieden werden die Browser per JavaScript, und die Erkennung der betr. Browser erfolgt durch Abfrage der Fähigkeiten. Mit document.layers wird eindeutig Netscape 4 ermittelt, und die Kombination document.all, aber nicht getElementById ist eindeutig dem Internet Explorer 4 zuzuordnen. Da das JavaScript von Netscape 4 vergleichsweise sicher ist und dieser Browser ohne Aktivierung von JavaScript gar kein CSS darstellen könnte ist diese Vorgehensweise optimal. Erst nach der Erkennung des Browsers kann bei Bedarf noch zusätzlich der userAgent abgefragt werden, um etwa nur für bestimmte Betriebssysteme eine Variante anzubieten. Es handelt sich bei den Browsern für verschiedene Betriebssysteme, insbesondere bei den älteren Browser, ja um ganz verschiedene Programme, und da kann es sinnvoll sein die Einbindung der CSS-Datei sowie die nötigen Korrekturen notfalls nicht für Mac oder Linux anzuwenden, falls hier doch die Variante ohne CSS oder mit minimalem CSS stabiler wäre.

 <script type="text/javascript"><!--
 /* <![CDATA[ */

Der Scriptanfang enthält vorschriftsmäßig type="text/javascript" und dann -für alle Fälle- die für andere Doctypes auskommentierte XHTML Variante. Danach erfolgt die Einbindung so, dass Netscape 4 auch beim ersten Laden der Datei klarkommen sollte:

if(document.layers){
 document.write("<link type='text/css' rel='stylesheet'"+
  " href='./scripte/demo4.css'><link rel='stylesheet'"+
  " type='text/javascript' href='./scripte/demo4.jss'>"+
  "<script src='./scripte/demo4.js'><\/script>");
 }

Noch einfacher wäre es, wenn die allgemeine CSS-Datei schon vorher normal eingebunden wäre, dazu könnte die JSS auch direkt eingebunden werden weil andere Browser die Kombination rel=stylesheet und type=javascript nicht ausführen, die Lösung könnte bei komplexen Dateien grundsätzlich auch die Stabilität erhöhen:

<link type='text/css' rel='stylesheet' href='./scripte/demo4.css'>
<link rel='stylesheet' type='text/javascript' href='./scripte/demo4.jss'>
<script ><!--

Die Variante ist für Netscape 4 und alle moderneren Browser eigentlich optimal. Probleme wären aber denkbar beim Internet Explorer 4 mit deaktiviertem JavaScript, und für die vorher gezeigte Variante könnte auch die doppelte Absicherung der JS-Styles per JavaScript und JSSS sprechen, falls andere Browser das type-Attribut beim Style-Tag nicht auswerten würden. Denkbar trotz der potentiell höheren Instabilität sind auch Vorteile für den NC4 bei der Einbindung externer Skripte per JavaScript und document.write, so können machnmal Probleme beim erstmaligen Laden der Skriptdatei verringert werden.

Das folgende Beispiel bindet die normale CSS, oder auch falls gewünscht eine spezielle NC4-CSS, nur für Netscpae Communicator 4 ein. Als Browserweiche dient eine nestcapespezifisches Inlinescript, per einer @import-Weiche können die anderen Browser bedient werden. Dann folgt ggf. die JSSS, welche sowieso nur von NC4 geladen wird, da die Kombination von rel='stylesheet' und type='text/javascript' von anderen Browsern nicht akzeptiert wird, also an sich schon als Weiche arbeitet, vgl. dazu das Kapitel Browserweichen nach oben :

<link rel="&{'stylesheet'};" type="&{'text/css'};" href="&{'./demo4.css'};">
<link rel='stylesheet' type='text/javascript' href='./demo4.jss'>

<style type="text/css">  @import url('./scripte/demo4.css');  </style>

oder die JSSS-Einbindung nicht nur durch die Kombination von Stylesheet (rel) und JavaScript (type), sondern zusätzlich abgesichert:

<link rel="&{'stylesheet'};" type="&{'text/css'};" href="&{'./demo4.css'};">
<link rel="&{'stylesheet'};" type="&{'text/javascript'};" href=&{'./demo4.jss'};">
 ....

Der grosse Vorteil dieser Variante kann der Verzicht auf eine JavaScript-Ebene mit document.write sein, dadurch wird die Seite i.d.R. stabiler und natürlich ist der Code auch etwas übersichtlicher. Im Einzelfall mag aber gerade die gleichzeitige Einbindung über mittels document.write erst erzeugten Code Vorteile beim erstmaligen Laden der Seite haben, falls also bei geleertem Cache und erstem Aufruf Scripte vom NC4 nicht ausgeführt werden, kann solch ein kleiner Umweg hilfreich sein.

Auch ein JavaScript kann so per Entity/Inlinescript im Attribut nur für den NC4 geladen werden, allerdings lässt sich der Internet Explorer im Gegensatz zu den Gecko-Browsern vom dem für ihn fehlendem type-Attribut nicht von einer -eigentlich harmlosen- Serveranfrage abhalten, ähnliche Effekte gibt es übrigens auch mit language-Angaben. Der W3C-Validator bescheinigt hier Valid HTML 4.01 Transitional.

<script src="&{'./demo4.js'};" type="&{'text/javascript'};"> </script>

Auch spezielle CSS-Dateien für die Internet Explorer 5 bis 6 liessen sich, wie schon vorher dargelegt, per Conditional Comment anfügen:

<!--[if lt IE 7]><link rel='stylesheet' href='./scripte/ie56.css'><![endif]-->

Und auch die Severanfrage der IE-Browser im vorherigen Beispiel kann per Comment unterbunden werden, und auch wenn das für den Explorer schliesslich entstehende HTML z.B. im Head der Datei nicht korrekt wäre, funktioniert es soweit getestet zuverlässig bei validem Code:

<!--[if IE]> <noscript> <![endif]-->
<script src="&{'demo4.js'};" type="&{'text/javascript'};"> </script>
<!--[if IE]> </noscript> <![endif]-->

Und noch eine Variante: Neu ist hier die Methode nur den Inhalt des type-Attributes vor anderen Browsern zu verstecken. Zur zusätzlichen Sicherheit kann im JavaScript selbst noch eine Browserweiche if(document.layers) eingesetzt werden.

<link rel="&{'stylesheet'};" type="&{'text/css'};" href="&{'./demo4.css'};">
<link rel="&{'stylesheet'};" type="&{'text/javascript'};" href=&{'./demo4.jss'};">
<script src="nc4.js" type="&{'text/javascript'};"> </script>

Schließlich noch der Hinweis auf die von mir zum Thema Netscape 4 und IEs zuletzt entwickelte Variante:

<!-- 2003 Kristof Lipfert Duesseldorf  -->

<!--[if !lt ie 7]> -->
<link rel="stylesheet" type="text/css" href="modern.css" media="all,screen"
style="/*/*//*/includesource:url(nn-css.htm)/* */" /><!-- <![endif]-->
<!--[if ie]><![if ie 6]>

Hier wird eine HTML-Datei für Netscape 4 eingebunden, in der sich JavaScript oder CSS-Angaben befinden. Die normale Datei für moderne Browser erhält Netcsape 4 nicht. Die Internet Explorer werden im Weiteren per conditional comment je nach Version mit eigenen CSS-dateien per link versorgt, vgl. das Kapitel zu importzurück zu Thema.

top Erkennung - OS

Die kompakte Variante zur Einbindung hätte aber nicht nur den Nachteil, dass ein IE4 mit deaktiviertem JScript trotzdem das anspruchsvolle CSS präsentiert bekommt. Bei der hier gezeigten aufwändigeren Variante können nämlich noch weitere Bedingungen gestellt werden, so falls Browserversionen abhängig vom Betriebssystem doch ausgeschlossen werden müsste, etwa der NC4 für Linux, oder so:

 if( document.layers && navigator.userAgent.indexOf('win') >-1 )

Das Fehlen der Angabe type="text/javascript" bei der Einbindung der .js ist beabsichtigt und hat für Netscape 4 Vorteile, es empfiehlt sich hier ebenso auf das für Netscape 4 verständlichere language=JavaScript oder die Schreibart "mocha" zu verzichten.

else if((document.all)&&(!document.getElementById)&&
(navigator.userAgent.indexOf("Win")>-1)){
 document.write(
  "<link rel='stylesheet' type='text/css' href='./scripte/demo4e.css' \/>");
 document.write(
  "<script src='./scripte/demo4e.js'><\/script>");
 document.write(
  "<link rel='stylesheet' type='text/css' href='./scripte/demo4.css' \/>");
}

Anders als beim NC4 ist für den IE4 die Reihenfolge der Einbindung der externen CSS Dateien nicht nur ausschlaggebend für den Endzustand der Styleanweisungen, trotzdem auch hier das Konzept der zusätzlichen ergänzenden CSS-Datei sowie Nachkorrektur per JavaScript. Für Opera 6 ist eine einfache Ergänzung für bottom: per JavaScript vorgesehen, die so tolerant angelegt ist dass hier eigentlich keine Abgrenzung gegen Opera 7 erfolgen muss, doch mittels der zusätzlichen Abfrage nach der Methode document.documentElement gelingt auch das. Per document.embed könnten übrigens bei Bedarf die Versionen 5 und 6 unterschieden werden.

else if((window.opera)&&(!document.documentElement))
document.write("<script src='./scripte/demo4o.js'><\/script>");
/* ]]> */
//--></script>

Nun erfolgt die Einbindung der CSS Datei für die neueren Browser per Weiche, also entweder die Einbindung per "import" oder per "media all", in folgenden Beispiel entspricht das media="all" dem Eintrag @media all{} im CSS-Abschnitt, wie bereits bei Browserweichen nach oben ausgeführt. Damit in diesem Beispiel sichergestellt wird, dass ein IE4 bei deaktiviertem JavaScript die CSS Datei, welche ja per JavaScript Korrekturen benötigt, nicht geladen wird, empfiehlt sich aber die zweite Variante.

<link type="text/css" rel="stylesheet" href="./scripte/demo4.css"  media="all" />

oder besser:

<style type="text/css">
 @import url('./scripte/demo4.css');
</style>

An dieser Stelle kann natürlich auch die Einbindung spezieller CSS Files für Printmedien usw. erfolgen.

top In HTML & CSS

Die konkreten Beispiele gehen von einem zusätzlichen Container-Div im Body aus. Anlass ein solches Div zu verwenden war erstmal gar nicht die Unterstützung älterer Browser, sondern Unterschiede neuerer Browser lassen sich damit in den Griff kriegen. Es ist für ältere Browser aber nicht zwingend erforderlich, und auch die bevorzugte Art der Styleangabe Position mit absolute ist nicht die einzige Möglichkeit. Bei den Beispielen hier liegt folgender Aufbau in der Seite zugrunde:

<body><div id="cont">
 ....
</div></body>

Dazu die Angaben in der CSS-Datei:

body{
   height:100%;
   min-width:400px;
   margin:0; padding:0;
   background-color:white;
}

#cont{
   position:absolute;
   left:0px; top:0px;
   height:100%;
   margin:0; padding:0;
   overflow:visible;
   background-color:white;
   width:100%;
}

#cont[id]{ height:auto }

Die Abfrage der ID in der letzten Zeile wird als Browserweiche für Mozilla und Opera7 benötigt. Je nach Doctype und Browser kann es leider nötig sein, Styleangaben für html, body oder auch wenn vorhanden ein Container-Div unterschiedlich anzulegen. Dabei gibt es die Möglichkeit für width oder height gar keine Angaben, oder 100%, oder auto zu schreiben. Für Netscape 4 kann es auch Vorteile haben, wenn keine Angabe oder auto eingesetzt wird, da z.B. body{width:100%} je nach Fenstergrösse unnötigen Seitenabstand verursachen kann, und gerade beim Netscape 4 ist auch eine dynamisch mittels JavaScript erzeugte Styleangabe möglich.

top Alte Bekannte

Netscape 4 Kenner werden schon bei der Dateiendung *.jss ahnen wo es lang geht. JSSS, JavaScriptStyleSheets, ist ein beim W3C gescheitertes Netscape Format für Styles, das eigentlich zu Recht nicht mehr beachtet wird. Netscape 4 kommt mit dem vom W3C abgesegneten heutigem CSS Format durchaus zurecht, auch wenn der Browser intern einiges übersetzen muss, Netscape 4 sollte und kann grundsätzlich mit CSS Angaben bedient werden, solange es keine Inlinestyles (mit denen er aber u.U. auch klarkommt) sind. NC4 kommt mit Divs klar, benötigt keine Layer, versteht visibility:visible, auch wenn er intern die Eigenschaft als show statt visible setzt. So schaut eine Styleangabe per JSSS aus:

tags.H1.backgroundColor="red";

Wer mit CSS und JavaScript etwas vertraut ist, kann sich recht schnell zurechtfinden. Attribute meist in Anführungszeichen, bei den Eigenschaften die Bindestriche weglassen und statt dessen den folgenden Begriff mit Großbuchstaben beginnen. Es gibt tags, classes, ids, und die Bedingung contextual. Beschreibungen von JSSS finden sich z.B. in "JavaScript" aus dem O'Reilly Verlag, aber auch beim W3C als Vorlage oder bei Netscape [63],[7],[8,9,11,13] nach unten. Warum denn überhaupt JSSS? Weil es gerade bei der Problemstellung CSS anzupassen ganz erhebliche Vorteile hat, mittels JSSS können nämlich die Werte schon erfolgter Stylezuweisungen abgefragt werden. Für Netscape 4 und Internet Explorer 4 wird also keine separate andere Styledatei eingebunden, vielmehr wird die vorhandene Styledatei, die eingebundene externe CSS, die Basis für die Vierer-Browser. Notfalls, wenn doch eine Angabe Netscape 4 hinderlich wäre, müsste sie per @media all{} vor Netscape versteckt werden, und je nach Projekt es ist sowieso eine weitere externe Datei für spezielle Medien nötig.

<style>
 #sampl{visibility:visible;
        position:relative;}
</style>
<style type='text/javascript'>
 alert(ids.sampl.visibility);
</style>
<body onload="alert(document.sampl.visibility);">
<div id=sampl>xxx</div>

Hier zeigt sich wie gut Netscape 4 Styleangaben nach der richtigen CSS-Definition erfassen kann. Zugleich zeigt die zweite Meldung die Eigenschaft beim Div, sowie die interne Netscapespezifische Übersetzung der Eigenschaft. Popup-Seite erfordert Netscape 4

Netscape wertet den CSS-Abschnitt aus, und setzt das CSS in das Netscape4 spezifische JSSS-Format um. Der Seitenaufbau beim Netscape 4 verläuft also so:

CSS -> JSSS -> HTML

top JSSS-CSS-JS

Und der Ablauf mit Korrekturen:

CSS <-> JSSS <-> JSSS -> HTML -> JS -> DHTML
                ----------------^

Bereits auf der JSSS-Ebene kann dynamisch mittels Formeln bzw. JavaScript mit CSS gearbeitet werden: Popup-Seite erfordert Netscape 4

<style>
 #sampl{visibility:visible;
        position:relative;}
</style>
<style type='text/javascript'>
 alert(ids.sampl.visibility);
 if(ids.sampl.visibility=="visible")
    ids.sampl.visibility="hidden";
</style>
<body onload="alert(document.sampl.visibility);">
<a href="javascript:document.sampl.visibility='visible';">
Zeigen</a>

Auf der document-Ebene, als bei den Korrekturen per JavaScript bzw. DHTML, kann ja nach dem Laden der Seite einiges über den tatsächlichen Zustand der Elemente in Erfahrung gebracht werden, und ggf. korrigiert werden. Neben der Position kann auch über clip der erstmal nicht korrigierbare Innenabstand Abstand von Divs korrigiert werden, auch der Body bzw. das u.U. eingesetzte Container-Div lässt sich so anpassen.

Und auch nach dem Laden der Seite können noch die gesetzten Styleeigenschaften abgefragt werden, nur wirkt sich eine Veränderung der JSSS-Daten nicht mehr auf die Seite aus.

top Heading Border JSSS

Ein erstes Beispiel für die Möglichkeiten Styleangaben und JavaScript zu kombinieren ist eine Korrektur für Überschriften mit Rahmen und Breite. Unter Netscape 4 gehen die Eigenschaften wie Schriftgrösse von Überschriften verloren, wenn verschiedene Styleangaben eingesetzt werden, so bei Angaben zu Grösse mit gleichzeitigem Rahmen.

Das Problem kann auf verschiedene Weise gelöst werden, so recht einfach in Form von zusätzlichen validen CSS-Angaben:

<style>
h1 { width: 100%;
     border: 1px solid black;

     font-size: 32px;
     font-weight: bold;}

Sehr praktisch ist folgende von JSSS abgeleitete Schreibweise, die den ergänzenden Code von anderen Browsern fernhält, aber kein valides CSS darstellt und deshalb noch um eine Browserweiche /*/*//*/ ergänzt werden sollte:

<style>
h1 { width:100%;
     border: 1px solid black;

     fontsize:  32px;
     fontweight: bold;}

Das folgende Beispiel zeigt, wie per JSSS alle Überschrift-Tags automatisch auf die normalen ursprünglichen Werte gesetzt werden, wenn ihnen ein Rahmen und eine Breite, aber keine besondere Schriftgrösse zugewiesen wurden.

<style type='text/javascript'>
 function header(hx, kx, kt){
     with(tags[hx]){
       if(borderColor&&width){
         if(!fontSize){
           fontSize = kx;
           lineHeight = parseInt(kx)*1.05+'%';
           marginTop=kt;
          }
      fontWeight='bold';
 }}}
 for(n=1;n<7;n++){
    kx=1*184-(n*22)+'%';
    kt=(0+Math.round(10*(-1+(n*.17)))/10)+.15+'em';
   header('h'+n, kx, kt);
 }

Popup-Seite

Da das Netscape JSSTag Objekt mit dem Operator [] angesprochen werden kann, lässt es sich komfortabel in einer Funktion verwenden und mittels Variablen aus einer Schleife heraus ansprechen.

top Resizebug

Resizebug meint den Verlust der Formatierung nach Änderung der Fenstergrösse. Er tritt typischerweise unter Netscape 4 bei absolut positionierten Divs und bei Seitenaufbau per DHTML auf, letzteres passiert auch bei anderen Browsern wie dem Internet Explorer 4.

Vermeiden liesse er sich also meist durch den Verzicht auf die genannten Techniken, beim Netscape 4 auch durch den Einsatz der Layertags. Beheben lassen sich die Auswirkungen des Resizebug recht einfach durch Neuladen der Seite, manchmal würde auch der Aufruf eines Skripts zur Neupositionierung ausreichen. Trotzdem habe ich auch einige Beispiele von "Tableless Layout" entwickelt, die wenig Korrektur erfordern und bei denen der Resizebug erstmal gar nicht auftritt.

Ein Schwerpunkt dieses Artikels ist aber die hinsichtlich älterer Browser freie Verwendung von CSS und HTML, auch im Hinblick auf Barrierefreiheit, also auch die Entscheidungsfreiheit über die Reihenfolge von Code im HTML. Mit dem Einsatz von JSSS und JavaScript ist solcher Code für Netscape 4 vielleicht nicht pixelgenau, aber wie gewünscht darstellbar, und bedarf ggf. doch eines Skripts zu Korrektur des Resizebugs

Zum Resizebug sind eigentlich gute Skripte hinreichend bekannt. In dem Zusammenhang möchte ich zunächst aber auf eine einfache Lösung hinweisen, und kurz darlegen warum sie nicht so empfehlenswert ist:

<body onResize="location.reload()">

Diese einfache Methode funktioniert bei älteren Netscape 4.x nicht zuverlässig, weil diese Browser beim Laden der Seite den Aufbau von Scrollbalken bei einer grösseren Seite als Resizevorgang bewerten. Dann wird in einer Schleife die Seite immer wieder neu geladen, wenn der Seiteninhalt über das Window hinausgeht. Zudem ist onresize als Attribut des Body-Tag kein valides HTML, auch wenn es bei den hier in Frage kommenden Browsern Nestcape und IE 4 funktioniert.

Zugleich kann man aber kurz prüfen, ob es auch Code gibt bei dem ein Neuaufbau der Seite überflüssig wäre, oder wie ein Script zur Lösung des Resizebug eingebunden werden kann. Das bereits vorgestellte einfache Dreispalten-Layout per CSS nach oben kann so ein Beispiel sein, bei welchem ein Neuladen erstmal überflüssig ist; auch das abschliessende Code im Abschnit Center Div nach unten zeigt eine einfache Seite ohne Resizebug beim Netscape Communicator 4. Und natürlich gibt es Möglichkeiten in einigen Situationen den Resizebug durch den Einsatz von Layer- und Ilayer-Tags zu umgehen, aber gerade diese ungültigen Tags gilt es ja meist zu vermeiden. Die in verschiedenen JavaScript-Beispielen schon ansatzweise erkennbare Trennung von Korrekturen per JSSS gegenüber Korrekturen nach dem Laden der Seite könnte womöglich in Einzelfällen den Reload überflüssig machen, wenn die Korrekturen per Eventhandler onLoad geladen werden und genauso zusätzlich an onResize zu binden wären. In der Praxis zeigt sich aber dass nach einem Resize besonders Divs mit einer absoluten Position ihre Eigenschaften verlieren, während relativ positionierte Elemente weniger betroffen sind.

var origWidth = innerWidth;
var origHeight= innerHeight;

function initResize(){

  onResize=function(){
      if((innerWidth!=origWidth)||(innerHeight!=origHeight))
        ...
  }
}

window.onLoad=function(){initLayer(); initMover(); initResize();}

Wenn die Einbindung des Scripts nicht im JSSS erfolgen soll, kann u.U. auch auf die Verknüpfung mit dem onLoad-Handler verzichtet werden Popup-Seite.

top Nur ein onload

Es kann nur einen geben. Deshalb muss der Eventhandler onload die verschiedenen nötigen Methoden über eine eigene Funktion aufrufen, ein Script zur Korrektur des Resizebug muss also in einen vorhandene Eventhandler integriert werden, mehr dazu auch im Abschnitt DHTML / Strategie. nach unten

Da es ja oft auch darum geht, alle Massnahmen für ältere Browser möglichst separat und mit möglichst geringem Einfluss auf die eigentliche Seite umzusetzen, ein Codebeispiel um einen vorhandenen Eventhandler onLoad zu ergänzen:

if(window.onload)wold = window.onload;
            else wold = function(){/**/};

Der Umweg über ein neues Objekt wold funktioniert so z.B. auch den 4er Browsern Netscape, IE oder Opera:

wold=window.onload||function(){/* */};

window.onload = function(){ ..... ; wold(); }

top CSS und Korrektur beim IE4

Weil es ja ein Ziel ist möglichst viele Browser zu berücksichtigen, zum Vergleich der InteretExplorer 4. Dieser Browser könnte wegen seiner geringeren Verbreitung zwar eher als Netscape 4 mit einem Not-CSS versorgt werden, andererseits macht es Sinn die Anwendbarkeit einer Strategie um vielleicht 10% zu vergrössern (bei 11% NC4 und rund 1% IE4, Okt.2002, Quelle webhits).

Beim InternetExplorer 4 können bereits erfolgte CSS-Anweisungen erstmal nicht so komfortabel abgefragt werden, und mit den dafür besser geeigneten Inlinestyles möchte man sowieso aus vielen Gründen nicht anfangen. Auch die Überschreibung bzw. Änderung von CSS-Eigenschaften scheint nicht so einfach wie beim Netscape, allerdings muss beim IE4 auch nicht an so vielen Stellen korrigiert werden, der Aufwand kann immer noch vertretbar sein.

CSS -> css -> HTML -> JS -> DHTML

Auch hier soll gleich schon ein konkreter Weg gezeigt werden, um auch beim IE4 das CSS zu korrigieren. Es ist wichtig, weil damit sichergestellt ist dass die grundsätzliche Strategie, möglichst alles an CSS was einen älteren Browser nicht zum Absturz bringt komplett einzubinden, auch hier beim IE4 beibehalten werden kann. So sieht eine Möglichkeit aus beim IE4 sicher zu überschreiben:

<style>
 #sampl{
  position:absolute;
  width:330px;
  top:60px;
  left:33%;
  padding:0;
  margin:0;
  clip:rect(0, 350px, 70px, 0);
        }
</style>
<style>
 #sampl{left:28%!important;}
</style>

Die nötige Änderungen bzw. Überschreibungen der CSS-Hauptdatei können für den IE4 vorsorglich noch per !important in der zusätzlichen CSS sichergestellt werden, das hat auch Vorteile falls man per @media all Angaben gemacht hat.

Zugleich gibt es mit der unter Browserweichen beschriebenen Methode einer Stylepassage @media tty oder handheld eine wirkungsvolle Browserweiche für den IE4.

Andere Probleme lassen sich ähnlich wie beimk NC4 lösen, so kann bei DHTML-Nachhilfe ein Workaround wie beim Resizebug sinnvoll sein. Auch die kleinen Unstimmigkeiten bei der Vererbung von Styles lassen sich leicht beheen, erfordern aber natürlich den Test einer Seite mit dem IE4.

Zu den Methoden für den IE4 folgt noch im übernächsten Abschnitt ein Beispiel.

top Tableless per CSS/JSSS

Bevor im Weiteren die sich abzeichnenden Möglichkeiten aufgezeigt werden, für alte Browser etwa per JSSS CSS2-Features zu ermöglichen, erstmal noch ein konservativeres Beispiel wie ein mehrspaltiges Layout flexibel ohne absolute Positionierungen möglich ist. JSSS wird eher zurückhaltend eingesetzt als stabile Browserweiche, die Angaben für den NC4 liessen sich auch per CSS-Weiche einbauen, wenn man statt "innerWidth" die jeweiligen Divs auf eine Breite von width:130% setzt. Für den IE4 kommt hier die bei Browserweichen entwickelte Methode per @media tty zum Einsatz, und ein Resizebug tritt weder beim IE4, noch beim NC4 auf. Dazu hat das Beispiel den Test mit Opera 3.60 bestanden. Popup-Seite

body { padding:0px;margin:5px; text-align:center; }
#ob  {width:100%; margin:0;}
#obi {width:100%; margin:0; text-align:center;    }
#cont{width:100%;margin:0 auto;padding-bottom:10px;  }
#mi  {margin-left:155px;margin-right:155px; 
     margin-top:10px; text-align:left;}
#li {width: 150px; margin-right:10px; margin-top:10px;
   float: left;}
#re { width: 150px;  margin-top:10px; float: right;  }
#un {  width:100%;  margin:0 auto;text-align:right; }
#uni { width:100%; margin:0 auto; padding:5px 0;
  text-align:center; }

@media tty{
body{width:100%}
#mi{position:relative;left:-5px;float:right;
margin-left:0;margin-right:0;}
}
</style>
<style type="text/javascript">
tags.body.margins(0);
ids.ob.width=
ids.obi.width=
ids.un.width=
ids.uni.width=
ids.cont.width=innerWidth; 
tags.div.borderWidths(0.1);
ids.cont.height=innerHeight;
ids.mi.margins(0);
ids.re.margintop=0;
ids.cont.margintop=-10;
ids.obi.margintop=-5;
</style>
</head>
<body>
<div id=ob> </div> <div id=obi> </div>
<div id=cont> 
 <div id=li>   </div>
 <div id=re>   </div>
 <div id=mi>   </div>
</div>
<div id=un> </div> <div id=uni> </div>

top Drei Spalten XHTML II

Wie das eben gezeigte Beipiel ist auch diese Varainte in validem XHTML und CSS realisierbar: Popup-Seite Das Containerdiv entfällt hier, die Positionierung erfolgt per float, Netscape 4 erhält hier allerdings ein zusätzliches leeres Element um float richtig anwenden zu können. Die Anpassungen von width usw. erfolgen nicht per JSSS, sondern durch einfache CSS-Weichen und doppelte Angaben.

<body>
 <div id=" oben  "> ...  </div>
 <div id=" links "> ...  </div>
 <div id=" mitte "> ...  </div>
 <div id=" rechts"> ...  </div>
  <div id=" nc   "> ..  </div>
 <div id=" unten "> ...  </div>
</body>

Drei Spalten XHTML III

Noch ein Beipiel XHTML und CSS: Popup-Seite

<body>
 <div id=" oben  "> ...  </div>
 <div id=" links "> ...  </div>
 <div id=" mitte "> ...  </div>
 <div id=" rechts"> ...  </div>
 <div id=" unten "> ...  </div>
</body>

Drei Spalten XHTML IV

Wenn auf CSS-Tricksereien weitgehend verzichtet werden soll, kann der Box-Bog auch valide mittels zusätzlicher Container-Divs berücksichtigt werden. Dennoch habe ich hier für Netscape 4 wenigstens einfachste CSS-Weichen per *-Selektor verwandt Popup-Seite

<body>
 <div id=" oben  "> <div class="innenDiv"> ...  </div> </div>
 <div id=" links "> <div class="innenDiv"> ...  </div> </div>
 <div id=" rechts"> <div class="innenDiv"> ...  </div> </div>
 <div id=" mitte "> <div class="innenDiv"> ...  </div> </div>
 <div id=" unten "> <div class="innenDiv"> ...  </div> </div>
</body>

Das CSS:

#links    { float:left;   width:10em; }
#rechts   { float:right;  width:10em; }
* #mitte  { margin:0 10em; }
.innenDiv { padding:0.5em 1em;}

VierSpaltenPlus

Auch das Beispiel mit vier Spalten käme ohne JSSS aus, allerdings wird jetzt nicht per float, sondern absolut, aber noch "fluid" mittles Prozentangaben positioniert. Die im gleich im folgenden beschriebenen und entwickelten Möglichkeiten, auch alte Browser mit right anzusprechen, können hier nützlich sein, sind aber noch nicht nötig. Auch die Unterstützung des Netscape 4 mittels JavaScript oder wie hier per JSSS ist nicht unbedingt nötig, um das Layout cross-Browser umzusetzen. Da aber gleich mehrere Punkte beim NC4 korrigiert werden können, der Resizebug sowieso berücksichtigt werden muss, kann das zusätzliche JSSS-Stylesheet trotzdem Sinn machen: Popup-Seite

html,body {width:100%;margin:0;padding:0}
#ob {position:absolute;top:0px;left:0px;border:1px solid;width:100%;height:60px;}
#li,#ml,#mr,#re { position:absolute;top:60px;border:1px solid;}
#li{left: 0%;width:15%;}
#ml{left:15%;width:35%;}
#mr{left:50%;width:35%;}
#re{left:85%;width:15%;}
*h1,*h2,*h3,p{margin:5px}

Die Schwierigkeiten des NC4, Prozentangaben exakt auszuführen, können durch die einfache Umrechnung in Pixelwerte anhand von innerWidth umgangen werden. Im JSSS-Stylesheet kann auch bereits window.onload zur Behebung des resizebug eingebracht werden.

var iW=innerWidth;
tags.body.width=ids.ob.width=iW;     
ids.li.width=ids.ml.left=ids.re.width=iW*.15;
ids.ml.width=ids.mr.width=iW*.35;
ids.mr.left=iW*.5;
ids.re.left=iW*.85;
ids.li.top=ids.ml.top=ids.mr.top=ids.re.top="63px";
tags.p.margins(3);

CSS Features

top Neu: right und bottom

Popup-Seite

Nun ein weiters konkretes Beispiel, bei welchem noch ein weitere Vorteil von JSSS im Zusammenhang mit CSS deutlich wird, nämlich der Komfort im Falle von späteren Änderungen an der eigentlichen CSS-Datei. Netscape 4 soll eine Styleangabe mit Abstand von rechts darstellen:

 #rDiv { right: 10px; }

Hier muss folglich zu einem Div mit dem bereits zugewiesenem Style für Netscape eine neue Anweisung left: erzeugt werden, da Netscape right nicht unterstützt. Die endgültige Seitengrösse steht noch nicht zur Verfügung, aber erstmal die Fensterbreite. Man kann nun, falls ein width: in der ersten CSS festgelegt ist, eine Formel nur mit den Eigenschaften oder Variablen erstellen:

 ids.rDiv.left = innerWidth - ids.rDiv.width - ids.rDiv.right;

Es ist so möglich, die gesetzten Angaben aus der eigentlichen Styledatei abzufragen bzw. einzubinden. Netscape 4 verfügt tatsächlich über den Inhalt der Eigenschaft right, auch wenn er damit erstmal nichts anzufangen weiss. Mit der Formel wird eine Änderung in der ersten CSS später automatisch umgesetzt, im Idealfall geben wir Netscape 4 im JSSS Code nur die IDs der zu prüfenden und mit ergänzenden Angaben zu versehenden Divs, der Rest kann automatisch erfolgen wenn die entsprechenden Formel und Scripte einmal entwickelt sind. So könnte z.B. per if(!rDiv.left&&rDiv.right) automatisch entschieden werden ob eine Korrektur nötig ist. Später, nach dem Seitenaufbau, kann falls erwünscht nochmals korrigiert werden. Etwa wenn die Breite des Div anders ausgefallen ist, wenn die Seite grösser als das Fenster, also horizontale Scrollbalken, ist. Grundsätzlich gilt hier das Schema Seitenbreite-rDivbreite-ids.rDiv.right. Dazu muss die Seitenbreite vom Body oder die Breite eines den ganzen Seiteninhalt umfassenden Divs ermittelt werden, dann muss, Stichwort DHTML, das zu positionierende Div adressiert werden.

top NC4 / IE4 right

Jetzt ein Beispiel ähnlicher Vorgehensweise bei IE und NC, um eine Angabe für left aus der vorhandenen Styleangabe von right zu errechnen:

<style type='text/css'>
 body{ margin:0; padding:0; margin-top:50px}
 #li{ position:absolute; top:50px;left:50px;width:100px;
                                       border:1px solid}
 #mi{ position:relative; margin-left:200px;margin-right:200px;
             margin-top:50px; top:0px; border:1px solid}
 #re{ position:absolute;left:auto;top:50px;width:100px;
                          right:50px; border:1px solid}
</style>
<style type='text/javascript'>
with(ids.mi){position="absolute";top=margintop;margintop=0;}
ids.re.left=innerWidth-parseInt(ids.re.width)-parseInt(ids.re.right);
if(document.layers&&navigator.appVersion.substring(2,3)>5)
window.onresize=function(){self.location.reload();}
</style'>
</head>
<body>
<script type='text/javascript'>
if(document.all&&!window.opera&&!document.getElementById){
for(i=0;i<document.styleSheets[0].rules.length;i++){
if(document.styleSheets[0].rules[i].style.right&&
document.styleSheets[0].rules[i].style.width)
document.styleSheets[0].rules[i].style.left=
document.body.clientWidth-
parseInt(document.styleSheets[0].rules[i].style.right)-
parseInt(document.styleSheets[0].rules[i].style.width)+"px";
window.onresize=function(){self.location.reload();}
}}

Statt bestimmte Objekte über ihre ID anzusprechen, wird hier beim IE in einer Schleife das erste Stylesheet komplett nach Angaben für right durchsucht. Um die Zuweisung zu vereinfachen, wird im Stylesheet bereits eine Eigenschaft left mit auto vorbelegt. Popup-Seite

top CSS/JS Right-Lib automatisch

Nun das Ganze als Lösung mit einem einzigen ausgelagertem Skript. Nachteilig hier, dass beim NC4 die Platzierung erst nach dem Laden der Seite per DHTML geschieht, da bei der für den IE4 vorteilhaften Einbindung des Skripts unmittelbar nach dem Bodytag ein Style/JSSS nicht mehr so gut möglich ist, und als style-Tag im Body invalides HTML zur Folge hätte. Vorteilhaft ist aber die vollautomatische und dazu die fast einheitliche Behandlung bei IE4 und NC4, und im Gegensatz zur JSSS-Lösung muss hier auch beim NC4 keine Angabe der ID gemacht werden, das Script läuft automatisch. Popup-Seite

<body>
<script type="text/javascript" src="./cssrightlib.js"></script>
/* Copyright (c) 2002-2003 Kristof Lipfert Duesseldorf  */

if(document.all&&!window.opera&&!document.getElementById){
with(document.styleSheets[0])for(i=0;i<rules.length;i++){
if(rules[i].style.right&&rules[i].style.width)
rules[i].style.left=document.body.clientWidth-
parseInt(rules[i].style.right)-
parseInt(rules[i].style.width)+"px";
window.onresize=function(){self.location.reload();}
}}
else if(document.layers)window.onload=function(){
window.onresize=function(){self.location.reload();}
for(i=0;i<document.layers.length;i++){
ivar=document.layers[i].id;
if(document.ids[ivar].right&&document.ids[ivar].width){
document.layers[ivar].left=innerWidth-
parseInt(document.ids[ivar].right)-
parseInt(document.ids[ivar].width);
}}}

cssrightlib.js Ein kleiner Unterschied ist die Abfrage von document.body.clientWidth beim IE4 und innerWidth beim NC4. Bei der Scripteinbindung nach dem Body-Tag wäre für den NC4 eigentlich auch die Abfrage einer window.document.width oder einer clip.width möglich, solch eine Variante müsste aber idealerweise auf ein Container-Div abgestimmt werden. .

top IMG border:0

Noch ein Beispiel wie per JSSS die eigentliche CSS-Datei von Workarounds frei gehalten werden kann, auch hier als Formel. Pauschal wird hier die Hintergrundfarbe des Body bzw. die entsprechende vorher per CSS gesetzte Eigenschaft abgefragt, um den bei Bildern in Links bzw. A-Tags ohne border=0 Eintrag im Image-Tag nicht abschaltbaren Rahmen zumindest farblich zu tarnen:

contextual(tags.A, tags.IMG).color=tags.BODY.backgroundColor;

top CSS-Nachkorrektur per JS

Für den IE4 erfolgt die Ergänzung um die Eigenschaft right am einfachsten auf die als Nachkorrektur beim NC4 vorgesehene Weise per DHTML. Da hier sowieso erst nach dem Laden der Seite korrigiert wird, bietet es sich an statt Bildschirm, Fenster oder Body ein den ganzen Seiteninhalt umfassendes Container-Div auf seine Abmessungen abzufragen, etwa falls die Seite breiter ist als der Bildschirm:

function doRechts(dieid,right,rechts){
 Breit=document.getElementById(dieid).clientWidth;
 document.getElementById(dieid).style.left=rechts-Breit-right;
}
var rechts=document.all.cont.clientWidth;
window.onload=loadInits;
function loadInits(){
 doRechts('rechtsoben',10,rechts);
}

Hier wird bereits auf getElementById für den IE4 zurückgegriffen, siehe auch Abschnitt JavaScript. Auch die endgültige Breite des betr. Div kann abgefragt werden, nur die ID und, hier beim IE4 anders als beim NC4, der Wert der Styleangabe für right muss übergeben, also nochmal eingetragen werden, hier 10.

Die bereits beim NC4 per JSSS ermöglichte Styleangabe right kann wie folgt in der JavaScript Datei ebenfalls nach dem Laden der Datei nachkorrigiert werden:

function initWidth(){
 getLayerById['rechstoben'].left=
 getLayerById['cont'].document.width-
 document.ids['rechstoben'].width;
 getLayerById['rechstoben'].clip.width=
 document.ids['rechstoben'].width;
 getLayerById['cont'].clip.width+=10;
}
window.onLoad=function(){initWidth();}

Hier ist wieder das Container-Div als Maßstab abgefragt worden, dann die Styleangaben aus der Haupt-CSS. Gearbeitet wird bereits mit dem erzeugten Array getLayerById, die Nachpositionierung erfolgt a la DHTML, und mit clip.width wird zugleich auch der rechte Rand am body verringert, hier wird also der bekannte Eintrag <body marginheight=0 marginwidth=0>per Korrektur am sowieso auch für neure Browser vorteilhaftem Container-Div erübrigt.

Nachdem in der Einführung ja bereits ein Dreispaltenlayout nach oben nur per CSS und ohne Scriptunterstützung gezeigt wurde, sind nunmehr die Voraussetzungen gegeben um auch komplexere Seiten im "Tableless-Layout" zu realisieren. Dabei kann eine mittlere Spalte per margin begrenzt werden, abhängig von der Positionierung rechts und links oder nur rechts, und die rechte Spalte wird a la right:0px bestimmt.

top Drei Spalten per Inlinescript

Ein interessante Mischung verschiedener Methoden ist mit den Inlinescripten des Netscape 4, die schon bei den Browserweichen als JavaScript-Entities erwähnt wurden, möglich. Die folgende Lösung ist W3C-valide, und die Verwendung von JavaScript geschieht eher unauffällig. Oft hat der Einsatz von Inlinestyles Nachteile, der Grund warum ich diesen Ansatz erstmal weniger empfehlen möchte: Popup-Seite (nicht für IE4 angepasst)

<body style="width:100%;&{'width:130%;'};">
<div style="position:absolute;top:0px;left:10px;width:100px;">
 .... links ....
</div>
<div style="position:absolute;left:120px;top:0px;padding-right:100px;">
 .... mitte ....
</div>
<div style="position:absolute;top:0px;width:100px;right:5px;
                               &{'left:'+(innerWidth-100)+'px;'};">
 .... rechts ....
</div>

top Drei Spalten dynamisch /em

Der folgende Code verbindet verschiedene Anforderungen und Techniken, absolut und nur in der Einheit em zu positionieren, dann per JavaScript stimmig für NC4 in Pixeln anzupassen, und schliesslich die Möglichkeiten der dynamischen Seitenerstellung entsprechend den Inlinescripten bei Netscape-Layern auf CSS konsequent zu übertragen: Popup-Seite

<style>
#li{ position:absolute; top:.1em; left:.1em; width:6em;
             border:1px solid red;}
#mi{ position:absolute; top:.1em; left:6.2em; right:6.4em; margin-left:.1em;
             border:1px solid blue;} 
#re{ position:absolute; top:.1em; right:.1em; width:6em;
             border:1px solid red;}
body div{text-align:justify}
</style>
</head>
<body style="&{'width:130%;'};"
 onresize="if(document.layers&&navigator.appVersion.substring(2,3)>5)
                                                      self.location.reload();">
<div id=li>
 ....
</div><div id=mi style="&{'marginright:'+document.ids.re.width};">
 ....
</div>
<div id=re style="&{'left:'+(document.layers[1].left+
   document.layers[1].clip.width+3)+'px;'};">
 ....
</div>

Der Resizebug ist dabei für Netscape 4 ab Version 4.6 berücksichtigt, in gleicher Schreibweise onresize="&{if(navigator... gäbe es Fehlermeldungen beim IE6. Die Korrektur des rechten Elementes erfolgt nach dem Aufbau der vorherigen Seitenteile, aber vor dem Laden der Seite. Die Breite des rechten Div könnte erst nach dem Laden Seite ermittelt werden, eine Umrechnung von em in px wäre auch nicht vorteilhaft, aber Position und Breite des mittleren Div sind vor dem Aufbau des rechten Div per Inlinescript abfragbar. So lässt sich Netscapes proprietäres Konzept zur dynamischen Seitenerstellung auch valide und mit CSS sowie JavaScript-Syntax einsetzen. Vorteilhaft gegenüber einer Lösung per DHTML ist z.B. die Anpassung während des Seitenaufbaus. Ein späteres Verschieben von Elementen ist vermeidbar und die Massnahmen sind unauffälliger als Änderung per window.onload.

Eine CSS-Weiche ist zunächst überflüssig, für den IE4 ist aber folgende Ergänzung im Style möglich:

@media handheld{
 #mi{ top:.1em; }
 #li, #re { width:12% }
 #mi{ width:75%; left:12.2% }
 #re{ left:87.5%; }
}

Dem IE4 kann aber auch wie bei Browserweichen dargelegt per import das CSS vorenthalten werden; für den NC4 wird dann die gleiche Styledatei per JavaScript Entities eingebunden, wie auch im Abschnitt "Im Kopf" beschrieben :

<link type="&{'text/css'};" rel="&{'stylesheet'};" href="&{'haupt.css'};">

<style type="text/css"> @import url('haupt.css'); </style>

Es kann durch den Einbau von JSSS- und JavaScript-Abfragen a la document.ids.re.width der Wartungskomfort einer solchen Seite deutlich erhöht werden. Somit kann diese beim Netscape 4 besonders elegante Vorgehensweise im Aufwand deutlich begrenzt werden. Vielleicht wünscht man sich aber auch solche Anpassungen in einer zentralen Datei oder möchte mehr Änderungen per DHTML vornehmen, so lassen sich die in den Inlinescripten vorgenommenen Berechnungen und Korrekturen auch per JSSS vor dem endgültigen Seitenaufbau, oder danach per JavaScript durchführen.

Als Beispiel für Lösungsmöglichkeiten beim Internet-Explorer 4 bei absoluten Positionierungen per DHTML folgt jetzt der weitere Ausbau, dabei dient die vorher gezeigte Browserweiche im CSS für den IE4 als erstmal einfache, aber nicht den HTML-Spezifikationen entsprechende Noscript-Ergänzung:

<style>
@media handheld{
         #mi{  top:.1em;}
         body{ width:100%}
         #re{  left:0px;}
         #mi{  left:12.4em}
}          
</style>
<noscript>
<style>
@media handheld{
        #mi{top:.1em;}
    #li,#re{    width:12%}
        #mi{ width:75%;left:12.2%}
        #re{left:87.5%;}
}
</style>
</noscript>

Um Schwierigkeiten mit der Breite des mittleren Div bzw. mit margin-right oder padding-right zu umgehen, wird hier einfach zum rechten Abstand der linke dazugerechnet, dadurch erhält das div die gewünschte Grösse. Das rechte Div erhält eine Position von left:0, damit diese Styleeigenschaft später angesprochen werden kann:

function initAll(){
document.all.mi.style.left=parseInt(document.all.re.clientWidth)+3;
document.all.re.style.left=parseInt(document.all.re.clientWidth)+
parseInt(document.all.mi.clientWidth)+8;
}
 if(!document.layers&&!document.getElementById)window.onload=initAll;

Da es so gelingt, auch beim IE4 einen "Resizebug" zu erzeugen, muss nach onresize je nach Seitenstruktur die Funktion initAll wieder aufgerufen werden, oder es wird gleich die ganze Seite neu geladen:

onresize="if((document.layers&&navigator.appVersion.substring(2,3)>5)||
          (document.all&&!document.getElementById))self.location.reload();">

Um die Seite als gültiges HTML anzubieten, sind aber noch einige Änderungen nötig. Statt des invaliden noscript im Head muss das IE4-CSS der noscript-Variante normnal eingebunden werden, und ein JavaScript erzeugt das anspruchsvollere CSS zur späteren DHTML-Korrektur. Auch das onresize Attribut muss durch JavaScript ersetzt werden.

function resizeIt(){ self.location.reload(); }
if(!document.layers&&!document.getElementById){ window.onload=initAll;
window.onresizeresizeIt;
document.write('<style>body{width:100%}#re{left:0px;}#mi{left:12.4em}<\/style>');
}

Da hier auch eine einfachere Notvariante für den IE4 bei deaktiviertem JavaScript denkbar ist, bei der nach der rechte Block zwischen "li" und "mi" sitzt, kann es auch kürzer realisiert werden: Popup-Seite

@media handheld{
 #mi{top:.1em;}
 #re{left:6.2em;}
 #mi{left:12.4em}
}
</style>
<script>
function initAll(){
document.all.mi.style.left=parseInt(document.all.re.clientWidth)+3;
document.all.re.style.left=parseInt(document.all.re.clientWidth)+
parseInt(document.all.mi.clientWidth)+8;
}

top max-width

max-width ist gerade bei flexiblem Layout hilfreich, etwa um Zeilenlängen wegen der Lesbarkeit zu begrenzen. Die Lösung für Netscape 4 ist hier oft einfach, da dieser Browser width sowieso entsprechend einsetzt. Somit sind es die aktuellen Internet Explorer, die hier den Einsatz von problemlos skalierenden Tabellen nahelegen.

<table>
<tr>
<td style="width:20em"> 
<p>

Alternativen zur Tabelle für den IE gibt es auch, z.B.: Popup-Seite

div {  width:20em; max-width:20em; }
body > div{ width:auto; }
* div{ width:expression((body.offsetWidth>500)?'20em':'auto');} 

Da die expression beim IE auf JavaScript beruhen und mitunter instabil sind, empfehle ich aber den Einsatz von per JavaScript nach onload generierten Tabellen. Denkbar wäre auch nur für den IE eine Tabellenversion per conditional comments einzubauen, jedoch widerspricht das dem Ziel ein einheitliches sauberes HTML, zumal mit der meist geforderten Verlagerung der Layoutbeschreibung ins CSS, zu verwirklichen.

Da einige Lösungen per expression JavaScript voraussetzen kann natürlich auch, z.B. per innerHTML oder outerHTML oder entspr. DOM, um einen ein Textblock nachräglich eine Tabelle mit den erforderlichen Eigenshaften erzeugt werden.

min-height

min-height kann aber auch per CSS-Weiche für den IE dargestellt werden da er height eintspr. berücksichtigt.

div { min-height:300px; height:auto; }
* html div{ height:300px; }

top Position Fixed CSS

position:fixed kann für die Internet Explorer 4 bis 6 sehr einfach ersetzt werden, schließlich geht es ja meist nur darum, ein div mit dem "Inhalt" zu scrollen. Die CSS-Eigenschaft overflow:auto ist also das eigentliche Werkzeug um Cross Browser position fixed zu verwirklichen, und ist umgekehrt auch für die moderneren Browser Mozilla und Opera verfügbar.

 #divscroll { height:100%;  width:100%; overflow:auto;
              right:0; left:0; top:0; margin:0;         }

Zunächst wird aber bei meiner Entwicklung die Möglichkeit beibehalten, fixed für einige Browser zu verwenden, und die IE 4 bis 6 mit den scrollbaren Divs zu versorgen, dennoch möchte ich auf die einfache Variante mit Nutzung von overflow hinweisen, die durch geringere Anforderungen an Browserweichen Vorteile hat.

Bleibt Netscape 4; beim üblichen einfachen Layout mit einer Navigation links kann für Netscape 4 eine ganz neue Strategie angewandt werden, es wird ein Frameset per JavaScript erzeugt, um danach die Datei passend in das Frameset zu laden. Popup-Seite Position Fixed CSS ist für Netscape 4 und IE ab 4 geeignet und basiert auf CSS.

document.write('</head><'+
'frameset cols="300,*" border=0 frameborder=0'+
' framespacing=0><frame'+
' src="about:blank" name="nfixed"'+
' scrolling=no border=0><'+
' frame src="about:blank" name="nscroll">'+
'</frameset></html>');

Möglichkeiten per DHTML sind noch später bei Position Fixed DHTML nach unten ausgeführt.

Hinweis: Für modernere Browser gibt es schließlich noch die Möglichkeit Elemente wie "Header" und "Footer" auch fixed zu positionieren, damit nähert sich das Layout der IE-Lösung mit einem scrollbaren Div an. Daraus ergibt sich einerseits die Möglichkeit einheitlicher vorzugehen, andererseits gilt es bei Verwendung von fixed die Sprungmarken in dem scrollabren Bereich anzupassen, z.B. per padding-top *>a.ziel{padding-top:2em}.

top Index der CSS-Layouts

Nach den Grundlagen von Spalten mittels float und Möglichkeiten per JSSS abschliessend noch einer Übersicht einiger als Datei ausgeführten Beispiele der von mir entwickelten CSS-Layouts. Die jeweilige Beschreibung ist bei einigen Beispielen aus diese Hauptdatei den vorherigen Abschnitten zu entnehmen; alle Beispiele sind z.B. für Netcape 4 geeignet.

  1. 3 Spalten Layout XHTML mit Kopf und Fuss
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/drei-spalten-kopf-fuss-layout.html
  2. 2 Spalten Layout XHTML ohne float
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/zwei-spalten-layout.html
  3. 3 Spalten Layout "liquid" in XHTML mit extra Style für Netscape 4 und WA für float-Bugs des IE
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/drei-spalten-liquid-layout-xhtml.html
  4. 3 Spalten Layout "liquid" in XHTML fast ohne CSS-Weichen, Box-Bug per Container berücksichtigt
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/3spaltenxhtml4.html
  5. 3 Spalten Layout "liquid" in XHTML ohne Container mit umfangreichen CSS-Weichen und einer IE-Anpassung per Expression
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/3spaltenxhtml3.html
  6. 3 Spalten Layout mit etwas CSS-Weichen und zusätzlichem Element
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/3spaltenxhtml2.html
  7. 3 Spalten Layout XHTML mit JSSS für Netscape 4 und einer Weiche für den Internet Explorer 4
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/dreispaltenxhtml.html
  8. Dieses Layout mit float und em ist auch für Opera 3.6 geeignet. Eine einfache Weiche per @media all{ und eine JScript-Korrektur für den IE4.
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/dreispaltenplus.html
  9. Inlinestyle mit Weichen
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/dreispaltenperentity.html
  10. JSSS für Netscape 4 und zu einer kleinen Korrekur Expressions für den IE
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/dreispaltenplusx.html
  11. Verschiedene Weichen
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/dreispalten2plus.html
  12. Drei Spalten Layout per CSS ohne Browser-Weiche
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/css3spalten2.html
  13. Float, margin und ein absolute bei diesem Layout ohne Weiche
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/css3spalten.html
  14. Dynamisches Inlinescript als Crossover für Netscape 4, Resizebug muss berücksichtigt werden, und Weiche für Internet Explorer 4
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/dreispalteneminlinescript.html
  15. Vier Spalten mit JSSS für Netscape 4
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/VierSpaltenPlus.html
  16. Drei Spalten, keine Browserweiche
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/dreispaltenoben.html
  17. Zwei Spalten ohne Browserweiche
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/css2spalten.html
  18. Zwei Spalten Position Fixed
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/position-fixed.html
  19. Statisches Layout Center Div
    Popup-Seite http://www.lipfert-malik.de/webdesign/tutorial/bsp/position-fixed.html

top Nachkorrektur Body / Tabelle

Mit der möglichen Nachkorrektur von position oder clip stehen wie schon dargelegt mächtige Werkzeuge zur Verfügung, um Grössen bei Divs oder auch beim Body sicherzustellen. Ein einfacher Trick bei Netscape 4 margin des Body indirekt zu verändern, also u.a. als Ersatz für o.g. < body marginwidth="0" marginheight="0" topmargin="0" leftmargin="0" > geht auch mittels einer Stylezuweisung position für den Body:

<body style="position:absolute;left:-1px;top:-1px;margin:0;padding:0;">

Statt -1 kann natürlich auch 0 eingesetzt werden. Als Definition mit zusätzlichen Angaben für bottom und right könnte zugleich auch für Mozilla sichergestellt werden, dass die Body-Grösse zumindest der des Window entspricht:

body { position: absolute; top:0; bottom:0; left:0; right:0; margin:0; padding:0;}

Weniger empfehlenswert zur Korrektur für NC4 ist eine Methode mit negativem margin beim body, zumal der rechte Rand immer noch nicht korrigiert wird:

 body { margin: -8px }
 @media screen {  body { margin: 0px } }

Die Begrenzung, bzw. die Seitenabstände des Body sind eigentlich bei einem üblichen mehrspaltigem Layout dadurch korrigierbar, dass zunächst eine Breite für den Body bestimmt wird, entweder durch das Window, also innerWidth, oder durch die tatsächliche Breite eines Container-Div. Anhand dieser Breite wird die rechte Spalte positioniert, und nun können sowohl bei body oder Container-Div als auch beim Div der rechten Spalte per clip.width Grössen richtig dargestellt werden, und damit auch abgeschnittene Bereiche sichtbar werden. Es ist also möglich beim div für die rechte Spalte nach dem Laden rSpalte.clip.width=document.ids.rSpalte.width zu setzen. Ähnlich wie ein Containerdiv für Mozilla funktioniert übrigens die zusätzlich Stylenangabe für das html-Tag, die, auch abhängig vom Doctype, nicht immer vorteilhaft ist:

body, html { height: 100%; }

Zunächst möchte ich aber nochmal Lösungen für das Problem mit dem Body, und gleich die erste Variante ganz ohne Einsatz eines Containerdiv, und ohne Verwendung von JSSS, zeigen. Die Beispiele haben ausnahmsweise einen unsicheren Workaround für den Resizebug nach oben , der hier als Notlösung noch am ehesten geeignet ist da sowieso keine Scrollbalken auftauchen sollen, ausserdem sind diese Beispiele in der Praxis nicht empfehlenswert da sie im Zusammenhang mit eigentlich zu vermeidenden "Layouttabellen" Sinn machen. Das Wissen um das Verhalten des Netscape 4 und auch die Lösungsansätze sind aber auf andere Situationen übertragbar.

Beim ersten Beispiel hat der Body eine andere Farbe als die Tabellenzelle, so man kann den hier trotz Korrektur bleibenden schmalen Rand sehen, dieser Abstand um Scrollbalken zu verhindern wäre bei reinem CSS-Layout leichter zu vermeiden, und wäre bei gleicher Hintergrundfarbe des Body sowieso nicht erkennbar. Wichtig ist beim ersten Beispiel zunächst für Netscape 4 eine Styleeigenschaft width bei Body mit innerWidth zu überschreiben, bzw. hier mit etwas Zuschlag. Popup-Seite

<style>
 body { background-color:#ecff99; width:100%; height:100%;
        margin:0; padding:0; }
 table{ height:100% }
</style>
<script><!--
 if(document.layers){
  document.write("<style>body{position:absolute;left:-24px;top:-1px;height:"+
  (innerHeight-2)+";width:"+(innerWidth+12)+";}<\/style>");
  window.onload=function(){
  window.onresize=function(){location.reload();}
  document.layers[0].left=0;
}}
//--></script>
<body>
<table width=100% height=100% cellpadding=0 cellspacing=0>
<tr><td width=100% height=100% align=center valign=center bgcolor=#ececec>0
</td></tr>
</table>

Noch eine kurze, w3c-validierbare Variante mit Inlinescripten bei den Angaben zu body im Styleattribut, und zu td bei height: Popup-Seite

<body 
style=" width:100%; margin:0; padding:0; 
 &{'width:130%;position:absolute;left:-16px;top:-1;height:'+(innerHeight-2)};"
onLoad="if(document.layers)document.layers[0].left=16;">
<table width=100% cellpadding=0 cellspacing=0 style="height:100%">
<tr><td width=50% align=left 
               style="height:50%;" height="&{innerHeight/2-3};" valign=top>1

Abgesehen von möglichen Nachteilen dieser Anweisungen auf den Body ist ja beim vorliegenden Konzept sowieso das vielseitigere Container-Div verfügbar, dazu noch ein Beispiel um Tabellen bis in die Ecken zu bekommen ohne noch fragwürdigere Methoden wie etwa ein Frameset zur Unterdrückung der Scrollbalken zu verwenden: Popup-Seite

<html>
<style>
 body { background-color:#ecff99; }
 table{ height:100% }
 #bd  { height:100% }
</style>
<style type='text/javascript'>
 with(ids.bd){
  position="absolute";
  left="-20px";top="0px";
  height=innerHeight-2;
  width=innerWidth-2;
  paddings(0);margins(0);
 }
</style>
<script>
 if(document.layers){
   window.onload=function(){
     window.onresize = function(){location.reload();}
     document.bd.left=2;
}}
</script>
<body>
 <div id=bd>
  <table width=100% height=100% cellpadding=0 cellspacing=0>
   <tr><td width=50% height=50% align=left valign=top>1
    </td><td width=50% height=50% align=right valign=top>2
    </td></tr>
   <tr><td width=50% height=50% valign=bottom align=left>3</td>
    <td width=50% height=50% valign=bottom align=right>4</td></tr>
  </table>
 </div>
</body>
</html>

Was passiert im Detail? Das Containerdiv, id=bd, wird für Netscape 4 nach links und oben aus dem Window verschoben aufgebaut, damit es bei voller Grösse nicht mit dem Seitenaufbau die Scrollbalken aktiviert, und es wird zugleich auf die Höhe des Window gesetzt. Je nach OS oder Browserversion mag die Vorgehensweise zu grob sein, grundsätzlich funktioniert es jedenfalls. Erst nach dem Laden der Seite wird die Position korrigiert, sodass nicht nur der Abstand oben und links stimmt, das wäre ja durch position:absolute und top:0px;left:0px; bereits erreicht, sondern rechts und unten kann die reservierte Zone der Scrollbalken überschritten werden. Im HTML-Code der Beispiele wird kein margin-Eintrag im Body-Tag benötigt, allerdings noch ein height bei Table.

Nachdem mit der absoluten Position des Containerdiv die Ränder links und oben schon automatisch per CSS vermieden sind, kann beim Tableless-Layout, bei welchem ja keine Tabelle über die ganze Seite aufgebaut werden muss, viel eleganter die Eigenschaft clip.width verändert werden, um Ränder rechts und unten zu vermeiden:

window.onload=function(){
 document.layers[0].clip.width+=10;
 window.onresize = function(){ ....

Hier wird einfach nach dem Laden der Seite das erste Div mit absoluter Position, also das Containerdiv, um zehn Pixel verbreitert, damit geht das Div bis zum rechten Scrollbalken. Der nächste Schritt ist dann die Eingangs gezeigte Funktion function initWidth(){ ...., bei der auch rechts positionierte Elemente auf ihre richtige bzw. per Style zugewiesene Grösse gebracht werden.

Nun sollte hier fairerweise auch bei der Thematik CSS der Layer-Tag erwähnt und als Lösung erprobt werden: Popup-Seite

<style>
 body{  background-color:#ffec99; }
 table{ height:100% }
 @media all{ body, html{height:100%;margin:0;padding:0;}}
</style>
</head>
<body>
<layer top="0" left="0" width="100%" height="99%">
<table width=100% height=100% cellpadding=0 cellspacing=0>
 ....

Bei dieser Variante lässt sich das Layertag auch per JavaScript dynamisch im Body erzeugen und wäre dann auch vor anderen Browsern oder dem Validator versteckt, allerdings entspräche diese vorgehensweise nicht dem Ideal, die Korrekturen für bestimmte Browser möglischt nur an einer Stelle zentral im Head vorzunehmen:

<script type="text/javascript">
if(document.layers)document.write('<layer ...

Wenn nun noch das Attribut height bei table durch Angaben bei tdersetzt wird, kann das Ergebnis z.B. als "valid HTML 4.01 Transitional" den w3c-Test bestehen. Eine CSS-Methode für td{height: beim NC4 ist übrigens im Abschnitt Tabellen nach unten zu sehen. Popup-Seite

<table width="100%" cellpadding=0 cellspacing=0>
<tr>
<td width="50%" height="&{innerHeight/2-2};" align=left valign=top>1
</td><td width="50%" align=right valign=top>2
</td></tr>
<tr>
<td width="50%" height="&{innerHeight/2-2};" valign=bottom align=left>3</td>

Auch wenn eine saubere Seitenstruktur mit einem schon erwähnten Containerdiv für alle Browser, auch Netscape 4, empfehlenswert ist, das selbstgestellte Ziel, Änderungen per Anweisungen im head durchzuführen, kann aber ebenfalls bei der Layerlösung erreicht werden, wenn im Vertrauen auf die gutmütige Interpretation der Netscape 4 Versionen der layer-Tag bereits vor dem body per JavaScript geschrieben wird Popup-Seite:

<script type="text/javascript"><!--
if(document.layers)document.write('<layer top="0" '+
'left="0" width="100%" height="100%">');
//--></script>
</head>
<body>

top NN4 IE6 inline dhtml

Nachdem zuvor die dynamische Beschreibung von Attributen beim Netscape 4 zur Positionierung gezeigt wurde, ein Beispiel mit ähnlichem Ansatz bei Internet Explorer ab 5 mit JScript, mit zusätzlicher JavaScript-Unterstützung teilweise sogar für den IE 4. Diese Positionierung funktioniert für den Netscape 4 bei einigen Attributen wie dem hspace ohne Resizebug. Für die IE ab 5 ist zu beachten, dass die Möglichkeiten als proprietäre Lösungen nicht empfehlenswert sind, und die gleichen Nachteile wie anderes DHTML haben, also z.B. nicht direkt im CSS verankert sind und nicht in Echtzeit arbeiten.

<img src=xy.gif width=100 height=100 border=2
style=" margin-left: expression( body.offsetWidth/2-60 ); "
hspace=" &{ innerWidth/2-60 }; ">

Als Weiche werden beim Beispiel mit dem img zwei verschiedene Attribute angesprochen. Aber auch nur mit Inlinestyles funktioniert es, z.B. so Popup-Seite Netscape 4, IE ab 5, JavaScript/JScript:

<div
style = " left:expression(body.offsetWidth/2-60); "
style = " width:100px;
 border:2px solid green;
 position:absolute;
 top:50px;
 &{ 'left:' + (innerWidth/2-60) + 'px'} ;">

top IE expression DHTML

Die proprietären "expression" für die Internet-Explorer werden von Microsoft ähnlich wie eine CSS-Defintion im Stylesheet dargestellt. Tatsächlich erspart der Einsatz im CSS eine Browserweiche im sonst nötigen JavaScript-Block, und so ist im Abschnitt Browser-Weichen auch eine eher statische Variante als mögliche CSS-Weiche top aufgeführt.

Auch bei Inlinestyles wie im vorherigen Beispiel ist der Einsatz möglich. Die weitgehenden dynamischen Einsatzmöglichkeiten lassen "expression" zumindest bei eher kosmetischen Korrekturen geeignet erscheinen, wenn ein deaktiviertes JavaScript beim IE trotzdem die Seite weitegehend richtig darstellt. Ideale Einsatzmöglichkeiten wären also etwa eine Korrektur des Versatzes nach float, oder als Möglichkeit min-width oder max-width zu realisieren. So ist expression auch hier bei einigen Beispielen zur Korrektur von XHTML-Layout und als max-width top Workaround im Einsatz.

Dennoch ist die Verwendung von expression gar nicht, oder nur bedingt in anderer als von Microsoft empfohlener Weise empfehlenswert. Die möglichen Probleme reichen von eher harmlosen und seltenen Script-Fehlern bis zum kompletten Absturz des IE 6. Hinzu kommt noch die unterschiedliche Umsetzung bei den verschiedenen IE-Versionen.

Expression Min-Width

Eine Verbesserungsmöglichkeit der expression liegt im Auslagern in ein Script, un den Aufruf der expression erst nach dem vollständigen Laden der Seite auszuführen. Zugleich zeigt das folgende Beispiel wie vergleichbar mit der Abfrage der gesetzten Stylewerte für right für IE4 und NC4 auch hier der im Stylesheet gesetzte Wert genutzt werden kann. Zugleich wird das Problem von Seitengrösse, Schriftgrösse und relativen Angaben gelöst. In der vorliegenden Form wird allerdings immer noch eine Art resize-bug erzeugt, der weitere Massnahmen erfordert, und auch hier bleibt ein dummy-expression nötig.


<!--[if lt IE 7]>
<style>
/* Autor 2002-2003 Kristof Lipfert Duesseldorf  */

p {color:expression( document.body.clientWidth >0 ? "black" :"black");}

</style>
<script type="text/javascript">
/* Autor 2002-2003 Kristof Lipfert Duesseldorf  */

function iek(){ 
  document.body.style.setExpression("width",
  " document.body.clientWidth > 75 *
  parseInt(document.body.currentStyle.fontSize)? 'auto' :
  document.body.currentStyle['min-width'] " );
              }

window.onload=iek;

</script>
<![endif]-->

Durch die Verwendung von setExpression ist der Aufruf nach dem Laden Seite möglich. Im vorliegenden Beispiel war beim Einsatz im Stylesheet sogar noch eine spezielle zusätzliche Dummy-expression nötig. Mit body.currentStyle.fontSize wird die eingestellte Schriftgrösse abgefragt, der Default ist "12pt" beim IE. Besonders komfortabel hier die entwickelte Lösung die vorhandenen Werte des Stylesheets abzufragen, min-width wird hier per body.currentStyle['min-width'] ermittelt. Popup-Seite

Die Instabilitäten bei den Expressions sind von verschiedenen Faktoren abhängig, so vom Doctype bzw. Rendermodus. Folgende Lösung für min-width scheint stabil zu sein wenn feste Grössen, also Pixel, statt relativer Angaben eingesetzt werden, und wenn dazu der Referenzwert, hier 604, größer festgelegt ist als die resultierende Angabe, hier 600px.

#test{
  width:expression(document.body.clientWidth < 604? "600px": "auto" );
}

Diese Variante führt beim IE 6 reproduzierbar zum Absturz:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<--[if lte IE 6]>
<style type="text/css" media="screen">
#test{
  width:expression(document.body.clientWidth < 600? "600px": "auto" );
}

Allerdings kann die Abhängigkeit vom Rendermodus per expression bzw. JavaScript auch durch Abfrage des document.compatModevorheriges Thema berücksichtigt werden:

#test{
  width:expression(((document.compatMode&&document.compatMode==
  'CSS1Compat')? document.documentElement.clientWidth:
  document.body.clientWidth) <600? "600px": "auto");
}

Expression Max Width

Der Code für max-width mittels Expression:

     #test {
  width:expression(document.body.clientWidth > 600? "600px": "auto" );
           }

IE: max / min per Table

Alternativ ist der Einsatz von Tabellen möglich. Der betr. Code läßt sich vor anderen Browsern per Conditional Comments verstecken, und/oder nach onload per JScript dynamisch erzeugen: Popup-Seitemax-width, min-width für IEs

Expression und float

Auch das Problem des IE, nach float einen kleinen Versatz in die Seite einzubauen, lässt sich per expression behandlen:

<!--[if lt IE 7]><style>
/* <![CDATA[                         */
/*   2002-2003 by Kristof Lipfert, Duesseldorf    */

#li, #re {height: expression(" "+
   (document.all.mi.offsetHeight)?
   (document.all.mi.offsetHeight)+
    "px":"auto");}

/* ]]>                               */
</style><![endif]-->

Hier werden die Spalten "li" und "re" in ihrer Höhe an den mittleren Block angeglichen. Normalerweise wird nun ein Effekt ähnlich dem Resizebug erzeugt, da der Browser nach Änderung der Fenstergrösse die expression nicht mehr richtig anpasst. Durch die bereits vorgenommene Realsierung per JavaScript bietet sich die Möglichkeit per return eine stimmige Massangabe abzufragen: Popup-Seite

/*   2002-2003 by  Kristof Lipfert, Duesseldorf    */

function hoch(){
var hx=document.all.mi.offsetHeight;
return hx;
}

function iek(){ 

document.all.li.style.setExpression("height", " hoch() " );
document.all.re.style.setExpression("height", " hoch() " );
             }

window.onload=iek;

In den meisten Fällen emfiehlt sich aber statt der manchmal instabilen Expressions eine Lösung per margin; zumindest der o.g. Versatz läßt sich so vermeiden:

#mi {float:left}
* html #mi {margin-left:-4px; margin-right:3px;}

IE: z-index select

Expressions können aber einige Probleme mit Ersatzlösungen für position:fixed beim IE beheben, so abhängig vom Scrollzustand der Seite bzw. im Beispielcode des content-Div Elemente ausblenden. Etwa eine Fußzeile die eigentlich nicht mitscrollen soll, oder select-Eleemnte, bei denen der z-index nicht greift und die unter einen Header scrollen sollen:

<!--[if IE]><script>if(document.uniqueID)window.onload=function(){
document.getElementsByTagName("select")[0].style.setExpression("visibility",
"parseInt(document.getElementById('content').scrollTop)<40?'visible':'hidden'" );};
</script><![endif]-->

top Opera bottom

Die Version 6 des Browsers von Opera Software benötigt hier ggf. etwas Nachhilfe, um mit bottom auch bei grossen Seiten an die Unterkante zu gelangen:

function loadInits(){setUnten();}

function setUnten(){
 su1=document.getElementById('cont').offsetHeight;
 su2=document.getElementById('untenbottom').style.top;
 su3=document.getElementById('untenbottom').offsetHeight;
 if(su1-su2-su3>5)
     document.getElementById('untenbottom').style.top=su1-su3;
}

window.onload=loadInits;

Die Korrektur setzt erst ein wenn ein Unterschied grösser als 5 Pixel festgestellt wird, bereits dadurch sollte bei Opera 7 wie auch bei einer Ansicht unter Opera 6 ohne Scrollbalken erst gar nichts passieren, dennoch kann wie schon bei Erkennung - OS nach oben beschrieben mit der zusätzlichen Abfrage von document.documentElement Opera 7 ganz vom Korrekturscript ausgeschlossen werden.

top Rundum Formel

Das folgende Beispiel zeigt eine Anwendungsmöglichkeit zur Korrektur der Abstände von Divs. Man kann gut die dynamischen Möglichkeiten per JavaScript sehen, zugleich werden Workarounds für background-color: eingesetzt. In der Praxis muss aber beachtet werden dass sich solch globale Lösungen erstmal auf alle Divs auswirken und dadurch oft neue Probleme entstehen können. Popup-Seite

with(tags.DIV){
 borderWidths(0.1);
 if(!height){
  marginBottom=parseInt(marginBottom)*.1 +"px";
  marginTop=parseInt(marginTop)*.65 +"px";
 }
else if(!position){
 layerBackgroundColor=borderColor=backgroundColor;
}
else{
 layerBackgroundColor=backgroundColor;
  if(marginLeft){
   left=parseInt(marginLeft);
   marginRight=parseInt(marginRight)*2;
   marginLeft=0;
}
  if(marginTop){
   clip=eval('"'+parseInt(marginTop)+','+
   (parseInt(window.innerWidth)*1-parseInt(marginRight)-
   parseInt(marginLeft))+','+
   (parseInt(marginTop)+parseInt(height)*1)+','+0+'"');
   marginTop=0;
   paddingBottom=parseInt(marginBottom);
   marginBottom=0;
   paddingTop=parseInt(paddingTop)/2;
}}}

Da clip sich nur bei absolut positionierten Divs auswirkt, sind aufwändige Formeln, die padding, margin in Beziehung zu Position und Grösse korrigieren, nicht immer einsetzbar, und können ausserdem bei zu gross geratenen Divs Inhalte abschneiden. Und oft ist sowieso erstmal das Problem der -möglichst auch noch homogenen- Hintergundfarbe zu lösen.

top Wahre Grösse durch JSSS

Farbe, Grösse und Abstände

Popup-Seite

Ein typisches Problem beim NC4 ist die unübliche Umsetzung von width, height sowie margin, padding und Hintergrundfarbe.

with(ids.divbg){
 layerBackgroundColor = backgroundColor;
 borderWidths(0.1);
}

Auch hier ist lediglich die Id des Div festgelegt, die zu ergänzende layer-background-color wird gleich der abfragbaren background-color gesetzt. borderWidths() ist eine netscapespezifische Methode zur Festlegung der Rahmenstärke per JSSS, und erfreulich kompakt.

top Center Div / clip

Ein gelegentliches Problem ist die Zentrierung von Divs per CSS für alle Browser. Dazu erstmal eine einfache Lösung, die aber bei kleinem Fenster Teile der Seite abschneiden kann, cont ist die ID des zentrierten Div:

body{
 height:100%;
 margin:0px
    }
#cont{
  width:620px;
  height: 100%;
  position:absolute;
  left: 50%;
  margin-top: 0px;
  margin-left:-310px;
  background-color: #000080;
    }

Immerhin lässt sich das Layout per JSSS auch für den Netscape 4 realisieren, im folgenden Beispiel erfolgen dazu noch kleine Korrekturen per clip:

with(tags.BODY){position="absolute";width="130%";top="-3px";
clip="0px "+innerWidth-6+"px "+innerHeight+"px 0px";
}
with(ids.cont){height="100%";borderWidths(0.1);
left=Math.max((innerWidth/2-parseInt(width)/2),0);
layerBackgroundColor=backgroundColor;
clip="1px "+parseInt(width)+"px 1800px 2px";
}

Nun eine umfassendere Lösung, die das Zentrieren richtiger per margin durchführt, dazu auch den Netscape 4 Resizebug berücksichtigt und dabei mit nur einem JSS-Script auskommt: Popup-Seite

<style>
body{   height:100%;margin:0px; text-align:center; }
#cont{  width: 620px; 
        text-align:left;
/*/*/   height: 100%; /* */
        margin-left:auto;
        margin-right:auto;
        background-color: #000080;color:white;
        font-weight:bold;                         }
</style>
<style type='text/javascript'>
with(tags.BODY){ position="absolute";
                 width="130%";
                 top="-3px"; left="-12px";        }
with(ids.cont){  position="absolute";
                 width=parseInt(width)+4+"px";
                 borderWidths(0.1);
 left=Math.max((innerWidth/2-parseInt(width)/2)-2,0);
 layerBackgroundColor = backgroundColor;          }

window.onload=function(){ 
  with(document.layers[0]){
   resizeBy(0,4);
    with(document.layers[0]){
     if(clip.height<innerHeight)
     clip.height=innerHeight;
    resizeBy(0,4);
    clip.left=2;}
  left=-2;}
 var origWidth = innerWidth; var origHeight= innerHeight;
function initResize(){
 window.onResize=function(){
 if((innerWidth!=origWidth)||(innerHeight!=origHeight))
 self.location.reload(); }} initResize();}
</style>

Da das window schon existiert kann der Eventhandler window.onload bereits im JSSS aufgerufen werden. Im zweiten Teil des JSSS sind hier per JavaScript mittels clip und resize kleinere Korrekturen beschrieben.

Die konkrete Vorgabe lässt sich aber auch deutlich einfacher umsetzen, zumal wenn es nicht pixelgenau sein muss: Popup-Seite

body {  text-align:center; padding:0;
        margin-top:0; margin-bottom:0; }
#cont{ width:640px; background-color:#000080;
text-align:left;
position:relative; color:white;
font-weight:bold; height:100%;
margin-left:auto; margin-right:auto;}
</style>
<style type='text/javascript'>
with(ids.cont){ borderwidth=.1;width=parseInt(width)+23+"px";
layerBackgroundColor=backgroundColor;}
with(tags.BODY){paddingleft=
 Math.max((innerWidth-parseInt(ids.cont.width))/2-7,0);
 margintop="-8px"; width:"130%" }

Der Resizebug muss bei dieser einfacheren Varainte nicht berücksichtigt werden, allerdings entfällt mit dem Verzicht auf absolute Positionierungen zugleich auch die Möglichkeit mittels clip Ränder und Flächen zurechtzustutzen.

Und dann noch eine einfache Ergänzung um die Eigenschaft middle, allerdings wie beim ersten Beispielcode in diesem Abschnitt mit dem Risiko dass unbemerkt an der Oberkante angeschnitten wird. Die Darstellung entspricht üblichen leeren Framesets: Popup-Seite

#cont{height:380px;}
@media all{#cont{top:50%;margin-top:-190px;}}
</style>
<style type='text/javascript'>
tags.BODY.paddingtop=
Math.max((innerHeight-parseInt(ids.cont.height))/2-7,0);

top Listen

Wichtig kann eine Lösung zur Verwendung von Listen in Menus sein. Üblicherweise wird in Navigationsmenus ganz auf Listen verzichtet, um z.B. die zu grossen Abstände bei Listen zu vermeiden:

&nbsp;<a href=p1..>..</a><br>
&nbsp;<a href=p2..>..</a><br>
&nbsp;<a href=p2..>..</a><br>

So schaut eine Lösung per JSSS aus, abhängig von der Id des Div, hier "list1", um die Abstände zu normalisieren:

with(contextual(ids.list1, tags.UL)){
 fontSize="85%"; paddingLeft="-30px"; marginLeft="-30px"; }

Wer nun die Abstände flexibler handhaben möchte meint, kann auch statt fester Werte dynamisch an die Sache herangehen und einen womöglich per CSS bereits gesetzten Wert abfragen und berücksichtigen:

tags.UL.marginLeft=(tags.UL.marginLeft?
parseInt(tags.UL.marginLeft):30)-44+"px";

Auch für altbekannte Bugs gibt es eine Lösung, hier eine Methode um list-style:none bei margin-left usw. doch zu realisieren. Popup-Seite

if(tags.UL.listStyleType=='none'){
 tags.UL.color="black";
 contextual(tags.UL, tags.LI).color="white";
}

So ist es dann möglich den HTML-Tag ul auch bei Linklisten oder Menus mit begrenztem Platz auf der Seite einzusetzen, ein Schritt zu richtigerem und barrierefreierem Code. Im folgenden Beispiel ist im CSS-Abschnitt eine CSS-Weiche für Mozilla vs. Opera 7 Beta eingesetzt, die evtl. bei einer endgültigen Opera 7 Version geändert werden müsste.

<style>
ul { margin-left:25px; list-style-type:none; color:black; }
html:root ul{ margin-left:-16px; }
</style>
<body>
<ul>
<li><a href=p1..>..</a></li>
<li><a href=p2..>..</a></li>
<li><a href=p2..>..</a></li>
</ul>

list-style-position

Auch bei der Listeneinrückung bei nummerierten Listen kann der NC4 wieder vielfältig unterstützt werden. list-style-position:inside führt er zwar nicht direkt aus, aber es gibt z.B. Lösungen per text-indent. Bei einer einfachen Anwendung auf ol ist noch nachvollziehbar, dass sich text-indent beim NC4 nur auf den ersten Listeneintrag auswirkt. Doch auch bei li{text-indent:1em} sieht es erstmal ähnlich aus. Immerhin reichen hier die CSS-Fähigkeiten des NC4 aus, um das Problem gleich an der Ursache zu korrigieren, mit display:block. Zum browser- oder auch bedingungsabhängigen Setzen der Eigenschaft sind viele der u.a. im Kapitel Browserweichen gezeigten Methoden verfügbar. Die Korrektur selbst kann, auch wenn es sich grundsätzlich empfiehlt auf diese Stylevariante möglichst zu verzichten, ebenfalls im Inlinestyle erfolgen:

  <ol style="list-style-position:inside;&{' marginleft:-1em;'};">
  <li style="&{'textindent:1em;display:block'};">text text und <br>
  weiter im text </li>
 

per JSSS

<style type="text/css">
ol{list-style-position:inside;}
</style>
<style type='text/javascript'>
tags.ol.marginleft="-1em";
tags.li.textindent="1em";
tags.li.display="block";
</style>

JSSS bedingt mit Abfrage der Eigenschaft list-style-position

<style type="text/css">
ol{list-style-position:inside;}
</style>
<style type='text/javascript'>
if(tags.ol.liststyleposition=='inside')
tags.ol.marginleft="-1em";
with(tags.li){
textindent="1em";
display="block";
}
</style>

einfach im Stylesheet auskommentiert und hier zusätzlich als Absicherung gegen andere Browser CSS in JSSS-Syntax:

<style type="text/css">
ol{list-style-position:inside;}
li{/*/*//*/ textindent:1em ; display:block; /**/}
</style>

oder CSS-Weiche mit Selektor (o. per Kommentar) und leichten Korrekturen für den IE 4: Popup-Seite

<style type="text/css">
ol { list-style-position:inside; }
li { text-indent:1em; display:block; }
* li { text-indent:0; }
@media all{ol li{ text-indent: 0em; }
           ol li{ text-indent:.5em; }}
@media all{ol li{ text-indent: 0em; }}
</style>

top Listen IE + Opera

Listen haben leider bei allen Browsern unterschiedliche Darstellungen. Ob verschiedene Bugs oder unterschiedliche Vererbung der Schriftgrössen, oder andere Ausgangswerte für padding und margin. Eine mögliche Strategie ist es für alle Browser erstmal sämtliche default-Werte auszugleichen.

ul, li { margin:0; padding:0; }
 
ul{ list-style-type:none; 
    font-family: Arial, Helvetica, sans-serif;
    font-size: .95em; 
   }
/*/*//*/
 ul ul li { textindent:-1em; }
/* */

Die IE weisen bis Version 6 verschiedene Darstellungsfehler und Eigenheiten auf. Dazu habe ich verschiedene Workarounds entwickelt, so als einfaches Mittel für Fehler bei Positionen und Zeilenabstand float, etwa bei verschachtelten Listen, mit der vor allem für Opera nötigen CSS-Weiche:

/* 2002 Kristof Lipfert Duesseldorf */

* html ul {  float:left; }
* html ul li{ clear:left; }

So lässt sich tableless ein einheitliches Layout mit CSS und Listen als Navigation für nahezu alle CSS-fähigen Browser verwirklichen Popup-Seite, auch mit Berücksichtigung älterer Netscape 4 Popup-Seite

Nötig sind solche Korrekturen übrigens auch beim Verlust der festgelegten Zeilenhöhe, wenn in der Liste ein img am Anfang steht:


li  { line-height:20px; }
img { float:left; }

</style>

<li><img height="9" width="9" alt=""><a href=#>Test</a>

Listen + Farbe

Auch farbige Buttons oder andersfarbige Nummern bei Listen sind zumindest für Netscape ab 4 möglich:

ol{color:black}
li{color:red}
* ol{color:red}
* li:first-line {color:black}
* html li:first-letter{color:red}

Auch ein Bullet aus einer externen Datei kann für Netscape 4 zumindest in der Farbgebung angepasst werden:

ul {list-style-image:url(./images/roterPunkt.gif);}
/*/*//*/\{! i{}
 ul li{color:red;}
 li {color:black;}
*}{}/* */

top float:

Float ist besonders hervorzuheben, weil es flexible Spalten ohne Tabellen für nahezu alle CSS interpretierenden Browser sogar ohne JavaScript und ohne Resizebug ermöglicht, also tableless-layout wie in den Abschnitten DreiSpalten2Plus nach oben oder Drei Spalten X nach oben dargelegt.

Die Eigenschaft float entspricht weitestgehend dem Attribut align, beim NC4 könnte denn auch die Formulierung align im CSS oder JS verwandt werden. Netscape 4 unterstützt float erstmal sehr zuverlässig, trotzdem sind Probleme auch hier möglich.

Da gibt es zunächst die etwas eigene Umsetzung von clear, hier kann es für NC4 ggf. nötig sein ein zusätzliches Dummy-Div einzusetzen, das für andere Browser per display:none versteckt wird. Bei mehreren nebeneinander positionierten Blöcken kann es mit bestimmten Browserversionen des IE4 oder frühen NC4 kleine Mängel geben, etwa dass Weiten nicht richtig beachtet werden.

Dann gibt es noch Probleme beim NC4 wenn float in Verbindung mit margin auf Image-Tags angewandt wird. Hier gibt es einfache Lösungen, so empfiehlt es sich (nur) die margin-Anweisung einfach vor dem NC4 zu verstecken:

img{float:left;}
* img{margin:10px;}

So einfach kann in den meisten Fällen eine Cross-Browser-Lösung aussehen, bei der die Information des beabsichtigten Layouts erhalten bleibt. Ergänzend könnte für den NC4 padding statt margin verwandt werden:

/*/*//*/ 
img{padding:10px;}
/* */

Noch ein einfacher, aber mit Vorsicht einzusetzender und nicht immer erfolgreicher Workaround, ohne CSS-Weiche für den NC4, falls ein Image mit float und margin ausgestattet wird, ist die Anwendung von display:block auf das das Bild umgebende Element:

p{display:block}

Im Einzelfall kann es auch noch möglich sein per textindent für den NC4 nachzuhelfen, aber das Verstecken des margin per *-Selektor dürfte die sauberste Möglichkeit sein.

Wer ältere Browser wie den Netscape Communicator 4 sinnvoll bei validem einheitlichem Code mitberücksichtigen möchte, kann ja auch die HTML-Attribute hspace und vspace bei Bildern verwenden. Diese Attribute sind vom W3C als deprecated eingeordnet, sind also noch einsetzbar und nicht nur als HTML 3.2, sondern z.B. bei HTML 4.01 Transitional valide einsetzbar. Die konkrete Verwendung gelingt ggf. sogar, wie im Abschnitt Browserweichen dargelegt, auschliesslich für den NC4:

* img{margin:10px;}
</style>
 ....
<img hspace="&{'10'};" vspace="&{'10'};" src=

Möglich ist auch eine Lösung, um die Vielzahl der möglichen Lösungsansätze aufzuzeigen, mit der zusätzlichen Anwendung von float bei p, ein Verfahren dass übrigens auch beim IE 6 in ähnlichen Situationen kleine Probleme in der Darstellung beheben kann, und einer unterstützenden Breitenangabe zum Bild im Inlinestyle: Popup-Seite

<style type="text/css">
    #bsp { width: 300px;             }
       p { width: 300px; float:left; }
 img.fll { margin: 30px; float:left; }
</style>
<body>
<div id=bsp>
<p>
<img class="fll" height=115 width=130 
hspace="&{parseInt(document.classes.fll.IMG.marginRight)};"
vspace="&{parseInt(document.classes.fll.IMG.marginBottom)};"
style="&{''};&{'margin:0;padding:1;width:1;'};"
src="sampl.gif">
text text 

float Image

Eine einfache Lösung für Netscape 4 ein Image floaten zu lassen besteht darin zunächst dem umgebenden Element gewissermassen Blockeigenschaften durch die Zuweisung eine Breite zu geben. Die nun erkennbaren Probleme des Netscape 4 lassen sich wie schon dargelegt zum Teil durch den Verzicht auf margin lösen.

p {width:200px}
img.b{float:left;margin:0;}

Nun ist -übrigens nicht nur- bei Netscape 4 oft ein verrutschen des Textes aus dem Element zu beobachten. Auch hier gibt es eine saubere Lösung, nämlich die Angabe der tatsächlichen Breite des Bildes: Popup-Seite

img.c{float:left;margin:20;width:100px;}

float IE

Float kann beispielsweise beim IE zur richtigeren Darstellung von Listen verhelfen, aber der IE hat mit float selbst auch Probleme. So sind oft zusätzliche clear für den IE hilfreich, und der störende Versatz des Inhalts gefloateter Divs von einigen Pixeln läßt sich so unterbinden:

  #sampl { float:left; }

  * html #sampl { margin-left:-4px; margin-right:4px; }

top Tabellen

Im Abschnitt Beispiel HTML zu CSS nach oben wurde am Beispiel einer Lösung für das Verhalten bei Hintergrundgrafiken und Tabellen gezeigt, wie netscapespezifische HTML-Syntax in CSS umgesetzt werden kann.

Um Tabellenzeilen ohne Angaben im HTML-Code, also anders als das beim Doctype HTML-4 "transitional" mögliche <td height=100> nur mittels CSS auf die richtige Höhe zu bringen, (ein Beispiel per Inlinescript für den NC4 td-Angaben zu machen wurde im Abschnitt Body / Tabelle nach oben gezeigt) steht der spacer-Tag aufgrund der Sollanforderungen wie W3C Kompatibilität natürlich auch nicht mehr zur Verfügung. Und eleganter als <td><img src="spacer.gif" alt=""></td> sollte es auch sein. Hier ein Workaround, der zwar ausnahmsweise doch noch Berücksichtigung im HTML in Form einer zusätzlichen Zelle erfordert, aber dennoch valide ist:

if(ids['spacer'].height.indexOf("%")>0)
 ids['spacer'].lineHeight=
 innerHeight/100*parseInt(ids['spacer'].height)+'px';
else
 ids['spacer'].lineHeight=parseInt(ids['spacer'].height)+'px';

und so sieht das im HTML aus

<table>
<tr><td id=spacer></td><td>
normaler Inhalt
</td>
</tr>

Alternativ geht es auch so:

ids['spacer'].marginBottom=parseInt(ids['spacer'].height)+'px';

oder: Popup-Seite

<style>
td { height:200px; }
th { display:none }
</style>
<style type='text/javascript'>
tags.th.marginBottom=tags.td.height;
</style>
<body>
<table>
 <tr>
  <td>
  normaler Inhalt
  </td>
  <th></th>
 </tr>
</table>

Zugleich ist hier auch ausnahmsweise ein Beispiel wo doch etwas Änderung am HTML erforderlich ist in Form einer zusätzlichen leeren Tabellenzelle oder -spalte, die irgendwo innerhalb des betr. TR sitzen muss. Andere Erfordernisse wie einen Iframe in ein Div zu setzen oder der Verzicht auf Inlinestyles sind sowieso vorteilhaft, und ein zusätzliches TD mit bestimmten Eigenschaften ist immerhin dichter am Problem und in der ohnehin vorhanden Struktur formuliert als etwa ein zusätzliches in eine Zelle eingesetzte Div.

top Rahmen Netscape 4

Bei den verschiedenen Möglichkeiten für Netscape 4 bei Divs Grössen umzusetzen gibt es eine ähnliche Situation wie bei den Tabellen. Wenn es darum geht eine Fläche nicht mittels layer-background-color usw. per Hintergrundfarbe, sondern mitteles border in der richtigen Höhe zu begrenzen, ist ein zusätzliches Element oft vorteilhaft und erspart DHTMl-Techniken wie clip.

Wenn sowieso verschachtelte Divs zum Einsatz kommen, etwa um den Box-Bug auszugleichen, ist manchmal eine Lösung für Netscape 4 mit der border beim äusseren Div bereits ausreichend. Die Höhe kann natürlich auch per img oder spacer sichergestellt werden, mittles JSSS sogar recht komfortabel.

<style type="text/css">
 #test{ height:200px }
</style>
<div id=test>
 <img src="" height="&{document.ids.test.height};"
  width="1" align="&{'left'};"
  style="display:none;&{'//'};">

Aber vielleicht möchte man nur die Höhe eines Div sicherstellen, und dabei auf die bewährten Leer-Gifs wie auch auf den spacer-Tag verzichen. Ein zusätzlicher, leerer span im Div, am Anfang oder am Ende eingesetzt, ist hier die Lösung:

<div
style="position:absolute; width:200px; height:200px;
             border:1px solid blue;">
<span
 style="display:none"
 style="&{'float:left;paddingtop:190px;margintop:-180px;'};"></span>
Dieses Div soll einen blauen Rahmen erhalten
</div>

Natürlich ist eine Lösung per CSS und JSSS statt Inlinestyles auch möglich, auch ein per JavaScript generierter Style wäre denkbar, nur die Mischung der Inlinestyles mit CSS ist etwas problematisch. Popup-Seite

<style type="text/css">
#zwei { position:absolute; top:300px; left:0px;
                width:200px; height:200px;
                border:1px solid blue; }
#zwei span {display:none}
</style>
<style type='text/javascript'>
contextual(ids.zwei, tags.span).display="block";
contextual(ids.zwei, tags.span).align="left";
contextual(ids.zwei, tags.span).paddingtop=document.ids.zwei.height;
contextual(ids.zwei, tags.span).margintop="-"+document.ids.zwei.height;
</style>

<div id="zwei"><span></span>
 Dieses Div soll einen Rahmen erhalten

Rahmen 2

Oft wird behauptet, Netscape 4 könne keine unterschiedlich breiten Rahmen anlegen. Offenbar ist folgender einfacher Weg nicht bekannt: Popup-Seite

#test{border-width: 0 10px  0 5px; border-color:gray; border-style:solid; }

Rahmen 3

Lästig ist mitunter das Verhalten der Internet Explorer einen gepunkteten Rahmen mit 1px Stärke nicht richtig anzuzeigen. Ein Workaround ist aber möglich, hier mit einem zusätzlichen Hilfscontainer (span-Element):

<style type="text/css">

 #test{border:1px dotted red;}

 * html #test {border:2px dotted red;zoom:.5;}
 * html #test span  { zoom:2;}

</style>

<div id="test">
 <span>
  Test
 </span>
</div>

top Alle Wege führen nach Rom - Relative Pfade

<style>
   background:url(../images/background1.png) repeat-x;

... nur bei den relativen Pfadangaben wird es schwierig. Wenn die Scriptdatei aus einem Unterverzeichnis geladen wird, muss für NC4 nachgeholfen werden, im Prinzip ähnlich wie bei dieser nicht validen Angabe im normalen CSS-Block:

<style>
   background-image: url(../images/background1.png);
   layer-background-image: url(./images/background1.png);

Noch einfacher die ebenfalls nicht valide CSS-Angabe ähnlich der JSSS-Syntax, ebenfalls im normalen CSS-Block:

<style>
   background-image: url(../images/background1.png);
 backgroundimage: url(./images/background1.png);

Statt dieser zusätzlichen Netscape-Syntax als Ergänzung geht es auch valide, und für spätere Änderungen auch wesentlich komfortabler. So ist eine automatische Variante innerhalb einer Methode zur Korrektur verschiedener Div-Eigenschaften per JSSS möglich, "idDiv" ist dabei die Variable mit der Id:

<style type='text/javascript'>
    if(idDiv.backgroundImage)
     backgroundImage=backgroundImage.replace(/\.\./,".");

top Hintergründe

Bereits im Abschnitt Beispiel HTML zu CSS nach oben ist das Thema Hintergrund in Verbindung mit Tabellen bearbeitet worden, mit einer "traditionellen" Lösung und deren CSS-Umsetzung um die Vererbung bei Tabellen zu steuern. Jetzt noch mehr zu Hintergrundgrafiken:

Backgroundrepeat ist möglich, zumindest ohne schwarze Flächen, so die Styleangabe CSS:

 { background:url(../images/background1.png) repeat-x;}

Und als universeller Workaround erhalten alle Divs mit Repeat zusätzlich die Hintergrundfarbe des Body:

if(backgroundRepeat)backgroundColor=tags.BODY.backgroundColor;

Hintergründe II

Zerrissener Hintergrund bei span;

with(classes.aufstellung.SPAN){
 borderStyle = 'none';
 borderWidths(0.1);
}

Hintergründe III

Korrektur der schwarze Flächen durch transparent und border beim Netscape 4 per CSS (in Netscape Syntax und CSS-Weiche):

div { background-color:transparent; color:red; width:50; border: 1px solid yellow; }

/*/*//*/
div { backgroundcolor:'none'; }
/*  */

top DHTML Strategie

Nun können einige Bugs per CSS oder JSSS korrigiert werden, andere erfordern DHTML, also hier Korrekturen per JavaScript gleich nach dem Laden der Seite. Das betrifft Iframe, aber auch Styleangaben wie overflow:auto oder position:fixed. Um alle nötigen Korrekturen komfortabel zu verwalten, wird im JavaScript ein onLoad= Handler gesetzt, der auch gleich den schon erwähnten Resize-Bug nach oben berücksichtigen kann.

var origWidth=innerWidth*1;var origHeight=innerHeight*1;
function initResize(){
 onResize=function(){if((innerWidth!=origWidth)||(innerHeight!=origHeight))
 self.location.replace(
 self.location.href.substring(0,self.location.href.indexOf("#")>0?
 self.location.href.indexOf("#"):999));}
}
window.onLoad=function(){initLayer(); initMover();initResize();initHover();
initIframe('miframe','hallo1.htm');initWidth();initPfixed('pfixed');
}

Bei dem hier gezeigten Beispiel werden verschieden Funktionen der Reihe nach ausgeführt. Zuallererst werden per initLayer die Objekte, also Divs, auch Links, Images erfasst.

top Luxus für Nr. 4

Nun soll erstmal das nötige Adressieren der Objekte beim Netscape 4 einfacher werden, bis hin zu einer Umsetzung von getElementById. Nach dem Laden Seite stehen alle Objekte zur Verfügung, jetzt ist der Zeitpunkt die Elemente möglichst anwendungsfreundlich zu erfassen. Die positionierten Divs verwaltet Netscape 4 als Layer, und die ganze verschachtelte Hierarchie von Dokumenten und den Dokumenten in den Layern der Dokumente ist zwar nachvollziehbar, würde nach einem verschachteltem Beispiel document.all.Tabelle1.rows(3).cells(2) in der Zeitschrift IP [69] sogar teilweise der Empfehlung des W3C zu DOM Level 1 vom 1. Oktober 1998 nahekommen, ist aber als einzige Ansprechmöglichkeit zu umständlich.

Also wird nach dem Laden der Seite automatisch per JavaScript ein Array der Layer erstellt. Dabei werden in Schleifen die von Netscape bereits angelegten Layer-Arrays durchlaufen, und mit der ID als Index entsteht ein assoziatives Array. Die IDs entsprechen dabei den schon mittels CSS oder JSSS verwandten IDs und natürlich den bei Divs und Spans im HTML-Code angelegten IDs, und das Array verweist auf die entsprechenden Objekte.

getElementById

Und weils gerade so schön ist, werden auch die Bilder, als images, erfasst usw. Nun können anhand der ID bereits Layer über das Array und ohne Kenntnis der Hierarchie angesprochen werden, und mit der Methode getEelementById wird das ganze kompatibel zu modernen Browsern.

function getElementById(dieid){
 window.dieSEid=dieid;
 return getLayerById[dieid];
}

Da verschiedene Verweise auf das gleiche Objekt angelegt werden können, ist es auch relativ einfach möglich, die verschiedenen Ebenen beim DOM auf das gleiche Objekt umzusetzen. Aber auch die erzeugte Methode getElementById kann entsprechend erweitert werden Popup-SeiteGetElementById für Netscape und IE 4 :

document.getElementById=getElementById;

var getLayerById=new Array();
 for(i=0;i<document.layers.length;i++){
ivar= document.layers[i].id;
getLayerById[ivar]=window.document.layers[i];
getLayerById[ivar].style=getLayerById[ivar];
getLinks(ivar);
 for(f=0;f<document.layers[i].document.layers.length;f++){
ivar= document.layers[i].document.layers[f].id;
getLayerById[ivar]=window.document.layers[i].document.layers[f];
getLayerById[ivar].style=getLayerById[ivar];
getLinks(ivar);

Zunächst werden die Layer im document erfasst, dann über die Methode getLinks() die Links, weiterhin Images. Nachdem die Layer also so einfach adressierbar sind, können wir eine Korrektur nach dem Laden der Seite vornehmen, etwa wenn ein Div auf einer längeren Seite unten positioniert sein soll. Um das Beispiel einfach zu halten muss hier nicht das Container Div oder der Body vergrössert werden, das Div wird rechts neben dem Hauptblock positioiniert. Für den Internet-Explorer 4 klappt das auch:

document.all.untenbottom.style.top=document.all.cont.clientHeight-
document.all.untenbottom.clientHeight;

Hier wird der Abstand vom Seitenanfang durch die Höhe des Containerdiv abzüglich der eigenen Höhe des Div festgelegt.

Auch der Ie4 erhält eine Methode getElementById, und beim Netscape 4 wird ergänzend innerHtml realisiert. Um das Paket abzurunden, erhält Netscape 4 noch einen mächtigen iframe Ersatz, der stabil ansprechbar ist. Hilfreich hier wieder das Array, denn damit lassen sich auch Links verwalten, die auf den iframe verweisen.

function getElementById(dieid){
 return document.all[dieid];
 }

top Vererbung

Mit der schon bei anderen Eigenschaften eingesetzten Verwendung von JSSS-Formeln kann eine einfache Vererbung von Eigenschaften automatisch geregelt werden. Allerdings ist es oft einfacher und übersichtlicher im normalen CSS ein paar für andere Browser redundante Einträge zu machen. Für das folgende Thema "innerHTML" muss aber auf jeden Fall per id oder class eine Vererbung simuliert werden. Zunächst ein einfaches Beispiel um Schrift vom Body auf Divs zu vererben:

<style>
 body{ font-size:13.4px; font-family:Arial,sans-serif; }
</style>
<style type='text/javascript'>
 tags.div.fontSize=tags.body.fontSize;
 tags.div.fontFamily=tags.body.fontFamily;
</style>

Auch für die bei einer "a:hover"-Lösung oder bei "innerHTML" benötigten neu erzeugten Elemente bietet es sich an nach oder während der Erstellung des Layer-Array halbautomatisch entsprechende JSSS-Angaben zu machen, hier im Beispiel werden mittels einer Methode addClass_idsid neue Style-classes mit den Eigenschaften der Divs erzeugt. Die spätere Zuordnung erfolgt durch die Bezeichnung 'ids' oder 'hover' plus der ID des Ausgangsdiv:

function addClass_idsid(clDiv){
 classes['ids'+clDiv].TD.fontSize = idDiv.fontSize;
 classes['hover'+clDiv].A.fontSize = idDiv.fontSize;
 classes['ids'+clDiv].TD.fontFamily = idDiv.fontFamily;
 classes['hover'+clDiv].A.fontFamily = idDiv.fontFamily;
 classes['ids'+clDiv].TD.color = idDiv.color;
 classes['ids'+clDiv].TD.paddingTop = idDiv.paddingTop;
}

top innerHTML

Nachdem die Verwendung von getElementById verfügbar ist muss natürlich noch einiges getan werden damit die Anwendung Sinn macht. Entsprechend gilt es für Netscape 4 und gff. IE4 die in Verbindung mit getElementById nötigen oder auch gefragten Methoden und Variablen zur Verfügung zu stellen. Zunächst ein einfaches Beispiel, für DHTML mag es nötig sein z.B. die clientWidth des body unter NC4 abzufragen:

body=new Array();
body.clientWidth=innerWidth-8;
document.body=body;

document.getElementById('rDiv').style.left=
                  document.body.clientWidth-110;

Bei der Methode innerHTML kann man wenn man perfekt damit arbeiten möchte allen verfügbaren Elementen einen Inhalt von innerHTML zuweisen. Einfacher ist es, nur bei Bedarf damit zu arbeiten, dann kann natürlich ein vorhandener Inhalt nicht ergänzt werden. Folgende Vorgehensweise würde das aber erfordern:

getElementById.rDiv.innerHTML+="und dies";

Hier ein Beispiel für die Einbindung von z.B. innerHTML in die Funktion getElementById für den NC4, dabei ermöglicht ein Timeout dass die Methode getElementById erst abgearbeitet wird, das ist schließlich nötig damit getElementById auch solche Variablen gleich verändern kann auf die danach mittels anderer Methoden zugegriffen werden muss:

function getElementById(dieid){
 window.dieSEid=dieid;
 window.dieSEinner=
  getLayerById[window.dieSEid].innerHTML;
 window.setTimeout(doTimeout,9);
 return getLayerById[dieid];
}

Und in der aufgerufenen Funktion können dann verschiedene Veränderungen durchgeführt werden:

getLayerById[window.dieSEid].document.open();
this.document.write('<layer width="'+
getLayerById[window.dieSEid].width+
'" height="'+getLayerById[window.dieSEid].height+
'" id="innnerHTMLlayer">'+
getLayerById[window.dieSEid].innerHTML+

So kann nach dem Timeout die geänderte Eigenschaft innerHTML des Arrays der Elemente eingesetzt werden, natürlich muss das Beispiel ggf. noch um eine Vererbung der Styleeigenschaften erweitert werden. Popup-SeiteinnerHTML für Netscape 4

Lauftext / Ticker

Mit den Werkzeugen getElementById und innerHTML kann nun browserübergreifend gearbeitet werden, als Beispiel ein Lauftext mit einer noscript-Variante und Berücksichtigung von Netscape 6/ Mozilla Popup-SeiteinnerHTML Ticker/Lauftext

top Div onClick

Es gibt doch eine Lösung: Popup-SeiteonClick bei Divs für Netscape 4

top Iframe für Alle

Die Frage ob Frames oder Iframes wünschenswert sind, da gibt es unterschiedliche Auffassungen, ist angesichts des einwandfreien Funktionierens von Iframes bei den neueren Browsern hier kein Thema. Wenn es darum geht den NC4 bei Styles optimal zu bedienen, ist es konsequent, auch den Einsatz von Iframes zu ermöglichen um wirklich allen Browsern einen gleichen Seitenaufbau vorsetzen zu können. Ein Layer-tag ist ebenso unerwünscht wie instabile Konstruktionen mittels <div src=....

Methoden zum Ersatz eine Iframe für Netscape 4 sind zwar bekannt, richtig überzeugen können übliche Methoden aber nicht. Mal ist doch der Layer-Tag im HTML nötig, dann wieder ist es nötig den Ersatz unten am Seitenende einzubauen weil die eingebundene Datei den Aufbau der Hauptdatei stört. Auch die hier bei den schon erfolgten Schritten naheliegende und elegante Variante einer Zuweisung per JSSS funktioniert erstmal sehr gut, erfüllte dann aber bei sehr komplexen Seiten nicht alle Ansprüche an maximale Stabilität:

<style>
 #ifdiv{ position:absolute;
         left:40px;top:160px;
         height:160px;width:160px;
         clip(160,160);
       }
</style>
<style type='text/javascript'>
 ids.ifdiv.includeSource="./sample.html";

Eine einfache Variante per Inlinestyle:

<iframe src="sample.html" frameborder="0">
<div style="include-source:url('sample.html')"></div>
</iframe><

Popup-Seite erfordert Netscape 4

Nun ist diese hier bei includeSource auffallende leichte Instabilität des Netscape 4 darauf zurückzuführen, dass der normale Seitenaufbau verzögert oder unterbrochen wird, und dass der Inhalt der eingebundenen Datei mit dem Seitenaufbau interferiert. Das ist manchmal durch eine Kontrolle des vom Browser angezeigten Quelltextes und darin erkennbaren Fehlern sichtbar, oder es kann aus der nicht vollständigen, oder sehr langsam arbeitenden Ladeanzeige im Browser unten links vermutet werden. Netscape 4 bindet den Code aus der Quelle eben zu direkt in die Seitenstruktur ein, includeSource ist deshalb zur Einbindung von HTML-Dokumenten weniger geeignet, spätestens nach dem </body> der eingebundenen Datei wird es schwierig.

Iframe II

Da das hier entwickelte CSS-Konzept sowieso eine Nachkorrektur per JavaScript oder DHMTL vorsieht, etwa wenn der Body grösser ist als das Window, bietet es sich an auch beim Iframe erst nach dem Laden der Seite die externe Datei einzubinden. Zugleich haben wir nach dem Laden der Seite wieder mehr Freiheiten netscapespezifisch zu arbeiten, schließlich können nachträglich ohne Probleme mit dem validen HTML-Code neue Layer dynamisch erzeugt werden. Und wie schon erwähnt ist JavaScript beim Netscape 4 recht verlässlich, meist sicherer als bei anderen Browsern, und laut Webstatistiken haben nur 0.1% der Surfer Script deaktiviert, beim Netscape sowieso unwahrscheinlich da ja alle CSS-Fähigkeiten verloren gingen. Besonders vorsichtige Naturen können letztendlich noch eine Ergänzung per <noscript> alternativer Link/Hinweis </noscript> einbinden. Popup-Seite

Die hier entwickelte Lösung ist also anders als bekannte Verfahren, aber hinreichend einfach, und bei allen Versuchen zumindest mit den eingebundenen Testdateien, absolut stabil. Der eigentliche Iframe wird in Div positioniert.

<!-- object data="./hallo1.htm" type="text/html"></object -->
<div id="miframe">
<iframe name="hFrame" src="hallo1.htm" frameborder="0">
</iframe></div>

Wieder basiert das Konzept auf JavaScript, was ja beim NC4 sowieso naheliegt. Mittels document.write wird nach dem Laden der Seite das Div mit dem iframe angesprochen.

function initIframe(owDiv, inIfr){
sbHoehe=parseInt(getLayerById[owDiv].clip.bottom);
sbLeft=parseInt(document.ids[owDiv].width);
getLayerById[owDiv].document.write('<LAYER'+
' z-index='+(document.ids[owDiv].zIndex)+
' clip="0,0,'+sbLeft+10+','+sbHoehe+'" width='+sbLeft+
' height="'+sbHoehe+'" top=0 left=0'+
' onload="if(this.document.height>(sbHoehe*1+10))'+
'this.parentLayer.layers[1].visibility=\'show\';'+
' else if(this.parentLayer.layers.length>1)'+
'this.parentLayer.layers[1].visibility=\'hide\';"></LAYER>'+
'<LAYER visibility="hide" z-index='+
(document.ids[owDiv].zIndex+1)+' id=navi name="navi"'+
' clip="0,0,16,'+sbHoehe+'" width=16 height="'+sbHoehe+
'" top=0 left='+sbLeft+''+
' bgcolor="#ececec">'+
'<a href="javascript:void(0)"'+
' onMouseDown={timerS=window.setInterval("scrollen(\'+2\',\''+
owDiv+'\')",44)}'+
' onMouseOut="if(window.timerS)clearInterval(timerS);"'+
' onMouseup="if(window.timerS)clearInterval(timerS);"><img'+
' src="./images/12bue.gif" border=0 hspace=0 width=16 height=16'+
' vspace=0></a><spacer type="block" width="16" height="'+
(sbHoehe-32)+'"><a'+
' href="javascript:void(0)"'+
' onMouseDown={timerS=window.setInterval("scrollen(\'-2\',\''+
owDiv+'\')",44)}'+
' onMouseOut="if(window.timerS)clearInterval(timerS);"'+
' onMouseup="if(window.timerS)clearInterval(timerS);"><img'+
' src="./images/12bde.gif" border=0 hspace=0 width=16 height=16'+
' vspace=0></a>'+
'</LAYER>');
getLayerById[owDiv].document.close();
setTimeout("getLayerById['"+owDiv+"'].document.layers[0].load('"+
inIfr+"',getLayerById['"+owDiv+"'].clip.width);",9);
}

Dabei ist, der zweite erzeugte Layer, auch eine Scrollmöglichkeit berücksichtigt falls die eingebundene Datei eine grössere Fläche benötigen würde. Aus Gründen der Ökonomie wird hier nur ein Code für vertikales Scrollen gezeigt, der im Weiteren entsprechend kompakt ausfällt:

function scrollen(richtung , owDiv){
 scrollDies=getLayerById[owDiv].document.layers[0];
 scrollMax=scrollDies.document.height-
 getLayerById[owDiv].clip.height-16;
 scrollBar=scrollDies.document.layers[0];
 if((scrollBar.top==0)&&(richtung>0))richtung*=0;
 if((scrollBar.top<scrollMax*-1)&&
 (richtung<0))richtung*=0;
 scrollDies.clip.height=scrollDies.clip.height-(4*richtung);
 scrollBar.top=scrollBar.top+(4*richtung);
}

Endlich ist ein stabiler Ersatz für Iframe realisiert, der nicht aus Sorge um den gestörten weiteren Inhalt der Seite möglichst am Ende des HTML-Code stehen muss. Dieses den Iframe einschliessende Div wird zu Positionierung für alle Browser genommen. Beim Netscape 4 wird nach dem Laden der Seite der Inhalt des Div verändert, zunächst wird ein Layer erzeugt, dann diesem Layer der Inhalt zugewiesen. Dabei erhält der iframe-Ersatz noch optionale Scrollbalken, bei kompaktem Quelltext, auch ein Aspekt. Es zeigt sich dass es doch Sinn machen kann auf verfügbare Bibliotheken zu verzichten, denn in bekannten JavaScript-Sammlungen bringen es Scripte a la "scrollable.js" auch mal locker auf 32k statt wie hier gezeigt nur 2k Code.

Aber es ist noch mehr möglich. Bei dem Erstellen des Arrays der Elemente und der Ersatzmethode getElementById der geladenen Seite können auch die in der Seite vorhandenen Links erfasst werden. Dabei kann hier das vom Browser verwaltete Ziel eines Links ausgelesen und verändert werden. Automatisch kann beim Erkennen eines vorgegeben Target eine JavaScript-Sequenz als Link-Adresse eingegeben werden:

function getLinks(ivar){
 for(n=0;n<getLayerById[ivar].document.links.length;n++)
 { derLink=getLayerById[ivar].document.links[n];
   derLink.parentLayerId=ivar;
  if(derLink.target=='hFrame'){
   derLink.target="";derLink.status=derLink.href;
   derLink.href="javascript:getLayerById['miframe']."+
    "document.layers[0].load('"+
    getLayerById[ivar].document.links[n].href+
    "',getLayerById['miframe'].clip.width);void(0);"
}}}

Eine schlankere Version ermöglicht Netscape 4 einen automatischen scrollbaren Iframe bei ingesamt 5k Code Popup-Seite Iframe für Netscape 4 per Script

Iframe Ilayer

Zum Verständnis für die eben dargelegte Lösung Iframe II (ohne Layer-Tags und mit automatisch generierten Scrollbalken) habe ich noch eine Lösung per Layer entwickelt: Popup-Seite

<iframe src=xy.htm width=300 height=300 scrolling="no" border=1>
<ilayer id=ilay name=ilay  width=302 height=302 clip="302,302" bgcolor="silver"
margin=1>
<layer name=iframe top=1 left=1 id=iframe width=300 height=300 clip="300,300"
bgcolor="white">
</layer></ilayer>
<script>
if(document.layers){window.onload=function(){
document.layers[0].document.layers[0].load('xy.htm',300);}}
</script>
</iframe>

Iframe III

Schließlich empfiehlt es sich oft, für Netscape 4 dynamisch per JavaScript eine HTML-Variante mit Frameset zu erstellen. Gerade die Kombination von Iframe mit der Positionierung fixed kann unter Browsern wie Opera oder Mozilla Konzepte klassischer Frames ersetzen. Für die Browser IE5 bis IE6 gibt es Möglichkeiten per CSS fixed nachzubilden, siehe auch das Beispiel im folgenden Abschnitt Position fixed nach unten. Per JavaScript kann beim Laden der Seite für NC4 eine Variante mit Frameset aufgebaut werden. Während es bei fixed gilt, in das erzeugte Frameset die gleiche Ursprungsdatei zweimal zu laden, werden beim Iframe natürlich zwei verschiedne Dateien geladen. Popup-Seite Iframe für Netscape 4 durch ein erzeugtes Frameset

if(document.layers){
 if(top.frames.length==0){
  document.write('</head><frameset ....

Auch hier bietet es sich für den Fall der Fälle an, eine <noscript>-Variante einzuplanen, allerdings benötigt leider der noscript-Tag unter NC4 noch etwas Nachsorge, ein nachfolgendes Dummy-Tag oder die Einbindung in einen geeigneten tag, oder eine günstigere Position (2).

<iframe ..> <noscript> <a href=..> ... </a> </noscript>
<ilayer ..><layer ..></layer><ilayer>
<script>  ..  </script></iframe>

<iframe ..> <ilayer><layer ..></layer><ilayer>
<noscript> <a href=..> ... </a>  </noscript>
<script> .. </script></iframe>

Eine ordentliche Weiterleitung etwa mittels eines entspr. eingebundenen Meta-Tags erscheint dabei zunächst natürlich konformer als im eigentlichen Iframe doch den netscapespezifischen Layertag einzusetzen, allerdings sollte nach W3C der noscript Tag eigentlich nicht im head einer HTML-Datei stehen.

<noscript>
<meta http-equiv="refresh" content="0; URL=./noscript.html">
</noscript>

So ist eine einfache Einbindung der Iframe-Datei in einem Noscript-Bereich möglich, falls beim Netscape 4 JavaScript deaktiviert sein sollte und das Frameset nicht erstellt wird:

<div id="dIframe">
 <iframe id="ifr1" src="xy.html" scrolling=no border=0>
  <noscript>
   <ilayer><layer src="xy.html"></layer></ilayer>
  </noscript>
 </iframe>
</div>

Konformer wäre z.B. folgende Lösung:

<div id="dIframe">
 <iframe id="ifr1" src="xy.html" scrolling=no border=0>
  <noscript>
   <a href="xy.html"> Kommentar </a>
  </noscript>
 </iframe>
</div>

top overflow auto

Nicht mit genau der gleichen Methode wie beim Iframe, aber recht ähnlich ist es möglich overflow:auto umzusetzen, ebenfalls abhängig von der Grösse des Inhalts wird ein Scrollbalken generiert, falls overflow:auto gesetzt ist. Popup-Seite

function scrollov( richtung , owDiv, sbHoehe ) {
 scrollDies = getLayerById[owDiv];
 if(!(scrollDies.clip.top==0)&&( richtung > 0 )||
 !(scrollDies.clip.top>scrollDies.document.height-
 sbHoehe-10 ) && ( richtung < 0 ))
  with( scrollDies ) {
   top-=(-4 * richtung );
   clip.top+=(-4 * richtung );
   resizeBy(0,(clip.top));
} else clearInterval(timerS);
}

Auch hier ist das automatische Erfassen der Divs möglich:

if(document.ids[ivar].overflow=='auto'){
if(getLayerById[ivar].document.height>
document.ids[ivar].height)ovscroll(ivar);
else getLayerById[ivar].resizeTo(parseInt(document.ids[ivar].width)*1+
16,parseInt(document.ids[ivar].height));
}

top Position Fixed DHTML

Um das Paket vollständig zu machen, noch die Styleeigenschaft position:fixed; nicht wie bereits im Abschnitt Position Fixed CSS nach oben gezeigt mittels CSS und JavaScript für Netscape 4, sondern per DHTML als Lösung per JavaScript und expression. Ähnliche Scripte zur Nachpositionierung für Netscape 4 sind zwar schon gezeigt worden, ich kenne aber nur sehr voluminöse Bibliotheken und deswegen gibt es auch hier meine kompakte Lösung: Popup-Seite Position Fixed DHTML

function initPfixed(pId){
lastY=parseInt(document.ids[pId].top);
doit = window.setInterval("doPfixed('"+pId+"',"+lastY+")",99);}

function doPfixed(pId,oldTop){
winY = window.pageYOffset;
if (winY!=lastY&&winY>-oldTop)step = winY-lastY+oldTop;
else if (lastY>0)step=lastY; else step=0;
getLayerById[pId].top=parseInt(getLayerById[pId].top)+step;
lastY+= step;}

Der Verzicht auf einen schnellen weichen Übergang ist beabsichtigt, der relativ langsame Interval schont die Ressourcen, und schnellere Abläufe ergeben oft sowieso keinen angenehmeren Eindruck.

Ein zusätzliches Div um für die IE-Versionen 5-6 Position fixed zu simulieren erhält die wenigen nötigen Styleangaben am besten in einem separaten Styleabschnitt wie schon im Kapitel Browserweichen nach oben ausgeführt; z.B. per <!--[if lt IE 7]> wird ein IE 7 oder grösser, der "position fixed" mit hoher Wahrscheinlichkeit beherrschen würde, vorsorglich ausgeschlossen.

Bei dem Code der Beispieldatei wird von Netscape Communicator 4 und Internet Explorer 4 die vorgegebene Eigenschaft position:fixed nachträglich auf absolute gesetzt, um das Div dann als Objekt per JavaScript nachzupositionieren. Statt eines Eventhandlers onscroll ist hier für beide Browser setInterval mit regelmäßigen Abfragen der Seitenposition zum Window der Korrekturauslöser. Vorteilhaft ist hier auch dass das normale Stylesheet mit fixed einfach allen berücksichtigten Browsern zugänglich ist, ein automatisches Erkennen der Divs wäre dabei auch vorstellbar. Für andere Browser oder einen IE4 mit deaktiviertem JScript ist aber dann ggf. sicherzustellen dass der Browser ein position:absolute vorfindet, Vorgehensweisen finden sich z.B. beim Unterkapitel Browserweichen IE3? nach oben.

Zuletzt soll noch der Hinweis wegen der bereits ausgeführten möglichen Probleme, auch bei den expression, zurückhaltend mit DHTML zu arbeiten. Zu den Problemen der geringeren Stabiliät kommt noch ein unergonomischer Eindruck, wie ja auch das Scrollen bei den IE4 und NC4-Lösungen von der Lästigkeit her weniger empfehlenswert ist als etwa die vorher gezeigte Framelösung.

top mouseover

Weiteres

Aus dem Katalog der möglichen Sollanforderung ist zunächst noch die Lösung für onmouseover und onmouseout bei Divs zu nennen, eine nicht W3C valide Lösung mittels zusätzlicher Layer-Tags ist ja schon als Beispiel im Abschnitt Crossbrowserstrategien nach oben vorgestellt worden. Das Thema überschneidet sich auch mit der Stylevariante a:hover, die zumindest bei Text und Farbeffekten ähnlich einer bekannten Lösung von Andreas Zierhut[46] nach unten. per JavaScript erfolgen kann. Beide Anwendungen lassen sich durch das Array getLayerById oder getElementById einfacher und sicherer anwenden. Das Beispiel mouseover für Divs wird etwas ausführlicher dargestellt, weil sich die Varianten für verschiedene Browser gut ergänzen können, ohne dass hier Anspruch auf Vollständigkeit erhoben wird. Zunächst die Ergänzung für Netscape 4, die im JavaScript und teilweise nach Laden der Seite erfolgt:

function layer1MouseOver (e){
 getLayerById['ru0'].visibility="visible"; }
function layer1MouseOut (e) {
 getLayerById['ru0'].visibility="hidden";  }
function initMover() {
 getLayerById['sampl'].onMouseOver=window['layer1MouseOver'];
 getLayerById['sampl'].onMouseOut =window['layer1MouseOut'];
}

Die Eventhandler nutzen das komfortable Array und benötigen auch keine Netscape-Syntax bei visibility. Im HTML-Code wird hier einfach beim Div ein onmouseover für die InternetExplorer formuliert, wobei natürlich zu bedenken ist dass Opera auch document.all anwenden mag.

<DIV id="sampl"
 onMouseOver="document.all.ru0.style.visibility='visible'"
 onMouseOut="document.all.ru0.style.visibility='hidden'">

Zuletzt die CSS-Angaben mit der Lösung für modernere Browser per CSS: Popup-Seite

#ru0{position:relative;visibility:hidden;}
#sampl:hover>#ru0{visibility:visible;}

a:hover

Bei der von mir entwickelten DHTML-Lösung für a:hover, s.o., ist endlich die Problematik des Layer-Modells gelöst, einerseits lässt es sich auf bestimmte Divs anwenden, und andererseits ermöglichen die verschiedenen Methoden wie das Layer-Array die bessere Positionierung. Auch hier ist natürlich die Style-Vererbung sicherzustellen bzw. durch geeignete Funktionen zu erzeugen. Schließlich bietet sich ein dynamisch erzeugter Hover-Layer auch zur Anpassung der Statuszeile beim Überqueren von Links auf den Iframe an.

function initHover(){
getLayerById['sampl'].document.captureEvents(Event.MOUSEOVER);
getLayerById['sampl'].document.onmouseover=hoverOn;
window.hoverLayer=new Layer(100);
}

So können komfortabel bestimmte Divs ausgewählt werden, etwa um Probleme zu vermeiden, ob nun die Styleangaben zu komplex sind um pixelgenau zu treffen, oder ob ein Aufklappmenu die Scripte und mouseovers überfordern würde. Nun muss noch entschieden werden ob man meint von jedem Layer die Position in der Seite erfassen zu können oder die beim Erstellen des Arrays erfasst, hier eine, verkürzt dargestellte, Möglichkeit die Position zu berechnen:

hoverLink=e.target;
inLayer=getLayerById[hoverLink.parentLayerId];
hoverLayer.left=hoverLink.x+
inLayer.left+inLayer.parentLayer.left;

Hier wird auf Netscape-Synatx entsprechend dem Layermodell zurückgegriffen, um bei wenig verschachtelten Layern sicher und möglichst auf gleichem Weg wie beim Seitenaufbau zur Position zu gelangen.

top quod erat demonstrandum?

Zumindest wird deutlich, CSS für ältere Browser ist möglich. Beim NC4 ist JavaScript relativ sicher und sowieso Voraussetzung für CSS, also Netscape 4 macht's. Und ohne nennenswerten Einfluss auf die jeweilige Seite oder den HTML Code selbst. CSS Layout für Netscape 4 ist nunmehr umfassend möglich. Dabei bleiben die Seiten W3C-kompatibel, und die Einbindung der Scripte findet an einer Stelle statt, der HTML-Code bleibt von JavaScripten usw. oder anderen invaliden Tricksereien verschont. Netscape 4 kann mit den wichtigsten Methoden der neuesten Browser angesprochen werden, getElementById ist für Mouseover-Effekte ebenso möglich wie die Verwendung von right: in der CSS-Datei oder overflow:auto.

Natürlich bleiben Defizite bei den älteren Browsern, und mancher Aufwand wie etwa eine perfekte a:hover Lösung oder der Kampf um den verbleibenden einen Pixel Randabstand bei Netscape 4 ist oft gar nicht nötig. Wichtig ist aber vor allem, dass man Netscape 4 Tableless Layout zumuten kann, auch ohne bei der Reihenfolge von Elementen in der Seite festgelegt zu sein, und dass mit den Korrekturen bei Listen usw. viele Einschränkungen bei der richtigen Wahl der HTML-Tags wegfallen.

top Layout a la W3C

Schließlich lässt sich auch das Beispiel des W3C http://www.w3.org/2002/03/csslayout-howto entsprechend den hier gezeigten Möglichkeiten ergänzen, wichtig ist aber bei der mir bekannten Musterseite eine Beachtung der unnötigerweise als Inlinestyle -der einzige Inlinestyle in der betr. Datei- formulierten Anweisung style="float: left;" bei der Grafik, die gut in der externen CSS-Datei stehen könnte oder einfach im Head:

<style>
 #layout #content p img{  float: left;} 
</style>

Natürlich tut es sowieso auch eine Anweisung align=left im Image-Tag, solange man als Doctype Transitional verwendet. Zur Demonstration wie grundsätzlich ohne Änderung des eigentlichen HTML- oder CSS-Code, insofern ohne Rücksicht auf ältere Browser, nachträglich eine zwar nicht pixelgenaue, doch grundsätzlich stimmige Ergänzung möglich ist, zeige ich hier die im Detail noch verbesserungsfähigen Scriptteile exemplarisch. Der letzte Eintrag ..align="left" ergänzt den Inlinestyle für NC4, der dann im Code verbleiben kann. Noch zuverlässiger für Netscape 4 wird solch eine Lösung, wenn die JSStyles ebenfalls in eine externe Datei ausgelagert werden, also auch in einer Partie abgearbeitet werden, falls es nicht sowieso möglich ist die externe CSS-Datei direkt und ohne JavaScript einzubinden.

<script type="text/javascript">
if(document.all&&!document.getElementById){
document.writeln(
'<link type="text/css" rel="stylesheet" href="csslayout-style.css">');
document.write(
'<style>#layout{width:100%}<\/style>'); /* ie 4 abfragbare Breite */
function loadInits(){
document.all['list2'].style.left=(document.all['layout'].clientWidth+170)+'px';
} window.onload=loadInits;
} else if(document.layers){
document.writeln(
'<link type="text/css" rel="stylesheet" href="csslayout-style.css">');
}
</script>

<style type="text/javascript">
ids.list2.left=innerWidth-parseInt(ids.list2.right)-170;
with(contextual(ids.list1, tags.DIV)){width='155px';borderColor='#000066';}
with(contextual(ids.list2, tags.H3)){paddingRight='20px';
                                     whiteSpace='pre';borderWidths('0.1');}
contextual(ids.list1, tags.H3).borderWidths('0.1');
contextual(ids.list1, tags.H2).lineHeight='0px';
with(tags.DIV){fontFamily="sans-serif";fontSize="90%";}
tags.H2.fontSize="120%";
tags.H1.fontSize="160%";
ids.list1.layerBackgroundColor='#000066';
contextual(ids.list1, tags.P).fontSize="85%";
ids.list2.layerBackgroundColor='#000066';
contextual(ids.list2, tags.DIV).borderColor='#000066';
contextual(tags.UL, tags.A).fontSize="85%";
with(contextual(ids.list1, tags.UL)){
                    fontSize="85%";paddingLeft="-30px";marginLeft="-30px";}
with(contextual(ids.list2, tags.UL)){
                    fontSize="85%";paddingLeft="-30px";marginLeft="-30px";}
 contextual(tags.P, tags.IMG).align="left";
</style>

Die Korrektur beginnt nach der Einbindung des Stylesheet mit der Festlegung der Position der rechten Spalte "List2" in Pixel vom linken Rand, Maßstab ist beim IE4 die Breite -nach dem Laden der Seite- des Elements "layout", beim NC4 innerWidth, abzüglich der eigenen Breite von "list2", hier auch der Einfachheit halber mit 170px. Für den IE ist noch vor dem Seitenaufbau per CSS die Breite von Layout mit 100% als Objekteigenschaft erstmal abfragbar zu machen. Für einige ältere Versionen des NC4 wird vorsorglich die Breite von "list1", der linken Spalte, angegeben, und mit whiteSapce wird ein ähnliches Problem bei der rechten Spalte geregelt, indem H3 indirekt eine Mindestbreite erhält.

top Fazit

Die Fähigkeiten von Browsern lassen sich erheblich unterstützen, und der Mehraufwand sich mit den älteren Browsern zu beschäftigen wird oft schon durch die frühere Umsetzung eines zukunftstauglicheren Konzeptes wieder wettgemacht, und ohne damit gleich Kunden oder Besucher zu verprellen, schließlich sind ältere Browser auf vielen Seiten noch sehr deutlich in der Besucherstatistik zu finden.

Bereits ganz ohne JavaScript-Tricks lässt sich z.B. ein dreispaltiges Layout per CSS für "alle Browser" realisieren, auch andere Probleme lassen sich bereits ohne oder mit sehr einfachen validen CSS-Strategien oder -Weichen lösen. Mit dem Einsatz von JSSS und JavaScript kann dann nochmal nachgelegt werden, und wem die Netscape 4 spezifischen JSStyles zu fremd sind, der kann auch per JavaScript und CSS ähnlich vorgehen, wie verschiedene Beispiele, etwa zum Problem einer Tabelle über die ganze Seite, zeigen.

Doch so wie einserseits die Berücksichtigung älterer Browser recht gut möglich ist zeigen sich aber andererseits auch grundsätzliche Unzulänglichkeiten der heute bei modernen Browsern anwendbaren CSS-Anweisungen. Gerade bei dem Browser mit dem höchsten Marktanteil kann eine saubere Anwendung von CSS und die strenge Umsetzung eines "Sematic Web" da zu einem zu unflexiblem Layout oder einem Verhau von CSS-Weichen mit unschönem HTML, Container-Divs und Hilfselementen führen, wo vielleicht eine einfacher Table-Tag mit weniger Code mehr bewirkt hätte.

top Index

Nachtrag

Z. Zt. nicht verfügbar

top Informationsquellen

  1. WebHits - Internetstatistiken
    Externe Seite http://www.webhits.de/deutsch/index.shtml?/deutsch/webstats.html
  2. Google Webaccess
    Externe Seite http://www.google.com/press/zeitgeist/zeitgeist-oct02.html
  3. Zugänglichkeitsrichtlinien für Web-Inhalte 1.0
    Externe Seite http://www.w3.org/Consortium/Offices/Germany/Trans/WAI/webinhalt.html
  4. Web Content Accessibility Guidelines 1.0
    Externe Seite http://www.w3.org/TR/WAI-WEBCONTENT/
  5. w3.org/TR/WCAG10/full-checklist.html
    Externe Seite http://www.w3.org/TR/WCAG10/full-checklist.html
  6. Tableless layout
    Externe Seite http://www.w3.org/2002/03/csslayout-howto
  7. JavaScript-Based Style Sheets
    Externe Seite http://www.w3.org/Submission/1996/1/WD-jsss-960822.html
  8. JavaScript-Accessible Style Sheets
    http://developer.netscape.com/library/documentation/communicator/stylesheets/jssindex.htm
  9. netscape.com/library/documentation/jsstyles
    http://developer.netscape.com/library/documentation/jsstyles.html
  10. Using JavaScript Expressions as HTML Attribute Values
    http://developer.netscape.com/docs/manuals/js/client/jsguide/embed.htm
  11. Using JavaScript-Accessible Style Sheets
    http://developer.netscape.com/library/documentation/communicator/jsstyles/jindex.htm
  12. Working with Objects
    http://developer.netscape.com/docs/manuals/js/client/jsguide/obj.htm#1008312
  13. Dynamic HTML in Communicator
    http://developer.netscape.com/docs/manuals/communicator/dynhtml/jss3.html
  14. JSBible3
    Externe Seite http://developer.netscape.com/viewsource/goodman_roadmap/jsbible3/NS4_Obj.pdf
  15. DevEdge Online - Online JavaScript Reference Manual
    http://developer.netscape.com/docs/manuals/communicator/jsguide4/index.htm
  16. DevEdge Online - Dynamic HTML Manual
    Externe Seite http://developer.netscape.com/docs/manuals/communicator/dynhtml/index.htm
  17. Introducing Visual DHTML
    Externe Seite http://developer.netscape.com/docs/examples/dynhtml/visual/index.html
  18. Document Object Model (DOM)
    Externe Seite http://www.w3.org/DOM/
  19. Document Object Model (DOM) Level 1 Specification
    Externe Seite http://www.w3.org/TR/REC-DOM-Level-1/cover.html
  20. Netscape Standards Challenge
    Externe Seite http://www.netscape.com/browsers/future/standards.html
  21. About Conditional Comments
    Externe Seite http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp
  22. Microsoft Chaat Sheet
    Externe Seite http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie50/html/cheatsheet.asp
  23. Tables in HTML documents
    Externe Seite http://www.w3.org/TR/html4/struct/tables.html
  24. JavaScript: W3C DOM Category
    http://dmoz.org/Computers/Programming/Languages/JavaScript/W3C_DOM/
  25. Layer Emulation API for Mozilla
    Externe Seite http://devedge.netscape.com/toolbox/examples/2002/xb/layer-emulation/
  26. STYLE SHEETS KNOWN ISSUES
    Externe Seite http://developer.netscape.com/support/bugs/known/css.html
  27. Hide Styles from NN4
    Externe Seite http://www.sam-i-am.com/work/sandbox/css/hide_styles_from_nn4.html
  28. Box Model Hack
    Externe Seite http://tantek.com/CSS/Examples/boxmodelhack.html
  29. Communicator and disk cache
    Externe Seite http://help.netscape.com/kb/consumer/19970613-1.html
  30. Index of /pub/communicator/english
    Externe Seite http://ftp.netscape.com/pub/communicator/english/
  31. Directory /
    Externe Seite ftp://ftp.netscape.com/pub/communicator/english/4.8
  32. Using JavaScript expressions as HTML attribute values
    Externe Seite http://wp.netscape.com/eng/mozilla/3.0/handbook/javascript/getstart.htm#1016301
  33. Internet Explorer 4
    Externe Seite http://www.microsoft.com/brasil/pr/ie4_unix.htm
  34. The Ultimate JavaScript Client Sniffer
    Externe Seite http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html
  35. DHTML Object Model Support for Data Binding
    Externe Seite http://msdn.microsoft.com/workshop/author/databind/objmodel.asp
  36. Internet Explorer
    c't 25/2002, Heise Vlg. Hannover, S. 100; Externe Seite http://www.heise.de/ct/02/25/100/
  37. Testversionen
    DerEntwickler 2/2000, Software & S. Vlg, Frankfurt, Leser CD
  38. Kalte Dusche
    iX 1/2001, Heise Vlg Hannover, S. 46
  39. Rivalen mit Macken
    PC Profess. 02/2001, VNU Zeitschriften München, S. 140
  40. talkback / NC4
    Externe Seite http://groups.google.de/groups?hl=de&lr=&ie=UTF-8&selm=382E13F2.7193F61D%40chello.at
    Externe Seite http://groups.google.de/groups?selm=3702037D.9439B48A%40FernUni-Hagen.de&output=gplain
  41. Report: Usability
    Screen Business Online 01/2001, MACUp Verlag Hamburg, S. 63
  42. How do I turn off the Netscape Quality Feedback Agent?
    Externe Seite http://help.netscape.com/kb/consumer/19990211-5.html
  43. How can I remove AIM (AOL Instant Messenger)?
    Externe Seite http://help.netscape.com/kb/consumer/19971116-8.html
  44. Opera Software NORWAY
    Externe Seite http://www.opera.no
  45. W3C's Editor/Browser
    Externe Seite http://www.w3.org/Amaya
  46. Positionierung von Layern (DHTML)
    http://www.t-online.de/home/andreas.zierhut/
  47. JavaScript 1.5
    Externe Seite http://www.mozilla.org/js/js15.html
  48. Core JavaScript Guide 1.5: 5 Statements
    Externe Seite http://developer.netscape.com/docs/manuals/js/core/jsguide15/stmtsov.html
  49. A way to hide styles from all browsers but IE5 Mac
    Externe Seite http://www.premonition.co.uk/cssd/ie51-only.html
  50. Introduction to the DOM of IE 5/ NS 6
    Externe Seite http://wsabstract.com/javatutors/dom6.shtml
  51. Semantic Web Road map
    Externe Seite http://www.w3.org/DesignIssues/Semantic.html
  52. Interpretation and Semantics on the Semantic Web
    Externe Seite http://www.w3.org/DesignIssues/Interpretation.html
  53. The Semantic Web as a language of logic
    Externe Seite http://www.w3.org/DesignIssues/Logic.html
  54. Internet World Listings
    http://www.internetworld.de/iw/magazin_listings_0500.htm
  55. Webhits
    http://www.webhits.de/webhits/inetstat.htm
  56. CSS1 Test Suite
    Externe Seite http://www.w3.org/Style/CSS/Test/CSS1/current/index.html
  57. Opera downloads
    http://www.opera.no/downloads/
  58. JavaScript Weirdness
    Externe Seite http://webdevelopersjournal.com/articles/javascript_limitations.html
  59. Determining Browser Type and Version with JavaScript
    http://developer.iplanet.com/docs/examples/javascript/browser_type.html
  60. Praxis Web-Design
    c't 20/2001, Heise Vlg. Hannover, S. 226;
  61. Apache Guide: Advanced SSI Techniques
    Externe Seite http://www.serverwatch.com/tutorials/article.php/1126091
  62. The Ultimate JavaScript Client Sniffer
    Externe Seite http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html
  63. JavaScript, David Flanagan
    O'Reilly, 1.Auflage Köln 1997, E.3 JavaScript-Stilvorlagen
  64. Conditional Comments, Radio Buttons Michael Wallent Microsoft Corporation, 1998
    Externe Seite http://msdn.microsoft.com/library/default.asp?URL=/library/en-us/dndude/html/dude071798.asp
  65. Positioning HTML Elements with Cascading Style Sheets W3C Working Draft
    Externe Seite http://www.w3.org/TR/WD-positioning
  66. Conditional Comments and the <NOLAYER> Tag, Netscape Communications 1997.
    Externe Seite http://jeff.sci.shu.ac.uk/Refdocs/JavaScript/ver1.2/layers/layers24.htm
  67. The <LAYER> and <ILAYER> Tags 1997, Netscape Communications 1997.
    Externe Seite http://jeff.sci.shu.ac.uk/Refdocs/JavaScript/ver1.2/layers/layers23.htm
  68. Working with Objects Chapter 7
    Externe Seite http://devedge.netscape.com/library/manuals/2000/javascript/1.3/guide/obj.html
  69. Document Object Model
    Internet Professionell 12/98, S. 98, Ziff-Davis Vlg. München.
  70. Media Queries, W3C
    Externe Seite http://www.w3.org/TR/2001/WD-css3-mediaqueries-20010517/

top