Umlaute, JQuery, Ajax, Formulare und PHP

Wir setzen im Rahmen unserer Web-Projekte neben dem serverseitigen PHP natürlich auch JQuery auf der Javascript-Seite ein – zunehmend auch, um in unsere CM-Applikationen ajax-basierte Features zu integrieren.

Gerne würden wir alles – Webseiten, JQuery/Ajax, PHP-Programme, MySQL etc. – stromlinienförmig auf UTF-8 ausrichten. Aber das geht leider nicht immer. Teils aus historischen Gründen, teils weil man es kundenseitig mit Apache-Webserver-Installationen zu tun bekommt, die per “AddDefaultCharset”-Directive auf ISO-8859-1 als Standard-Character-Set eingestellt sind, teils aber auch, weil man nicht beliebig an den vorgefundenen Datenbanken herumdrehen kann.

In diesem Umfeld stolpere ich dann ab und zu in das eine oder andere Problem mit Umlauten – zuletzt tatsächlich mal wieder im Zusammenhang mit den Ajax-Tools von JQuery. JQuery/Ajax kann in einem serverseitigen ggf. heterogenen Zeichensatz-Umfeld durchaus für Überraschungen sorgen. So sind im Internet haufenweise Fälle beschrieben, in denen eine bislang laufende PHP-Anwendung nach dem Einsatz von JQuery/Ajax z.B. deutsche Umlaute in den üblichen kryptischen Zeichensalat verwandelt hat, der bei einer ungewollten Zeichensatz-Konversion halt entsteht. Links zu Beispielen findet man weiter unten.

Nachfolgend deshalb ein paar Hinweise darauf, warum und wann man beim Einsatz von JQuery/Ajax aufpassen muss, und wie man mit den eventuell resultierenden Problemen umgehen kann. Auf Code-Beispiele habe ich verzichtet, da die Kenntnis der Problemursache einem Entwickler i.d.R. schon zeigt, was er zu tun hat. Ich hoffe, die Ausführungen sind trotzdem für den einen oder anderen, der sich mit JQuery, PHP und Umlauten herumschlagen muss, nützlich.

Ich rede nachfolgend übrigens nur über Systeme, in denen ISO-8859-1 bzw. Latin1-Zeichensätze sowie der UTF-8-Zeichensatz eine Rolle spielen.

Problemseparation: Klassische Umlautprobleme aufgrund von Webserver, PHP- und MySQL-Einstellungen

Es ist wichtig, JQuery/Ajax-induzierte Umlautprobleme von anderen Umlaut-Problemen bei Einsatz von PHP-Anwendungen abzutrennen.

Umlaute sind im PHP-, MySQL-Umfeld auch ohne JQuery von Haus aus ein Thema, das eine gewisse Komplexität aufweisen kann:

Dies liegt daran, dass neben Einstellungen des Webservers und neben der php.ini-Konfiguration natürlich auch die Zeichensatz-Einstellungen des Datenbankservers eine Rolle spielen.

Zeichensätze spielen grundsätzlich eine essentielle Rolle im Datenaustausch zwischen Client- und Serverkomponenten einer Applikation – also bei der Client/Server-Kommunikation. Hier gelten zwischen Web-Client und Web-Server Regeln und Konventionen, die man u.U. mit geeigneten Mitteln beeinflussen kann. Server und Client können sich im Rahmen bestimmter Protokolle in vielen Fällen auch darüber informieren, welchem Zeichensatz die eben ausgetauschten (Web-Daten) unterworfen sein sollen und wie die Daten dementsprechend vom Empfänger zu interpretieren und darzustellen sind.

In manchen Fällen gelten aber auch harte Regeln, die man dann schlicht kennen muss. Wie wir sehen werden, liefert JQuery/Ajax u.U. für letzteres ein wichtiges Beispiel.

(Hinweis zur Sicherheit: Ich spreche hier bei der Betrachtung der Web-Server-Client-Kommunikation nicht von URL-Encoding oder ähnlichem, sondern davon, welchem Zeichensatz die empfangenen Daten von der empfangenden Applikation letztlich zuzuordnen sind. Das hat mit URL-Encoding nichts zu tun.)

Klarmachen muss man sich ferner, dass auch viele Datenbanksysteme definierte oder einstellbare Zeichensätze in der Kommunikation und beim Datenaustausch mit ihren jeweiligen Clients einsetzen. Hierfür liefert MySQL ein schönes Beispiel (s.u.).

Andererseits gelten definierte Zeichensätze auch für die interne Repräsentation von Daten in einer Applikation und /oder einer
Datenbank. Der Zeichensatz für die interne Datenrepräsentation oder die Ablage in einer Datenbank kann dabei vom Zeichensatz, den die Datenbank in der Kommunikation mit ihren Clients anwendet, durchaus abweichen! Für die korrekte Zeichenumsetzung sorgt die Bank selbst, man muss als Entwickler aber dennoch wissen, was für ein Zeichensatz für die Kommunikation gilt oder gelten soll und wie man das im Bedarfsfall beeinflussen kann.

Der Unterschied zwischen Zeichensätzen für die Datenbanktabellen und den Zeichensätzen für die Kommunikation mit den Datenbank-Clients führt im Zusammenspiel von MySQL und PHP oftmals zu erheblichen Verwirrungen. Man schaut auf die Kollation der Datenbank-Tabellen und vergisst leider oftmals, dass der Zeichensatz für den Transfer der Daten zwischen Datenbank und PHP-Applikation im Umfeld von Umlautproblemen viel entscheidender ist!

Als Konsequenz mussten auch wir immer wieder lernen, dass es sinnvoll und wichtig ist, die Datenbehandlung in den Basisklassen unseres hauseigenen Frameworks auf der PHP-Seite mit zeichensatzbezogenen Kodier- und Dekodier-Funktionen (unter Einsatz von z.B. “utf8_decode”, “utf8_encode”, “iconv” ) sowie MySQL-Anweisungen der Art

auszustatten – und zwar so, dass die Durchführung einer De- oder Enkodierung und/oder der jeweils zu beachtende Zeichensatz sich über Konfigurations- oder Setup-Parameter der Applikation steuern lassen. Damit kann man sich dann flexibel an die vorgefundene Server-Umgebung anpassen!

Dass man sich ohne Vorkehrungen und systematische Analyse der verschiedenen Server-Einstellungen sehr schnell in einem Gestrüpp wiederfinden kann, zeigen z.B. folgende Artikel:

