Centrar verticalmente texto girado con CSS

76

Tengo el siguiente HTML:

<div class="outer">
    <div class="inner rotate">Centered?</div>
</div>

div.outeres una franja vertical estrecha. div.innerse gira 90 grados. Me gustaría el texto "Centrado?" aparecer centrado en su contenedor div. No sé el tamaño de ninguno de los div de antemano.

Esto se acerca: http://jsfiddle.net/CCMyf/2/ . Puede ver en jsfiddle que el texto está centrado verticalmente antes de transform: rotate(-90deg)que se aplique el estilo, pero está algo desplazado después. Esto es particularmente notable cuando div.outeres corto.

¿Es posible centrar este texto verticalmente sin conocer ninguno de los tamaños de antemano? No he encontrado ningún valor transform-originque resuelva este problema.

danvk
fuente
¿Te opones a asentarte display: tablesobre los elementos? Porque la forma 'estándar' de alinear divs dinámicos verticalmente debería funcionar con la transformación sin problemas: stackoverflow.com/a/6182661/188221
DigTheDoug
No me opongo a display: table. Este violín muestra que la solución de la tabla tiene los mismos problemas que la anterior: jsfiddle.net/4d384
danvk
Intente poner la rotateclase en el elemento medio. Eso debería bastar, pero parece que estropea el ancho del artículo. Puede que tenga que jugar con el relleno o los accesorios de ancho o alto, pero debería ser posible: jsfiddle.net/digthedoug/jWYuq
DigTheDoug
Solucionar el problema del ancho es significativamente más difícil de lo que cabría esperar. Poner min-width: 16px; width: 16pxen .outerresultados en el exacto mismo no centrado como en la pregunta original.
danvk

Respuestas:

146

La clave es establecer la posición superior e izquierda al 50% y luego transformX y transformY a -50%.

.inner {
    position: absolute;
    top: 50%;
    left: 50%;
}

.rotate {  
    transform:  translateX(-50%) translateY(-50%) rotate(-90deg);
}

ver: http://jsfiddle.net/CCMyf/79/

bjnsn
fuente
2
Trabajando con elementos de texto en lugar de divs, tuve que agregar margin: 0el elemento interno para que el texto se centrara perfectamente.
kapoko
Muchas gracias. No estaba tan lejos. No sé por qué, pero si fijo primero como esto la regla de rotación: transform: rotate(-90deg) translateX(-50%) translateY(-50%);no funciona, y si lo pongo última como su ejemplo muestra, funciona: translateX(-50%) translateY(-50%) rotate(-90deg);.
Maxime Lafarie
6

Puede que sea un poco tarde para responder esa pregunta, pero tropecé con el mismo problema y encontré alguna forma de lograrlo, agregando otro div en el camino.

<div class="outer">
    <div class='middle'><span class="inner rotate">Centered?</span></div>
</div>

y aplicando un text-align: centeren ese elemento del medio, junto con algunas cosas de posicionamiento:

.middle {
    margin-left: -200px;
    width: 400px;
    text-align: center;
    position: relative;
    left: 7px;
    top: 50%;
    line-height: 37px;
}

El .innertambién recibe una display: inline-block;para permitir rotatey text-alignpropiedades.

Aquí está el violín correspondiente: http://jsfiddle.net/CCMyf/47/

Pascal M
fuente
2

¿Puedes agregar margin: 0 auto;a tu clase "rotar" para centrar el texto?

.rotate {
  -webkit-transform: rotate(-90deg);
  -ff-transform: rotate(-90deg);
  transform: rotate(-90deg);
  width: 16px;  /* transform: rotate() does not rotate the bounding box. */
  margin: 0 auto;
}
97ldave
fuente
Esto no funciona. Aquí está el violín actualizado con "margin: 0 auto": jsfiddle.net/CCMyf/3 . Puede ver que el "?" en "Centrado?" está mucho más cerca de la parte superior que la "C" de la parte inferior.
Danvk
2

La respuesta de 'bjnsn' es buena pero no perfecta, ya que falla cuando el texto contiene espacio. Por ejemplo, usó 'Centrado?' como texto, pero si cambiamos el texto para que supongamos '¿Centrado? o no ', entonces no funcionará bien y ocupará la siguiente línea después del espacio. No hay ancho ni alto definido para el bloque div interno.

.inner {
  font-size: 13px;
  font-color: #878787;
  position: absolute;
  top: 50%;
  left: 50%;
  background: #DDD;
}

https://jsfiddle.net/touqeer_shakeel/f1gfy1yy/ Pero podemos hacer que todo el texto centrado se alinee correctamente, estableciendo el ancho div interno igual a la altura del div externo, la altura de la línea del div interno igual al ancho del div externo div y estableciendo la propiedad display flex para el div interno con las propiedades align-items: center y justify-content: center.

.inner {
  font-size: 13px;
  font-color: #878787;
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  justify-content:center;
  align-items:center;
  line-height:40px;
}
$('#height').on('change', function(e) {
  $('.outer').css('height', $('#height').val() + 'px');
  $('.inner').css('width', $('#height').val() + 'px');
});

violín actualizado https://jsfiddle.net/touqeer_shakeel/cjL21of5/

usuario3809178
fuente
0

Eliminando: margin-top: -7px;de .innerhecho el texto girado verticalmente centrado para mí. También hizo que el texto horizontal no estuviera centrado.

¿Simplemente eliminar el código anterior?

Miguel
fuente
Esto puede hacer que esté más cerca de estar centrado, pero aún no está correctamente centrado. Puede ver esto claramente en esta versión del violín: jsfiddle.net/CCMyf/4
danvk
0

Podrías agregar esto:

$('.inner').css('margin-top', $(this).parent().height() - 2*$(this).height());

A su .on('change')función, como puede ver aquí: http://jsfiddle.net/darkajax/hVhbp/

DarkAjax
fuente
Esto funciona, aunque preferiría una solución CSS si es posible.
danvk
¿Encontraste una solución CSS?
Crashalot