55
loading...
This website collects cookies to deliver better user experience
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.
article
y anidando las futuras secciones usando header
, section
y footer
, las cuales comienzan a darle estructura a nuestro posteo.<article>
<header></header>
<section></section>
<footer></footer>
</article>
div
, no te castigues si ves que realmente no podes evitarlo, pero es importante saber que utilizar la menor cantidad posible tiene sus beneficios: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 documentoheader
representa contenido introductorio o links de navegaciónfooter
es el pie de página o el final del contenido y suele tener información, autor, o contenido relacionado.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.<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>
category
y seed
. La librería nos va a dar es una imagen diferente para cada seed
dentro de cada categoría.div
que la contenga para poder manipularla sin alterar sus proporciones.<section>
<div class="img-wrapper">
<img src="https://i.imgur.com/bxPoqdw.jpg" alt="">
</div>
</section>
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..data
quien le dió like, el creador del contenido con su descripción, y en una etiqueta time
hace cuanto se posteó.<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>
#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.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.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;
}
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;
}
div
donde poner a nuestra imagen.object-fit: cover
para que cubra toda la superficie del padre.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%;
}
strong
por defecto es bolder (equivale a 700), así que lo suavizamos un poco al reducirlo a 600*.*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,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.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;
}
* + *
, 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.