http://www.php-resource.de/forum/php-developer-forum/100181-umlauteproblem-bei-formulardaten-ms-sql.html
http://www.sebastianviereck.de/de/mysql-php-umlaute-sonderzeichen-utf8-iso/
http://www.php.de/datenbanken/45101-problem-mit-utf8-latin1.html
http://www.winfuture-forum.de/index.php?showtopic=193063

Wie gesagt: Bei der MySQL-Datenbank muss man begrifflich sorgsam unterscheiden zwischen den “Collations”-Einstellungen für das Hinterlegen der Daten in den Datenbanktabellen und dem Zeichensatz, den die Bank in der Kommunikation mit ihren Clients (hier: PHP-Modulen des Webservers) einsetzt. Das sind verschiedene Dinge – vor allem eine fehlerhafte oder unerwartete Einstellung des Zeichensatzes für die Kommunikation mit DB-Clients ist nach meiner Erfahrung Ursache für viele Umlaut- und Zeichensatz-Probleme im PHP/MySQL-Umfeld.

Man führe sich im Falle des Falles nochmals den Artikel http://dev.mysql.com/doc/refman/5.1/de/charset-connection.html und die Möglichkeiten des Einsatz des “SET NAMES”-Kommandos bei der Initialisierung der Datenbankverbindung zu Gemüte! Ein kurzer Test mit “SET NAMES” hat mir schon oft geholfen – genau deswegen habe ich ja irgendwann eine generelle Möglichkeit zur Parametrierung in unseren PHP-Applikationssetup vorgesehen.

Bevor man JQuery-induzierte Umlaut-Probleme angeht, sollte man also wissen,

  • ob und mit welchen Zeichensätzen der Webserver und die Datenbank arbeiten und
  • auf Basis welchen Zeichensatzes jede dieser Serverkomponenten Informationen zu ihren jeweiligen Clients überträgt.

Insgesamt sollte man sich beim Analysieren von JQuery/Ajax-induzierten Umlaut-Problemen sicher sein, dass die eigene Applikation mit den unterschiedlichen Webserver- und Datenbankeinstellungen konsistent umgeht und dass nicht schon ohne JQuery ein Umlaut-Problem vorliegt.

Warum muss ich zusätzlich an JQuery denken?

Bei der Parametrierung, der Konfiguration und der Konzeption eigener PHP-Applikationssysteme tut man in jedem Fall gut daran, von vornherein an den Einsatz von JQuery/Ajax zu denken. Warum?

Weil JQuery und seine Ajax-Tools bestimmte Regeln für die Kommunikation mit Webservern befolgen, auf die man sich zumindest serverseitig einstellen muss ! Zu finden sind solche Regeln auf der Seite

http://api.jquery.com/jQuery.ajax/

Es lohnt sich, sich diese Seite in Gänze (!) zu Gemüte zu führen. Liest man dort vorschnell nur den nachfolgend zitierten Abschnitt zum “ContentType” beim Ajax-Setup, so kann man schnell Schiffbruch erleiden.

contentTypeString
Default: ‘application/x-www-form-urlencoded; charset=UTF-8’
 
When sending data to the server, use this content type. Default is “application/x-www-form-urlencoded; charset=UTF-8”, which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it’ll always be sent to the server (even if no data is sent). If no charset is specified, data will be transmitted to the server using the server’s default charset; you must decode this appropriately on the server side.

Der letzte Satz deutet schon mal Schwierigkeiten an – man muss sich ggf. um die Servereinstellungen kümmern! Andererseits könnte man aber auch glauben, dass man den Zeichensatz für die Kommunikation mit dem Server clientseitig durch ein geeignetes Setup für die JQuery/Ajax-Transaktion vorgeben kann. Dies ist aber nicht durchgehend der Fall, denn es gilt auch folgendes weitere Zitat von der genannten api.jquery.com-Webseite:

Sending Data to the Server
 
By default, Ajax requests are sent using the GET HTTP method. If the POST method is required, the method can be specified by setting a value for the type option. This option affects how the contents of the data option are sent to the server. POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard.

Das spielt natürlich eine essentielle Rolle, wenn man – wie wir – bei der Erstellung und dem Einsatz von CM-Systemen größere Nutzdaten aus umfangreichen Formularen per JQuery/Ajax zum Server übertragen muss. Eine solche Übertragung wird man typischerweise statt mit GET mit POST durchführen (Datenmenge, Sicherheit).

Anders als beim Datenaustausch über GET ist JQuery/Ajax im Falle eines Datenversands mit POST offenbar aus guten Gründen eigen und legt sich auf UTF-8 fest!

Blöd nur, wenn die serverseitige Zielumgebung konsistent auf ISO-8859-1 und nicht auf UTF-8 ausgelegt ist.

Sprich:
Du hast es mühsam geschafft, in einer konsistenten “ISO-8859-1/latin1”- Apache/MySQL-Kundenumgebung eine interaktive PHP-Applikation einwandfrei zum Laufen zu bringen. Dann schaltest du irgendwann nette JQuery/Ajax-Features auf POST-Basis dazu und bekommst möglicherweise und “überraschend” Zeichensalat in allen Texten.

Von solchen Erlebnissen zeugen viele Anfragen in Foren mit z.T. halbgaren Lösungsansätzen – ein paar Beispiele:

http://stackoverflow.com/
questions/2539090/jquery-ajax-umlauts-special-characters-are-a-mess

http://forum.de.selfhtml.org/archiv/2009/7/t188450/
http://www.ajax-community.de/javascript/6113-jquery-formular-umlaute.html
http://www.ajax-community.de/javascript/8872-problem-umlauten.html
http://www.buildblog.de/2009/05/01/ajax-und-umlaute-das-ewig-wahrende-utf-8-problem-und-seine-losung/
http://www.php.de/javascript-ajax-und-mehr/71100-formular-umlaute.html
http://www.perl-community.de/bat/poard/thread/17021
http://www.fundstücke-im-netz.de/2012/03/28/umlaute-mit-ajax-verwenden/
http://ecotronics.ch.honorius.sui-inter.net/wordpress/2010/jquery-ajax-und-encoding/
http://de.softuses.com/68699
http://www.mail-archive.com/discuss@jquery.com/msg19364.html

Das ungewollte Erzeugen von Zeichensalat kann dabei selbst in Testumgebungen ein Problem werden, denn die nach dem Ajax-Einsatz durch kryptische Zeichen ersetzten Umlaute der deutschen, französischen oder skandinavischen Texte muss man auch da ggf. erstmal wieder aus Backups restaurieren. Wenn es sich um größere Texte handelt, wird ja keiner anfangen, das wieder von Hand zu bereinigen!

Was hilft beim JQuery/Ajax-Einsatz in eventuellen ISO-8859-1/Latin1-Umgebungen ?

