prozentuale Angaben - was Browser meinen zu verstehen
codestyling | 18. Januar 2009 | 22:20
Während der Arbeit an meinem neuen, erweiterten Plugin Page Columnist hab ich schmerzhaft zur Kenntnis nehmen müssen, daß Browser eine eigene Vorstellung von Mathematik, Prozentrechnung und Fehlerkorrektur haben.
Es ist ja schon länger bekannt, daß es Probleme gibt, wenn man mit prozentualen Angaben arbeitet. Wenn man jedoch versucht, auf die Eigenheiten der Browser einzugehen, erlebt man ungeahnte Überraschungen.
Eine allgemein gültige Lösung des Problems scheint unmöglich, man kann sich dem nur annähern.
Ziel meines neuen Plugins ist es ja, die nextpage Funktionalität von WordPress im Bereich der Seiten sozusagen zu erweitern, damit diese wahlweise die Unterseiten als Spalten darstellen kann. Dies würde eine normale Eingabe der Spalteninhalte ermöglichen und man braucht nur die nötigen Spalten per nextpage abzutrennen.
Diese Herangehensweise kommt dem normalen Blog Nutzer entgegen, der sich mit Themes, PHP und CSS nicht auseinander setzen will. Auch sind Herausgeber eines Blogs dann in der Lage, Seiten im Spaltenlayout zu entwerfen, ohne in das Theme eingreifen zu müssen.
prozentuale Angaben für die Breite von div Containern
Die Browser verstehen ja alle prozentuale Angaben für Breiten und auch Ränder. Somit sollte es ja einfach sein, die Breite der zu erzeugenden Spalten prozentual von 100 % her ausrechnen zu lassen unter Berücksichtung von y Rändern zu je x % zwischen den Spalten. So wurde auch das ursprüngliche Konzept erstellt und umgesetzt.
Als Ergebnis dessen zeigte sich, das alle Browser bis auf den IE in der Lage waren, die links umfließenden Spalten nebeneinander zu bekommen. Der IE patzt bei der letzten Spalte je nach “Mondstand” und bricht diese unter die existieren Spalten um. Was also macht der IE da ?
Testarena von 4 Browsern
Um dem Ganzen auf den Grund zu gehen, hab ich in der Entwicklerversion des Plugins die Breiten der entsprechenden Spalten mit anzeigen lassen und die 4 Browser mit dem auf Breite fixierten Standard-Theme übereinander verglichen. Hier das Ergebnis:
Wie man dem Test entnehmen kann (bitte anklicken zum vergrößern), haben einige Browser eine merkwürdige Vorstellung von Prozentrechnung.
Obwohl alle Browser durch die Bank weg mit 31.33 % Breite der Container erzeugt wurden, sind die realen Pixel basierten Breiten sehr unterschiedlich.
Firefox und erstaunlicherweise auch IE errechnen dafür 141px reale Breite. Opera aber meint, das dieser Prozentwert nur 139px entspricht und der Safari hat Mut zur Lücke und kommt auf 140px.
Das ergibt nun schon mal 3 verschiedene Summen:
- Firefox und IE: 141px * 3 = 423px
- Safari: 140px * 3 = 420px
- Opera: 139px * 3 = 417px
Das sind schon 6px Differenz zwischen größter und kleinster Kalkulation, die man deutlich sehen kann. Aber dem eigentlichen IE Problem kommt man über die Spaltenbreite nicht auf die Schliche, denn diese stimmt mit der von Firefox überein. Übrigens hat Firefox keine Fehler in all den Tests gemacht und dient als Referenz für alle anderen Browser bei mir.
Wurzel des IE Übels - prozentuale Ränder (margin)
Der IE beherrscht es überhaupt nicht gut, mit margin Angaben auf prozentualer Ebene umzugehen. Selbst wenn alle errechneten Werte aller Spaltenprozente und Abstandsprozente exakt 100% in Summe sind, bricht der IE unter Umständen die letzte Spalte um. Selbst wenn man künstlich dafür sorgt, dass man unter 100% bleibt und niemals 100% erreicht, hilft das überhaupt nicht. Denn die margin Werte in % Angaben rechnet der IE irgendwie falsch, jedoch ist nicht erkennbar nach welchem Muster.
Daher hab ich mich entschieden, für IE alle margin Werte mit einem serverseitigen Korrekturfaktor anzupassen. Sagen wir mal 3% ist der eigentliche margin Wert. Dann werden alle Spaltenbreiten unter Berücksichtigung von 3% Abständen berechnet, was auch stimmt, nur werden die margin Werte selbst dann nicht mit 3% sondern mit 3% * 0.66 = 1.98% eingetragen. Dieser Korrekturwert ist bei Tests mit fluid Themes entstanden, die auch 1600px Breite ausnutzten.
Der Pferdefuß daran ist, wenn die verfügbare Gesamtbreite niedriger wird, müßte dieser Fehlerkorrekturwert umgekehrt proportional (evtl. logarithmisch) ansteigen. Im Standard-Theme bräuchte man so in etwa den Korrekturwert 0.75 was zu 2.25% führen würde. Diese margin Korrektur ist im Screenshot auch zu erkennen, aber für den IE nicht anders lösbar. Wenn jemand einen besseren Vorschlag hat, ich bin gespannt.
Fazit der bisherigen Tests
Als einziger Browser kann Firefox die verfügbare Gesamtbreite gleichmäßig aufteilen, hat eine hervorragende Fehlerkorrekturrechnung und nutzt exakt die 100% Summe aller Spaltenbreiten und Abstände, um auf die geforderten 100% total zu kommen.
Der IE kann zwar erstaunlicher Weise die Spaltenbreiten korrekt berechnen, hat aber erhebliche Probleme, die Abstände in den Griff zu bekommen. Eine 100% Summe führt je nach verfügbarer Gesamtbreite zum Umbruch der letzten Spalte, hier muß man in die Angabe der Abstände eingreifen, um Schlimmeres zu verhindern!
Opera und Safari haben in den Tests zwar nie umgebrochen, jedoch nutzen sie die 100% Gesamtbreite nicht aus. Je nach verfügbarer Gesamtbreite variiert der verbleibende Leerraum nach der letzten Spalte. Während das beim Safari nur eine geringe Toleranz zu sein scheint, macht Opera zum Teil wilde Sprünge von mehr als 10px, wenn man kontinuierlich die Gesamtbreite erhöht.
Wenn man also prozentual arbeiten möchte (oder muß), sollte einem klar sein, das es Leerraum am Ende geben kann und das man den IE eine spezielle Behandlung zukommen lassen muß.






