Animaciones con CSS y JavaScript: crea un componente de feedback

Curso de Transformaciones y Transiciones en CSS

Toma las primeras clases gratis

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

¡Te doy la bienvenida a un nuevo reto de CSS! Esta vez vamos a simular que calificamos una página de regalos de navidad con con animaciones de CSS y JavaScript.

Compártenos el resultado final en los comentarios y/o en Twitter con el hashtag #RetosPlatziCSS. 😉

0

Antes de comenzar, los cursos de Platzi que te recomiendo para realizar este reto son los siguientes:

Paso 0: planeación

Para este reto te propongo que realices los siguientes 5 pasos:

  1. Analiza el diseño
  2. Elabora la maquetación con HTML y CSS
  3. Crea la funcionalidad de las estrellas con JavaScript
  4. Haz aparecer y desaparecer la cajita de comentarios con JavaScript
  5. ¡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 (Sin afán, tómate tu tiempo). Sólo de esta forma podrás convertirte en un(a) experto(a) en maquetación con CSS.

ʕ•́ᴥ•̀ʔっ ¡Empecemos!

Paso 1: analiza el diseño

Algo que nos ayuda mucho a la hora de escribir nuestro HTML y CSS es tener un entendimiento general del diseño que debemos replicar. No solo porque nos da una idea de lo que haremos, sino también porque podemos hacer preguntas al diseñador o diseñadora antes de comenzar y evitar eventos inesperados en el camino.

Aquí te comparto el diseño en Figma con el que estaremos trabajando en este reto para que lo puedas revisar con detalle.

1

Una vez que vemos el diseño podemos crearnos un mapa mental de cómo vamos a crear cada estructura en el código:

2

Analizar el diseño también nos da una comprensión de los recursos que necesitaremos, como por ejemplo:

Paso 2: elabora la maquetación con HTML y CSS

Para elaborar la maquetación de nuestra página comenzaremos desde lo esencial (como el contenedor, la imagen, los textos y el botón), luego continuaremos con las estrellas y con la cajita de comentarios.

Contenedor principal

Este contenedor principal luce de la siguiente forma:

3

Para ello nuestro HTML sería el siguiente:

<section class="modal">
  <img class="main-image" src="https://i.ibb.co/PmV6Qgn/Christmas-tree-01.png" alt="Hand with tree">
  <h1 class="title">Do you like uGift?</h1>
  <p class="subtitle">Rate your expirience</p>
  <div class="stars-container"></div>
  <div id="comment-box" class="comment-box"></div>
  <button id="submit-button" class="submit-button">Submit</button>
</section>

Y nuestro CSS sería el siguiente:

@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300;500&display=swap');

:root {
  --gray: #C8C6C6;
  --red: #CD1818;  
  --white: #FFFFFF;  
}

body {
  display: grid;
  font-family: 'Nunito', sans-serif;
  height: 100vh;
  margin: 0;
  place-items: center;
}

.modal {
  align-items: center;
  background: var(--red);
  border-radius: 16px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  padding: 24px;
  width: 360px;
}

.main-image {
  margin-top: -112px;
  width: 314px;
}

.title {
  color: var(--white);
  font-size: 36px;
  margin-bottom: 12px;
  margin-top: 0;
}

.subtitle {
  color: var(--white);
  font-size: 24px;
  font-weight: 300;
  margin-bottom: 32px;
  margin-top: 0;
}

.submit-button {
  background: var(--white);
  border: none;
  border-radius: 16px;
  cursor: pointer;
  font-size: 24px;
  padding: 8px;
  width: 100%;
  z-index: 10;
}

Estrellas

Este contenedor principal con las estrellas lucen de la siguiente forma:

4

Para ello nuestro HTML para las estrellas sería el siguiente:

<div class="stars-container">
    <div class="gray-stars-container">
      <img src="https://i.ibb.co/j4LkR89/icons8-star-30.png" alt="gray star">
      <img src="https://i.ibb.co/j4LkR89/icons8-star-30.png" alt="gray star">
      <img src="https://i.ibb.co/j4LkR89/icons8-star-30.png" alt="gray star">
      <img src="https://i.ibb.co/j4LkR89/icons8-star-30.png" alt="gray star">
      <img src="https://i.ibb.co/j4LkR89/icons8-star-30.png" alt="gray star">
    </div>
    <p class="yellow-stars-container">
      <span id="star1" class="star">⭐️</span>
      <span id="star2" class="star">⭐️</span>
      <span id="star3" class="star">⭐️</span>
      <span id="star4" class="star">⭐️</span>
      <span id="star5" class="star">⭐️</span>
    </p>
  </div>

