El modelo de cajas

Los elementos de un documento HTML son considerados como una caja rectangular invisible al usuario y en la que se pueden aplicar ciertas propiedades para ubicar los elementos respecto a otros.

Modelo de cajas CSS

Imagen obtenida de  Mozilla en The box model.

margin: margen exterior, que separa la caja del elemento de las demás. si escribimos margin:5px; establecemos un margen de 5 píxeles en los 4 lados de la caja.  Podemos especificarlos de forma independiente mediante margin-topmargin-right, margin-bottom y margin-left.

padding: margen interno o relleno, que se aplica del borde hacia adentro. Se puede usar de forma independiente también con padding-toppadding-rightpadding-bottom y padding-left.

Cualquiera de las propiedades anteriores las podemos especificar también en una sola indicando los 4 valores uno detrás de otro, comenzando desde arriba y en sentido horario:

padding: 10px 5px 10px 6px;

Por tanto, la propiedad anterior especifica un padding de 10px arriba, 5 a la derecha, 10 abajo y 6 a la izquierda.

Un truco para centrar cajas dentro de su contenedor es asignar el valor auto a la derecha y a la izquierda:

padding: 10px auto 10px auto;

Adicionalmente, se pueden expresar los valores dos a dos si se repiten el de arriba y el de abajo o el de izquierda y derecha:

padding: 10px auto;

Esta propiedad provocaría un efecto igual a la anterior.

background-color: para asignar un color de fondo a la caja.

background-image: Para asignar una imagen de fondo a la caja mediante el valor url(‘imagen.jpg’), siendo imagen.jpg la ubicación del archivo de la imagen que queramos utilizar.

border-width: para definir el grosor del borde, por ejemplo, 2px.

border-style: Para especificar el tipo de línea del borde. Hay varios tipos que podemos consultar aquí, pero lo normal es usar el valor solid.

border-color: Asignamos el color del borde.

border: con esta propiedad podemos especificar las tres anteriores en una en el mismo orden que las hemos indicado. El único valor que no podemos omitir sería el segundo, indicando el estilo de línea.

border: 4px dotted blue;

overflow: Con esta propiedad especificamos los que ocurre cuando el contenido no cabe en la caja. Los posibles valroes son:

  • visible. Valor predefinido. Aunque el contenido supere el tamaño dela caja, se mostrará como tal.
  • hidden. Sólo aparece el contenido que no supere el límite de la caja.
  • scroll. Aparece una barra de desplazamiento.
  • auto. Dejamos a criterio del navegador el comportamiento.

Ejemplo de uso de cajas

Posicionamiento de cajas

Podemos diferenciar dos tipos de elementos HTML, de los que podemos usar dentro del cuerpo de las páginas para agregar contenido, en función de cómo se representan en pantalla. En bloque (block) o en línea (inline).

Block

Los bloques ocupan todo el ancho de pantalla y siempre comienzan en una línea nueva. Estos elementos pueden contener a otros elementos de bloque o en línea y su altura varía en función de su contenido. Ejemplos son div, form, h1-h6, ol, p, table o li.

Podemos especificar su tamaño en pantalla mediante CSS como hemos visto con width height.

Inline

Ocupan el espacio de su contenido, no tienen por qué comenzar en una nueva línea, sólo pueden contener a otros elementos inline y sus dimensiones no se pueden especificar mediante CSS. Ejemplos: a, br, img, input, label, select, span, strong

Posicionamiento predefinido (estático)

De forma predefinida los elementos de bloque aparecen unos debajo de otros según el flujo en que los pongamos en el documento. Si asignamos una altura o anchura a uno, los que pongamos en su interior estarán limitados a ese tamaño.

Posicionamiento relativo

Podemos especificar desplazamiento a una caja con respecto a su posición original en el flujo de ejecución (predefinida).

Utilizamos la propiedad:

position: relative;

Y después para aplicar el desplazamiento, las propiedades top, left, right y bottom.

Por ejemplo:

left: 15px;

