La propiedad display en CSS
Tags: css, tutorial, spanish, latam
Published: 2021-06-01 00:56:13

¡Hola gente bonita!👋

En este articulo voy a explicar sobre la propiedad `display` y los diferentes valores que esta contiene, antes de empezar es necesario comprender algunos conceptos, como el modelo de caja (box-model) o incluso el [box-sizing](https://dev.to/lupitacode/que-es-el-box-sizing-en-css-2pi9) ya que considero que estos temas (tal como en la serie Dark 📺) están conectados 😂. Vamos a empezar a repasar algunas cosas importantes.
 
Es importante que entiendas que cada elemento HTML en una pagina web es una caja rectangular, esta es la forma en que se representan todos los elementos, no existen elementos triangulares, redondos, poligonales etc. Todos los elementos en HTML por defecto son rectangulares ya que internamente el navegador dibuja un rectángulo.

Aunque usted visualice en un sitio web algún elemento redondo diseñado en CSS, ese elemento seguirá siendo rectangular y esto es porque como he dicho anteriormente cada elemento del diseño web es una caja, el navegador renderiza cada elemento de la página web como un elemento rectangular y con CSS nosotros definimos las propiedades como el tamaño, el color, los estilos, el margen y mucho más de estos elementos rectangulares.

Esto puedes comprobarlo con el siguiente ejemplo, con ayuda de la propiedad `outline`, podemos ver todos los elementos de la pagina de inicio de Google de forma rectangular y esto lo puedes hacer con cualquier otro sitio web.

```
* {
    outline: 1px solid red;
}
```
![Página de inicio de Google.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hyykfbzrr25abrxbmmio.png)

Entonces cada elemento HTML esta formado por 4 áreas: `content`, `padding`, `border` y `margin`. Estas áreas se apilan para formar el modelo de caja (box model).

Como ya lo mencionamos anteriormente cada elemento HTML es una caja, pero hay dos tipos básicos de cajas:

* Block boxes.
* Inline boxes.

Estos dos tipos de cajas, existieron desde el principio de la web:

###📦 Cajas de bloque (Block boxes)

Las cajas de bloque, por defecto, ocupan todo el espacio a lo ancho del contenedor.
El elemento HTML común para una caja de bloque es el elemento
`<div>`.

###📦 Cajas en línea (Inline boxes)

Las cajas en línea, por defecto, toman el espacio según el contenido envuelto. El elemento HTML más común para una caja en línea es el elemento `<span>`.

## La propiedad Display

El comportamiento de todas las cajas proviene de la propiedad display de CSS. 

La documentación de la MDN define la propiedad display de la siguiente manera:

> La propiedad CSS display especifica si un elemento es tratado como `block` o `inline` y el diseño usado por sus hijos, como flow layout, grid (Cuadricula) o flex (Flexible). 

Los valores básicos de la propiedad display son el valor `inline` y el valor `block`.
Entonces el elemento HTML `<span>`, por defecto, utiliza el valor de `inline`  mientras que el elemento HTML `<div>`, por defecto, utiliza el valor de block.

```
div{ 
   display: block; /* browser default styles */
}
span{ 
   display: inline; /* browser default styles */
}
```

Y ahora, si quieres, puedes cambiar el comportamiento de cada elemento HTML. Por ejemplo, puede convertirlo en un comportamiento opuesto:

```
div{ 
   display: inline; 
}

span{ 
   display: block; 
}
```
Entonces podemos decir que de forma natural existen elementos HTML en línea y elementos de bloque, esto es cierto, pero curiosamente todos los elementos HTML utilizan la propiedad display con el valor `inline`, Te estarás preguntando ¿cómo sé esto? la respuesta es que cada propiedad en CSS tiene sólo un valor por defecto y para la propiedad `display`, el valor inicial es siempre `inline`.

¿No me crees? La misma documentación oficial de la MDN lo dice:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyzcy1vcpod2hx3ph7f0.png)

Ahora la pregunta que debemos hacernos es: ¿Por qué el elemento HTML `<div>` es un elemento de bloque o se comporta con el valor display: block?
La respuesta está en el user-agent-stylesheet (hoja de estilo) del navegador.

