¡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:
- Curso de Transformaciones y Transiciones en CSS
- Curso de Animaciones con CSS
- Curso Práctico de Maquetación y Animaciones con CSS
Diseño de animaciones interactivas 🎵
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.
Principio #1: tener un propósito conocido
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”.
Principio #2: evitar que las animaciones se convierten en obstáculos
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.
Principio # 3: mantener las animaciones flexibles
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:
- Generalmente la animación es de naturaleza lineal. Tiene un conjunto específico de estados o cuadros para reproducir de principio a fin y debe pasar cierto tiempo para que eso suceda.
- Por otro lado, la interacción no es lineal. Los usuarios pueden hacer click, desplazarse, deslizar el dedo y ofrecer otros tipos de entrada en cualquier momento.
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.
Principio # 4: sé rápido, sé legible (tiempo)
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.
Principio # 5: el rendimiento importa
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.
Cómo diseñar animaciones interactivas
Cuando quieras diseñar una animación que sea tan hermosa como agradable de interactuar como hermosa:
- Ten un propósito conocido para cada animación en tu interfaz.
- No crees obstáculo al usuario con las animaciones.
- Mantén las animaciones flexibles y sin bloqueos.
- Céntrate en la legibilidad por encima de la duración.
- Anima teniendo en cuenta las propiedades de CSS de mayor rendimiento y prepárate para un buen rendimiento desde el principio.
¡Animemos nuestro reproductor de música! 🎵
¡Ahora sí! Comencemos a crear la animación de nuestro reproductor de música.
Paso 0: planeación
Te propongo que realices los siguientes 5 pasos para completar el reto:
- Crea los dos contenedores (lista de canciones y canción que estás escuchando)
- Agrega los estilos a la lista de canciones
- Agrega los estilos de la canción que estás escuchando
- Agrega las diferentes animaciones e interacción
- ¡Compártenos tu resultado en los comentarios!
⚠️ 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!
Paso 1: crea los dos contenedores (lista de canciones y canción que estás escuchando)
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:
<div class="wrapper">
<ul class="background"><!-- Lista de canciones -->
<li class="card">
</li>
<li class="card">
</li>
<li class="card">
</li>
<li class="card">
</li>
<li class="card">
</li>
<li class="card">
</li>
</ul>
<div class="foreground"><!-- Canción que estamos escuchando actualmente -->
<img class="main-image" src="" alt="">
<div class="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:
<li class="card">
<img src="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: 106px 20px 20px 20px;
overflow: scroll;
}
.foreground {
background: white;
position: absolute;
}
Con el HTML y CSS anterior tendremos el siguiente resultado:

Paso 2: agrega los estilos a la lista de canciones
Así se debe ver nuestra lista de canciones agregándole estilos:

Para ello tenemos el siguiente CSS:
.card {
display: flex;
width: 100%;
padding: 20px 0;
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: 8px 0;
width: 100%;
}
.card div p:first-child {
font-size: 16px;
margin: 0;
}
.card div p: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.
Paso 3: agrega los estilos de la canción que estás escuchando
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ú -->
<img class="main-image" src="https://i.ytimg.com/vi/BC19kwABFwc/maxresdefault.jpg" alt="Dua Lipa">
<div class="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-child div {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 8px 0;
width: 100%;
height: 46px;
}
.music-player-box > div:first-child div > p:first-child {
font-size: 16px;
margin: 0;
}
.music-player-box > div:first-child div > 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: 6px 0 10px 0;
}
.music-player-box > div:last-child div:first-child {
background: LightSkyBlue;
border-radius: 5px;
position: absolute;
width: 80%;
height: 100%;
}
.music-player-box > div:last-child div: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.
Paso 4: agrega las diferentes animaciones e interacción
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: 20px 10px 0px 20px;
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: 0 5px 10px rgba(0,0,0,0.1), 0 3px 3px rgba(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:
- Curso de Transformaciones y Transiciones en CSS
- Curso de Animaciones con CSS
- Curso Práctico de Maquetación y Animaciones con CSS
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')
function animateElements() {
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.
Paso 5: ¡compártenos tu resultado en los comentarios!
¡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 😉
Curso de Transformaciones y Transiciones en CSS