2011-01-20 28 views
9

Sí, sí, sé que esta es otra pregunta sobre la alineación vertical con CSS y se ha realizado un millón de veces antes. Tenga la seguridad de que me he topado con este problema muchas veces y ya he leído varias formas de centrar verticalmente con CSS. Pregunto aquí porque ninguna de esas formas hace exactamente lo que quiero hacer, y solo quiero asegurarme de que mi sospecha (que la alineación vertical CSS está rota y no hará lo que quiero que haga) es definitivamente correcta.Alineación vertical con CSS

En primer lugar, aquí es mi caso de prueba: http://www.game-point.net/misc/testAlign/

Aquí está el criterio:

  • quiero alinear el 'texto centrado' verticalmente, con respecto a la DIV que contiene el 'a TestTestTest ... 'texto.
  • No quiero especificar CUALQUIER altura.
  • Quiero que los DIV 'TestTestTest' y 'Centered text' obtengan sus alturas dinámicamente, de acuerdo con la cantidad de texto que tienen y el límite de ancho que tienen.
  • No quiero usar Javascript.

Esto parece ser imposible incluso en CSS3, y mucho menos en CSS2. Lo molesto es que casi estoy allí; El DIV position:absolute; top:-50%; funciona para establecer la parte superior de ese DIV a la mitad del contenedor DIV. El problema es que el DIV interior, con el estilo position:relative; top:-50%;, no hace nada para mover el contenido a la mitad de su altura, centrarlo completamente, porque CSS dice que un DIV completamente posicionado no tiene altura y por lo tanto top:-50% no tiene sentido . Por lo que puedo decir, este es solo un error fundamental en CSS sin ningún motivo en particular. Un elemento absolutamente posicionado tiene una altura, y no sé por qué CSS pretende que no. Solo quería preguntar si alguien tenía alguna idea sobre cómo podría lograr el efecto deseado, representado en la parte inferior, dado el criterio que describí anteriormente. Irónicamente, el modelo de caja "rota" de IE6/7/8, en modo peculiar, me da este efecto. Es una pena que lo "arreglen" en IE9, así que ya no lo hará.

+0

Bueno, siempre se puede utilizar jQuery para hacer la magia. Pero tu sospecha es probablemente correcta, hasta donde yo sé. –

+0

Cree que puede hacer esto con flexbox ahora http://css-tricks.com/snippets/css/a-guide-to-flexbox/ – Ruskin

Respuesta

5

bien, mi sospecha era de hecho correcta y esto no es posible (Creo que es un defecto en CSS y deberían proporcionar un medio de alineación vertical dentro de un DIV sin especificar las alturas de los elementos internos).

La solución menos mala con la que terminé fue esta: especifique la altura del DIV 'medio' - es decir, el DIV que se muestra usando position:absolute y contiene el contenido real. Lo he agregado a la página de casos de prueba al http://www.game-point.net/misc/testAlign/ bajo el encabezado Con altura de línea: 100% y DIV 'medio' con codificación rígida. Esta solución significa que debe conocer la altura del contenido para que se centre verticalmente de antemano, lo cual es una mierda porque el navegador lo calcula y no debería necesitar especificarlo, pero es la única manera (hasta que CSS actúe en conjunto). Usé em s para especificar también la altura, por lo que acercar y alejar el texto no arruina el centrado vertical. Resulta que para las 2 líneas de 'Texto centrado' que tuve, esta altura equivale exactamente a 2 em s (al menos en mi máquina). Si tuviera que cambiar la altura de ese contenido, o cambiara dinámicamente para decir 3 líneas o 1 línea, la altura de div codificada por el padre em también tendría que cambiar.

lo tanto, aquí está el código que finalmente terminó con si alguien está interesado:

<div style="border:1px solid black; padding-left:60px; width:250px; position:relative; word-wrap:break-word;"> 
     TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest 
     <!-- Unfortunately, must set this DIV's height explicitly or the contained DIV's relative positioning won't work, as this DIV is considered to have NO implicit height --> 
     <div style="position:absolute; display:block; top:50%; left:0px; height:2em;"> 
      <div style="position:relative; top:-50%; background-color:#00aa00; line-height:100%;"> 
       Centred text<br/> 
       Centred text 
      </div> 
     </div> 
    </div> 