Cuando creamos páginas web, el navegador carga su propia hoja de estilos CSS antes de que carguemos una sola línea de CSS, esto quiere decir, que cada navegador viene con cierta cantidad de CSS por defecto que llamamos user-agent-stylesheet.

Entonces todos los elementos HTML que por defecto tienen un valor de block, esto es sólo porque el navegador decide añadirles la propiedad display con un valor de block. Si inspeccionamos el elemento `<div>` tiene el valor de block por esta razon:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pte474ifn3wwd03hskwu.png)

Esto quiere decir que muchas etiquetas HTML tienen asignado estilos CSS del navegador aunque no lo hayas especificado, todos los elementos tienen establecido un valor de la propiedad `display` que puede ser `inline` o puede ser `block` gracias a la hoja de estilo del navegador.

Esta tambien es la razón por la que sin ningún tipo de CSS de nuestra parte, el elemento `<h1>` es mas grande que un `<h2>` y el `<body>` tenga un margen que a veces es necesario eliminar.

Es importante recordar que estos estilos no son los estilos por defecto de CSS, si reestablecemos el elemento `<div>` a su valor inicial pasara a ser `inline`. ¡Vamos a comprobarlo!

```
div {
    display: initial; /* es igual a inline */
}
```
La única razón por la que tenemos esas diferencias entre los distintos tipos de elementos HTML (block vs inline) es porque el navegador carga su propio CSS.

Para tener una idea de como es la hoja de estilo de cada navegador (Chrome, Firefox) en los recursos de este articulo dejare los enlaces para que les des un vistazo.

En el concepto de la propiedad display también nos menciona que esta propiedad establece los tipos de **visualización interna y externa de un elemento**. La de tipo externa establece la participación de un elemento en el flujo normal; la tipo interna establece el layout (Diseño) de los hijos.

#### Flujo Normal (normal flow)

El flujo normal en HTML es el orden natural en el que los elementos aparecen en pantalla, es decir, los elementos aparecerán colocados tal como estén ordenados en el código HTML solo si no se aplica ningún CSS que cambie la forma en la que se comportan.

Como ya hemos mencionado anteriormente estos elementos en HTML por defecto son elementos "en línea" o elementos "en bloque".

Conociendo esto, la documentación de la MDN define el flujo normal de la siguiente manera:

> El flujo normal, o flow Layout, es la forma en que los elementos de bloque y en línea se muestran en una página antes de que se realicen cambios en su diseño.

### ¿Cómo se comportan los elementos Block e Inline cuando forman parte del flujo normal?

En el flujo normal, los elementos en línea se muestran en la dirección en línea, es decir, se muestran uno tras otro, comenzando por la izquierda. Los elementos en bloque se muestran uno detrás de otro, es decir, comienzan en la parte superior y se mueven hacia abajo en la página.

📖 Esto lo podemos comprender cuando leemos un libro, siempre vamos a leer de arriba hacia abajo y de izquierda a derecha.

La propiedad display aparte de tener los valores anteriores también tiene un valor llamado: `inline-block` que junto con los demás nos sirve para definir la colocación de elementos individuales, también tiene otros valores importantes como: `none`, `flex` y `grid`. 

##🍫 display: inline

Los elementos en línea no admiten dimensiones (width, height) pero si admiten margin, padding y border, solo ocupan lo que tengan en su contenido, es decir, aunque quieras declarar un ancho y alto a un elemento de línea no podrá tener efecto ya que estos elementos no aceptan dimensiones, así también lo explica la documentación de la MDN:

> Los elementos en línea tienen su altura y anchura determinados por su contenido. 

Si hay varios elementos en línea estarán colocados de izquierda a derecha (uno al lado de otro).

Por ejemplo, el elemento HTML `<span>` es un elemento de línea por defecto y no importa cuántas etiquetas `<span>` haya, siempre aparecerán en línea o, en otras palabras, una inmediatamente después de la otra, produciendo una cadena continua de texto.