Nachdem man einmal verinnerlicht hat, dass JQuery/Ajax bei POST als Datentransfermechanismus UTF-8 in der Kommunikation mit dem Webserver erzwingt, ist klar: Man muss serverseitig etwas tun, wenn in der dortigen Verarbeitungskette nicht UTF-8 vorgesehen ist.

Das Zauberwort – besser die einzusetzende Funktion – heißt dann:

utf8_decode().

Siehe hierzu

http://de.php.net/manual/de/function.utf8-decode.php

Spätestens an den Stellen, an denen die PHP-Module sich des übertragenen und im $_POST-Array gelandeten Inhalts annehmen (Prüfungen, Vorverarbeitung, etc.), muss man die per JQuery/Ajax übertragenen Strings in einer ISO-8859-Umgebung prophylaktisch mit “utf8_decode()” dekodieren!

Ob man eine pauschale initiale Decodierung für alle Strings im $_POST-Array vor allen weiteren Schritten vornehmen will, hängt ein wenig von den eingesetzten Analyse- und Prüfroutinen für die Daten ab ab. Das gilt im besonderen für sicherheitsbezogene Prüfungen – hier muss jeder selber wissen, was sinnvoll und richtig ist. Irgendwann im Zuge der Verarbeitung ist die Dekodierung unter den angenommenen Voraussetzungen aber unvermeidbar.

Aber:
Das gilt nur im Fall eines vorhergehenden Ajax/JQuery-Transfers auf ein auf ISO-8859-1 eingestelltes Zielsystem und genau genommen nur im Falle von Strings.

Wie weiss oder erfährt mein PHP-Programm darüber etwas?

Bzgl. der String-Eigenschaft:

Man kann z.B. is_string(), is_numeric(), etc. zum Testen einsetzen. Aus meiner Sicht sollte man aber sowieso durch andere Mechanismen bei der Übertragung von Formulardaten dafür gesorgt haben, dass das empfangende PHP-Programm sehr genau weiß, was es an welcher Stelle des
POST-Arrays als Datentyp erwartet. Schon aus Sicherheits- und Validierungsgründen! Dieses Thema hat man also in der Regel von Haus aus schon im Griff.

Bzgl. der Kennzeichnung eines Ajax-Transfers für die PHP-Seite:

Ich benutze hierfür typischerweise ein wohldefiniertes zusätzliches “Hidden Input-Feld” im selben Web-Formular, dessen Nutz-Daten übertragenen werden sollen. Da ich ja eh’ JQuery im Falle eines Ajax-Transfers bemühe, kann ich vor der Durchführung der POST-basierten Ajax-Transaktion dieses Input-Feld von JQuery auch noch schnell mit einem numerischen Wert füllen lassen, der dem PHP-Programm dann anzeigt, dass ein Ajax-Transfer vorliegt. Einfache numerische Werte sind von UTF-8 / ISO-8859-Transformationen ja nicht gefährdet (ASCII-Kompatibilität von UTF-8)!

Das serverseitige PHP-Programm kann aufgrund der übertragenen Zusatz-Information in einem speziellen, mit numerischem Inhalt belegten $_POST-Array-Feld herausbekommen, ob die POST-Daten per JQuery/Ajax-Transaktion geschickt wurden. Hat das PHP-Programm auf Basis seines parametrierten Grund-Setups nun noch Informationen darüber, ob es in einer UTF8-Server-Umgebung oder in einer ISO-8859/Latin1-Umgebung läuft, so ist klar, wann utf8_decode() einzusetzen ist und wann nicht.

Client- bzw. serverseitig läßt sich so ein informatives “Zusatz-Feature” natürlich sehr schön generalisiert und über entsprechende Methoden eigener Bibliotheksobjekte für Datentransaktionen abhandeln – sowohl unter Javascript als auch auf der PHP-Seite. Die benötigte Code-Menge ist wirklich minimal!

Hat man das erstmal codeseitig erledigt, kann man anschließend normale POST-Transfers mit Web-Seitenwechsel locker und entspannt mit Ajax-Transaktionen ohne Web-Seitenwechsel jederzeit kombinieren und zwischen beiden hin- und herwechseln.

Den geringen Aufwand, den man für die notwendigen Vorsorgemaßnamen client- und serverseitig investieren muss, spielt man danach locker wieder durch den bequemen, einfachen Einsatz der Ajax-Tools von JQuery ein.

Ohne jeden Zeichensalat! Zumindest in “ISO-8859-1”-Umgebungen. Mit anderen Zeichensätzen als ISO-8859-Varianten und UTF-8 bin ich nicht so vertraut, so dass ich das, was ich oben beschrieben habe, nicht auf andere Zeichensätze generalisieren möchte.

Viel Spaß nun mit Umlauten, JQuery/Ajax und PHP in UTF-8 und ISO-8859-Umgebungen!

Dynamische Höhensteuerung mehrer DIVs

Im HTML/CSS2-Bereich gibt es immer mal wieder Dinge, von denen man glaubt, man bekäme sie aus grundsätzlichen Erwägungen nie vernünftig hin. Probleme, über die ich immer wieder stolpere, sind Kombinationen aus mehreren Anforderungen:

  • vertikal expandierbare Webseiten mit gefloateten und/oder mehreren übereinander liegenden DIV-Layern,
  • gegenseitige Höhensteuerung oder Höhen-Synchronisation unabhängiger, vertikal frei expandierbarer DIV-Layer mit vorab unbekanntem (!) Inhalt und damit initial nicht definiertem Wert der Höhe,
  • em-skalierbare Webseiten mit Layern, in denen ebenfalls em-skalierbare Hintergrundsbilder untergebracht werden müssen.

Warum sind solche Anforderungskombinationen problemträchtig? Dies liegt daran, dass die Anforderungen zum Teil im Widerstreit miteinander liegen.

Konkurrierende Anforderungen unter CSS2 bei unbestimmten Höhen, die erst zur Laufzeit festgelegt werden

Schwierigkeiten entstehen vor allem dann, wenn es in der DIV-Schichtung Layer gibt, deren Höhe erst zur Laufzeit durch eingefügte Elemente – z.B. Text – festgelegt wird und nicht von Anfang an bestimmt ist (dynamische Höhenfestlegung). Solche Situationen tauchen typischerweise immer dann auf, wenn man DIVs mit Datenbank-Inhalten füllt. Dies ist u.a. typisch für Content-Management-Systeme und zugrunde liegende Template-Strukturen. So auch bei unserem hauseigenen CMS, das auf einem Framework beruht, welches sich ITX-Templates zunutze macht.

