Peter Thomassen: vertical-align nur für Tabellen?

Hallo liebes Forum!

Folgender Code:

<html>  
<head><title></title></head>  
<body>  
  
<div style="background: #AAA; height: 200px; vertical-align: middle">test</div>  
  
</body>  
  
</html>

Ich möchte den Text vertikal in der Mitte der Box positionieren, aber die Angabe von vertical-align hat keinerlei Wirkung. Warum?

Vielen Dank und schöne Grüße,
Peter

  1. Ich möchte den Text vertikal in der Mitte der Box positionieren [...]

    http://suit.rebell.at/artikel/horizontal-und-vertikal-zentrieren-mit-xhtml-und-css
    user: suit
    pass: rebell

    aber die Angabe von vertical-align hat keinerlei Wirkung. Warum?

    http://de.selfhtml.org/css/eigenschaften/ausrichtung.htm#vertical_align

    1. Begrüßung,

      Ich möchte den Text vertikal in der Mitte der Box positionieren [...]

      http://suit.rebell.at/artikel/horizontal-und-vertikal-zentrieren-mit-xhtml-und-css
      user: suit
      pass: rebell

      Ich möchte nicht in der Mitte der Seite positionieren, sondern in der Mitte der Box, und ich weiß vorher auch nicht, wie hoch die Box ist. Dein Vorschlag impliziert, dass man die Höhe wüsste (bei dir 24em).

      aber die Angabe von vertical-align hat keinerlei Wirkung. Warum?

      http://de.selfhtml.org/css/eigenschaften/ausrichtung.htm#vertical_align

      Das hatte ich natürlich gelesen, beantwortet die Frage aber nicht.

      Schlussformel,
      Peter

      1. Ich möchte nicht in der Mitte der Seite positionieren, sondern in der Mitte der Box, und ich weiß vorher auch nicht, wie hoch die Box ist. Dein Vorschlag impliziert, dass man die Höhe wüsste (bei dir 24em).

        Woher nimmt das div-Element seine Höhe?

        Das hatte ich natürlich gelesen, beantwortet die Frage aber nicht.

        vertical-align richtet Elemente in einer Zeile aus, das umgebende Element muss ein inline-Element sein - zudem kann die vertikale ausrichtung in Tabellenzellen bestimmt werden.

        Eine alternative wäre also ein Kind-Element mit einer line-height die der Höhe des div-Elements entspricht - darin lässt sich dann vertikal ein weiteres Element ausrichten.

        Wenn du beschreibst, was du eigentlich erreichen möchtest, wird die Sache deutlich einfacher.

        1. Hi,

          Eine alternative wäre also ein Kind-Element mit einer line-height die der Höhe des div-Elements entspricht - darin lässt sich dann vertikal ein weiteres Element ausrichten.

          aber auch nur, wenn der zu zentrierende Text nur eine Zeile umfasst.
          Ich kann übrigens auch nicht nachvollziehen, warum der Anwendungsbereich von vertical-align auf inline- und table-cell-elemente beschränkt wurde.

          So long,
           Martin

          --
          Gültig sind Frauen ab 16, wohlgeformt ab 160 Pfund.
            (Gunnar Bittersmann)
          1. aber auch nur, wenn der zu zentrierende Text nur eine Zeile umfasst.
            Ich kann übrigens auch nicht nachvollziehen, warum der Anwendungsbereich von vertical-align auf inline- und table-cell-elemente beschränkt wurde.

            Ich schon - allerdings ist es nicht ganz schlüssig :)

            Zum absoluten, vertikalen Zentrieren von belieben Elementen gibt es in CSS wunderbare Lösungen - der IE findet das halt nicht cool:

            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
            <html xmlns="http://www.w3.org/1999/xhtml">  
            	<head>  
            		<title>center</title>  
            		<style type="text/css">  
            			body, html {  
            				height: 100%;  
            			}  
            			div {  
            				position: absolute;  
            				top: 50%;  
            				bottom: 50%;  
            			}  
            		</style>  
            	</head>  
            	<body>  
            		<div>  
            			blah  
            		</div>  
            	</body>  
            </html>
            
            1. Hallo,

              Ich kann übrigens auch nicht nachvollziehen, warum der Anwendungsbereich von vertical-align auf inline- und table-cell-elemente beschränkt wurde.
              Ich schon - allerdings ist es nicht ganz schlüssig :)

              aha, erwischt. ;-)

              Zum absoluten, vertikalen Zentrieren von belieben Elementen gibt es in CSS wunderbare Lösungen - der IE findet das halt nicht cool:

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml">
              <head>
              <title>center</title>
              <style type="text/css">
              body, html {
              height: 100%;
              }
              div {
              position: absolute;
              top: 50%;
              bottom: 50%;
              }
              </style>
              </head>
              <body>
              <div>
              blah
              </div>
              </body>
              </html>

                
              Das ergibt ein vertikal zentriertes div mit der Höhe 0 (100%-50%-50%), dessen Inhalt nach unten, in Richtung des normalen Textflusses, über diese Höhe 0 hinausläuft. Zentriert ist damit also die Oberkante eines ein- oder mehrzeiligen Textes, aber nicht der Textblock an sich. Darunter würde ich verstehen, dass die Mitte des Textblocks auch in der Mitte des umgebenden Elements sitzt.  
              So einfach ist es also doch nicht.  
                
              Ciao,  
               Martin  
              
              -- 
              Ein Theoretiker ist ein Mensch, der praktisch nur denkt.  
              
              
              1. Xewe!

                Ich hatte neulich die Idee, das zu zentrierende Element als inline-block zu definieren, und dem äußeren eine line-height von 100% seiner Höhe zu verpassen. Das haben aber alle Browser zerrissen.

                Nächste Idee: display:table-cell und vertical-align:middle für das äußere Element. Hat funktioniert in Firefox ab 2, Opera, Safari und IE 8. IE 6 und 7 könnte man dann, sofern relevant, mit einer expression für die margin-top des inneren Elements bedienen (bei deaktiviertem JS haben sie dann allerdings verloren).

                Viele Grüße vom Længlich

                --
                Mein aktueller Gruß ist:
                Xitswa (gesprochen in Moçambique)
                1. @@Længlich:

                  nuqneH

                  IE 6 und 7 könnte man dann, sofern relevant, mit einer expression für die margin-top des inneren Elements bedienen (bei deaktiviertem JS haben sie dann allerdings verloren).

                  Expression ist hier unschön. Der Trick, dass die Expression sich selbst überschreibt und damit nur einmal ausgeführt wird, funktioniert hier nicht so recht, da bei Änderung der Viewportgröße neu berechnet werden müsste.

                  Qapla'

                  --
                  Volumen einer Pizza mit Radius z und Dicke a: pi z z a
                  1. Padioxei!

                    IE 6 und 7 könnte man dann, sofern relevant, mit einer expression für die margin-top des inneren Elements bedienen (bei deaktiviertem JS haben sie dann allerdings verloren).

                    Expression ist hier unschön.

                    Expression ist immer unschön. ;-)
                    Wenn jemandem was Besseres einfällt, immer her damit! Ich verwende expressions grundsätzlich nur, wenn ich keinen anderen Weg finde (der nicht noch häßlicher ist, z.B. Layouttabelle).

                    Der Trick, dass die Expression sich selbst überschreibt und damit nur einmal ausgeführt wird, funktioniert hier nicht so recht, da bei Änderung der Viewportgröße neu berechnet werden müsste.

                    Stimmt. Vielleicht kann man die anonyme Funktion, die bei besagtem Trick verwendet wird, dem onresize-Event zuweisen? Dazu müßte sie noch etwas umgebaut werden, weil wir bei dem Event die Referenz auf das zu stylende Objekt nicht mehr haben. Schaue ich mir mal an, wenn ich mehr Zeit habe.

                    Viele Grüße vom Længlich

                    --
                    Mein aktueller Gruß ist:
                    Zapotekisch (gesprochen in Yatzachi, México)
                    1. N'amahoro!

                      Stimmt. Vielleicht kann man die anonyme Funktion, die bei besagtem Trick verwendet wird, dem onresize-Event zuweisen? Dazu müßte sie noch etwas umgebaut werden, weil wir bei dem Event die Referenz auf das zu stylende Objekt nicht mehr haben. Schaue ich mir mal an, wenn ich mehr Zeit habe.

                      Uiuiui, so eine expression wird ziemlich eklig. Um einigermaßen universell einsetzbar zu sein, müßte sie ja
                      • das onresize-Event ergänzen, nicht überschreiben (es könnte ja mehrere geben, oder auch ganz andere Scripte, die das Event verwenden)
                      • sich das gewünschte Element selbst aus dem DOM porkeln, und dabei nicht nur IDs oder Tag-Namen unterstützen, sondern praktisch jede Art von Selektor. Man bräuchte also sowas wie jQuery o.ä.
                      Und das dann in eine Zeile im CSS gedrückt: Tschüß Lesbarkeit, tschüß Wartbarkeit!

                      Das lohnt sich meiner Meinung nach nicht. Alternativen:
                      • expression so schreiben, daß sie bei jedem Event neu berechnet wird. Bei nicht allzu komplexen Layouts sollte die Performance-Beeinträchtigung erträglich sein.
                      • expression wie von Gunnar beschrieben schreiben und damit leben, daß der Abstand nach einem Resize nicht mehr stimmt.
                      • eine margin-top angeben, die beim aktuellen Inhalt einigermaßen paßt (Formel: π × Daumen). Müßte allerdings nach jeder Inhaltsänderung angepaßt werden, und geht bei variierendem Inhalt gar nicht.
                      • den ollen Partykiller IE 6/7 einfach ignorieren. Der Text bleibt ja schließlich auch lesbar, wenn er am oberen Rand hängt. Je nach Layout genügt vielleicht eine margin-top von 1em oder so, damit das ganze nicht allzu gedrängt aussieht.

                      Viele Grüße vom Længlich

                      --
                      Mein aktueller Gruß ist:
                      Kirundi (gesprochen in Burundi)
                      1. @@Længlich:

                        nuqneH

                        Uiuiui, so eine expression wird ziemlich eklig.

                        Das mag der Grund sein, warum ich das noch nicht angegangen bin. ;-)

                        • sich das gewünschte Element selbst aus dem DOM porkeln,

                        ?? this hat man doch.

                        Und das dann in eine Zeile im CSS gedrückt: Tschüß Lesbarkeit, tschüß Wartbarkeit!

                        Man kann auch CR escapen:

                        td  
                        {  
                          background-color: expression( [code lang=javascript](new Function('elem', '\  
                            elem.values = ["#FCC", "#CFC", "#CCF"];\  
                            elem.modulo = elem.previousSibling && elem.previousSibling.modulo + 1 < elem.values.length ? elem.previousSibling.modulo + 1 : 0;\  
                            elem.style.backgroundColor = elem.values[elem.modulo];\  
                          '))(this)
                        ~~~ );  
                        }[/code]  
                          
                        Hallo Lesbarkeit, hallo Wartbarkeit!  
                          
                          
                        
                        > • den ollen Partykiller IE 6/7 einfach ignorieren.  
                          
                        Meine Rede. ;-)  
                          
                        Qapla'
                        
                        -- 
                        Volumen einer Pizza mit Radius z und Dicke a: pi z z a
                        
                        1. Nenànkäk nätäydëk häjit shò trì'nlay!

                          Uiuiui, so eine expression wird ziemlich eklig.

                          Das mag der Grund sein, warum ich das noch nicht angegangen bin. ;-)

                          Der Gedanke »Also deswegen hat Gunnar das nicht eingebaut …« kam mir durchaus. ;-)

                          • sich das gewünschte Element selbst aus dem DOM porkeln,

                          ?? this hat man doch.

                          Beim onresize-Event nicht mehr. Man könnte die Referenz natürlich in irgendeinem globalen Objekt hinterlegen, aber schlank und hübsch wird das auch nicht.

                          Und das dann in eine Zeile im CSS gedrückt: Tschüß Lesbarkeit, tschüß Wartbarkeit!

                          Man kann auch CR escapen:

                          td

                          {
                            background-color: expression( [code lang=javascript](new Function('elem', '\     elem.values = ["#FCC", "#CFC", "#CCF"];\     elem.modulo = elem.previousSibling && elem.previousSibling.modulo + 1 < elem.values.length ? elem.previousSibling.modulo + 1 : 0;\     elem.style.backgroundColor = elem.values[elem.modulo];\   '))(this)

                          
                          > }[/code]  
                          >   
                          > Hallo Lesbarkeit, hallo Wartbarkeit!  
                            
                          Joa, schon etwas besser. Aber immer noch wesentlich schlechter les- und wartbar als ›normales‹ CSS und ganz schön viel Aufwand für eine kleine Krücke. Da würde ich doch wirklich eher damit leben, daß der Wert beim Resize nicht aktualisiert wird. Wie viele User ändern schon ständig die Fenstergröße während des Surfens?  
                            
                          
                          > > • den ollen Partykiller IE 6/7 einfach ignorieren.  
                          >   
                          > Meine Rede. ;-)  
                            
                          Meine auch, aber manche Kunden sind leider noch nicht so weit. Ich befürchte: Je größer und finanzkräftiger ein Unternehmen, desto gammeliger die Browser seiner Mitarbeiter.  
                            
                          Viele Grüße vom Længlich  
                          
                          -- 
                          Mein aktueller Gruß ist:  
                          Gwich'in (gesprochen in Alaska und Canada)
                          
                          1. Rena-voítse!

                            Ich habe gerade eine Möglichkeit für IE7 ohne expression gefunden! Sie setzt aber voraus, daß das innere Element nicht ganz so breit ist wie das äußere.

                            <span><span>Text mit<br /> mehreren Zeilen</span>&nbsp;</span>

                            span  
                            {  
                              display:block;  
                              height:10em;  
                              line-height:10em;  
                            }  
                            span span  
                            {  
                              display:inline-block;  
                              line-height:normal;  
                              vertical-align:middle;  
                            }  
                            
                            

                            Anmerkungen:
                            • Alles nur für IE7; die anderen Browser bekommen nach wie vor die table-cell-Variante.
                            • Ich hoffe, das läßt sich so auf andere Elemente übertragen, z.B. auch body und ein div, habe das aber nicht getestet.
                            • Wenn statt des inneren spans ein Block-Element verwendet wird, muß display nochmal auf inline gesetzt werden (inline-block funktioniert ja strenggenommen im IE7 gar nicht richtig, sondern setzt nur hasLayout).
                            • Man beachte den &nbsp;! Ohne den klappt es nicht, und das innere Element bleibt oben. (Beliebiger anderer Text geht auch.)
                            • Dieser No-Break Space ist auch der Grund, warum das innere Element nicht so breit sein darf wie das äußere. Wenn er nicht mehr hinpaßt, bleibt das innere Element auch wieder oben. Overflow:visible oder hidden hat nicht geholfen.

                            • den ollen Partykiller IE 6/7 einfach ignorieren.

                            Jetzt ist IE 6 der letzte Partykiller. :-)

                            Viele Grüße vom Længlich

                            --
                            Mein aktueller Gruß ist:
                            Calapalo (gesprochen in Brasilien)
                            1. Da dika xalda hwa!

                              Ich habe gerade eine Möglichkeit für IE7 ohne expression gefunden! Sie setzt aber voraus, daß das innere Element nicht ganz so breit ist wie das äußere.

                              <span><span>Text mit<br /> mehreren Zeilen</span>&nbsp;</span>

                              span

                              {
                                display:block;
                                height:10em;
                                line-height:10em;
                              }
                              span span
                              {
                                display:inline-block;
                                line-height:normal;
                                vertical-align:middle;
                              }

                                
                              Und für IE 6 ist die font-size auch noch auf denselben Wert zu setzen wie height und line-height. Für das innere Element muß sie dann freilich wieder auf einen vernünftigen Wert zurückgesetzt werden. Der No-Break Space wird dadurch noch erheblich breiter.  
                              Font-size aber nur im IE 6 ändern, nicht im IE 7 – in dem hängt das Element sonst zu weit unten.  
                                
                              Viele Grüße vom Længlich  
                              
                              -- 
                              Mein aktueller Gruß ist:  
                              Inguschisch (Inguschetien, Russische Föderation)
                              
        2. Hi.

          Ich möchte nicht in der Mitte der Seite positionieren, sondern in der Mitte der Box, und ich weiß vorher auch nicht, wie hoch die Box ist. Dein Vorschlag impliziert, dass man die Höhe wüsste (bei dir 24em).

          Woher nimmt das div-Element seine Höhe?

          Ich möchte nicht das div-Element selbst vertikal auf der Seite ausrichten, sondern ich möchte den Text innerhalb der div-Box vertikal in dieser Box ausrichten. Die Höhe der div-Box ist vorgegeben, die des Textes variiert durch die Zeilenanzahl.

          Any ideas?

          Danke!
          Peter

          1. @@Peter Thomassen:

            nuqneH

            Ich möchte nicht das div-Element selbst vertikal auf der Seite ausrichten, sondern ich möchte den Text innerhalb der div-Box vertikal in dieser Box ausrichten. Die Höhe der div-Box ist vorgegeben, die des Textes variiert durch die Zeilenanzahl.

            Any ideas?

            Die Lösung ergibt sich unmittelbar aus der bereits verlinkten Spec: Mache das 'div' zu einem 'table-cell'-Element!

            Für die paar noch im Umlauf befindlichen Uralt-IEs müsste man mit JavaScript nachhelfen (CSS-Expression) oder auf den Effekt verzichten.

            Qapla'

            --
            Volumen einer Pizza mit Radius z und Dicke a: pi z z a
      2. Hallo Peter

        Ich möchte nicht in der Mitte der Seite positionieren, sondern in der Mitte der Box, und ich weiß vorher auch nicht, wie hoch die Box ist. Dein Vorschlag impliziert, dass man die Höhe wüsste (bei dir 24em).

        Vielleicht hilft dir Vertical Centering in CSS oder CSS Vertical Centering weiter.

        Auf Wiederlesen
        Detlef

        --
        - Wissen ist gut
        - Können ist besser
        - aber das Beste und Interessanteste ist der Weg dahin!
  2. @@Peter Thomassen:

    nuqneH

    aber die Angabe von vertical-align hat keinerlei Wirkung. Warum?

    Weil es so spezifiziert wurde. [CSS2 §10.8.1]

    Qapla'

    --
    Volumen einer Pizza mit Radius z und Dicke a: pi z z a
  3. Hi there,

    Ich möchte den Text vertikal in der Mitte der Box positionieren, aber die Angabe von vertical-align hat keinerlei Wirkung. Warum?

    weil's nicht vorgesehen ist. Du kannst jetzt irgendwelche Verrenkungen machen und mehrere Stunden investieren, oder Du baust einfach eine Tabelle drumherum und erzählst es hier niemandem. (Andere interessierts eh nicht...)

    1. @@Klawischnigg:

      nuqneH

      oder Du baust einfach eine Tabelle drumherum

      Warum das denn? https://forum.selfhtml.org/?t=194497&m=1300911

      und erzählst es hier niemandem.

      Na besser is’ auch. ;-)

      Qapla'

      --
      Volumen einer Pizza mit Radius z und Dicke a: pi z z a