Looking for a simple and fun JavaScript project to improve your frontend skills? A Random Joke Generator is the perfect way to practice API integration, event handling, and smooth animations. In this blog, we’ll explore how HTML, CSS, and JavaScript come together to create an interactive joke app that makes users smile with a single click.
HTML: Creating the Structure:
The HTML structure of this project is minimal yet effective. It includes a div
with the class wrapper
that serves as the container for the emoji, the joke text, and a button. The <p>
tag with the id="joke"
is used to dynamically display the fetched joke. The emoji is added via a Unicode character to give the app a playful and engaging vibe. The button triggers the joke-fetching functionality when clicked.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Random Joke Generator</title> <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet"></link> <link rel="stylesheet" href="style.css"> </head> <body> <div class="wrapper"> <span>😂</span> <p id="joke"></p> <button id="btn">Get Random Joke</button> </div> <script src="script.js"></script> </body> </html>
CSS: Designing the Look:
The CSS adds visual appeal and improves the user experience. The page has a cheerful yellow background (#fab22e
), while the joke container uses a dark background (#15161a
) to make the text pop. The layout is centered using absolute positioning and CSS transforms. The emoji is styled with a large font size, and the joke text is centrally aligned with a readable font size and line spacing. The .fade
class controls the transition effect, giving the joke a smooth fade-in animation. The button is styled to match the background color, providing visual consistency.
* { padding: 0; margin: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body { background-color: #fab22e; } .wrapper { width: 80vmin; padding: 50px 40px; background-color: #15161a; position: absolute; transform: translate(-50%, -50%); top: 50%; left: 50%; border-radius: 5px; box-shadow: 20px 20px 40px rgba(97, 63, 0, 0.4); } span { display: block; text-align: center; font-size: 100px; } p { font-size: 16px; color: #ffffff; font-weight: 400; text-align: center; word-wrap: break-word; line-height: 35px; margin: 30px 0; opacity: 0; } .fade { opacity: 1; transition: opacity 1.5s; } button { display: block; background-color: #fab22e; border: none; outline: none; cursor: pointer; font-size: 18px; color: #171721; font-weight: 600; margin: 0 auto; padding: 12px 25px; border-radius: 5px; }
JavaScript: Powering the Functionality
The real magic happens in the JavaScript. It fetches jokes from the JokeAPI using the Fetch API. The endpoint is filtered to exclude inappropriate content and only retrieves single-line jokes. When the page loads or the button is clicked, the getJoke()
function is triggered. It removes the fade
class to reset the animation, fetches a new joke, and then re-applies the fade
class to animate the new content. This simple logic makes the app responsive and fun to use.
const jokeContainer = document.getElementById("joke"); const btn = document.getElementById("btn"); const url = "https://v2.jokeapi.dev/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist,explicit&type=single"; let getJoke = () => { jokeContainer.classList.remove("fade"); fetch(url) .then((data) => data.json()) .then((item) => { jokeContainer.textContent = `${item.joke}`; jokeContainer.classList.add("fade"); }); }; btn.addEventListener("click", getJoke); getJoke();