Contenido del curso
Optimización de imágenes
Paginación
Almacenamiento local
Bonus
Próximos pasos
Botón de like sobre pósters con CSS y JS
Resumen
Marcar películas como favoritas en una aplicación web requiere tres piezas que trabajan juntas: una sección visual con scroll horizontal, un botón superpuesto sobre cada póster y una lógica que diferencie el clic en la imagen del clic en el corazón. Aquí te muestro cómo armar esa interfaz reutilizando estilos existentes y resolviendo el conflicto de eventos que aparece en el camino.
Cómo maquetar la sección de películas favoritas en HTML
La sección de favoritos vive justo debajo de las categorías y replica el comportamiento de la sección de tendencias: un header con título y una lista con scroll horizontal.
La estructura base que necesitas en tu HTML es directa:
- Una etiqueta
sectionconid="liked"y claseliked-container. - Un
divcon claseliked-headerque contenga unh2con el texto Películas favoritas. - Un
articlecon claseliked-movie-listdonde JavaScript inyectará cadamovie-containercon su imagen.
¿Por qué usar la misma nomenclatura que en otras secciones? Porque te permite reutilizar estilos CSS existentes con solo agregar selectores separados por coma, sin reescribir reglas para padding, margin o scroll horizontal. [02:45]
Cómo reutilizar estilos CSS sin duplicar código
En lugar de escribir reglas nuevas, agregas tus clases liked-container, liked-header, liked-movie-list y liked-movie-container a los selectores que ya estilizan la sección trending.
El truco es identificar qué estilos compartir:
- El padding horizontal y el
margin-topde la clase compartidashaded. - El
margin-bottomdeltrending-preview-headerpara separar el título del listado. - Los estilos de scroll horizontal del
movie-list. - Las dimensiones y el
border-radiusdemovie-containery demovie-img.
Un detalle importante: el padding-left que necesitas en el header no debe vivir en el contenedor general, porque rompe el scroll de las películas. Muévelo al liked-header y el problema desaparece.
Cómo crear el botón de like con JavaScript
Dentro de la función que crea cada tarjeta de película, agregas un button con document.createElement y le asignas la clase movie-btn para que aplique a cualquier sección, no solo a favoritos.
El flujo dentro de esa función queda así:
- Crear el
movieContainery lamovieImgcomo ya existían. - Crear
movieBtncondocument.createElement('button'). - Agregar la clase con
movieBtn.classList.add('movie-btn'). - Escuchar el evento de clic con una arrow function que ejecute
movieBtn.classList.toggle('movie-btn--liked'). - Insertar el botón dentro del
movieContainerconappendChild.
¿Qué hace classList.toggle? Agrega una clase si no existe y la quita si ya está aplicada. Es la forma más limpia de alternar estados visuales sin escribir condicionales. [13:20]
Dejas un comentario marcando el punto donde después conectarás el guardado en local storage, pero por ahora el toggle de clase es suficiente para validar el comportamiento visual.
Cómo posicionar el corazón sobre la imagen con CSS
El botón debe flotar en la esquina superior derecha del póster. Para lograrlo necesitas dos posicionamientos coordinados.
En el movie-container aplicas position: relative para que sirva de referencia. En el movie-btn configuras:
position: absolutecontop: 5pxyright: 10px.width: 30pxyheight: 30pxpara una caja cuadrada.border-radius: 30pxpara convertirla en círculo.padding: 0ymargin: 0para limpiar los estilos por defecto del botón.
El corazón se inyecta con un pseudo-elemento ::before cuyo content contiene un emoji copiado desde Emojipedia. Cuando el botón recibe la clase movie-btn--liked, cambias el background-color a una variable CSS de morado claro y reemplazas el emoji por su versión inversa para que el contraste funcione.
Por qué el clic abre los detalles de la película y cómo solucionarlo
Al probar el botón, ocurre algo inesperado: hacer clic en el corazón también dispara la navegación a la vista de detalles. La causa es que el movie-container tiene su propio addEventListener que mueve el hash de la URL.
La solución más directa es mover ese event listener del contenedor a la imagen. Así el botón, que está superpuesto pero fuera del flujo de la imagen, no propaga el clic hacia la navegación.
¿Por qué no usar stopPropagation en el botón? Mover el listener a
movieImges más simple y declarativo: cada elemento responde solo a lo suyo, sin depender de detener eventos en cadena. [18:40]
Con ese cambio, el corazón alterna su clase sin disparar la navegación, y el clic sobre el póster sigue llevando al detalle de la película.
Habilidades y conceptos clave que aplicaste
- Maquetación con
section,articley nomenclatura BEM-like para reutilizar estilos [01:30]. - Selectores CSS agrupados con coma para compartir reglas entre secciones [05:10].
- Creación dinámica de elementos con
document.createElementyclassList.add[11:50]. - Posicionamiento
absolutedentro de un contenedorrelativepara superponer elementos [15:20]. - Pseudo-elementos
::beforeconcontentpara inyectar iconos sin tocar el HTML [17:05]. - Delegación de eventos correcta moviendo el listener al elemento adecuado [18:40].
Cuéntame en los comentarios qué emoji usaste para tu botón de favoritos y si encontraste una forma distinta de evitar la propagación del clic.