Skip to content

Creating Winter Mad Libs

Bree Hall edited this page Jan 31, 2022 · 13 revisions

This Wiki will walk you through the process of creating your own version of Winter Mad Libs. The full video tutorial can be found here.

// TO DO: EXPLAIN WHERE TO FIND THE STORIES // TO DO: ADD LINKS / RESOURCES SECTION

Table of Contents

1. Project Setup & Structure

2. Creating the Mad Libs Form

3. Create Form Submit and Story Generation Functionality

4. Making This Tutorial Project Your Own

5. Links & Resources Used

1. Project Setup & Structure

1. This first thing we want to do is create the required files for our project and connect them. This project will only require vanilla HTML, CSS, and JavaScript, so we won't be adding in additional libraries or frameworks. In your desired directory, create the following files:

MadLibs.html for the structure

MadLibs.css for the styling

MadLibs.js for added functionality

2. Configure the HTML Document

After the files have been created, open MadLibs.html. Create a basic HTML5 page by creating or copying the HTML5 boiler plate code.

Hint: If you're using Visual Studio code, you can type html:5 to render the boiler plate code for you. Not using Visual Studio Code? You can copy the HTML5 boiler plate code here.

After loading in the HTML5 boiler plate, update the <title> to reflect the name of the project (or whatever you see fit). Then, connect the other two files that will help us build Mad Libs (MadLibs.css and MadLibs.js).

In order to connect MadLibs.css, add a <link> to the <head> in MadLibs.html where rel="stylesheet" and href is equal to the local address of the MadLibs.css file.

To connect the MadLibs.js, add a <script> to the bottom of the <body> where the src is equal to the local address of the MadLibs.js file.

Hint: I always like to create some simple logic in my CSS and JavaScript files when I link them to my HTML just to make sure they're connected properly. If you would like to do the same, try this:

In MadLibs.css, add a rule to make the backgroud-color of the body blue. Use: body { background-color: blue; }.

In MadLibs.js, add an alert statement with a simple message like Hello. Use alert("Hello!");.

Open your MadLibs.html file in your favorite browser and you should notice that the background color of the document is blue and there should be an alert with the message you entered. If you notice one of these two things didn't happen, you may need to review the location you provided to the <link> or the <script>. Just make sure to remove these statements after you've validated the connections.

Checkpoint

At this current point, the MadLibs.html should look something like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./madlibs.css">
    <title>Mad Libs</title>
</head>
<body>
    <!-- JS Script inclusion -->
    <script src="./madlibs.js"></script>
</body>
</html>

3. Create the Document <header>

Now that the structure of the project has been created and all required files have been connected, let's create the <header> for our page. The header will tell users what our app is, give a description about the game, and tell users how to play the game. Feel free to get creative with this!

In the <body>, create a <header>. Inside of the <header> create the following:

  • An <h1> with the title of our project

  • An <h2> with the subtitle of our project. For this, I will be using the name of the story the users will be creating.

  • A <p> with an explanation of the game

Here's what your <header> should look like:

<header>
   <h1 >Winter Mad Libs</h1>
   <h2>❄️Fun Facts About Winter ☃️</h2>
   <p><strong>Mad Libs</strong> are stories with words removed and replaced by blank spaces. Fill in the blanks for a fun winter story! Make sure to think outside the box. The wackier the better!</p>
</header>

At this point, we have a very bare bones app! If you open MadLibs.html in your browser, you won't see a lot, but you will be able to see the content from the <header> we just created. Here's an example of what you should see:

Mad Libs Checkpoint #1

4. Add Styling to the Header and Home Page

The styling for this app is completely optional as you may want to style your app a different way. The styling that I create in this tutorial is just what I think looks nice. Get as creative as you would like! Open MadLibs.css to get started.

  • Add a Background: The first thing I'm going to tackle is the background. Let's add a rule that targets the body to add a nice blue gradient.
