¡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. 😉
Antes de comenzar, los cursos de Platzi que te recomiendo para realizar este reto son los siguientes:
Para este reto te propongo que realices los siguientes 5 pasos:
💡 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!
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.
Una vez que vemos el diseño podemos crearnos un mapa mental de cómo vamos a crear cada estructura en el código:
Analizar el diseño también nos da una comprensión de los recursos que necesitaremos, como por ejemplo:
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.
Este contenedor principal luce de la siguiente forma:
Para ello nuestro HTML sería el siguiente:
<section class="modal">
<imgclass="main-image"src="https://i.ibb.co/PmV6Qgn/Christmas-tree-01.png"alt="Hand with tree"><h1class="title">Do you like uGift?</h1><pclass="subtitle">Rate your expirience</p><divclass="stars-container"></div><divid="comment-box"class="comment-box"></div><buttonid="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;
}
Este contenedor principal con las estrellas lucen de la siguiente forma:
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-containerimg {
width: 42px;
}
.yellow-stars-container {
cursor: pointer;
font-size: 37px;
left: 45px;
margin: 0 auto;
position: absolute;
top: 0;
}
Este contenedor principal con las estrellas y la cajita de comentarios lucen de la siguiente forma:
Nuestro HTML para la cajita de comentarios sería el siguiente:
<divid="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-boxlabel {
color: var(--white);
display: inline-block;
font-weight: 300;
margin-bottom: 12px;
}
.comment-boxtextarea {
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-boxtextarea::placeholder {
color: var(--gray);
}
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:
Estas consideraciones las puedes visualizar en el siguiente GIF para tener una idea más clara de lo que debemos hacer:
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:
visibleStarsArr.findIndex(e => e === star.getAttribute('id'))
.visibleStarsArr.slice(starNumber + 1, 5)
.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')) // 0const 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;
}
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í:
Nuestro HTML para la cajita quedaría de la siguiente forma:
<divid="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')) // 0const 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')
})
})
¡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
Este tipo de actividades es de las mejores cosas que puede haber en Platzi!!
Me alegra infinito leer esto !!! 💚💚💚
Me lo apunto!!, Que buena práctica!!!
Esooo 🎉✨ Feliz de ver tu resultado !!!
Increible actividad. Es posible que Platzi realice un reto en donde se diseñe un juego, usando JavaScript ?
Wow, estaría increíble ! Podemos hacerloooo 🎉
Te imaginas el juego más o menos cómo ? (Para poderlo tener en cuenta).
Viste el jueguito que hacemos en el curso de Animaciones con CSS (https://platzi.com/cursos/animaciones-css/) ? Sería algo así por el estilo ?
Quedo atenta !!!
Aquí mi solución! 😃
Wow, te quedó espectacular !!! 😍
Impresionante!
🥰🎉
Buen aporte gracias
💚💚💚
Genial!
🎉🎉🎉
❤️
❤️
habrán cursos específicamente de este tema?
Hola !!! Ya los tenemos, te los recomiendo justo al principio de este blog:
· Curso de Frontend Developer: https://platzi.com/cursos/frontend-developer/
· Curso Práctico de Frontend Developer: https://platzi.com/cursos/frontend-developer-practico/
· Curso de Animaciones con CSS: https://platzi.com/cursos/animaciones-css/
· Curso Básico de JavaScript: https://platzi.com/cursos/basico-javascript/
Lo que hacemos con este tipo de publicaciones es tomar todas las bases de estos cursos y crear diferentes mini proyecticos 🥰
Reto cumplido #RetosPlatziCSS no lo pude subir en gif por que no se como 🙊 pero se cumplio llevando de la mano este gran tutorial
Super, comparto dos lecturas muy significativas por parte del sitio de Developers acerca de las animaciones.
**Animaciones de CSS frente a JavaScript **
https://developers.google.com/web/fundamentals/design-and-ux/animations/css-vs-javascript?hl=es
Animaciones y Rendimiento
https://developers.google.com/web/fundamentals/design-and-ux/animations/animations-and-performance?hl=es#css-vs-javascript-performance
Muy bonito, yo lo hice com componente en React aprovechando que estoy aprendiendo esta libreria.
F como dicen los chavos, no se subio el GIF :c
Pero aca lo dejo de nuevo 😄
que entretenido !!! lo hare de inmediato
Gracias por hacer éste tipo de prácticas. Aveces, necesitamos estos “pequeños” ejercicios para quitarnos el “miedo” cuando vamos comenzando.
Simplemente espectacular!
Cuando sea grande quiero ser como tu …
Con este tipo de actividades es que realmente se aprende, no solo es teoría muchachos, ¡la práctica es sumamente importante!