Y nuestro CSS sería el siguiente:

.stars-container {
  display: flex;
  justify-content: center;
  margin-bottom: 32px;
  position: relative;
  width: 100%;
}

.gray-stars-container img {
  width: 42px;
}

.yellow-stars-container {
  cursor: pointer;
  font-size: 37px;
  left: 45px;
  margin: 0 auto;
  position: absolute;
  top: 0;
}

Cajita de comentarios

Este contenedor principal con las estrellas y la cajita de comentarios lucen de la siguiente forma:

5

Nuestro HTML para la cajita de comentarios sería el siguiente:

<div id="comment-box" class="comment-box hidden">
  <label for="comment">Leave us your comment</label>
  <textarea name="comment" id="" cols="30" rows="10" placeholder="Type your comment"></textarea>
</div>

Y nuestro CSS:

.comment-box label {
  color: var(--white);
  display: inline-block;
  font-weight: 300;
  margin-bottom: 12px;
}

.comment-box textarea {
  background: none;
  border: 1px solid white;
  border-radius: 16px;
  box-sizing: border-box;
  color: var(--white);
  display: inline-block;
  font-family: 'Nunito', sans-serif;
  height: 80px;
  margin-bottom: 24px;
  padding: 12px;
  width: 100%;
}

.comment-box textarea::placeholder {
  color: var(--gray);
}

Paso 3: crea la funcionalidad de las estrellas con JavaScript

La idea principal con las estrellas es que puedas “calificar” la página de regalos de navidad. Si te gustó la página, les dejas 5 estrellitas, pero si no te gustó ni un poquito, les dejas 1 estrellita. Para ello, debemos tener en cuenta las siguientes consideraciones:

  1. Si el usuario quiere dejar su calificación de 5 estrellitas, presiona Submit y listo.
  2. Si el usuario quiere dejar su calificación menor a 5 estrellitas, debe salir una cajita de comentarios y luego presionar el botón de Submit.
  3. Si el usuario quiere dejar una calificación de 4 estrellitas, por ejemplo, la quinta estrellita debe mostrarse de color gris.
  4. Al presionar Submit, el componente de calificación debe regresar a su estado inicial (es decir, todas las estrellitas amarillas).

Estas consideraciones las puedes visualizar en el siguiente GIF para tener una idea más clara de lo que debemos hacer:

6

Para lograr lo anterior, debemos tener en nuestro CSS una clase que se llame hidden para remover nuestra estrellita amarilla (y así se dejará ver la estrellita gris que está por debajo) una vez sea presionada:

.hidden {
  display: none;
}

Ahora accederemos al DOM para poder manipular desde JavaScript tanto el grupo de estrellas amarillas como el botón de Submit:

const stars = document.querySelectorAll('.star')
const submitButton = document.getElementById('submit-button')

También haremos un objeto que almacenará cada una de las estrellas y haremos un array con las keys de ese objeto, esto nos ayudará a detectar más adelante cuál fue la estrella presionada y cuáles son las siguientes estrellas después de esa para poder removerlas:

const visibleStars = {
  star1: document.getElementById('star1'),
  star2: document.getElementById('star2'),
  star3: document.getElementById('star3'),
  star4: document.getElementById('star4'),
  star5: document.getElementById('star5')
}

const visibleStarsArr = Object.keys(visibleStars) // ["star1","star2","star3","star4","star5"]

Una vez tenemos acceso a las estrellitas, lo que vamos a hacer es recorrerlas y agregarle un “escuchador” para saber cuándo se le hizo click a determinada estrellita, así:

stars.forEach(star => {
  star.addEventListener('click', () => {
    // Aquí irá más código ahorita
  })
})

Ahora necesitamos:

  1. Saber cuál fue la estrella clickeada y en qué posición del array de keys (que hicimos al principio) está. Para ellos usamos visibleStarsArr.findIndex(e => e === star.getAttribute('id')).
  2. Una vez tenemos esa posición, le decimos que seleccione las estrellas que están después de esa posición clickeada haciendo visibleStarsArr.slice(starNumber + 1, 5).
  3. Recorremos las estrellas que están después de la posición clickeada (del ítem anterior) y les añadimos la clase hidden que creamos con CSS.