```
 <span class="inline">Soy un elemento de linea</span>
 <span class="inline">Soy otro elemento de linea</span>
 <span class="inline">Soy otro elemento más de linea</span>
```
```
.inline {
    background-color: khaki;
}
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1xr8rpxh6rxk8eb8898.png)

Si quieres cambiar el tamaño, tienes que tener en cuenta que no podrás hacerlo porque recuerda que los elementos de línea no admiten dimensiones, esto lo puedes cambiar por `display: block` o `display: inline-block` de esta forma ya podrás cambiar el tamaño de tus elementos.

###🤔 ¿Cuáles son los elementos de línea?

La siguiente es una lista de los elementos en línea de HTML, podemos ver algunos de estos elementos en los cuales colocamos contenido en forma de texto:

`b`, `big`, `i`, `small`, `tt`, 
`abbr`, `acronym`, `cite`, `code`, `dfn`, `em`, `kbd`, `strong`, `samp`, `time`, `var`, 
`a`, `bdo`, `br`, **`img`**, `map`, `object`, `q`, `script`, `span`, `sub`, `sup`, 
`button`, `input`, `label`, `select`, `textarea`.

😰 ¿Debo aprender de memoria todos los elementos de línea? La respuesta es que no es necesario, simplemente con la practica lograras identificar que elementos son de línea o de bloque. Recuerda que la practica hace al maestro. 🤓 

##📄 display: block

Un elemento de bloque es un elemento que ocupa el ancho máximo disponible. Tal y como dice la documentación de la MDN:

> De manera predeterminada, el contenido de un elemento de nivel de bloque es el 100% del ancho de su elemento padre y su altura viene determinada por su contenido.

Esto nos quiere decir que los elementos de tipo bloque abarcan el 100% del espacio que tengan disponible, es decir, se estiran por todo el ancho de la página.

Cabe mencionar que estos elementos si admiten dimensiones pero no pueden tener otro elemento a su lado ya que abarcan todo el espacio que tengan disponible por lo tanto estarán colocados de arriba hacia abajo, aunque este comportamiento por defecto puede ser modificado colocando `display: inline-block`.

Cuando hay varios elementos, estos están separados por sus márgenes, como vemos en la siguiente imagen, esto tiene que ver con un tema fundamental llamado: Colapso de márgenes.

```
 <p class="block">Soy un elemento de bloque</p>
 <p class="block">Soy otro elemento de bloque</p>
 <p class="block">Soy otro elemento más de bloque</p>
```
```
.block {
    background-color: khaki;
}
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qhhg516qhqvtnkitr90c.png)

En general, los elementos en bloque también pueden contener elementos en línea y otros elementos en bloque, así que los elementos en bloque crean estructuras "más grandes" que los elementos en línea.

###🤔 ¿Cuáles son los elementos de bloque?

La siguiente es una lista de los elementos en bloque, alguno de ellos los podemos ver como contenedores:

`<address>`, `<article>`, `<aside>`, `<audio>`, `<blockquote>`, `<canvas>`, `<dd>`, `<div>`, `<dl>`, `<fieldset>`, `<figcaption>`, `<figure>`, `<footer>`, `<form>`, `<header>`, `<hgroup>`, `<hr>`, `<li>`, `<main>`, `<nav>`, `<noscript>`, `<ol>`, `<output>`, `<p>`, `<pre>`, `<section>`, `<table>`, `<tfoot>`, `<ul>`, `<video>`, `<h1>`...`<h6>`. 

Recuerda que no es necesario que memorices cada uno de estos elementos, ya que con la practica lograras identificarlos fácilmente.

##⏸️ display: inline-block

Es una combinación entre los dos tipos de elementos mencionados anteriormente (block e inline), los elementos con el valor `inline-block` admiten dimensiones pero todavía son elementos de línea, es decir estarán colocados uno al lado de otro.

### El elemento `<img>`

