Roland Skop: CSS3 lernt mit der Funktion calc() rechnen / Vergleich mit box-sizing

Mit einer neuen Methode soll es in CSS3 möglich sein, Werte zu berechnen und somit absolute und relative Einheiten in Beziehung zueinander zu setzen, was den Umgang mit dem Boxmodell erleichtern würde.

CSS bis einschließlich Version 2.1 erlaubt die Zuweisung relativer oder absoluter Werte, beispielsweise mittels width einer Breite von 100%, 30em oder 200px. Problematisch ist dies vor allem dann, wenn Einheiten gemischt notiert werden müssen, da eine Umrechnung nicht zuverlässig möglich ist.

Das am weitesten verbreitete Problem dürfte die Kombination aus width:100% und padding/margin/border darstellen. Da deren Werte gemäß CSS-Boxmodell addiert werden, ergibt sich eine Breite von über 100 Prozent. Zwar soll es künftig möglich sein, W3C-konformen Browsern mittels box-sizing das Box-Modell des Internet Explorer aufzuzwingen, doch wäre es wünschenswert, Ausmaße in der Form em ± px notieren zu können.

Der am 19.09.2006 veröffentlichte Entwurf des CSS3-Werte- und Einheiten-Moduls enthält eine interessante Funktion namens calc(), die nun genau das ermöglichen soll.

Gegeben seien zwei Elemente mit den IDs a und b, die sich den verfügbaren Platz teilen und einen Rahmen von 3px Stärke aufweisen sollen.

Beispiel für calc()

#a, #b {
  float:left;
  border:3px double black;
  width:calc(100%/2 - 2*3px);
}

Die innerhalb von calc() definierten Größen werden vor der Anwendung auf die Elemente berechnet. Daraus ergibt sich für width effektiv eine Innenbreite von 50% minus zweimal 3px, die vom linken und rechten Rahmen vereinnahmt werden. In Summe, das heißt nach Addition von width und border gemäß W3C ergibt sich eine Gesamtbreite von jeweils 50 Prozent:

50

0% - 6px gemäß calc() + 6px Rahmen links und rechts --------- 50% Gesamtbreite

Ergebnis: Die Elemente werden wie gewünscht nebeneinander dargestellt.

Beispiel für box-sizing

#a, #b { float:left; border:3px double black; width:50%; box-sizing:border-box; }

Ergebnis: wie oben, da die 50 Prozent für die Außenbreite einschließlich Rahmen gelten und der Inhalt entsprechend schrumpft.

Offen ist, ob Autoren eher auf calc() und das ursprüngliche W3C-Boxmodell, oder auf box-sizing:border-box (das für den Mac-Internet Explorer erfunden wurde) und das MS-Boxmodell setzen werden. Derzeit hat box-sizing die Nase weit vorne, da diese Eigenschaft von IE für Mac, Mozilla/Firefox (nur mit Präfix -moz-), Opera und Safari bereits unterstützt wird, calc() dagegen von keinem einzigen Browser, liebe Standardistas …