Con la regla anterior desplazamos el elemento 15px respecto a su borde izquierdo, de modo que observaremos un desplazamiento hacia la derecha.

Este tipo de posicionamiento no modifica el posicionamiento de las demás cajas a su alrededor, pero sí puede provocar solapamientos.

Posicionamiento absoluto

Con este modo de posicionamiento tomamos como referencia al primer elemento padre o contenedor que no esté estático. Si no existe, la referencia sería la ventana del navegador.

position: absolute;

Las propiedades top, left, right y bottom aplican desplazamiento desde el borde en cuestión del elemento hasta los bordes correspondientes en el elemento padre. En este caso, el desplazamiento influye en el resto de elementos de la página, tratando los demás elementos de rellenar el hueco abandonado.
Veamos un ejemplo en el que podemos probar los posicionamientos vistos hasta ahora:

Prueba a posicionar por ejemplo el div segundo anidado dentro del primero para comprobar otras opciones con el posicionamiento absoluto.

Z-index

Con la propiedad z-index seguida de un valor de número entero podemos modificar la superposición de capas, siendo los valores numéricos más altos las capas por encima de las otras.
Prueba a aplicar un z-index mayor al primer div del ejercicio anterior.
Ten en cuenta que z-index sólo funciona con posicionamiento distinto al estático.

Aquí podemos ver otra versión con el padre con posicionamiento relativo para comprobar que ahora las cajas hijas se colocan dentro de la exterior:

https://jsfiddle.net/diegocmartin/sf4w936c/17/

Fixed

El posicionamiento fijo lo empleamos mediante el valor fixed y es como el absoluto salvo que en este caso siempre se toma como referencia la ventana del navegador. En este caso aunque hagamos scroll, el elemento permanecerá en la misma posición.

Sticky

en este caso la posición del elemento pasa de ser relativa a fija (fixed) cuando el usuario hace scroll de forma que el elemento dejara de verse. Hay navegadores en que no funcionará correctamente.

Ver ejemplo en W3Schools.

Inherit

La propiedad position también puede asignarse con el valor inherit. En este caso, la caja hereda el posicionamiento de su contenedor inmediato.

Float

Es una propiedad que puede tomar los valores right, left, none (predefinido) e inherit. Lo que provoca es que ele elemento flote hacia el lado indicado de su contenedor. Cuando un elemento flota, deja el hueco que ocupaba y otro puede ocupar su ubicación anterior.

float: right;

Si otros elementos flotan hacia una misma dirección en el mismo contenedor, entonces sí respetan el orden y posiciones y no se solaparían.

Ver variantes en la versión:
https://jsfiddle.net/diegocmartin/pq2k07h9/1/

Si flotamos varios elementos hacia la derecha, aparecerán colocados en orden inverso.

Otro ejemplo de esto es la colocación de texto alrededor de una imagen en un artículo de un blog. Este es el uso original y más indicado para el que se creó esta propiedad.

A pesar de que el uso para el que se creó float fue para colocar texto alrededor de otro objetos como imágenes, durante mucho tiempo se ha empleado para maquetar las estructuras de las páginas web, creando zonas dentro de las mismas como las barras laterales o elementos dispuestos en filas y columnas como una galería de imágenes o un listado de productos.

Clear

Es otra propiedad que sirve para evitar que un elemento tenga a sus lados algún elemento flotante pasándolo a la siguiente línea o hueco en el flujo del documento.

Por tanto, el valor left provocará que el elemento en cuestión se desplace hacia abajo hasta encontrar un hueco en el que no exista un elemento flotante a su lado izquierdo.
Podemos asignarle los valores leftrightboth inherit.

both implica ambos lados.

Solución al problema del alto de la caja contenedora de flotantes

Cuando hacemos flotar elementos surge el problema de que, como los elementos flotantes salen del flujo normal del documento, los elementos que estén a continuación pasan a ocupar los huecos disponibles.

