Eddie: Verhält sich <div> inkonsistent?

Hallo allerseits!

Ehrlich gesagt verstehe ich das Verhalten von <div> noch nicht so ganz. Könnt ihr mir sagen, warum diese beiden <divs> eine verschiedene Breite haben?

====================
<div style="border-style:solid;">
    Text über die gesamte Breite
</div>

<div style="position:absolute; top:280px; border-style:solid;">
    Text über ein paar Zentimeter
</div>

Ich hätte gerne, dass das zweite <div> sich von der Breite her so verhält, wie das erste - nämlich automatisch den gesamten Platz einzunehmen.

Danke Euch, Eddie

(P.S.: hey COOL, die Vorschau-Funktion ist wieder die alte!!!)

  1. Hi!

    Ehrlich gesagt verstehe ich das Verhalten von <div> noch nicht so ganz. Könnt ihr mir sagen, warum diese beiden <divs> eine verschiedene Breite haben?

    Mit position:absolute verlierst du die Beziehung zum Dokument, also auch die Breite.
    Diese musst du dann explizit setzen!

    cu

    Marc Reichelt || http://www.marcreichelt.de/

    --
    Linux is like a wigwam - no windows, no gates and an Apache inside!!!
    SELFCode: ss:| zu:) ls:[ fo:} de:[ va:} ch:? sh:) n4:° rl:? br:^ js:( ie:% fl:) mo:)
    http://emmanuel.dammerer.at/selfcode.html
    1. Ehrlich gesagt verstehe ich das Verhalten von <div> noch nicht so ganz. Könnt ihr mir sagen, warum diese beiden <divs> eine verschiedene Breite haben?

      Mit position:absolute verlierst du die Beziehung zum Dokument, also auch die Breite.

      Jein. Absolut positionierte Elemente richten sich nach dem nächsthöheren Elternelement aus, welches als position nicht static (also Normaleinstellung) hat, siehe http://www.w3.org/TR/REC-CSS2/visudet.html#containing-block-details.

      Diese musst du dann explizit setzen!

      Nein. Die Berechnung der Breite von absolut positionierten, nicht ersetzten Elementen ist unter http://www.w3.org/TR/REC-CSS2/visudet.html#abs-non-replaced-width beschrieben. Dort ist klar beschrieben, daß die Gleichung

      left + margin-/border-/padding-left + width + padding-/border-/margin-right' + 'right'

      "width of containing block" ergeben soll (der "containing block" ist jenes eben beschriebene Elternelement). Noch etwas weiter in den Details gewühlt, kommt zu Tage, daß Eddies <div>-left die aktuelle Elementposition bekommt, weil es 'auto' ist (Regel 1), right 0 wird, weil width 'auto' ist (Regel 3), margin links und rechts 0 werden, weil width immernoch 'auto' ist (Regel 4) und -last but not least-, width die restlichen Pixel bekommt, wegen 'auto', genau (Regel 6).

      Unter diesen Gesichtspunkten müsste das absolute <div> IMHO tatsächlich die volle Fensterbreite einnehmen. Der Haken ist aber die Frage, was nun genau den Container darstellt, denn das hängt vom Browser ab, falls das Element kein passendes Elternelement (s.o.) findet. Für mein Verständnis müsste das das Browserfenster sein, aber möglicherweise sehen die Browserschreiberlinge das anders..

      Gruß,
        soenk.e

      1. Hallo Sönke,

        [Die Breite] musst du dann explizit setzen!

        Nein. (...) Unter diesen Gesichtspunkten müsste das absolute <div> IMHO tatsächlich die volle Fensterbreite einnehmen.

        Vielleicht habe ich nicht verstanden, worauf du hinaus willst, aber redest du davon, wie sich die Browser verhalten sollten, wenn die Breite explizit auf 100% gesetzt wird? Denn komplett ohne width-Angabe richtet sich die Breite eines absolut positionierten Elements offensichtlich nach dessen Inhalt (in dem Fall Text). right wird im Normalfall nicht 0 und der rechte Rand des Elements endet auch nicht am rechten Rand des Browserfensters, sondern schon vorher nach Ende des Inhalts (sofern selbiger wie im Beispiel kürzer ist), wie das Ursprungsbeispiel zeigt.

        Der Haken ist aber die Frage, was nun genau den Container darstellt, denn das hängt vom Browser ab, falls das Element kein passendes Elternelement (s.o.) findet. Für mein Verständnis müsste das das Browserfenster sein, aber möglicherweise sehen die Browserschreiberlinge das anders..

        Die Beobachtung bei width:100% würde deine Theorie bzw. Lesart der Specs teilweise unterstreichen (falls du wie gesagt das meintest):
         ________________________________
        |  ____________________________  |
        | |Text eins___________________| |
        |  ______________________________|___
        | |Text zwei_____________________|___| <- Überlappung im Gecko
        |                                |
        |_______________________________>|

        |____________________________|
             Breite content edge body
        |_|                            |_|
                 padding von html
        (oder irgendein margin/padding bei html oder body, welches die content edge von body einschränkt)
        |________________________________|
             Breite margin edge html

        Text eins ist in einem normal fließenden (position:static) Element untergebracht, Text zwei in einem absolut positionierten Element mit top-Angabe, aber ohne left-Angabe, und hat width:100%. Im Gecko/Mozilla wird das zweite Element so breit wie das html-Element insgesamt (und da es aufgrund der fehlenden left-Angabe links dort anfängt, wo die Innengrenzen des body-Elements anfangen, also bündig mit dem frei fließenden ersten Element ist, geht es über das Fenster hinaus und es werden horizontale Scrollbalken angezeigt). Im Opera 7.11 und MSIE 6 hingegen bedeutet width:100% die Breite des body-Elements (beide Elemente sind gleich breit, wie in der Ursprungsfrage wünscht). Erst wenn border, padding oder margin beim zweiten Element hinzukommen, unterscheiden sich die Breiten. Opera 6.06 verhält sich anscheinend wie Gecko, nur reserviert 20 Pixel für die (in dem Falle nicht sichtbare) vertikale Scrollbar.

        Grüße,
        Mathias

        1. (...) Unter diesen Gesichtspunkten müsste das absolute <div> IMHO tatsächlich die volle Fensterbreite einnehmen.

          Vielleicht habe ich nicht verstanden, worauf du hinaus willst, aber redest du davon, wie sich die Browser verhalten sollten, wenn die Breite explizit auf 100% gesetzt wird?

          Nein, das war in der Fragestelle ja auch nicht der Fall. Ich habe lediglich das nachvollzogen, was laut CSS-Doku passiert, wenn width=auto ist.

          Denn komplett ohne width-Angabe richtet sich die Breite eines absolut positionierten Elements offensichtlich nach dessen Inhalt (in dem Fall Text).

          Nein, laut CSS-Doku soll das ja gerade nicht sein. Im bereits zitierten Absatz 10.3.7, "Absolutely positioned, non-replaced elements" (http://www.w3.org/TR/REC-CSS2/visudet.html#abs-non-replaced-width),  der CSS-Doku heißt es unter Regel 3 eindeutig:

          "If 'width' is 'auto', replace any remaining 'auto' for 'left' or 'right' with '0'."

          Ein absolut positioniertes <div> ohne width-, left- und right-Angabe muß also die gesamte Breite seines Containers einnehmen, nicht die Breite seines eigenen Inhalts.

          right wird im Normalfall nicht 0 und der rechte Rand des Elements

          Was ist normal[tm]? :) Falls Du position:static meinst, wird right in der Tat 0, deshalb nimmt das normale <div> (Element 1 in Deinem Beispiel unten) ja auch die volle Breite des Fensters ein. Siehe Absatz 10.3.3 (obwohl ich mich da frage, wie width funktionieren kann, wenn left und right von vornherein 0 sind).

          Die Beobachtung bei width:100% würde deine Theorie bzw. Lesart der Specs teilweise unterstreichen (falls du wie gesagt das meintest):
          ________________________________
          |  ____________________________  |
          | |Text eins___________________| |
          |  ______________________________|___
          | |Text zwei_____________________|___| <- Überlappung im Gecko
          |                                |
          |_______________________________>|

          |____________________________|
               Breite content edge body
          |_|                            |_|
                   padding von html
          |________________________________|
               Breite margin edge html

          Text zwei in einem absolut positionierten Element mit top-Angabe, aber ohne left-Angabe, und hat width:100%. Im Gecko/Mozilla wird das zweite Element so breit wie das html-Element insgesamt (und da es aufgrund der fehlenden left-Angabe links dort anfängt, wo die Innengrenzen des body-Elements anfangen, also bündig mit dem frei fließenden ersten Element ist, geht es über das Fenster hinaus und es werden horizontale Scrollbalken angezeigt).

          Das passt aber auch nicht. Bei Prozentangabe ist die Breite relativ zur Breite des Containers - und _die_ Breite ist, wie wir aus leidvoller IE-Erfahrung wissen, nicht jene inklusive Ränder, sondern exklusive. Das Element 2 müsste also genauso groß sein wie Element 1, den left nimmt den dem aktuellen Fluß entsprechenden Wert ein (Regel 1), width wird mit 100% kalkuliert (Regel 3 trifft nicht zu) und right wird abschließend aus left und width berechnet (Regel 6).

          Im Opera 7.11 und MSIE 6 hingegen bedeutet width:100% die Breite des body-Elements (beide Elemente sind gleich breit, wie in der Ursprungsfrage wünscht).

          Sollte der IE es tatsächlich mal besser machen als Gecko? Da bricht ein Weltbild zusammen ;)

          Gruß,
            soenk.e