¡Te doy la bienvenida a un nuevo reto de CSS! Vamos a crear la siguiente animación de un reproductor de música usando HTML, CSS y un poquito de JavaScript:
Compártenos el resultado final en los comentarios y/o en Twitter con el hashtag #RetosPlatziCSS. 😉
Antes de empezar, te recomiendo tomar los siguientes cursos en Platzi:
Aprender sobre el diseño de animaciones interactivas es bastante importante si queremos o debemos trabajar con animaciones en nuestra interfaz. Por esta razón que te hice un pequeño resumen ilustrado basado en el libro de Designing Interface Animation de Val Head para conocer sobre los principios de la animación interactiva.
El diseño de animaciones interactivas, que suelen ser las animaciones de interfaz, requieren enfocar la animación de manera un poco diferente y trabajar con un conjunto de reglas diferentes al comportamiento de los 12 principios clásicos de animación de Disney. Estas nos enseñan mucho sobre la creación de animaciones naturales y agradables, pero no consideran el contexto interactivo del usuario en las interfaces.
Los siguientes principios de animación interactiva son pautas para diseñar animaciones que siempre funcionarán con nuestros usuarios y nunca se interpondrán en su camino.
Todas las animaciones de interfaz deben tener un propósito para estar allí. Si no se puede justificar en términos de diseño, probablemente no valga la pena tenerlas.
Ejemplos de animaciones con propósito pueden ser “llamar la atención del usuario sobre el cambio en el estado de los elementos” o incluso “comunicar el estado de ánimo y la personalidad de tu marca”.
No permitas que un usuario deba esperar a que una animación se efectúe, especialmente en tareas que son repetitivas.
La animación no debe obstaculizar que el usuario realice una tarea en particular. Por su puesto, nunca vamos a dificultar intencionalmente que nuestros usuarios completen una tarea determinada, pero es fácil dejarse llevar por el diseño de algo hermoso. Aunque, existen momentos en los que no se puede evitar la espera (loaders).
Por ejemplo, si vas a animar un menú de navegación con un submenú, haz que se deslice rápidamente hacia abajo desde la parte superior de la pantalla y que no tome cantidades de tiempo innecesarias.
Las buenas animaciones de interfaz deben ser flexibles y siempre responder a la entrada de un usuario, incluso si la animación se está animando actualmente.
A veces la animación y la interacción se encuentran en desacuerdo:
Incluso si una animación dura solo una fracción de segundo, es posible que se produzca alguna entrada durante ese tiempo. Y ahí es donde las cosas pueden complicarse.
Una animación que ignora la entrada mientras está activa es una animación de bloqueo. Y el comportamiento de bloqueo puede hacer que la interfaz se sienta rota o lenta cuando no responde como se esperaba.
Debemos tener en cuenta que las tareas de nuestros usuarios de por sí ya toman un tiempo en realizarse, así que debemos tener en mente que nuestras animaciones son un factor adicional a los demás factores de tiempo.
Un buen rango para las animaciones está entre 200ms y 500ms en general (y de 200ms a 350ms para Small UI transitions). Sin embargo, curvas de aceleración más complejas necesitan más tiempo para ser legibles.
Los navegadores pueden animar algunas propiedades más eficientemente que otras en función de cuántos procesos (layout, paint & composite) deben suceder detrás de escena para actualizar dicha propiedad (esto lo puedes ver con más detalle en los cursos que te mencioné al principio de esta guía 😄). Este, es uno de los factores más importantes a tener en cuenta a la hora de animar: saber qué propiedades son mejores para animar y cuáles no.
Cuando quieras diseñar una animación que sea tan hermosa como agradable de interactuar como hermosa:
¡Ahora sí! Comencemos a crear la animación de nuestro reproductor de música.
Te propongo que realices los siguientes 5 pasos para completar el reto:
⚠️ Recomendación
Evita copiar y pegar el código. Trata de transcribir cada detalle y entender muy bien su funcionamiento. Solo de esta forma podrás convertirte en experta o experto maquetando con CSS.
ʕ•́ᴥ•̀ʔっ ¡Empecemos!
Nuestro reproductor de música tiene dos vistas principales: la vista de la lista de canciones (parte de atrás) y la vista de la canción que estás escuchando actualmente (parte de adelante):
Teniendo en cuenta la imagen anterior, revisemos cómo sería la estructura del diseño en etiquetas de HTML para la vista de la canción que estamos escuchando actualmente:
Y revisemos cómo sería la estructura del diseño en etiquetas de HTML para la vista de la lista de canciones:
Ahora escribamos lo anterior en código HTML:
<divclass="wrapper"><ulclass="background"><!-- Lista de canciones --><liclass="card"></li><liclass="card"></li><liclass="card"></li><liclass="card"></li><liclass="card"></li><liclass="card"></li></ul><divclass="foreground"><!-- Canción que estamos escuchando actualmente --><imgclass="main-image"src=""alt=""><divclass="music-player-box"><div><!-- Caja con información del artista y canción --><div><p>Dua Lipa</p><p>Love again</p></div></div><div><!-- Barra de reproducción --><div></div><div></div></div></div></div>
A cada card
le añadiremos el siguiente HTML:
<liclass="card"><imgsrc="https://jenesaispop.com/wp-content/uploads/2020/01/dua-lipa_future-nostalgia_portada.jpg"alt="Dua Lipa"><div><p>Dua Lipa</p><p><span>Levitating</span><span>3:23</span></p></div></li>
La idea es que coloques las canciones que más te gusten en este momento. Añade una imagen, el nombre del artista, el título de la canción y su duración. Adicionalmente, el CSS nos quedaría de la siguiente forma:
body {
margin: 0;
height: 100vh;
display: grid;
place-items: center; /* Para centrar el reproductor vertical y horizontalmente */background: LightSkyBlue;
font-family: 'Lato', sans-serif; /* Fuente sacada de Google Fonts */
}
.wrapper {
width: 360px;
height: 425px;
position: relative;
border-radius: 30px;
overflow: hidden;
}
.foreground, .background {
width: 100%;
height: 100%;
border-radius: 30px;
}
.background {
background: white;
box-sizing: border-box;
margin: 0;
position: absolute;
/* Un padding grande en el top porque si colocamos una canción ahí no se va a ver ya que la taparía la vista principal */padding: 106px20px20px20px;
overflow: scroll;
}
.foreground {
background: white;
position: absolute;
}
Con el HTML y CSS anterior tendremos el siguiente resultado:
Así se debe ver nuestra lista de canciones agregándole estilos:
Para ello tenemos el siguiente CSS:
.card {
display: flex;
width: 100%;
padding: 20px0;
border-bottom: 1px solid Gainsboro;
}
.card > img {
width: 60px;
height: 60px;
border-radius: 24px;
margin-right: 10px;
object-fit: cover;
}
.card > div {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 8px0;
width: 100%;
}
.carddivp:first-child {
font-size: 16px;
margin: 0;
}
.carddivp:last-child {
color: DarkGray;
display: flex;
justify-content: space-between;
font-size: 12px;
margin: 0;
}
Aquí también te comparto el código en Codepen para que puedas visualizarlo.
En esta vista principal tenemos un menú, una imagen principal y, una caja con varios elementos como el nombre del artista, canción, íconos y barra de reproducción:
El HTML tiene esta forma:
<div class="foreground">
<!-- Aquí va tu ícono de menú --><imgclass="main-image"src="https://i.ytimg.com/vi/BC19kwABFwc/maxresdefault.jpg"alt="Dua Lipa"><divclass="music-player-box"><div><!-- Aquí va tu ícono para ir a la canción anterior --><div><p>Dua Lipa</p><p>Love again</p></div><!-- Aquí va tu ícono para ir a la canción siguiente --></div><div><div></div><div></div></div></div></div>
Los íconos puedes sacarlos de icons8. Yo use el ícono end para la flechita que mira hacia la izquierda, el ícono skip to start para la flechita que mira hacia la derecha y el ícono menu para el menú.
El CSS nos queda de la siguiente manera:
.foreground > svg {
position: absolute;
margin: 20px;
left: 0;
cursor: pointer;
}
.main-image {
width: 100%;
height: 75%;
border-radius: 30px;
object-fit: cover;
align-self: start;
}
.music-player-box {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 8px auto;
position: absolute;
}
.music-player-box > div:first-child {
display: flex;
width: 70%;
align-items: center;
}
.music-player-box > div:first-childdiv {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 8px0;
width: 100%;
height: 46px;
}
.music-player-box > div:first-childdiv > p:first-child {
font-size: 16px;
margin: 0;
}
.music-player-box > div:first-childdiv > p:last-child {
color: DarkGray;
font-size: 12px;
margin: 0;
}
.music-player-box > div:last-child {
background: Gainsboro;
width: 80%;
height: 5px;
border-radius: 5px;
position: relative;
margin: 6px010px0;
}
.music-player-box > div:last-childdiv:first-child {
background: LightSkyBlue;
border-radius: 5px;
position: absolute;
width: 80%;
height: 100%;
}
.music-player-box > div:last-childdiv:last-child {
background: LightSkyBlue;
position: absolute;
right: 50px;
width: 10px;
height: 10px;
top: -3px;
border-radius: 50%;
}
De nuevo, aquí te comparto el código en Codepen para que puedas visualizarlo.
Ya que tenemos los estilos de la lista de canciones y de la canción que estamos escuchando actualmente, debemos agregarle animaciones a nuestra vista principal para que nos quede de la siguiente manera:
El menú cambia de tamaño, así que su clase de CSS quedaría de la siguiente forma:
.menu__small {
animation: menu-small 0.5s ease-in-out forwards;
}
@keyframes menu-small {
to {
width: 0;
height: 0;
}
}
La imagen principal cambia de tamaño, así que su clase de CSS quedaría de la siguiente forma:
.main-image__small {
animation: main-image-small 0.5s ease-in-out forwards;
}
@keyframes main-image-small {
to {
width: 60px;
height: 60px;
border-radius: 24px;
margin: 20px10px0px20px;
object-fit: cover;
}
}
La cajita donde está el nombre del artista con la barra de reproducción cambia de lugar, así que su clase de CSS quedaría de la siguiente forma:
.music-player-box__small {
animation: music-player-box-small 0.5s ease-in-out forwards;
}
@keyframes music-player-box-small {
0% {
width: 100%;
right: -10px;
}
100% {
width: 85%;
right: -10px;
bottom: 0;
}
}
Y el alto del contenedor de la vista cambia, así que su clase de CSS quedaría de la siguiente forma:
.foreground__small {
animation: foreground-small 0.5s ease-in-out forwards;
}
@keyframes foreground-small {
100% {
height: 25%;
box-shadow: 05px10pxrgba(0,0,0,0.1), 03px3pxrgba(0,0,0,0.1);
}
}
En este punto, te recuerdo que es muy recomendable tomar los siguientes cursos en Platzi para que tengas una mayor comprensión de las animaciones que acabamos de crear:
Solo nos queda crear un evento que escuche cuando le hacemos click en el menú para que a cada elemento se le agreguen las clases con las animaciones que creamos anteriormente. Esto nos quedaría en JavaScript de la siguiente forma:
const foreground = document.querySelector('.foreground')
const menu = document.querySelector('.menu')
const mainImage = document.querySelector('.main-image')
const musicPlayerBox = document.querySelector('.music-player-box')
functionanimateElements() {
foreground.classList.add('foreground__small')
menu.classList.add('menu__small')
mainImage.classList.add('main-image__small')
musicPlayerBox.classList.add('music-player-box__small')
}
menu.addEventListener('click', animateElements)
Aquí te comparto el código en Codepen para que puedas visualizarlo.
¡Este paso es mi favorito! Compártenos en los comentarios y/o en Twitter el resultado final de tu reproductor de música animado. 😄
Te comparto mi Codepen con el resultado final basado en esta animacion del UX Designer Mauricio.
Te espero en un próximo reto. #NuncaParesDeAprender 😉
Tremendo. Lo voy a realizar y ponerlo en mi portafolio. Saludos y gracias por compartir
Excelente Jorge !!! Feliz de verloooo 😍
이번 챌린지 너무 좋다
Manos a la obra … 😄
Eso Jeferson !!! Ya por ahí lo vi en Instagram 😍 Espectacular !!!
Wow, se ve bastante interesante para intentar, me gusto
Súper, Lady !!! Feliz de ver tu resultadooo 😍
Listo que hermosura parce!
No quedo perfecto, pero me siento orgulloso! Jejeje 😄
<h1>Aquí esta mi Código & Aquí mi Page.</h1>Listo que hermosura parce!
No quedo perfecto, pero me siento orgulloso! Jejeje 😄
<h1>Aquí esta mi Código & Aquí mi Page.</h1>Me encanto, esta muy genial. Realmente un buen producto o solo una feature bien pensada y analizada en detalle dara al final un muy buen resultado.
Los detalles hacen que sea sutilmente increible.
Así es ! Los detalles lo son todo… Gracias por tu aporte, Jose !!! 🤗💚
😲😲😲
Wow! Está excelente y que grandes consejos para entender el por qué y para qué de una animación… Vamos a hacer el reto y a compartirlo. Gracias!
Esoooo !!! Feliz de ver el resultadooo 😍
WOW
Gran reto! lo hare para sumarlo a mis proyectos 👌