Esto tiene el problema de que la caja contenedora de los elementos flotantes, si no contiene a otros elementos, no llega hasta el final de los elementos flotantes.

En el siguiente ejemplo podemos ver como la caja negra, que contiene a las grises, no llega al final:

Soluciones:

  1. Indicar overflow: auto a la caja contenedora. (no siempre funciona).
  2. Agregar un div limpiador tras los flotantes.
  3. Emplear la pseudoclase after con un clear.

Dos recursos interesantes (English):
HTML: Give Parent Div 100% Height Of Child Floated Elements
CSS Tricks: Float

Si en el ejemplo anterior descomentamos el clear de la línea 33 del CSS, podemos ver cómo el problema se soluciona mediante la opción 2, gracias también al div vacío que se ha incluido tras las cajas flotantes en el HTML.

Display

Es interesante considerar que podemos modificar el comportamiento de un elemento HTML sobrescribiendo la propiedad display e intercambiando su comportamiento de bloque o en línea a conveniencia.

Los valores más comunes de asignar al valor de esta propiedad son por tanto block, inline, none, hidden e inline-block.

Tanto none como hidden hacen desaparecer al elemento, la diferencia es que con hidden simplemente se oculta, aunque este sigue ocupando su lugar. Con none, desaparece totalmente.

Un uso común es poner los elementos de una lista en línea para que muestren en horizontal y aplicarlo en menús.

li {display: inline;}

o poner un span en bloque para que ocupe todo el ancho o un ancho específico.

span {display: block;}

Es importante recordar que a los elementos inline no les podemos asignar un ancho o un alto.

Inline-block

Inline-block nace tras la necesidad de un método más eficaz que float para colocar elementos en disposición horizontal.

Un uso muy común es para generar menús de navegación, en los que, a partir de una lista desordenada, ubicamos los elementos li en hilera asignándoles también un ancho específico.

Una vez hayamos practicado con inline block, podemos ver esta posibilidad. Respecto a inline:

  • Podemos asignar width height al elemento.
  • Nos respeta padding margin.

Respecto a block

  • No genera una nueva línea al final.

Inline-block vs float

Ya hemos observado que los resultados de emplear inline-block y float son similares cuando tratamos de construir la estructura de un sitio. ¿Pero cuál es más correcto?

Si indagamos un poco sobre las particularidades y diferencias de cada uno obtenemos que en general es más beneficioso emplear inline-block ya que float no ha sido diseñado para hacer esto, sino más bien para el clásico ejemplo en el que el texto flota alrededor de una imagen.

Aquí tenemos un artículo y un debate en el que se comenta el caso:

Por una web más fluida: Menos “float” y más “inline-block”

Advantages of using display:inline-block vs float:left in CSS

Una de las principales ventajas de inline-block es que podemos hacer uso de propiedades como text-align o vertical-align, sin embargo, clear dejará de surtir efecto.

También hemos tener en cuenta el margen derecho de 4 píxeles que se incluye en el elemento cuando le asignamos este display. Para corregirlo podemos darle un margin negativo de 4px:

#caja {
    display: inline-block;
    margin-right: -4px;
    vertical-align: top;
    padding: 10px;
    box-sizing: border-box;
}

Box-sizing

Esta propiedad tiene dos posibles valores distintos, aparte de initial e inheritcontent-box y border-box.

content-box es el valor predefinido, en el que cuando aplicamos medidas a la caja con width o height el grosor del paddingborder y margin se sumará al indicado.

Con border-box conseguimos que el padding y el borde estén ya incluidos en esta medida, siendo así más fácil de cuadrar el resultado final cuando trabajamos con varias cajas.

El valor border-box de la propiedad boxsizing se emplea para facilitarnos la tarea de calcular y ajustar las dimensiones de los elementos cuando pretendemos que quepan varios colocados horizontalmente.

Podemos verlo gráficamente aquí:

border-box01

Imagen obtenida de CodeBoxR.

border-box02

Imagen obtenida de StackOverflow by Toan Lu.

Flexible Box Layout