Bei der Generierung dynamischer Webseiten hängt die Menge des Inhalts und damit auch die vertikale Ausdehnung mancher DIVs sowie ggf. auch der gesamten Web-Seite davon ab, was der Kunde eingepflegt hat. Das kann man natürlich nicht im vorhinein wissen. Die sich zur Laufzeit ergebende DIV-Höhe mit Javascript zu bestimmen, finde ich aber einfach unelegant. Lässt man Javascript aber außen vor, wird es schwierig,

  • die Höhe von Seitenleisten mit unabhängigen DIVs zur Laufzeit zu synchronisieren,
  • die Höhe verschiedener DIVs in einer Layerschichtung in z-Richtung oder in gefloateten Kontexten zur Laufzeit zu synchronisieren
  • oder aber den sichtbaren Bereich “em”-skalierbarer Hintergrundsbilder zusammen mit einem DIV, in das erst zum Zeitpunkt der Seitengenerierung Texte eingelesen werden, auf einen initial unbekannten Höhenwert wachsen zu lassen.

So kann man etwa absolut positionierte DIVs per CSS über die “z-index”-Anweisung gut übereinander schichten. Damit entkoppelt man sie dimensionsmäßig aber auch voneinander!

Oftmals soll gerade der oberste Layer einen Text tragen, dessen Länge nicht von vornherein bekannt ist. Dennoch soll die Textlänge letztlich die sich ergebende vertikale Ausdehnung des umgebenden DIV-Layers, die Höhenausdehnung der gesamten Seite und verschiedener anderer dort enthaltener Layer – z.B. mit Hintergrundsbildern – bestimmen. Das geht mit absolut positionierten DIVs allein überhaupt nicht!

Hinzu kommt, dass gefloatete DIVs, die auf vielen Web-Seiten eingesetzt werden, ebenfalls eine eigene Layerstruktur definieren, so dass besondere Vorkehrungen getroffen werden müssen, wenn umgebende DIVs auf eine potentielle vertikale Expansion der gefloateten DIVs reagieren sollen.

Noch problematischer wird es, wenn man zusätzlich alle Elemente einer Website in “em”-Einheiten definiert hat. Ein Ziel eines solchen Vorgehens kann es sein, die gesamte Seite auf Knopfdruck mit vordefinierten Faktoren zu skalieren. Dies ist jedoch mit Hintergrundsbildern, die per CSS-Anweisung “background-image” z.B. in DIV-Layer eingesetzt wurden, nicht möglich. Solche Hintergrundsbilder skalieren nämlich nicht mit. Womit die Behandlung “em
“-skalierbarer Hintergrundsbilder wieder zu einem Lösungsansatz mit per z-Index übereinander geschichteten DIVs führt.

Betrachten wir einmal das Beispiel einer über den z-Index geschichteten Layer-Struktur, wie sie in der nachfolgenden Abbildung dargestellt ist:

div_layer

Die Layer mit unterschiedlichem z-Index wird man in der Regel mit CSS-Anweisungen der Form

position:absolute; z-index:n;”

mit wachsendem “n” übereinanderlegen. Es ist dann natürlich einfach, das Hintergrundsbild ebenso wie die Größe des halbtransparenten Layers “em”-skalierbar zu machen. Die Transparenz erreicht man entweder über die CSS-Anweisung “opacity:0.x;” – was inzwischen die meisten Browser verstehen – oder aber über browserspezifische Anweisungen (Browserweichen). Kennt man die Größe – Breite und Höhe – des Bereiches, den der Text einnehmen wird, von vornherein, hat man alles unter Kontrolle.

Typischer Code für eine einfache Website mit solchen Elementen sieht dann wie folgt aus:

<div id=”cont” style=”position:relative; width:50.0em; height:60.0em; background-color:#CCC; “>
    <div id=”bg_img” style=”position:absolute; top:0; left:0; width:53.0em; height:60.0em; z-index:1;”><img src=”….” style=”width:100%; …..”></div>
    <div id=”bg_transp” style=”position:absolute; top:0; left:0; width:53.0em; height:60.0em; background-color: #FFF; opacity:0.7; z-index:2;”></div>
    <div id=”bg_transp” style=”position:absolute; top:0; left:0; width:53.0em; height:60.0em; z-index:3;”><p>LANGER TEXT</p></div>
</div>

Man kann natürlich die Bilddimensionen auch explizit in “em”-Einheiten vorgeben. Hier passt dann natürlich alles, weil wir die Höhen von vornherein explizit so festlegen, dass der bekannte Text hinein passt. Alternativ legt man die Höhen der Seitenelemente von vornherein fest und aktiviert bei zu langem Text einen vertikalen Scrollbar.

Wir allerdings wollen etwas anderes: Verschiedene Seitenelemente sollen sich höhenmäßig und synchron an einen Textinhalt beliebiger Länge anpassen.

Hinweis:
Hier wie in den nachfolgenden Beispielcodes werden wir CSS-Vorgaben immer direkt in den TAGs angeben. Im realen Leben würde man natürlich CSS-Klassen definieren.

Anforderungen an automatische Höhenbestimmungen zur Laufzeit bei gleichzeitiger em-Skalierung von Hintergrundsbildern

Nun stellen genauer folgende Anforderungen:

  1. Wir möchten eine dynamische Skalierung aller (!) Seitenelemente mit der Schriftgröße, die für das BODY-Tag definiert wird (“em”-Skalierung). Dies soll auch für eventuelle Hintergrundsbilder gelten.
  2. Die Höhe eines zentralen Textbereiches der Webseite soll durch die beliebige Länge eines unbekannten (!) Textes aus einer Datenbank definiert werden.
  3. Wir möchten eine dynamische Expansion der gesamten Webseite in vertikaler Richtung mit der Höhe des Textbereichs.
  4. Die Layer für das Hintergrundsbild, einen ggf. zwischengeschalteten semitransparenten Layer sowie für den Text unbekannter Länge sollen in z-Richtung übereinander geschichtet sein.
  5. Wir möchten gleichzeitig mit der dynamischen Expansion des Text-DIVs auch eine entsprechende Höhen-Expansion des halbtransparenten DIV-Layers.
  6. Wir möchten gleichzeitig eine dynamische Expansion des DIV-Layers, der das Hintergrundsbild enthält. Dabei
    soll das Bild selbst eine wesentlich größere Basishöhe als das eingrenzende DIV haben. Das DIV, welches das IMG-Tag beinhaltet, soll automatisch die gleiche Höhe annehmen, wie das DIV mit dem Textbereich. Ferner soll dieses DIV während seines vertikalen Wachstums einen entsprechenden Bereich des von Haus aus größeren “Hintergrundsbildes” in vertikaler Richtung freigeben und den Rest abschneiden.
  7. Wir möchten, dass die vertikale Expansion der gesamten Seite auch dann gegeben ist, wenn sich die dargestellte Layer-Schichtung in z-Richtung innerhalb eines gefloateten DIV-Bereichs befindet.
  8. Wir möchten ferner, dass die Hintergrundsbereiche von optisch unabhängigen Seitenbereichen, die über gefloatete DIVs erzeugt wurden, synchron die Höhe annehmen, die durch einen zentralen Textbereich innerhalb eines der gefloateten DIVs zur Laufzeit vorgegeben wird.

