Centrar contenedor y contenido
Podemos decir que hay dos tipos de etiquetas, las que por defecto son bloques (p
, ul
, pre
, div
, table
, etc) y las que por defecto no son bloques a las que llamamos etiquetas inline (span
, img
, strong
, em
, small
, etc) Pero ¿qué es eso de bloques?
Los bloques tienen una particularidad, poseen un ancho equivalente al total del área donde se encuentran y crean un salto de línea automático; es decir, ocupan todo el ancho y se separan del elemento anterior y del elemento siguiente; por el contrario, los elementos inline se muestran uno al lado del otro y, si el contenido supera el ancho disponible, continuan debajo.
Todo lo que agregamos en una página mediante etiquetas HTML es un rectángulo que tiene un contenido y un borde (border
) que puede estar visible o no. Entre ese borde y el contenido hay un área de relleno (padding
) y entre ese borde y otro elemento hay un área de margen (margin
) que los separa.
A la pregunta de ¿cómo centrar algo? uno debería repreguntar: ¿qué queremos centrar? ¿el contenedor o el contenido?
Y esta pregunta debería resultar bastante sencilla de responder si tenemos claro un concepto: no todos los elementos (etiquetas) de una página web pueden centrarse; sólo aquellos llamados bloques o sus contenidos.
Vamos a ver un código común; una imagen en un div
al que le damos un tamaño y le ponemos un borde. Como no la alineamos, aparecerá sobre la izquierda:
<div style="border: 1px solid black; width: 300px;"><img src="url_imagen" /></div>
¿Cómo haríamos para centrar ambas etiquetas?
Allá lejos y hace tiempo usábamos la etiqueta center
pero es una etiqueta depreciada; de todos modos, aunque la usáramos, no se resolvería el problema ya que se centraría el div
contenido pero no su contenido.
La segunda posibilidad sería usar la propiedad text-align
center:
<div style="border: 1px solid black; text-align:center; width: 300px;"><img src="url_imagen" /></div>
Y como se ve, centramos el contenido pero no el contenedor. Entonces ¿qué pasaría si colocamos ese estilo en la imagen? Nada, no produciría ningún efecto porque la etiqueta img
es de tipo inline. Entonces ¿cómo centramos el contenedor?
Para eso, usamos la propiedad margin
al que le ponemos un valor especial: auto pero ... siempre hay pero ... siempre y cuando esté definido su ancho con la propiedad width
ya que si no lo está, el ancho por defecto es todo el ancho disponible.
En nuestro ejemplo ya podemos centrar ambas cosas o alinearlas de modo independiente:
<div style="border: 1px solid black; margin: 0 auto; text-align: center; width: 300px;"><img src="url_imagen" /></div>
En términos generales, para centrar un contenido debemos establecer la propiedad text-align
en el contenedor y no en el contenido.
<div style="margin:0 auto; text-align: center;"> <span> ....... un texto ....... </span> <img src="URL_imagen" /> <br><span> ....... otro texto ....... </span> </div>
Ut wisi enim ad minim veniam.
Todos los elementos HTML tienen propiedades CSS por defecto pero pueden cambiarse así que, un elemento de bloque puede ser transformado en un elemento inline y viceversa; para eso usamos la propiedad display
.
En resumen, todos los elementos de bloque o convertidos en bloque usando CSS, se centran poniendo el valor auto en sus márgenes izquierdo y derecho pero, requieren que establezcamos su ancho.
¿Es posible centrar algo sin conocer ese ancho o sin establecerlo? Salvo en el caso de imágenes esto no era posible hasta que la propiedad display
comenzó a aceptar otros valores como table y table-cell.
Un ejemplo sencillo, un párrafo cuyo contenido está centrado pero desconocemos su dimensión; margin
no nos ayuda a centrarlo porque ocupa todo el ancho:
<p style="margin: 0 auto; text-align: center;"> ....... un texto ....... </p>
sed vitae ante libero, vitae bibendum turpis
Podríamos centrarlo si agregamos la propiedad display
con un valor table sin la obligación de establecer el ancho:
<p style="display: table; margin: 0 auto; text-align: center;"> ....... un texto ....... </p>
Sed vitae ante libero, vitae bibendum turpis.
Podemos probarlo cambiando el contenido: demo 1 | demo 2 | reset