Desde 2016 podemos usar los nuevos valores flex inline-flex en sustitución de block inline-block para crear diseños flexibles.

Algunas de sus ventajas son:

  • Gestión de alineación de las cajas.
  • Centrado horizontal y vertical.
  • Altos de caja similares.
  • Fondos de colores uniformes.

Ejemplo sencillo:

Dirección del contenido en flex

flex-direction permite especificar el eje prioritario del contenedor. Tiene los siguientes valores posibles:

  • row: Dispone a los elementos hijo de forma horizontal o en fila. (Predeterminado).
  • row-reverse: Igual al anterior, pero los ubica en el orden inverso a su declaración en el flujo del documento.
  • column: Disposición vertical o en columna.
  • column-reverse: vertical en sentido inverso.

Corte del contenido en flex

flex-wrap con el valor wrap sirve para autorizar el salto de fila o columna cuando los elementos no caben. nowrap para impedirlo, valor predefinido y wrap-reverse para autorizarlo en orden inverso.

flex-flow es la propiedad abreviada para las dos anteriores.

Ejemplo:

flex-flow: column wrap;

Alineación del contenido en flex

justify-content admite los siguientes valore:

  • flex-start para ajustar los hijos al inicio del contenedor (predeterminado).
  • flex-end para ajustar al final. La derecha si la dirección es horizontal.
  • center centrado.
  • space-between justificado y hacia los extremos.
  • space-around justificado dejando hueco en los extremos también.

align-items permite alinear los elementos en el eje secundario, es decir, si el principal es row, el secundario es column y viceversa. permite los siguientes valores:

  • stretch estira los elementos a lo largo del eje (predeterminado).
  • flex-start alinea los ítems en la parte superior.
  • flex-end, parte inferior.
  • center, en el centro.
  • baseline, con la línea base del texto.

align-content permite decidir la alineación cuando los elementos tienen asignado el salto de línea con flex-wrap: wrap.

Posibles valores: stretchflex-startflex-endspace-between y space-around.

Propiedades de flexbox

order con números enteros como valor permite ordenar los elementos independientemente del orden en el flujo del documento. A menor es el valor, más arriba aparece.

align-self sirve para alinear un elemento de manera independiente y puede tomar los valores de la propiedad align-items. Con auto coge el valor definido en esta propiedad.

flex-grow permite a un ítem aumentar su tamaño hasta el límite de la caja contenedora. Toma valores numéricos que expresan la proporción. 0 impide su crecimiento, 2 lo duplicaría.

flex-shrink es la inversa a la anterior y con el valor 1 permite reducir al elemento si este no cupiera en su caja contenedora. Aquí un ejemplo muy ilustrativo en W3 Schools.

flex-basis permite especificar tamaño si no entra en conflicto con max-width o max-height. el valor impide su cambio, auto hace que se defina según el tamaño del padre. También podemos usar un valor normal de tamaño.

flex: propiedad shorthand de las 3 anteriores, growshrink basis con valores predefinidos:

flex: 0 1 auto;

Por ejemplo, con flex: 1; en la caja contenedora, permite que todos los elementos hijo se repartan el espacio disponible.

Grid

También disponemos de display:grid para disponer los elementos usando una rejilla. Este módulo es tan novedoso ahora mismo que debemos especificar en la configuración del navegador que deseamos usar las opciones experimentales.

En CSS Tricks hay un estupendo artículo dónde se explica el uso y propiedades específicas de grid.

A Complete Guide to Grid

Para activar las opciones en experimentales en Firefox debemos escribir about:config en la barra de direcciones y posteriormente en este caso activar la opción layout.css.grid.enabled.

En el caso de Chrome vamos a: chrome://flags/#enable-experimental-web-platform-features

Sería genial leer tus experiencias y consejos sobre esto. Comenta y suscríbete a los comentarios para mantenerse al día en la conversación.

Por favor, si te ha gustado, ¡comparte!. Me será de gran ayuda. ¡¡Gracias!!