Anforderung 1 ist nicht mit CSS-definierten Hintergrundsbildern (background-image) erfüllbar. Also müssen die Bilder in eigenen DIVs mit niedrigem z-Index untergebracht werden.
Anforderung 2 lässt sich einfach dadurch erfüllen, dass man die Höhe des entsprechenden relativ positionierten DIVs offen lässt.
Anforderung 3 läuft darauf hinaus, dass sich mehrere ineinander geschachtelte DIVs an der Höhe des Text-DIVs orientieren, dessen Ausdehnung erst zur Laufzeit bestimmt wird. Dies setzt einerseits zwingend den Einsatz relativ positionierter DIVs für den Text und dessen Container voraus (position:relative;).
Anforderung 4 spricht insgesamt für absolut positionierte und per z-Index geschichtete DIVs.
Die Anforderungen 5) und 6) bedeuten, dass das DIV mit dem Text die Höhe der darunter liegenden DIVs definiert. Das geht aber mit unabhängigen, absolut positionierten DIVs nicht ohne weiteres !
Anforderung 7 erschwert die Aufgabe zusätzlich, da sich die Höhe gefloateter DIVs nicht automatisch auf die umgebender DIVs auswirkt.
Anforderung 8 ist mehr als problematisch, da gefloatete Bereiche nicht gegenseitig ihre Höhen festlegen können.

Das schwierigste Problem liegt zunächst eindeutig in Anforderung 5. Wie kann ein Layer mit Inhalt unbekannter Länge die Höhe darunter liegender – notwendigerweise – absolut positionierter DIVs vorgeben? Auf die Lösung bin ich Zufall gestoßen, als ich mich mal aus einem anderen Grund mit der Vererbung in CSS2 (inherit-Anweisung) befassen musste.

Absolut positionierte DIVs können die dynamisch berechnete Höhe eines umgebenden relativ positionierten DIVs annehmen

Der erste Schlüssel für einen Lösungsansatz ist folgender:

Absolut positionierte DIVs können die Höhe eines umgebenden relativ-positionierten DIVs über die “inherit”-Anweisung oder Anweisungen der Art “height:100%;” übernehmen, sobald die Höhe des relativ positionierten DIVs zur Laufzeit von der Engine des Browsers bestimmbar ist oder aber über eine Analyse des Platzbedarfs seines Inhalts berechnet wurde.

Zum Beispiel nimmt in folgendem Beispiel dass “inner”-DIV die vorgegebene Höhe des “cont”-Divs an. :

<div id=”cont” style=”position:relative; height:40.0em; width:50.0em;”>
    <div id=”inner” style=”position:absolute; top:0px; left:10.0em; height:100%; width:20.0em; background-color:#F00; “></div>
</div>

Natürlich kann man die Höhe des inneren DIVS über eine geeignete %-Angabe auch anders mit der Höhe des umgebenden DIVs mitskalieren lassen.

Im Fall dynamisch generierten Inhalts ist die gewünschte Höhe der DIVs aber leider nicht vorab bekannt. Die Höhe des Inhalts eines absoluten DIVs kann in W3C-konformen Browsern zudem nicht die Höhe eines umgebenden relativ oder auch absolut positionierten Container-DIVs festlegen. Wir können den gewünschten
Inhalt also eigentlich nicht wie im obigen grafischen Beispiel in absolut positionierte DIVs einfüllen.

Höhenfestlegung verschachtelter DIVs zur Laufzeit – der umgebende Container als Vermittler der Höhe

Was aber, wenn man ein inneres, relativ positioniertes DIV verwendet, um die Höhe des umgebenden relativ positionierten DIVs festzulegen? Würde sich diese Höhenfestlegung dann indirekt auch auf das absolut positionierte, innere DIV auswirken?

Tatsächlich funktioniert Folgendes:

<div id=”cont” style=”position:relative; width:50.0em; background-color:#CCC; “>
    <div id=”in_rel” style=”position:relative; width:80%; height:200px; background-color: #999; margin-left:auto; margin-right:auto; “></div>
    <div id=”in_abs” style=”position:absolute; top:0px; left:20.0em; width:10.0em; height:80%; background-color: #F00;”></div>
</div>

Wir können also die Höhe des inneren absolut positionierten DIVs durch ein auf gleicher Verschachtelungs-Ebene befindliches relativ positioniertes DIV steuern. Der umgebende DIV-Container wirkt dabei quasi als Vermittler der Höhe!

[Einschränkung: Auf der MS Seite geht das erst ab dem MS IE7, nicht aber mit dem MS IE6!]

Hier das Ergebnis für moderne Browser (wobei arme IE6-Anwender natürlich nichts Vernünftiges zu Gesicht bekommen werden) :

Nun sind wir nur noch einen kleinen Schritt von unserem ersten Ziel entfernt. Wir unterlassen eine Festlegung der Höhe des inneren relativ positionierten DIVs “<div id=”in_rel” >” per CSS und steuern die Höhe dieses DIVs vielmehr dynamisch durch seinen Inhalt.

Also z.B. folgendermaßen:

<div id=”cont” style=”position:relative; width:50.0em; background-color:#CCC; “>
    <div id=”in_rel” style=”position:relative; width:80%; background-color: #999; margin-left:auto; margin-right:auto; “>
        <p>Lorem ipsum dolor sit amet, … LANGER TEXT … ut laoreet dolore magna aliquam erat volutpat.</p>
    </div>
    <div id=”in_abs” style=”position:absolute; top:0px; left:20.0em; width:10.0em; height:80%; background-color: #FEFE99;”></div>
</div>

Auch dies geht offenbar, wie man testen kann:

Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril elenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, ed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

Der vertikale Platzbedarf des Textes wird vom Browser erst zur Laufzeit bestimmt. Dies gilt selbst dann, wenn wir den Text in unserem Beispiel vorgeben und nicht aus einer Bank auslesen haben lassen. Entscheidend ist, dass der Browser die benötigte Höhe des umgebenden DIVs erst zur Laufzeit ermitten muss, weil sie nicht per “height”-Anweisungen vorgegeben ist ! Daher zeigen auch die nachfolgenden Beispiele durchaus auch, wie man im Fall von dynamisch ermitteltem Content vorgehen kann.