Teniendo en cuenta lo anterior, nuestro código se vería de la siguiente forma:

stars.forEach(star => {
  star.addEventListener('click', () => {
    const starNumber = visibleStarsArr.findIndex(e => e === star.getAttribute('id')) // 0
    const hiddenStars = visibleStarsArr.slice(starNumber + 1, 5) // 1-5
    hiddenStars.map(hiddenStar => {
      visibleStars[hiddenStar].classList.remove('visible')
      visibleStars[hiddenStar].classList.add('hidden')
    })
  })
})

Finalmente añadimos otro “escuchador”, pero esta vez para nuestro botón:

 submitButton.addEventListener('click', () => {
    // Aquí irá más código ahorita
 })

Y luego tomamos el array de keys que hicimos al principio, lo recorremos y le agregamos la visibilidad a cada una de las estrellitas para que vuelvan a su estado inicial:

 submitButton.addEventListener('click', () => {
   visibleStarsArr.map(showStar => {
     visibleStars[showStar].classList.remove('hidden')
     visibleStars[showStar].classList.add('visible')
   })
 })

Por cierto, nos faltaba la clase visible y para ello, escribimos lo siguiente en nuestro CSS:

.visible {
  display: inline-block;
}

Paso 4: haz aparecer y desaparecer la cajita de comentarios con JavaScript

Teniendo en cuenta las consideraciones de nuestro paso anterior, si el usuario quiere dejar su calificación menor a 5 estrellitas, debe salir una cajita de comentarios y luego presionar el botón de Submit, así:

0

Nuestro HTML para la cajita quedaría de la siguiente forma:

<div id="comment-box" class="comment-box hidden">
  <label for="comment">Leave us your comment</label>
  <textarea name="comment" id="" cols="30" rows="10" placeholder="Type your comment"></textarea>
</div>

Y el CSS así:

.comment-box {
  height: 0;
}

.visible {
  display: inline-block;
  animation: visible 0.3s ease-in-out forwards;
}

@keyframes visible {
  from {
    height: 0;
  }
  to {
    height: 138px;
  }
}

Aquí lo que hicimos fue agregar una animación para que no se vea tan rápida la aparición de la cajita y también para atraer la atención del usuario justo en esa parte para que pueda dejarnos su comentario.

Ahora en JavaScript lo que debemos hacer es acceder a la cajita de la siguiente forma para poder manipularla:

const commentBox = document.getElementById('comment-box')

Y luego debemos decirle que si la estrellita es diferente a star5, entonces muestre la cajita:

if (star.getAttribute('id') !== 'star5') {
  commentBox.classList.remove('hidden')
  commentBox.classList.add('visible')
}

Con esto, nuestro código del paso anterior nos quedaría así:

stars.forEach(star => {
  star.addEventListener('click', () => {
    const starNumber = visibleStarsArr.findIndex(e => e === star.getAttribute('id')) // 0
    const hiddenStars = visibleStarsArr.slice(starNumber + 1, 5) // 1-5
    hiddenStars.map(hiddenStar => {
      visibleStars[hiddenStar].classList.remove('visible')
      visibleStars[hiddenStar].classList.add('hidden')
    })
    
    if (star.getAttribute('id') !== 'star5') {
      commentBox.classList.remove('hidden')
      commentBox.classList.add('visible')
    }
  })
})

Adicionalmente, al presionar el botón de Submit debemos ocultar nuevamente la cajita y para ello, nuestro código del “escuchador” para el botón nos quedaría de la siguiente forma:

submitButton.addEventListener('click', () => {
  visibleStarsArr.map(showStar => {
    visibleStars[showStar].classList.remove('hidden')
    visibleStars[showStar].classList.add('visible')
    commentBox.classList.remove('visible')
    commentBox.classList.add('hidden')
  })
})

Paso 5: ¡Compártenos tu resultado en los comentarios!

¡Este paso es mi favorito! Compártenos en los comentarios y/o en Twitter con el hashtag #RetosPlatziCSS el resultado final de tu calificacación de la página de regalos de navidad. 😄

Aquí te comparto mi codepen, mi repositorio de GitHub y el deploy con el resultado final.

Además, cuéntanos qué otro tipo de retos te gustaría encontrar en esta sección.

#NuncaParesDeAprender

Curso de Transformaciones y Transiciones en CSS

Toma las primeras clases gratis

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

0 Comentarios

para escribir tu comentario

Artículos relacionados