body{
    background-color: #63a4ff;
    background-image: linear-gradient(315deg, #63a4ff 0%, #83eaf1 74%);
}

Now, when you take a look at this change in your browser, you may notice that the gradient is repeated for the height of our header section. That's not exactly what we want. It should span the height of the entire document, so add a rule to target the html and give it a height of 100%.

html{
    height: 100%;
}

Hint: Gradients can be very tricky to work with, so don't feel like you always have to create them on your own. There are lots of designers and developers who have submitted their work to make our lives a little easier. The gradient being used here can be found here on EggGradients.com.

  • Update the Document Font: Let's change the basic Times New Roman font within our app. Google has a whole repo of free fonts that can be added to your projects. They're free and easy to use. For this app, I'll be using Poppins, but visit fonts.google.com to check out all of the fonts that are available.

Once the font has been selected on Google Fonts, they provide us with a <link> to use in the <head> of our HTML that will link the font so we can use it. We're going to copy all three links provided by Google and add them to our MadLibs.html in the <head> between the existing metadata and the link to MadLibs.css.

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">

After the links have been added to MadLibs.html, we will be able to use them in our CSS. In MadLibs.css, let's add a style to the existing body{} rule to set the font-family of our body to Poppins.

font-family: 'Poppins', sans-serif;

Checkpoint

At this point, your MadLibs.html should look like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="./madlibs.css">
    <title>Mad Libs</title>
</head>
<body>
    <header>
        <h1 >Winter Mad Libs</h1>
        <h2>❄️Fun Facts About Winter ☃️</h2>
        <p><strong>Mad Libs</strong> are stories with words removed and replaced by blank spaces. Fill in the blanks for a fun winter story! Make sure to think outside the box. The wackier the better!</p>
    </header>
    <!-- JS Script inclusion -->
    <script src="./madlibs.js"></script>
</body>
</html>

At this point, your MadLibs.css should look like this:

html{
    height: 100%;
}

body{
    background: rgb(131,234,241);
    background: linear-gradient(135deg, rgba(131,234,241,1) 9%, rgba(99,164,255,1) 99%);
    font-family: 'Poppins', sans-serif;
}
  • Create a Glassy Background for the Game Board: In order to make the game board stand out from the background, let's add some styling to play area. This will require us to make a slight adjustment to our structure. Let's create a container <div> that will hold our <header> and soon our <main>. Give it the class="container" so we can apply styles to it.

Note: Be sure to add this the new elements above the JavaScript inclusion tag.

<div class="container">
    <header>
        <h1 >Winter Mad Libs</h1>
        <h2>❄️Fun Facts About Winter ☃️</h2>
        <p><strong>Mad Libs</strong> are stories with words removed and replaced by blank spaces. Fill in the blanks for a fun winter story! Make sure to think outside the box. The wackier the better!</p>
    </header>
</div>

Over in MadLibs.css, we're going to create a new rule to target the container class and give it a white background with 60% opacity. This is going to create the glassy effect for us.

.container{
    background-color: rgba(255,255,255,.6 );
}

This looks nice, but we can make it look better by adding a border-radius and shadows. Let's give the container a border-radius of 20px and padding.

.container{
    background-color: rgba(255,255,255,.6 );
    padding: 30px 0;
    border-radius: 20px;
}

Let's give the container some dimension by adding a shadow. Similar to the gradients from above, you don't have to be an expert at shadows to use them. I found lots of great shadows on getcssscan.com. Once I found one I liked, I just had to plug in the code! Let's update the .container rule with a shadow.

.container{
    background-color: rgba(255,255,255,.6 );
    padding: 30px 0;
    border-radius: 20px;
    box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
}

Things look ok now, but it's taking up a good majority of the width of the page. Let's provide some height and width restrictions so we can still see the nice gradient in the background.

.container{
    background-color: rgba(255,255,255,.6 );
    padding: 30px 0;
    border-radius: 20px;
    box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
    min-width: 60vw;
    max-width: 70vw;
    min-height: 60vh;
    max-height: 90vh;
    margin: 0 auto;
}

The last styling adjustment we’ll make for now is adding a style to center the container in the middle of the screen so it doesn’t just stay at the top. There are lots of ways to do this, but I’m going to do it by adding flex to the parent of .container (which is the <body>) and telling it to align-items: center;. This will vertically align any child elements of body.

We need to add a rule for height here because the flex will vertically center the child items based on the height of it’s content, but we want it to be the whole page, so we increase the height of the container to be the height of the entire page. But then, we get a scroll bar on the side. This is because we have two elements with heights set to 100%. I wouldn’t use this in all cases because it can get messy, but since we know we only care about the card in the middle, we’re going to set the overflow of y to hidden as well.

Let's update the body{} rule:

body{
    background: rgb(131,234,241);
    background: linear-gradient(135deg, rgba(131,234,241,1) 9%, rgba(99,164,255,1) 99%);
    font-family: 'Poppins', sans-serif;
    height: 100%
    display: flex;
    align-items: center;
    overflow-y: hidden;
}

Checkpoint

So far, we've completed the following:

✅ Created the structure for our Mad Libs projects

✅ Created our document <header>

✅ Created the initial styling for the project

At this point, your MadLibs.html should look like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="./madlibs.css">
    <title>Mad Libs</title>
</head>
<body>
    <div class="container">
        <header>
            <h1 >Winter Mad Libs</h1>
            <h2>❄️Fun Facts About Winter ☃️</h2>
            <p><strong>Mad Libs</strong> are stories with words removed and replaced by blank spaces. Fill in the blanks for a fun winter story! Make sure to think outside the box. The wackier the better!</p>
        </header>
    </div>
    <!-- JS Script inclusion -->
    <script src="./madlibs.js"></script>
</body>
</html>

At this point, your MadLibs.css should look like this:

html{
    height: 100%;
}

body{
    height: 100%;
    overflow-y: hidden;
    background: rgb(131,234,241);
    background: linear-gradient(135deg, rgba(131,234,241,1) 9%, rgba(99,164,255,1) 99%);
    font-family: 'Poppins', sans-serif;
    display: flex;
    align-items: center;
}

.container{
    margin: 0 auto;
    min-width: 60vw;
    max-width: 70vw;
    min-height: 60vh;
    max-height: 90vh;
    padding: 30px 0;
    background-color: rgba(255,255,255,.6 );
    border-radius: 20px;
    box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
    overflow-y: auto;
}

Here's what our project looks like so far:

Mad Libs - Progression #2

2. Creating the Mad Libs Form

With the basic structure and styling of our app set, it's time to create the actual form that users will interact with to create and submit their Mad Libs.

In order to create our form, we'll be using a basic HTML <form> to compose our play area. The form inputs will be based on the amount of works that should be filled in to complete the story. The story we'll be using for this tutorial has 12 blanks the user must fill in, this means our form should have 12 inputs. If you're interested, you can find a like to the story we'll be using here (Fun Facts About Winter).

1. Create the structure of the play area

Let's create the area of the board where users will input their terms for Mad Libs. We always want to use semantic HTML, so in MadLibs.html, below the <header>, add a <main> containing a <form>. Be sure to give the <form> a name and id.

<main>
      <form id=”madlibs-form” name=”madlibs-form”></form>
</main>

take a second and think about the structure of our form. In the demo, after we input our text, and submit the form to generate the story, the input text goes away and the text on the Generate Button changes to Play Again. One little piece of set up we can do now to help us with that later is to break our form into two

elements. The first section will hold our inputs, and the other section will hold our submit button.
<main>
    <form id=”madlibs-form” name=”madlibs-form”>
        <section id="madlibs-inputs"></section>
        <section id="madlibs-submit"></section>
    </form>
</main>

2. Create Mad Libs Form Elements

Since Mad Libs is a word game, all of our <input> elements will have the type of text. Something that will be helpful for this step is having a list of inputs your specific story will need right next to you in a list as you develop. Most stories will have multiple inputs that require the same parts of speech, so we have to be good and consistent with our naming conventions.

This two step process will need to be repeated for each term the user will have to submit. First, give each <input> a <label>. The label will be paired with an <input> and tell the browser which input the user is filling out. The for attribute maps the <label> to the <input>, so the text used on this attribute should match the id attribute of the <input>.

Label Example

<label for="number">number</label>

Input Example

<input type="text" id="number" name="number" required>

We will be styling the <input> elements in a later step, so combine these two elements in a <div> with the class input-group.

<div class="input-group">
    <label for="number">number</label>
    <input type="text" id="number" name="number" required>
</div>

Notice that we've also included the required attribute on the <input>. This is because we don't want anyone to be able to submit this form without completing all of the fields because they won't have a full story. By adding the required attribute, we're telling the submit button for the form to double check and make sure all fields are fill out. If not, the user has to go back and review parts they may have missed. Now, complete this process for all of your inputs.

Note:

You may notice I’ve added some emojis to go with my labels. You don’t have to by any means, I just think they’re cute. But if you’re interested, I just got them from emojipedia.com where they allow you to copy and paste emojis.

Now that we have our inputs, all we need is a button to submit our form. Since we're "generating" a story for our users, let's call this button generate. This will be added in the <section> below the madlibs-inputs section we created earlier. This button is being used inside of a <form>, so be sure to set the type attribute to submit.

<section id="madlibs-submit">
    <button type="submit">Generate</button>
</section>

When completed, your MadLibs.html should look like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="./madlibs.css">
    <title>Mad Libs</title>
</head>
<body>
    <div class="container">
        <header id="intro" class="center">
            <h1 >Winter Mad Libs</h1>
            <h2>❄️Fun Facts About Winter ☃️</h2>
            <p><strong>Mad Libs</strong> are stories with words removed and replaced by blank spaces. Fill in the blanks for a fun winter story! Make sure to think outside the box. The wackier the better!</p>
        </header>

        <main>
            <!-- Main MadLibs Form Input Area -->
            <form id="madlibs-form" name="madlibs-form" onsubmit="submitMadLibs(event)">
                <section id="madlibs-inputs">
                    <div class="input-group">
                        <label for="number">🔢 number</label>
                        <input type="text" id="number" name="number" required>
                    </div>
                    
                    <div class="input-group">
                        <label for="adjective_1">🦄 adjective</label>
                        <input type="text" id="adjective_1" name="adjective_1" required>
                    </div>
        
                    <div class="input-group">
                        <label for="noun_1">✏️ noun</label>
                        <input type="text" id="noun_1" name="noun_1" required>
                    </div>
        
                    <div class="input-group">
                        <label for="noun_2">✏️ noun</label>
                        <input type="text" id="noun_2" name="noun_2" required>
                    </div>
                    
                    <div class="input-group">
                        <label for="noun_3">✏️ noun</label>
                        <input type="text" id="noun_3" name="noun_3" required>
                    </div>
        
                    <div class="input-group">
                        <label for="adjective_2">🦄 adjective</label>
                        <input type="text" id="adjective_2" name="adjective_2" required>
                    </div>
        
                    <div class="input-group">
                        <label for="noun_4">✏️ noun</label>
                        <input type="text" id="noun_4" name="noun_4" required>
                    </div>
        
                    <div class="input-group">
                        <label for="sport_1">🏀 sport</label>
                        <input type="text" id="sport_1" name="sport_1" required>
                    </div>
        
                    <div class="input-group">
                        <label for="sport_2">🏀 sport</label>
                        <input type="text" id="sport_2" name="sport_2" required>
                    </div>
        
                    <div class="input-group">
                        <label for="sport_3">🏀 sport</label>
                        <input type="text" id="sport_3" name="sport_3" required>
                    </div>
        
                    <div class="input-group">
                        <label for="beverage">🧃 beverage</label>
                        <input type="text" id="beverage" name="beverage" required>
                    </div>
        
                    <div class="input-group">
                        <label for="food">🍕 food</label>
                        <input type="text" id="food" name="food" required>
                    </div>
                </section>
                <section id="madlibs-submit">
                   <button type="submit">Generate</button>
                </section>
            </form>
        </main>
    </div>
    
    
    <!-- JS Script inclusion -->
    <script src="./madlibs.js"></script>
</body>
</html>

If you hop over to the browser to check on your work, you should see something similar to this:

Mad Libs - Progression #4

3. Styling the Mad Libs Form Inputs

At this point, we have 99% of the inputs we'll be using to generate our Mad Libs! However, as you saw from the last progression photo, our form doesn't look great. The labels and elements are appearing side by side and it would be easier to read if they were stacked. Let's open MadLibs.css and give this form a facelift.

  • Add padding to form sections: Let's start by adding padding to section elements within the <form>.
form section {
    padding: 0 5%;
    margin-top: 20px;
}

There are lots of ways to achieve a stacked look for the <label> and <input>, but this time let's apply flex properties. This will allow us to stack input groups, allow them to flow from left to right, and wrap when there's no room left. In the game of Mad Libs, the users concept for the order of words doesn't matter too much.

  • Stack <label> and <input> elements: Let's target the <div> elements we encased the and` elements in, apply flex, and add a margin.
.input-group {
   display: flex;
   flex-direction: column;
   margin: 10px;
}

This looks better already, but let's add some custom styling to the <label> and <input> elements. I like to pill shaped inputs, so let's give the <input> elements that treatment by making them taller, wider, and adjusting the border-radius. A thicker border and box shadow add dimension as well.

.input-group label{
    padding-left: 10px;
}

.input-group input[type="text"] {
    height: 30px;
    width: 250px;
    border: 1px solid #edede8;
    border-radius: 20px;
    box-shadow: rgba(99, 99, 99, 0.1) 0px 2px 2px 0px;
    padding-left: 10px;
    margin: 3px 0 10px;
}

After these quick styling changes, you MadLibs.css should look like this:

html{
    height: 100%;
}

body{
    height: 100%;
    overflow-y: hidden;
    background: rgb(131,234,241);
    background: linear-gradient(135deg, rgba(131,234,241,1) 9%, rgba(99,164,255,1) 99%);
    font-family: 'Poppins', sans-serif;
    display: flex;
    align-items: center;
}

.container{
    margin: 0 auto;
    min-width: 60vw;
    max-width: 70vw;
    min-height: 60vh;
    max-height: 90vh;
    padding: 30px 0;
    background-color: rgba(255,255,255,.6 );
    border-radius: 20px;
    box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
    overflow-y: auto;
}

form section{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    padding: 0 5%;
    margin-top: 20px;
}

.input-group {
    display: flex;
    flex-direction: column;
    margin: 10px;
}

.input-group label{
    padding-left: 10px;
}

.input-group input[type="text"] {
    height: 30px;
    width: 250px;
    border: 1px solid #edede8;
    border-radius: 20px;
    box-shadow: rgba(99, 99, 99, 0.1) 0px 2px 2px 0px;
    padding-left: 10px;
    margin: 3px 0 10px;
}

If you hop over to the browser to check on your work, you should see something similar to this:

Mad Libs - Progression #5

4. Connect Submit Button to Form

We’re going to step away from styling just for a second to connect our submit button to our form and connect our form to our JavaScript.

Currently, if you select the Generate button (with inputs), it appears as though the page has refreshed, but when you take a look at the URL, it’s been updated to include our form inputs. This isn’t exactly what we want, so let’s tell our app what we do want.

In MadLibs.html, let’s start by providing our <form> element with the onsubmit attribute. This is a space where we can pass in a function and tell our form exactly what to do when the submit button is clicked. Let’s give it a function that we’re going to wire up in our JavaScript file next.

<form id="madlibs-form" name="madlibs-form" onsubmit="submitMadLibs(event)">

Now, let's go over to MadLibs.js and create a simple function to ensure that it is connected to the submit properly.

const submitMadLibs = (event) => {
    alert('hey!');
}

Now, when we fill out the form and generate, we get our "hey" message. However, the page still refreshes. What we can do to prevent the page from refreshing by adding one line.

const submitMadLibs = (event) => {
    alert('hey!');
    event.preventDefault();
}

Now, when we fill out our form and generate, we get our "hey" message and the page doesn’t refresh!

Checkpoint

So far, we've completed the following:

✅ Created the Mad Libs playing board <form> with inputs

✅ Styled the Mad Libs form

✅ Wired up the Mad Libs form to our JavaScript with a simple submit function

3. Create Form Submit and Story Generation Functionality

Clone this wiki locally