-3
.item { 
    height: 40px; 
    top: 50%; 
    margin-top: -20px; 
} 

posición relativa o absoluta;

+2

OP: "No quiero especificar CUALQUIER altura". La solución – kapa

+0

con "superior: 50%" funciona solo con la altura especificada. – jcubic

+0

También hay otra solución que usa el margen establecido en automático, pero creo que también requiere una altura específica. – jcubic

2

Uso margin-top: en lugar de como top:margin-top: -25%;

+0

nice, works for me – kapa

+1

Esto es bastante bueno, pero no tiene en cuenta la altura del cambio centrado de la caja. Como se supone que es dinámico, esto podría ser un problema. – sfarbota

+0

Interesante ... ¿Cuál es el valor porcentual del margen superior en relación con? Entonces, ¿es -25% de qué? Si reduzco el texto centrado a 1 línea de texto, no se centra correctamente. – Jez

2

La cosa es sin embargo que el manejo vertical de contenidos se hace de esa manera, por razones obvias, que estoy seguro de que está ya en cuenta. Pero estás tratando de resolver un problema sin solución, eso no es realmente un problema. (tiene sentido cuando sabes por qué las cosas son como son)

Al usar la posición absoluta, estás sacando contenido del flujo natural. Es mucho mejor hacer todo como debería ser con flotadores y tamaños adecuados o lo que sea necesario, por lo que se degrada bien y parece estar bien en todos los dispositivos. Luego, escriba dos líneas de código en jquery para verificar las alturas y alinear todo (lo que también funcionará en "todos" los dispositivos). El 2-3% sin JS tendrá que vivir con sitios aburridos.

+4

Sí, estoy sacando algo de contenido del flujo natural; esa es la única manera de superponer texto sobre otro texto. ¿Qué sugieres? Pareces estar diciendo que para obtener algo más que la capacidad de Netscape 3, necesitas usar Javascript. Creo que CSS tenía la intención de ser un poco más robusto que eso. – Jez

+0

Lo que digo es que si quitas el contenido del flujo natural, estás quitando las capacidades dinámicas del contenido del div para expandirse de forma natural. Una div posicionada absoluta es limitada en esta área. Así que resolverlo EXACTAMENTE como dices estoy bastante seguro de que no es posible. Por curiosidad, ¿por qué no jQuery, por ejemplo? Es tan rápido y simple hoy en día. – plebksig

+0

"esa es la única forma de superponer texto sobre otro texto". ¿Qué pasa con 'z-index'? – Knu

0

He empezado a llegar a alguna parte con el siguiente código ... aunque necesita trabajar.

Sobre la base de los elementos que se encuentran en http://www.jakpsatweb.cz/css/css-vertical-center-solution.html

Note que su código se ejecuta en modo de peculiaridades, he cambiado esto a html 5

<!DOCTYPE HTML> 
<html> 
<head> 
    <title>Vertical align test</title> 
</head> 

<style type="text/css"> 


#outer { overflow: hidden; position: relative; border: 1px solid red; } 
#outer[id] {display: table; position: static;} 

#middle {position: absolute; top: 50%;} /* for explorer only*/ 
#middle[id] {position: relative; display: table-cell; vertical-align: middle; width: 100%;} 

#inner {position: relative; top: -50%; width: 100px} /* for explorer only */ 
/* optional: #inner[id] {position: static;} */ 

</style> 

<body> 
<h1>New test</h1> 

<div id="outer"> 
    <div id="middle"> 
    <div id="inner"> 
     any text<br> 
     any height<br> 
     any content, for example generated from DB<br> 
     everything is vertically centered 
    </div> 

    </div> 

test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test 
</div> 


</body> 
</html> 
+0

Por desgracia, este utiliza display: table. Eso evita que uno use el CSS 'word-wrap: break-word;' (no se rompe dentro de las celdas de la tabla), así que estaría buscando hacer esto sin display: table. – Jez

Cuestiones relacionadas