Un dato curioso es que el elemento `<img>` [es un elemento **inline**](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#styling_with_css), esto quiere decir que incluso puedes colocar una imagen en medio de un párrafo. 

Sin embargo, una imagen es como cualquier otro elemento de bloque porque puede tener: `border`, `margin`, `padding` y también puedes modificar su altura y anchura.

🤯 Para ser precisos una imagen es en realidad un elemento de línea y de bloque al mismo tiempo, en otras palabras: `display: inline-block`. ¡Vamos a comprobarlo!

```css
.image {
    width: 300px;
    height: 300px;
    padding: 20px;
    margin: 30px;
    border: 5px solid red;
}

/* HTML */
<img class="image" src="https://picsum.photos/200/200"/>
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpddhnrg3l97psdi2mcp.png)

Como las imágenes son elementos inline, esto produce un espacio debajo debido a su `line-height`. Si alguna vez has tenido un misterioso espacio de `4px` que no era `border`, `margin`o `padding`, probablemente era el llamado "“inline magic space”" que los navegadores añaden al `line-height`.

Se puede solucionar de dos formas:

* Añadiendo `line-height:0`  al contenedor de la imagen. 
* Asignando `display:block` a la imagen directamente (`img { display: block;}`). ✅  

 Así evitamos toda una serie de problemas.

##👻 display: none

Lo que hace el valor `none` de la propiedad `display` es que oculta un elemento, por lo que no ocupara ningún espacio. El elemento estará oculto y la pagina será desplegada como si el elemento no estuviera allí.

Este valor se utiliza constantemente cuando en los dispositivos móviles no queremos que haya elementos que tengan que mostrarse al usuario por el espacio que ocupan, pero que en pantallas grandes si tengan que aparecer.

Hay que tener cuidado con este valor, porque sabemos que si oculta el elemento pero se sigue renderizando, por ejemplo, si en una pagina web al `body` le colocáramos la declaración: `display: none` no se mostraría nada pero los recursos se seguirían cargando, por lo tanto hay que utilizarlo con cuidado.

##↕️↔️ display: flex y display: grid

Los últimos valores mas importantes de la propiedad display es `grid` y `flex`. No voy a profundizar en estos temas porque considero que merecen un articulo propio e incluso un tutorial completo, bien explicado y con muchos ejercicios ya que son temas extensos.

De manera general podemos decir que el valor `flex` se usa para maquetar componentes como por ejemplo, un menú de navegación y `grid` se usa para maquetar el layout. Se que estoy generalizando y esto, no es 100% así, porque pueden haber componentes complejos en los que es necesario usar `grid` y algunos layouts son simples y otros no, todo depende de lo que estés diseñando.

De todas maneras comparto una infografía de un gran desarrollador llamado Addy Osmani (Ingeniero en Google Chrome) que se basó en el articulo de Ahmad Shadeed para realizar esta comparación.

{% twitter 1272423597550657537 %}

No te preocupes, realizare todo un articulo para ver en profundidad flexbox y grid, pero por ahora es necesario que comprendas como funciona la propiedad display.

Antes de correr, aprende a caminar 🚶‍♀️...🏃‍♀️

##📋 Conclusión

☑️ Todas las etiquetas HTML tienen configuraciones de estilo CSS por defecto, incluso si ninguna es proporcionada por usted.
☑️ Los elementos en HTML usualmente son elementos "en línea" o elementos "en bloque". Pero este comportamiento por defecto puede ser modificado.
☑️ Los elementos en línea no admiten dimensiones (width, height) aunque si admiten margin, padding y border.

##🔎Recursos:

* [Display | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/display) 
* [Flujo normal | MDN] (https://developer.mozilla.org/es/docs/Learn/CSS/CSS_layout/Normal_Flow)
* [Elementos en línea | MDN] (https://developer.mozilla.org/es/docs/Web/HTML/Inline_elements)
* [Elementos en bloque | MDN] (https://developer.mozilla.org/es/docs/Web/HTML/Block-level_elements)
* [Understanding the CSS Box-Model | Elad Shechter
](https://medium.com/cssclass-com/understanding-the-css-box-model-97e4228670d6)
* [Firefox | Stylesheet](https://searchfox.org/mozilla-central/source/layout/style/res/html.css)
* [Chromium | Stylesheet](https://chromium.googlesource.com/chromium/blink/+/refs/heads/main/Source/core/css/html.css)
* [WebKit de Chrome | stylesheet](http://trac.webkit.org/browser/webkit/trunk/Source/WebCore/css/html.css?rev=276657)


Gracias por leer🦸🏻‍♀️
Mis redes sociales donde comparto notas de código:

[▶️Youtube](https://www.youtube.com/lupitacode)
[📷Instagram](https://instagram.com/lupitacode)
[🐦Twitter](https://twitter.com/lupitacode)
[🔵Facebook](https://facebook.com/lupitacode)
[🔲Codepen](https://codepen.io/lupitacode/)
[✍️Medium](https://lupitacode.medium.com/)
[🎵Tik Tok](https://www.tiktok.com/@lupitacode)