Aprendiendo de los Grandes: El feed de Instagram 
Tags: spanish, webdev, beginners, html
Published: 2021-07-28 15:24:06

> En el proceso de aprender a desarrollar sitios web y utilizar las herramientas más básicas como lo son CSS y HTML, lo más desafiante es elegir ejemplos fáciles que reproducir.
Una web que es sorprendentemente familiar a todos con un moderado nivel de dificultad es Instagram. Vamos a ver como resolvemos muchos de los desafíos detrás de crear su feed y aprender en el camino una o dos cosas.

Lo primero que vamos a hacer es armar el tan conocido y emblemático posteo de Instagram en las diferentes partes que después vamos a maquetas con HTML.

![An Instagram Post Breakdown](https://cdn.hashnode.com/res/hashnode/image/upload/v1627057224144/1MyDWFCpn.jpeg)

## 🏗 Maquetando

Es bastante claro mirando el posteo, que tenemos

- un área superior que encabeza el componente donde está el usuario y su foto de perfil
- una sección principal donde está la imagen
- un area inferior donde vamos a poner las acciones, los datos y una sección donde el usuario puede comentar.

Ya mismo empezar a maquetar haciendo uso de la etiqueta semántica `article` y anidando las futuras secciones usando `header`, `section` y `footer`, las cuales comienzan a darle estructura a nuestro posteo.

```html
<article>
    <header></header>
    <section></section>
    <footer></footer>
</article>
```

### ¿Por qué no usar muchos div?
Es inevitable el uso de `div`, no te castigues si ves que realmente no podes evitarlo, pero es importante saber que utilizar la menor cantidad posible tiene sus beneficios:

- El código es mucho más fácil de leer, interpretar y mantener.
- Agregar estilo (CSS) a nuestros componentes se vuelve más sencillo y con menos clases.
- Estás utilizando las herramientas mas avanzadas y correctas para el maquetado.
- Mejores puntajes de SEO ✨
- Habla bien de vos como developer

### Y ¿por qué estas en particular?

- `article` es una etiqueta excelente para contenido auto-contenido (como lo es un posteo, un producto, el articulo de un blog, etc).
- `section` define una sección dentro de un documento
- `header` representa contenido introductorio o links de navegación
- `footer` es el pie de página o el final del contenido y suele tener información, autor, o contenido relacionado.

## 🏗 Agregando más elementos

### Header

Necesitamos agregar la imagen para la foto de perfil y un título para nuestro usuario.
También vamos a envolver a la imagen en un `div` en caso de que necesitemos manipularla dentro de la estructura sin alterar sus proporciones, y el titular va a contar con un `a` para llevarnos al perfil que corresponde.

![Post header](https://cdn.hashnode.com/res/hashnode/image/upload/v1627059574128/nCN4W4ApM.jpeg)

```html
<header>
  <div>
    <img width="32" height="32" src="https://avatars.dicebear.com/api/avataaars/alebonzo.svg">
  </div>
  <h2><a href="https://instagram.com/alebonzo">alebonzo</a></h2>
</header>
```

#### Maquetando con Placeholders

Para la imagen de perfil use **[Dicebear Avatars](https://avatars.dicebear.com/),** una librería de imágenes con una amplia cantidad de avatares que podemos usar solo poniendo una URL. Este tipo de librerías **es ideal cuando estamos maquetando y aún no tenemos las imágenes finales** pero queremos poner algo que denote la **intención que va a tener esa imagen.** En este caso es el avatar o foto de perfil de un usuario.

Para usarla ponemos la URL cambiando los valores de `category` y `seed`. La librería nos va a dar es una imagen diferente para cada `seed` dentro de cada categoría.

> https://avatars.dicebear.com/api/category/seed.svg


![Dicebear Avatars Website](https://cdn.hashnode.com/res/hashnode/image/upload/v1627059448034/jFmHIBxj1.jpeg)
*Las categorías están en el link, y el seed puede ser cualquier cosa **URL friendly** _(pst, para los espacios podes-usar-guiones)._*



### Section

Siendo un poco más fácil, acá solo queremos poner una imagen, y de nuevo vamos a poner un `div` que la contenga para poder manipularla sin alterar sus proporciones.

![Post main section](https://cdn.hashnode.com/res/hashnode/image/upload/v1627059497357/qBQjwa8nT.jpeg)

```html
<section>
  <div class="img-wrapper">
    <img src="https://i.imgur.com/bxPoqdw.jpg" alt="">
  </div>
</section>
```

### Footer

Vamos a comenzar por poner los iconos en su lugar con `svg` (los que nos ahorra tener que hacer iconos para cada tamaño, ya que los SVG son vectores y siempre se van a ver bien) y envolverlos en un `div` que los separe del resto de los elementos del footer al que vamos a llamar acciones.

Vamos a poner en `.data` quien le dió like, el creador del contenido con su descripción, y en una etiqueta [**`time`**](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time) hace cuanto se posteó.

![Post Footer](https://cdn.hashnode.com/res/hashnode/image/upload/v1627059531755/h4Ft5Axg0.jpeg)

```html
<footer>
  <div class="actions">
    <svg aria-label="Like" height="24" viewBox="0 0 48 48" width="24">...</svg>
    <svg aria-label="Comment" height="24" viewBox="0 0 48 48" width="24">...</svg>
    <svg aria-label="Share Post" height="24" viewBox="0 0 48 48" width="24">...</svg>
    <svg aria-label="Save" height="24" viewBox="0 0 48 48" width="24">...</svg>
	</div>
  <div class="data">
    <div class="likes">Liked by <strong>you</strong> and <strong>others</strong></div>
    <div class="description"><strong>ladyahorro</strong></div>
    <time>2 hours ago</time>
	</div>
  <div class="comment">
    <div class="emote">
			<svg height="24" viewBox="0 0 48 48" width="24">...</svg>
    </div>
    <input type="text" placeholder="Add a comment...">
    <button>Post</button>
  </div>
</footer>
```

## 🎨 Agregando estilo

¡Ahora es cuando se pone divertido! Con todo el HTML ya escrito, solo queda agregar estilo a los componentes para que se vean exactamente como queremos.

Comenzamos por definir la paleta inicial que vamos a utilizar. En este caso en particular, los obtuve directamente de la página de Instagram.

- `#ffffff`: Blanco, el fondo del articulo.
- `#dbdbdb`: Gris, para los bordes.
- `#262626`: Negro, para el color de los textos.
- `#0095f6`: Azul, para el botón.

### Article

Comenzamos con el aspecto en general de nuestro posteo, un **fondo** blanco, un **borde** gris con las **esquinas ligeramente redondeadas**. Y en caso de que haya algún elemento lo suficientemente *rebelde* como para extenderse sobre el padre, vamos a **ocultarlo**.
También en caso de que haya más de un posteo al lado del otro, queremos que estén separados entre sí, y para eso usamos márgenes.

**💡 PRO CSS TIP:** El selector `a + b` selecciona un elemento **b** que esté inmediatamente después de un elemento **a**. Esto puede ser usado con cualquier elemento, ya sea una clase, una etiqueta o un id.

```css
article {
  background-color: #ffffff;
  border: 1px solid #dbdbdb;
  border-radius: 4px;
  overflow: hidden;
}

/* Hacemos uso del selector a + b para seleccionar a cualquier posteo que este seguido de otro, y lo separamos verticalmente desde el lado superior. */
article + article {
	margin-top: 1rem;
}
```

### Header

Al header de nuestro posteo le vamos a poner una **borde inferior** gris del mismo color  que nuestro articulo, un poco de **espacio entre el contenido** y la caja, y vamos a hacer que los hijos estén **alineados al medio**.

Además de quitarle todo el estilo al link, al titular lo vamos a **separar** de la imagen desde el **lado izquierdo**, y vamos **redondear los bordes** de la imagen de perfil**.**

```css
article header {
  z-index: 20;
  background: #ffffff;
  display: flex;
  width: 100%;
  align-items: center;
  padding: 1rem;
  border-bottom: 1px solid #dbdbdb;
}

article header h2 {
  margin: 0;
  margin-left: 0.5rem;
  font-weight: 500;
  font-size: 1rem;
  color: #262626;
}

article header h2 a {
  text-decoration: none;
  color: #262626;
}

article header img {
  display: block;
  height: 32px;
  width: 32px;
  padding: 2px;
  border-radius: 100%;
  border: 1px solid #262626;
}
```

### Section

Para la sección de la foto, vamos a hacer un `div` donde poner a nuestra imagen.
Vamos a forzar la relación de aspecto de este elemento a 1:1 usando **[el truco del padding](https://mates-n-code.com/relaciones-de-aspecto-perfectas-en-css)**.
Por último, la imagen va a usar `object-fit: cover` para que cubra toda la superficie del padre.

```css

article section {
  width: 100%;
  position: relative;
  height: auto;
}

article section .img-wrapper {
  padding-top: 100%;
  position: relative;
}

article section img {
  position: absolute;
  display: block;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  object-fit: cover;
  height: 100%;
  width: 100%;
}
```

### Footer

El **peso tipográfico** de la etiqueta `strong` por defecto es **bolder** (equivale a 700), así que lo suavizamos un poco al reducirlo a 600**.**

Lo que vamos a hacer es poner las acciones separadas entre sí con **márgenes** y de los **bordes** laterales de la caja con **padding**.

La etiqueta `time` va a requerir que le bajemos un poco la intensidad, por lo que en vez de jugar con los colores, sencillamente **le bajamos la opacidad**,

Vamos a **remover los bordes del**  `input` y `button`. Para facilitar el armado de la estructura, vamos a usar `display: grid` en su padre, pero esta estructura también se puede lograr fácilmente con **flex**, sólo que con más líneas de código.

```css
article footer strong {
  font-weight: 600;
}

article footer svg {
  display: block;
}

article footer > * + * {
  margin-top: 1rem;
}

article footer > .actions,
article footer > .data > *,
article footer > .comment {
  padding-left: 1rem;
  padding-right: 1rem;
}
article footer > .data > * + * {
  margin-top: .5rem;
}

article footer .actions {
  padding-top: 1rem;
  display: flex;
}

article footer .actions > * + * {
  margin-left: .5rem;
}

article footer .actions > *:last-child {
  margin-left: auto;
  margin-right: 0;
}

article footer time {
  display: block;
  opacity: .6;
  font-size: .7rem;
  text-transform: uppercase;
}

article footer .comment {
  display: grid;
  grid-template-columns: auto 1fr 50px;
  align-items: center;
  gap: .15rem;
  margin-top: 1rem;
  padding-top: .7rem;
  padding-bottom: .7rem;
  border-top: 1px solid #dbdbdb;
}

article footer .comment input,
article footer .comment button {
  line-height: 1;
  background-color: #fff;
  padding: .5rem 1rem;
  border: 0;
}

article footer .comment button {
  color: #0095f6;
  font-weight: bold;
  text-align: center;
  cursor: pointer;
}

article footer .comment input::placeholder {
  color: #262626ee;
}
```

**💡 PRO CSS TIP:** El selector `* + *`, también conocido como Owl Selector, o Selector Buho 🦉, es excelente para seleccionar y darle espacio a varios elementos que no conocemos que van a ser; sólo que son hermanos. Combinarlo con el selector de hijos directos `>` va a ser ideal para evitar problemas con descendencias mas profundas.

## ✨ Uniendo todo

Una vez que juntamos todo tenemos y agregamos algunos post más, tenemos una interfaz más que conocida. Que como vimos, es un desafío fácil de tacklear si analizamos previamente que es lo que vamos a necesitar, maquetamos el HTML con conciencia y después le damos estilo.

{% codepen https://codepen.io/NOMADE/pen/abWbEWV %}

## 👋 Palabras Finales

Recrear estos sitios web nos sirve de práctica a la vez **que ayuda a incorporar técnicas y reglas de CSS**, que eventualmente nos van a salir de forma natural.

En otro posteo vamos a cubrir los pasos que nos faltan para terminar con la home de Instagram, mientras tanto cuéntenme en los comentarios sus opiniones y que les gustaría ver a futuro.

¡Hasta la próxima!