Pascal
18.01.2009 | 23:35Hast du auch schon mit ems gearbeitet? Damit kann man auch ganz viel anstellen. siehe zum beispiel hier: http://greattalk.ch/2008/02/09/die-unglaublichen-em-elastischen-layouts-mit-css/
Antworten »
codestyling
18.01.2009 | 23:44Mit em kann man arbeiten (genauso wie mit exakter px Rechnung), wenn man hart codierte Breiten im Theme hat. Das ist aber bei fluid Themes, die ihre Content Breite der Bildschirm/Browser Breite direkt anpassen können, keine Option. Denn man kann dann ja nur 100% einer unbekannten Breite berücksichtigen, denn der User entscheidet erst bei Anzeige in seinem Browser darüber, wie breit es wirklich wird.
Für einen Ansatz auf fester Breite im Theme wäre allerdings auch px möglich, den hierbei kann die Fehlerrechnung auf’s Pixel genau gemacht werden. Denn Rundungsfehler müsste man pro Browser ggf. aber anders korrigieren.
Antworten »
flöschen
19.01.2009 | 00:23Interessante Ausführung. Ich kann mir gut vorstellen, wie du die Wände hochgehst, weil irgendwo wieder komisch gerechnet wird.
Antworten »
Monika
19.01.2009 | 15:03da ich zu einem hohen % nur mit % arbeite
ein wenig besser wird es, wenn man zumindest auf einer Seite left right mit fixen px arbeitet und die jeweils andere % ausrechnen läßt. Da habe ich öfter schon 4.58% wo stehen und dann passt es.
Grund der Rechnerei ist - alle gehen von unterschiedlichen Eckdaten aus wovon sie die 100% hernehmen.
Der eine nimmt einen etwaigen border mit dazu, der andere berechnet den border extra - der 3. Browser nimmt nur die border Breite von Links dazu ..
bloß ich weiß mittlerweile worauf ich achten muss und Feldforschungen erspar ich mir meist -
dazu fehlt mir die Geduld
lg
Antworten »
codestyling
19.01.2009 | 15:27Leider sind die Eckdaten ja bei allen gleich:
- äußerer Container hat keine margin, kein padding und keine Border (100% Basis).
- innere Container (Spalten) haben ebenfalls kein padding und keine Border.
Nur ab der 2. Spalte haben die Spalten eine prozentuale margin links. Also sollte die Rechengrundlage für alle identisch sein, solche Späße wie Border oder Padding sind dadurch außen vor.
Deshalb ist es ja verwunderlich, dass jeder Browser eine andere Vorstellung von Prozentrechnung hat.
Antworten »
flöschen
19.01.2009 | 18:07Ist eigentlich nicht das Box Model massgebend für solche Dinge? Aus einem Grund hat man es ja mit all den Standards erschaffen…
Antworten »
codestyling
19.01.2009 | 18:23Im Normalfall schon. Ab IE 7, den ich hier im Test habe (IE 6 unterstütze ich aus Protest nicht mehr), verarbeitet der auch korrekt den Doctype mit dem korrekten Box Model. Somit haben alle die gleiche Voraussetzung. Wenn es dann immer noch nicht klappt, ist das ein mathematisches Problem im Browser und nicht eine “Interpretation” eines falschen Box Models.
Antworten »
f-j-k
25.01.2009 | 15:35wenn ich mir deinen screenshot so anschaue, dann seh ich beim ff rechts gar keinen abstand mehr. würde es nicht im sinne des layouts sowieso sinn machen nur zwischen den spalten einen abstand zu haben? dann würde es ja auch nur darum gehen, ob der browser die spaltenbreite richtig berechnet. was ich mir auch vorstellen könnte, wäre dass man statt prozent einfach deppenprozentrechnungen mit variablen macht. also spaltenbreite ist $variable1 und der abstand zwischen den spalten ist $var2=($var1 *100)/110 für zB10% und so dem browser gar nicht erst die möglichkeit gibt, selbst zu rechnen. wenn du die prozent eh aus einer admin-einstellung/db-zelle holen musst, ist es doch eh schon wurscht obst jetzt deswegen 2,3 variablen mehr einsetzt und holst, oder?
beste grüße!
Antworten »
codestyling
25.01.2009 | 16:58Das Plugin erzeugt auch nur Abstände zwischen den Spalte, deshalb ist der Screenshot von Firefox ja auch ok. Nur die anderen Browser haben eine komische Vorstellung von Umrechnung von % in Pixel. Deshalb bleibt dann auch in den anderen Browsern rechts ein “Rest”, was den Rechenfehler darstellt.
Die % Werte sind korrekt ermittelt, wenn ich das so rechnen würde, wie von dir vorgeschlagen, würde der “Rest” rechts nur noch größer werden.
Antworten »
f-j-k
25.01.2009 | 17:07Ich hab ja eigentlich gemeint überhaupt keinen “Rest” aufkommen zu lassen. Also nur die Spaltenabstände zu errechnen. Oder kommst Du um den “Rest” rechts nicht herum? Weil dann hab ich Dein Problem leider nicht richtig verstanden.
Antworten »
codestyling
25.01.2009 | 17:28Beispiele für 48,5% | 3% | 48,5% bei 450 px Breite des Containers
Firefox: 218px | 14px | 218px = 450px -> Rest 0px
IE: 218px | 12px | 218px = 448px -> Rest 2px
Einige Browser berechnen auch die Spaltenbreite durch Rundungsfehler nicht korrekt, somit summieren sich die restlichen Pixel je Browser und Spaltenanzahl dann auf und sind dann wegen float: left immer rechts zu sehen. Grundübel ist die falsche Rundung in den Browsern, wenn gebrochene Pixel das Resultat der Prozentrechnung sind. Außer Firefox gleicht das kein anderer Browser aus.
(IE hat auch noch andere Rechenmacken, die allein mit Rundungsfehlern nicht erklärbar sind)
Antworten »
f-j-k
25.01.2009 | 17:33was wäre mit folgender idee: zuerst die gesamtbreite erruieren, dann diese mit der summe der px-werte, die sich aus den %-werten ergeben vergleichen. mit der differenz kannst du dann ja irgend etwas machen, wie zB die hälfte jeweils auf die spaltenabstände aufrechnen. bei 4-spaltigem layout dann auf die spalten selbst usw (gerade»spaltenabstand, ungerade»spaltenbreite). ich glaube, dass sich das mathematisch sicher umgehen lässt… als anderer vorschlag könntest du ja auch die rundungswerte selbst (mathematisch) au ganze zahlen auf- oder abrunden…
Antworten »
codestyling
25.01.2009 | 18:04Das ist ein Problem, wenn man fluid Designs benutzt und kein Javascript erlaubt. Bei fixen Layouts könnte der Benutzer die exakte Pixelbreite bei der Erstellung der Seite angeben und man könnte das von Anfang an in Pixel korrekt ausrechnen (inklusive eigener Fehlerkorrektur). Aber bei fluid designs, die ihre Breite dynamisch der Auflösung der Browserfensters anpassen, kann man genau das nicht. Denn man müsste immer wieder bei Änderung der Fenstergröße die Breite neu besorgen und alles umrechnen und neu ausrichten.
Dies würde beim 1. Aufruf der Seite erfordern, das irgendwie die Fensterbreite mit übertragen wird und Javascript im Browser, der bei resize des Fensters, die Spalten live neu rechnet.
Beides versagt bei ausgeschaltetem Scripting im Browser, was in manchen Firmen z.B. zur Policy gehört !
Antworten »
f-j-k
25.01.2009 | 20:18Na gut. Da bin ich mit meinem Latein jetzt wirklich am Ende… Vorallem, wenns Fluid und ohne JS sein soll. …
Antworten »