SELF-Wiki: Berechnungen- Die calc()-Funktion

  1. Mit solchen Pseudo-Programmiersprachennotationen wird aus CSS noch irgendwann eine Turing-fähige Sprache ;-)

  2. … und mit Version 4 wird CSS dann in JavaScript umbenannt ;-)

  3. Jau. Vllt. schafft man es bei CSS 5 auch, eine Box ohne 1000 Zeilen Code genau in die Mitte zu setzen. *g*

  4. Auf den ersten Blick freut mich diese Idee, sie löst doch diverse Layoutproblem und zeigt, daß das W3C doch manchmal zuhört. (Oder es bekommt manchmal "Notizen aus der Praxis" gesteckt.) Aber bei näherer Betrachtung irritiert mich die gesamte CSS3-Entwicklung doch sehr. Zum einen wird modularisiert wie bei XTML. Das macht den Überblick nicht leichter. Dann werden auf einmal zwei Boxmodelle erlaubt. Sehr seltsam. Und zu guter Letzt werden die Grenzen zwischen Layout und Skripting eingerissen.

    Ich fürchte auch, daß CSS irgendwann zu einer Skriptsprache mutiert. Was soll das? Die einzige Sache, die mich dabei "beruhigt" ist: vor 2010 ist bestimmt nix mit CSS3. Sollte das W3C wider Erwarten vorher in die Puschen gekommen sein, haben die Browserhersteller damit noch lange nichts umgesetzt.

    Es wär schön, wenn wir auch sowas wie CSS-Mikroformate bekämen, eine Problemlösung für heute, ohne die Herren Philopsophen des Wolkenkucksheims.

  5. calc() kennt der IE nicht, aber ein ähnliches Feature bereits seit Version 5: Dynamic Properties. Siehe http://msdn.microsoft.com/workshop/author/dhtml/overview/recalc.asp. Damit kann man zumindest JScript-Anweisungen direkt in Style-Bereichen unterbringen.

  6. Woher soll auch irgendein Browser calc() kennen, wenn die CSS WG sich erst zu dieser Zeit auf eine konkrete Syntax geeinigt hat und diese vor drei Tagen veröffentlicht hat, um Feedback zu bekommen? Vor einem Jahr war es ja nur ein flüchtiger Gedanke. Manchmal zweifel ich wirklich an eurem Leseverständnis.

  7. Was hier immer gleich für ein Theater losgeht, nur weil mal eine grosse und auch sinnvolle Neuerung präsentiert wurde. Für mich geht das Ganze keineswegs in Richtung JavaScript/Scriptsprache allgemein, sondern vielmehr in Richtung XSLT, und das finde ich auch gut so. Selbst beim Design muss ein bisschen Programmiererei möglich sein, um gewisse Dinge sinnvoll zu implementieren.

    Ich frage mich allerdings auch, wieso das W3C zwei verschiedene Möglichkeiten für ein und dieselbe Sache präsentiert – das verwirrt mehr, als es nützt.

  8. Jens, die Modularisierung halte ich für äußerst sinnvoll, da damit keine vollständige Implementierung aller Möglichkeiten erforderlich ist, um dann CSS3 als Ganzes zum Standard zu erheben. Jedes Modul, das den Prozess vollständig durchlaufen hat, ist damit für sich ein gültiger Standard. Angesichts der doch vorhandenen Bürokratie bin ich froh, dass es so ist. Andernfalls würde das vermutlich ewig dauern.

    Deine Skepsis betreffend die Browserhersteller kann ich nicht so recht nachvollziehen. Viele CSS3-Selektoren funktionieren bereits, Media Queries werden fleißig implementiert, usw. usf. Mir scheint, der Fokus liegt derzeit sogar mehr auf CSS3 als auf den Dingen, die von CSS2.1 noch offen sind.

  9. Ich verstehe nicht, warum in diesem und in anderen Fällen hier und anderswo sofort auf etwas geschimpft wird, das wir alle doch sicher schon vermisst haben: Berechnungen im Stylesheet für Positionierung und Größe.

    Für mich sind die nur logisch und konsequent. Wenn ich Inhalt und Form sauber trennen will, mich also weder im HTML-Bereich mit Layout befassen, noch in der Seite per Skript irgendwelche Positionierungen und Größen angeben will, aber gleichzeitig die Vorteile von HTML - die flexible Anapssung an beliebige Umgebungen nämlich - nutzen will, dann brauche ich genau so etwas. Was sehen wir heute in durchaus sauberen Seiten im CSS-Part? Oft so etwas wie # content { width: 750px; }

    Ich persönlich versuche zwar, das zu Gunsten flxiblen Layouts zu vermeiden, aber die Klimmzüge sind gewaltig und die Ergebnisse nicht immer optimal. Klar kann ich per Javascript das alles schöner machen. Aber genau das will ich eben nicht - und die Schreiber über mir augenscheinlich auch nicht. Denn es gehört nicht in noch einmal zusätzlich Aufgesetztes (Skript), sondern dahin, wo das Layout beschrieben wird, in den CSS-Part.

    Genau aus diesem Grund hat das, was wir hier lesen, eben mit Java- oder Was-weiß-ich-Script gar nichts zu tun. Es kommt endlich dorthin, wo es logisch hingehört, wo es sinnvoll ist und wo es gebraucht wird.

  10. Diese Berechnungen haetten ja was fuer sich, allerdings bin ich auch davon ueberzeugt, dass dies bei Puristen nicht generell auf Verstaendnis stossen wird.

    Der Browser aus Norwegen wird mit Sicherheit der Erste sein, der erlauben/verbieten fuer sowas wie calc() implementieren wird. Es kann ja nicht sein, dass der Ersteller eine Hoheit ueber sein Werk erhaelt. Der User will ja selber entscheiden koennen, wie breit er einzelne Elemente darstellen will. ;-)

    Na denn, harren wir der Dinge. Ich bin irgendwie zwiespaeltig bei dem Gedanken, dass auch in CSS Programmlogik jedweder Art eingefuehrt wird.

  11. allerdings bin ich auch davon ueberzeugt, dass dies bei Puristen nicht generell auf Verstaendnis stossen wird.

    Was sind Puristen in diesem Kontext? Wieso sollte man die Fähigkeiten von calc() ablehnen? Die Probleme, die damit gelöst werden können, sind doch alltäglich.

    Der Browser aus Norwegen wird mit Sicherheit der Erste sein, der erlauben/verbieten fuer sowas wie calc() implementieren wird.

    Wieso? Inwiefern kann calc() im Speziellen den Anwender einschränken und wieso sollte ein Browser im Speziellen diese Möglichkeit unterbinden?

    Es kann ja nicht sein, dass der Ersteller eine Hoheit ueber sein Werk erhaelt.

    Was ist das für eine seltsame Unterstellung? »Der Browser aus Norwegen« ist z.B. der erste, der Media Queries unterstützt, womit sich sehr anpassungsfähige Layouts umsetzen lassen.

    Opera unterstützt – wie andere Browser auch – das selektive Ausschalten und Zuschalten von Stylesheets sowie Optionen zur Anpassung an die jeweiligen Gegebenheiten. Wenn der Anwender z.B. »Fit to width«, »Small screen« oder den Zoom benutzt, wird wahrscheinlich auch calc() außer Kraft gesetzt, sollte Opera das irgendwann unterstützen. Das wäre aber keine besondere Behandlung von calc(), das gilt jetzt schon für normale Werte und würde dann nur übertragen – das wird in jedem Browser mit entsprechenden Fähigkeiten so gehandhabt.

    Ich verstehe deinen Gedankengang ehrlich gesagt nicht... Natürlich verliert der Ersteller die Hoheit über sein Werk, weil jeder Browser das durch Schriftgrößeneinstellungen, Benutzerstylesheets usw. vornimmt. Das ist aber nichts neues, so ist das Web eben im Gegensatz zu Print. Der Trend geht zu Browsern, die individuelle Anpassung ermöglichen. Bist du generell gegen diese Konfigurierbarkeit? (Ok, was hat das mit calc() zu tun?)

  12. Lieber Tim, den Vorwurf mit dem Leseverständnis kann ich so nicht auf mir sitzen lassen. So natürlich ist das auch wieder nicht, dass noch kein Browser calc() implementiert haben kann. Gerade bei HTML zeigt doch die Geschichte, dass manchmal Implementierungen vor einer Spezifikation da sind und letztere um erstere drumrumgestrickt werden (müssen). Ich hätte statt meines einleitenden Halbsatzes sicher auch etwas anderes formulieren können, und vielleicht war er missverständlich, doch er, bzw. mein Beitrag im Ganzen, sollte keineswegs, liebe Christine, als Geschimpfe - und ein solches kann ich auch nicht in den anderen Beiträgen vor dir erkennen - angesehen werden. Mein Anliegen war nur, wertungslos zu informieren, dass es etwas Ähnliches gibt.

    Vielleicht ist der Gedanke zu calc() auch aus der Kenntnis der ein ähnliches Ziel verfolgenden IE-Implementation entstanden. Vielleicht hatten auch beide, Implementierer und Vorschlagender, unabhängig voneinander das gleiche Ziel vor Augen, nur der eine ging es halt diktatorisch an und der andere demokratisch ...

    (Sollte ich hiermit die Falschen angesprochen haben, so bitte ich doch darum, die Kritik beim nächsten Mal konkret zu adressieren und nicht nur allgemein zum Ausdruck zu bringen. Danke.)

  13. Moin Mathias,

    irgendwie hast Du was in den falschen Hals gekriegt oder ich haette vielleicht noch einen Punkt ironischer formulieren sollen, denn so war es eigentlich gedacht.

    Nein, ich bin *nicht* gegen persoenliche Konfigurierbarkeit, warum auch. Nur ist es doch so, dass heute bereits verschiedene Einstellungen des Autors durch den Benutzer ausgehebelt werden koennen. calc() waere sicherlich eine feine Sache, aber die Vergangenheit zeigte doch, dass viele feine Sachen mit z.B. Javascript relativ einfach abgeschaltet werden koennen. Und irgendwann werden Leute auf die Idee kommen, dass sie berechnete Elementbreiten eben nicht wollen, weil es z.B. bei einem moeglichen Einsatz von Spaltentext vielleicht nicht ihrer Lesegewohnheit entspricht und sie beide Elemente eben untereinander wollen.

    Es war ja nur ein Denkansatz von meinereiner bzgl. Rechenlogik in CSS und dass gerade Opera viele Features fuer Aushebelungen und Einstellungen als Erster ermoeglichte, duerfte wohl unbestritten sein, darunter mit Sicherheit der ueberwiegende Anteil sinnvoll, ueber andere liesse sich trefflich streiten, je nach Standpunkt. Opera zeigt sich halt sehr innovativ bzgl. Weiterentwicklungen.

    Also nochmal zur Klarstellung: Ich bin nicht gegen calc(), Userstyles o.ä.

  14. Wilhelm, dass allerlei Unsinn deaktiviert werden kann ist gemeinhin bekannt, doch bei CSS viel weniger verbreitet als bei JavaScript, sieht man von etwaigen Mindestschriftgrößen ab, die dann aber eher direkt in den Browsereinstellungen als über ein Benutzerstylesheet definiert werden. Mir fällt auch kein Szenario ein, das es erforderlich machen könnte, calc() punktuell zu deaktivieren. Da auf Abwärtskompatibilität geachtet werden wird, käme in solchen Fällen eine Darstellung analog zu nicht calc-fähigen Browsern zum Tragen:

    selektor {
      width:10em; /* Fallback */
      width:calc(100%/2);
    }

    Viel spannender finde ich da die Frage, ob sich derartige Neuerungen jemals durchsetzen werden, wenn man dennoch über Jahre hinweg HTTP-Kröten™ bedienen muss, die damit nichts anzufangen wissen.

  15. Somit würde dann endlich die Mühsame Doppeldefinition für IE hinfällig, was letztlich automatisch einen höheren Stundenlohn bei pauschal Aufträgen bedeuten würde! Hehe! Mich (und viele andere) freut es!

  16. Ich freue mich schonn auf calc() und hoffe, dass sich das sehr schnell durchsetzt. Denn genau sowas brauche ich oft. Man könnte CSS natürlich auch ganz umdefinieren und angeben, das Margin/Boder werte automatisch vom width abgezogen werden, aber dass währe ja auch nix anderes als die Calc Funktion, nur schon eingebaut.

  17. Also ich freue mich auch schon CSS3 aber welcher Browser kann es schon? Firefox 2.0 oder Inet Expl 7.0? Wer hat hier Erfahrungen?

    Gruß

    Gerald

  18. In meinen Augen ist das "Flickschusterei" auf der falschen Baustelle!

    CSS ist als HTML-Ergänzungssprache konzipiert worden, um die jeweiligen HTML-Elemente entsprechend zu formatieren (Stichwort: Trennung von Inhalt und Design). Leider ist man dabei auch so vorschnell gewesen, oder hat nicht über die Reichweite der Entscheidung nachgedacht, auch die Positionierung mit einzubeziehen. Und hier fängt das Verhängnis an, denn wenn ich davon ausgehe, dass eine Textauszeichnungssprache wie HTML sich eben nur auf Text bezieht, dann erwarte ich eigentlich auch nur dafür relevante Elemente. Und Text besteht im wesentlichen meist aus Überschriften, Absätzen und einzelnen Wörtern. Zusätzlich können auch noch Bilder enthalten sein. Wobei man schon auf das erste Problem stößt. Denn Bilder sind eigentlich, was ihre Informationsübermittlung anbelangt, auf visuelle Ausgabemedien angewiesen.

    Und eben bei diesen stoßen wir auch in erster Linie auf die Notwendigkeit der Positionierung von Inhalten (wohingegen bei den meisten anderen Ausgabemedien, wie etwa bei Screenreadern (aural) oder Braille lediglich die Reihenfolge wichtig ist).

    In dem Bestreben auch diese Anforderungen mittels CSS umzusetzen, musste man ertsmal entsprechende Elemente in HTML hinzufügen, wie etwa das DIV-Element in HTML 3.2 oder das SPAN-Element in HTML 4.0. Diese "sinnfreien" Elemente stehen nach meinem Verständnis schon im Widerspruch zu einem semantisch korrekten Markup und dienen lediglich als "Krücke" für eine mögliche Positionierung von Inhalten mittels CSS.

    Da aber für eine Positionierung von Inhalten die entsprechenden Gegebenheiten beim verwendeten visuellen Ausgabegerät/ -programm des jeweiligen Benutzers eine entscheidende Rolle spielen, kann man hier keine individuell zufriedenstellende Ergebnisse erreichen, ohne diese Gegebenheiten zu kennen.

    Hier wäre also eine gewisse "interaktive" Programmlogik von Nöten, um dies zu ermöglichen, und zwar so, dass auch deren Zuverlässigkeit gegeben ist. Nicht wie etwa bei Javascript, welches man eben nicht zuverlässig für diese Zwecke einsetzen kann.

    Ich bin der Meinung, dass man für diesen Zweck besser eine zusätzliche, dritte Sache ins Spiel bringen sollte - eine Layoutsprache! Diese müsste eine Programm-Logik, sowie eine Kommunikation mit dem Browser zulassen. Ein weiterer Vorteil wäre, dass man durch die neue Einführung für alle Browserhersteller dieselben Startbedingungen hätte, auf keine Abwärtskompatibilität achten müsste und ältere Browser, getreu dem Motto "Was ich nicht verstehe, ignoriere ich!", damit auch kein Problem kriegen würden.

    Diesen Ansatz erachte ich jedenfalls für wesentlich besser, als den Versuch, Dinge in CSS zu implementieren, für die es erstens nicht gedacht/ gemacht ist, und die in ihrer praktischen Umsetzung wahrscheinlich mehr neue Probleme aufwerfen dürften, als dass sie vorhandene lösen.

    Aber auf mich hört ja keiner ;)

    Gruß Gunther

  19. Ich kann mich da Gunthers Ausführungen nur anschließen und bin der Hoffnung, dass diese Idee bis zum W3-Konsortium durchdringt.

  20. Die Idee finde ich super, ist genau das, was ich schon die ganze Zeit vermisse. Die Syntax wundert mich zwar, denn m.E. könnte man das "calc()" auch weglassen und einfach direkt die Formel hinschreiben (z.B.: "width: 10px + 8em + 10%;"), aber damit könnte man leben. Ich hoffe jedoch ganz schwer, daß die Spezifikatoren bei den Prozentangaben auch die Möglichkeit vorsehen, sich nicht nur auf das Vaterelement zu beziehen, sondern auf einen beliebigen Ahnen, mindestens aber auf die Fenstergröße. (Alle Prozentangaben auf die Fenstergröße zu beziehen würde die Gestaltung geradezu revolutionär vereinfachen.)

  21. Gute Idee. Aber die Funktion calc() bei css3 kann nicht von allen Brownser unterstützt werden.

  22. Interessantes Thema! Wann ist es soweit mit CSS3?