Der Inhalt des DIVs mit der id=”in_rel” bestimmt also zur Laufzeit dessen Höhe. Die Höhe des DIVs mit der id=”in_rel” wiederum wird vom umgebenden relativ positionierten Container-Div (id=”cont”) übernommen. Nach dessen vom Browser ermittelter Höhe richtet sich dann das enthaltene, innere absolut positionierte DIV mit der id=”in_abs”.

Schichtung relativer und absolut positionierter DIVs in aktuellen Browsern

Nun gefällt uns die Schichtung noch nicht – wir wollen ja eigentlich das DIV mit dem Text im Vordergrund haben. Ferner müssen wir die Breite des absolut positionierten DIVs so anpassen, dass es als Hintergrund dienen kann. Also :

<div id=”cont” style=”position:relative; width:50.0em; background-color:#CCC; “>
    <div id=”in_rel” style=”position:relative; width:80%; margin-left:auto; margin-right:auto; padding:2.0em 0 2.0em 0; z-index:10;”>
        <p> Lorem ipsum dolor sit amet, … LANGER TEXT … ut laoreet dolore magna aliquam erat volutpat. </p>
    </div>
    <div id=”in_abs” style=”position:absolute; top:0; left:0; width:100%; height:100%; background-color: #FEFE99; z-index:1;”></div>
</div>

Hinweis: Man beachte die z-Index-Werte! Bei älteren Browsern – speziell beim MS IE – musste man übrigens höllisch aufpassen, wenn man die gleichzeitige Schichtung relativ und absolut positionierter DIVs richtig hinbekommen wollte. Im besonderen hing beim MS IE ( < Version 8 ) das Ergebnis davon ab, in welcher Reihenfolge die DIVs im HTML-Code definiert wurden. Es empfahl sich, innerhalb des Codeblocks für einen Container zuerst die relativ positionierten DIVs und dann die absolut positionierten anzugeben. Dies ist heute in der Regel nicht mehr nötig.

Dass das Übereinanderlegen von relativen und absoluten DIVs in modernen Browsern bei gleichzeitiger dynamischer Höhensteuerung des absolut positionierten DIVs durch den umgebenden Container funktioniert, sieht der Leser hoffentlich am nachfolgenden Ergebnis:

Testbeispiel – relatives DIV über absolutem DIV und Höhenvermittlung durch den Container

Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril elenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, ed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

Hinweis: Alle Beispiele/Ergebnisse setzen die in diesem Beitrag diskutierten HTML-Code direkt auf der vorliegenden Blog-Seite um. Man kann sich den Code also auch aus dem Quelltext kopieren.

Testbeispiel zur inhaltsabhängigen Höhenfestlegung verschachtelter DIVs mit Hintergrundsbild

Nun unterlegen wir den Text noch mit einem Hintergrunds-Bild:

<div id=”cont” style=”position:relative; width:50.0em; background-color:#CCC; “>
    <div id=”in_rel” style=”position:relative; width:80%; margin-left:auto; margin-right:auto; z-index:10; padding:2.0em 0 2.0em 0; “>
        <p> Lorem ipsum ……</p>
    </div>
    <div id=”in_abs” style=”position:absolute; top:0; left:0; width:100%; height:100%; z-index:1;”>
        <img src=”….” style=”width:100%;”>
    </div>
</div>

Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril elenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, ed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

yellow_bryce

Bei einer Höhenveränderung des Textes (hier durch künstliche Umbrüche erzwungen) passt sich die Umgebung automatisch an und der vertikal längere Text gleitet über das Hintergrundsbild weg, das dabei in entsprechender Länge enthüllt wird ( vergl. mit Anforderung 6 weiter oben ) :

Lorem ipsum dolor sit amet, consectetur adipisici elit,
sed eiusmod tempor incidunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquid ex ea commodi consequat.
Quis aute iure reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
Excepteur sint obcaecat cupiditat non proident,
sunt in culpa qui officia
deserunt mollit anim id est laborum.
Duis autem vel eum iriure dolor in hendrerit in vulputate
velit esse molestie consequat, vel illum dolore eu
feugiat nulla facilisis at vero eros et accumsan
et iusto odio dignissim qui blandit praesent luptatum zzril
delenit augue duis dolore te feugait nulla facilisi.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit,

ed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat.

yellow_bryce

In vielen Fällen muss man das Hintergrundsbild abdämpfen, um die Lesbarkeit zu verbessern. Einen für alle gängigen Browser funktionierenden Semi-Transparenz-Layer hinzuzufügen, überlassen wir dem Erfindungsreichtum des Lesers. Das nachfolgende Code-Beispiel funktioniert zumindest im aktuellen Firefox und demonstriert das Prinzip:

<div id=”cont” style=”position:relative; width:50.0em; background-color:#CCC; “>
    <div id=”in_rel” style=”position:relative; width:80%; margin-left:auto; margin-right:auto; z-index:10; padding:20px 0 20px 0; “>
        <p> Lorem ipsum ……</p>
    </div>
    <div id=”in_abs” style=”position:absolute; top:0; left:0; width:100%; height:100%; z-index:1; background-color:#FFF; opacity:0.70; “></div>
    <div id=”in_abs” style=”position:absolute; top:0; left:0; width:100%; height:100%; z-index:1;”>
        <img src=”….” style=”width:100%;”>
    </div>
</div>

Lorem ipsum dolor sit amet, consectetur adipisici elit,
sed eiusmod tempor incidunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquid ex ea commodi consequat.
Quis aute iure reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
Excepteur sint obcaecat cupiditat non proident,
sunt in culpa qui officia
deserunt mollit anim id est laborum.
Duis autem vel eum iriure dolor in hendrerit in vulputate
velit esse molestie consequat, vel illum dolore eu
feugiat nulla facilisis at vero eros et accumsan
et iusto odio dignissim qui blandit praesent luptatum zzril
delenit augue duis dolore te feugait nulla facilisi.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
ed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat.

yellow_bryce

Hinweis: Im MS IE muss man halt mit proprietären CSS-Anweisungen der Art “filter: alpha(opacity=70);” arbeiten!

Höhensteuerung gekoppelter DIVs zur Laufzeit und gefloatete Container

Nun das Ganze in einer Umgebung mit floatenden Seitenbereichen. Eine typische Anwendung ist folgende:

Wir wollen in einem “right”-gefloateten Layer zur Laufzeit einen Text noch unbekannter Länge unterbringen. Dieser soll jenseits einer Minimalhöhe die vertikale Ausdehnung der gesamten Web-Seite bestimmen (welche im nachfolgenden Beispiel über ein umfassendes DIV repräsentiert wird). In einem “left”-
gefloateten DIV soll ferner eine vertikale Menü-Struktur untergebracht werden, deren Länge typischerweise kürzer als die des Textbereichs (rechts) ist. Der Hintergrund des Menübereichs soll sich jedoch parallel zur Länge des Textbereiches ausdehnen. Der Anspruch ist also:

Der Textbereich in einem “right”-gefloateten Bereich determiniert die Höhe des Hintergrunds eines “left”-gefloateten Bereichs!

Eigentlich unmöglich, denkt man! Mit folgendem Trick geht es aber doch – wie das Beispiel zeigt ! Und es geht auf der MS-Seite ab dem MS IE7.

Testbeispiel mit gefloateten DIvs und gekoppelter vertikaler Ausdehnung

Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.

yellow_bryce

Links erkennt man den gelben Hintergrund eines Menübereichs. Der Menütext befindet sich in einem “left”-gefloateten Container-DIV. Der gelbe Hintergrundsbereich – ein DIV (in dem sich auch ein Bild befinden könnte) – dehnt sich auf exakt die Höhe aus, die der Textbereich rechts in einem “right”-gefloateten Container-DIV vorgibt. Gleichzeitig folgt die gesamte Webseite der Größe des Textes im rechten Float-Container. Alles klar?

Natürlich haben wir ein wenig unterschlagen: Nachfolgend wird das DIV für den Menübereich mal mit einer blauen “Border” umgeben:

Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.

yellow_bryce

Wir sehen, dass die Größe des left-gefloateten Bereichs kleiner ist als die des Hintergrunds. Also steuert der rechte Textbereich nicht wirklich die Höhe des links gefloateten Bereichs. Und dennoch erhält der linksseitige gelbe Hintergrund die richtige Höhe ….

Wie sieht der Code dazu aus?

<div id=”bsp_cont” style=”position: relative; margin-left: auto; margin-right: auto; width: 50.0em; border: #666 0.4em solid; background-color: #EEE; “>
    <div id=”float_cont” style=”position:relative; min-height:5em; border:2px #0F0 solid;”>
        <div id=”menu_left” style=” position:relative; float:left; width:12.6em; padding:1em; border: #CCC 0.2em solid; z-index:2; “>
                <p style=”margin:0;”>menu<br>menu<br>menu<br>menu</p>
        </div>
        <div id=”main_right” style=”position: relative; float:right; width:25.6em; border: red 0.2em solid; background-color:CCC; z-index: 2; “>
             <div id=”txtbox_right” style=”position:relative; color:#000; z-index:3; padding:0.6em; “>
                <p style=”margin:0;”>Lorem ipsum dolor sit amet, ……. mollit anim id est laborum.</p>
            </div>
            <div id=”transp” style=”position:absolute; top:0; left:0; width:100%; height:100%; background-color: #FFF; opacity:0.7; filter: alpha(opacity=70); z-index:2; “></div>
            <div id=”bg_img” style=”position:absolute; top:0; left:0; height:100%; width:100%; overflow:hidden; z-index: 1; “>
                <img src=’https://linux-blog.anracom.com/wp-content/uploads/2011/07/yellow_weit_ext_1_640.jpg’ alt=’yellow_bryce’ style=”width:100%;”>
            </div>
        </div>
&
nbsp;       <p style=”clear: both; line-height: 0; font-size: 0; height: 0; margin: 0; padding: 0;”> </p>
        <div id=”bg_left” style=”position:absolute; top:0; left:0; width:15.0em; height: 100%; border: red 1% solid; background-color: #FEFE77; color: blue; z-index:1;”></div>
    </div>
    <div id=”bsp_footer” style=”position:relative; background-color: #CCC; width: 49.6em; height:2.0em; text-align:center; border: green 0.2em solid; margin-top:1.0em; margin-bottom:0; “><p style=”margin:0;”>Footer</p></div>
</div>

Man erkennt nach eine wenig Analyse vier Punkte:

  • Im rechts gefloateten Container-DIV mit der id=”main_right” nutzen wir das oben besprochene Muster zur Höhenvermittlung zwischen einem relativ positinierten DIV (id=”txtbox_right”) für den Text, dessen vertikaler Platzbedarf erst zur Laufzeit bestimmt wird, und den absolut positionierten DIVs (id=”transp” und id=”bg_img”) für die Gestaltung des zugehörigen Hintergrunds.
  • Die gesamte vertikale Ausdehnung des äußeren Containers mit der id=”bsp_cont” ist zunächst unbestimmt. Sie wird festgelegt durch die Höhe des DIV-Containers mit der ID id=”float_cont” plus der Höhe des DIVs mit der id=”bsp_footer”. Die Höhe des DIVs mit der id=”float_cont” hängt ab von den beiden beinhalteten und gefloateten DIVs. Dass deren Höhe nach außen an das umgebende DIV (id=”float_cont”) weitergegeben wird, ist dem <p>-Tag zu verdanken, dass noch innerhalb des Containers die Float-Strukturen (eig. Ebene) per “clear”-Anweisung beendet.
  • Die Höhe des äußersten Containers mit der id=”bsp_cont” hängt ab von der Höhe des DIVs mit der id=”float_cont”. Dessen Höhe wiederum wird durch die Höhe des gefloateten DIVs mit der id=”main_right” bestimmt. Die Höhe des DIVs mit der id=”main_right” wird dagegen definiert durch die Höhe des DIVs mit der id=”txtbox_right”. Und dessen Höhe hängt von einem Textinhalt ab, den wir in CM-Systemen des realen Lebens erst (mit PHP oder Java) aus einer Datenbank auslesen würden. Obwohl wir hier im Beispiel einen Text vorgeben, wird auch dessen Höhe erst vom Browser zur Laufzeit berechnet.
  • Aus logischen Konsistenzgründen kann es nicht so sein, dass ein gefloatetes Element die Höhe eines anderen gefloateten Elements festlegt. Also kann man die Höhe des Hintergrunds auf der linken Seite nicht direkt über die Höhe des “left”-gefloateten DIVs beeinflussen. Der Trick besteht nun darin, ein weiteres DIV in dem DIV-Container mit der id=”float_cont” zu positionieren und zwar mit “position:absolute; top:0; left:0;” ! Denn dieses absolut positionierte DIV mit der id=”bg_left” kann die dynamisch ermittelte Höhe des umgebenden relativ positionierten Containers übernehmen. Das war ja genau das, was wir schon weiter oben gesehen hatten !
  • Im MS IE7 ist die Reihenfolge der Codezeilen für gefloatete, relativ oder absolut positionierte DIVs in einem Container für die Ergebnisdarstellung leider nicht egal! Anweisungen für absolut positionierte DIVs sollten auf Anweisungen für relativ positionierte DIVs und auch nach Anweisungen für gefloatete DIVs folgen. Für den MS IE 7 ist es in unserem Beispiel also wichtig, dass die Zeile für das absolut positionierte DIV mit der id=”bg_left” im Code erst nach (!) den Zeilen für die gefloateten DIVs und nach dem P-Tag mit der “clear”-Anweisung gesetzt ist. Eine Positionierung vor den Zeilen mit den gefloateten DIVs führt zu einer fehlerhaften Abarbeitung. Im MS IE8 ist dieses Problem behoben. (Wer ganz auf Nummer sicher gehen will, der umgibt die Zeilen für die gefloateten DIVs und das P-Tag auch noch mit einem weiteren kapselnden DIV, das dann relativ
    positioniert werden muss.)

Will man dagegen eine Lösung haben, bei der auch der links gefloatete Textbereich – falls er denn länger als der rechte werden würde – die Gesamtausdehnung steuern soll, so muss man den obigen HTML-Code etwas umstellen:

<div id=”bsp_cont” style=”position: relative; margin-left: auto; margin-right: auto; width: 50.0em; border: #666 0.4em solid; background-color: #EEE; “>
    <div id=”float_cont” style=”position:relative; min-height:5em; border:2px #0F0 solid;”>
        <div id=”menu_left” style=” position:relative; float:left; width:12.6em; padding:1em; border: blue 0.2em solid; z-index:3; “>
            <p style=”margin:0;”>menu<br>menu<br>menu<br> menu<br>menu<br>menu<br>menu<br>menu<br>menu</p></div>
        <div id=”main_right” style=”position: relative; float:right; width:25.6em; border: red 0.2em solid; background-color:CCC; z-index: 3; “>
            <div style=”position:relative; color:#000; z-index:2; padding:0.6em; “>
                <p style=”margin:0;”>Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. </p></div></div>
        <p style=”clear: both; line-height: 0; font-size: 0; height: 0; margin: 0; padding: 0;”> </p>
        <div id=”bg_left” style=”position:absolute; top:0; left:0; width:15.0em; height: 100%; border: red 1% solid; background-color: #FEFE77; color: blue; z-index:1;”></div>
        <div id=”bg_right” style=”position:absolute; top:0; right:0; width:25.6em; height: 100%; overflow:hidden; z-index:1;”><img src=’…..’ alt=’yellow_bryce’ style=”width:100%;”></div>
        <div style=”position:absolute; top:0; right:0; width:25.6em; height:100%; background-color: #FFF; opacity:0.7; filter: alpha(opacity=70); z-index:2; “></div>
    </div>
    <div id=”bsp_footer” style=”position:relative; background-color: #CCC; width: 49.6em; height:2.0em; text-align:center; border: green 0.2em solid; margin-top:1.0em; margin-bottom:0; “><p style=”margin:0;”>Footer</p></div></div>

Das muss man nach dem oben Gesagten nicht mehr erläutern. Das Ergebnis sieht wie folgt aus:

Testbeispiel mit gefloateten DIvs und gekoppelter vertikaler Ausdehnung

Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

yellow_bryce

Im dargestellten Beispiel bestimmt nun der zur Laufzeit längere der beiden Inhalte der gefloateten DIVs die Höhenskalierung der Seite und die Höhe der eingesetzten Hintergründe (ggf. mit Bildern).

Wir haben nun eine Lösung, die alle unsere Anforderungen erfüllt, und zudem haben wir eine sehr flexible Art gefunden, den Hintergrund gefloateter Bereiche dynamisch vom Inhalt innerer DIVs abhängig zu machen. Ohne Javascript !

Ferner bleibt die Erkenntnis, dass man die Höhe optisch entkoppelter Bereiche sehr wohl auch erst zur Laufzeit durch einen dynamisch erzeugten Inhalt festlegen und synchronisieren kann.

Viel Spaß weiterhin mit den Möglichkeiten von CSS2!

Opensuse, Firefox 4, Flashplayer 32 oder 64 Bit?

Unter Opensuse 11.4 ist der Firefox 4 Standard. Ich habe – wie immer schon – die 64 Bit Variante des Betriebssystems und des Firefox installiert. Zudem läuft KDE 4.6.2.

Nun denkt man so, dass der von Suse als RPM ausgelieferte aktuelle Flashplayer 10.2 in der 32Bit-Variante über den üblichen “nspluginwrapper”-Mechanismus mit Firefox 4 (64 Bi) vernünftig zusammenarbeiten würde. Schießlich ging das mit Firefox 3.6.16 (64 bit) unter Opensuse 11.3 ja auch problemfrei !

Beim Firefox 4 (64 Bit) ist dem leider nicht so! Komplexe Flash-Filme oder sogar Adobe eigene Flashelemente (etwa die Audio oder Video-Player) werden häufig durch Darstellungsfehler so entstellt, dass es keinen Spaß mehr macht, Flash-Seiten anzusehen. Fehler über Fehler ! Man fragt sich, ob das jemals vernünftig getestet wurde ….

In meiner Not habe ich dann mal wieder nach einer halbwegs aktuellen 64Bit -Variante des Flash-Players für Linux umgesehen. Damit habe ich früher schon ganz gute Erfahrungen gemacht. Fündig wird man zur Zeit unter

http://labs.adobe.com/technologies/flashplayer10/square/

Ich habe mir dort die aktuelle Version heruntergeladen. Zur Installation der “libflashplayer.so”-Datei unter Opnsuse sehen Sie bitte folgenden früheren Beitrag:

https://linux-blog.anracom.com/2009/01/26/kurztest-der-64-bit-version-des-flash-plugins-von-adobe/

Bitte nicht die vorher notwendige Deinstallation des “nspluginwrapper” vergessen.

Das Ergebnis des Tests der 64-Bit-Variante: Das allermeiste an Flash-Seiten wird richtiger und schneller dargestellt als mit der für 64-bit Linux und 64-Bit Firefox 4 völlig ungeeigneten offiziellen 32Bit-Variante des Players.

Bleibt erneut die Frage offen: Wann sehen die verantwortlichen bei Adobe endlich ein, dass sie für Linux eine vernünftige “offizielle” 64Bit-Unterstützung bieten müssen?