Create your own adventure game

Section 1: Proof of Concept

In this section, you will make a proof of concept web page that changes when you click on it.

In particular, you will:

  • Edit an HTML page to change the content of a web page
  • Create CSS rules to change the look of the web page
  • Add JavaScript code to make your page interactive
Preview of your first web page
Figure 1. Preview of your first web page

Click here to see a working demonstration of the page that you will create.

A "proof of concept" is something very simple that you create quickly, to show that your idea will work in practice. Today you will show that you can follow instructions in English and that you can type instructions for a computer to follow, and the proof will be a simple game online.

Discovering HTML

In this step, you will use Mozilla Thimble to create unique web page.

In particular, you will:

  • Learn about HTML tags
  • Edit the content of an HTML page

Starting a new project

When you start a new project in Mozilla Thimble, you will see the following text in the pane on the left:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <h1>Welcome to Thimble</h1>
    <p>
      Make something <strong>amazing</strong> with the web!
    </p>
  </body>
</html>

This is an HTML document. You use a browser, such as Mozilla Firefox, Яндекс.Браузер or Google Chrome to see an HTML document. If you click on the Preview button above, you will see how this document is displayed in a browser.

A new Thimble project
Figure 2. A new Thimble project

HTML means HyperText Markup Language. An HTML document consists of:

tags
Most markup tags have two parts: an opening section like <this> and a closing section like </this>. Some special tags, like <!DOCTYPE html> only have one part.
content
Content appears between an opening and closing tag. The content inside the <body> tag is what you see on the web page in your browser.

The tags tell your browser how the content should look. Each tag and its content is called an element.

Only the elements inside the <body> element are visible in the web browser. The information inside the <head> element tells the browser how to show the body.

Notice how the HTML elements are nested, like matrioshka dolls.

The <html> element is on the outside. The <head> and <body> elements are inside the <html> element, and the <h1> and <p> elements are inside the <body>.

To make this structure easier to see, each child element is indented by an extra 2 spaces on the left. However, the indentation is not important. An HTML page with no indentations is perfectly good.

How many different elements are there on this simple HTML page?

  1. !DOCTYPE
  2. html
  3. head
  4. body
  5. meta charset
  6. meta "viewport"
  7. title
  8. link
  9. h1
  10. p

You will learn more about these elements later.

  • The <h1> tag creates a major header. A header is big and in bold letters. A header appears on a separate line.
  • The <p> tag creates a paragraph. A paragraph is in normal-sized text. Each paraphraph starts on a new line.
  • The <strong> tag makes any piece of text appear bold. It does not create a new line.

You can find a list of all the HTML tags here. In this section, you will be using these new tags:

Edit the content

Change the text inside the <body> tag, as shown below. You can use your own name instead of Me!

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
  </body>
</html>

Now click on the Preview button above to see the result.

The result of your first edit
Figure 3. The result of your first edit

Compare the image above with the image on the previous page. What differences do you see?

In the image on the previous page:

  1. The text is centered.
  2. There are dots after the word "by", but these dots do not appear in the HTML file.
  3. Me! appears in red.

Styling your Content

In this step, you will learn about Cascading Style Sheets (CSS).

In particular, you will:

  • Create CSS rules
  • Learn how to center text
  • Learn how to change the color of text

What "cascading" means

CSS means Cascading Style Sheet. When you want to find the meaning of a word, one technique is to look online for images of that word. Try these searches:

In the next step, you'll discover why "cascading" is used to describe CSS style sheets.

The <head> tag

The <head> tag contains information to tell the browser how to show the content in the <body> tag. The simplest way center the text, or to change its color, is to add a <style> tag to the head element of your HTML page.

Edit your HTML page so that it looks like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
  </body>
</html>

Creating a style rule

You are now ready to create some CSS rules. A CSS rule has two parts:

A selector
The selector tells the browser which elements to look for.
Instructions
The instructions tell the browser how to show the selected elements.

Each instruction consists of two parts: a property and a value :

selector {
  property: value;
}

Here is an example:

body {
  text-align: center;
}

In this example:

  • The selector refers to the <body> element
  • The property is text-align
  • The value is center
  • The selector appears first
  • The instructions appear inside curly brackets { }
  • Each instruction is followed by a semi-colon ;.
  • The instructions are indented by 2 spaces.

If you forget the curly brackets or the semi-colon, the rule will not work correctly.

The use of spaces to indent the instructions is not important. It simply helps to make the rule easier to read. The rule below will work just as well:

body{text-align:center;}

You may have noticed the spelling of center and color. All the keywords that you will meet in this tutorial are written with the spelling used in the USA. To avoid confusion, the American spelling of these words is used everywhere in the text.

Adding a style rule

Add this rule to your HTML page, so that your page looks like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        text-align: center;
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
  </body>
</html>

Now click the Preview button above, and see how the layout of the page changes.

The effect of text-align: center;
Figure 4. The effect of text-align: center;

Multiple tag names

You can create a selector using more than one tag name. For example, the rule ...

body h1 {   }

... will be applied to all <h1> elements that are part of a <body> element.

All the elements that you can see in a browser window are part of the <body> element, so you don't usually need to include it in a selector. But you're going to learn a little magic trick in a moment, and this is part of the set-up for the trick.

Add a new rule to your HTML page, as shown below.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        text-align: center;
      }
      body h1 {
        opacity: 0.2;
        color: red;
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
  </body>
</html>

Before you click on the Preview button, can you predict what this rule will do? What do you think opacity means?

You have explicitly set the color of the h1 element to red. Why did you not need to set the color of the p element to black?

Black is the default color for text. White is the default color for the background. If you don't explicitly set a color, the default colors will be used.

The power of class

In this step, you will learn to create dynamic CSS rules, using classes.

In particular, you will:

  • Create more than one rule for the same element
  • Discover that the specificity of rules is important
  • Discover that the order of rules is important
  • Create a class to decide which rule will apply

More than one rule

What happens if you create more than one rule for the same element? Here's a new rule for you to try:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        text-align: center;
      }
      body h1 {
        opacity: 1;
        color: red;
      }
      h1 {
        opacity: 0.2;
        color: black;
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
  </body>
</html>

After making these changes, click on the Preview button above. Both rules apply to the <h1> element where you have typed your name. Your name is still red. Why did the new rule not have any effect?

Using two rules for the same element
Figure 5. Using two rules for the same element

Specificity

The new h1 rule is less specific than the earlier body h1 rule. The earlier rule uses two tag names for the selector, but the later rule only uses one tag: h1. So the more specific rule wins.

Order of precedence

So what happens if you make both selectors the same:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        text-align: center;
      }
      body h1 {
        opacity: 1;
        color: red;
      }
      body h1 {
        opacity: 0.2;
        color: black;
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
  </body>
</html>

When several rules use the same number of tags, the last rule wins. Now your name should be black, with 20% opacity.

The last rule wins
Figure 6. The last rule wins

Adding class

A third way to tell the browser that a CSS rule is important is to use a class. The version below shows the rule with opacity: 0.2; placed first, but with body.foo as part of the selector. The <body> element has also been given a new attribute: class="foo".

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        text-align: center;
      }
      body.foo h1 {
        opacity: 0.2;
      }
      body h1 {
        opacity: 1;
        color: red;
      }
    </style>
  </head>
  <body class="foo">
    <p>This game was made by</p>
    <h1>Me!</h1>
  </body>
</html>

Make these changes in your HTML file, but before you press the Preview button, make a prediction about what will happen.

The color: red; instruction is applied from the last rule, but the opacity: 0.2; instruction is applied from the earlier rule.

Why does this happen?

All the instructions from the lowest-priority rule are applied first. The instructions in higher-priority rules will override instructions applied earlier. Any specific instructions that are not overridden will still apply.

There is no instruction for color in the rule with the body.priority h1 selector, so the color: red; rule still applies.

Defining a CSS rule using a class
Figure 7. Defining a CSS rule using a class. Multiple rules apply.

foo is a nonsense word used by programmers. It tells you: "You can use any word here, and the result will be the same.There are several other nonsense words that can be used in the same way, such as bar and baz.

Interactivity with JavaScript

HTML and CSS create static pages, where the content does not change. JavaScript gives you the power to do everything. With JavaScript, you can:

  • Change the HTML content
  • Change the HTML tags
  • Change the CSS rules
  • Change the JavaScript itself
  • Send messages across the Internet
  • Change the world...?

In this step, you will use JavaScript to add a class to the <body> element when the user clicks.

In particular, you will:

  • Edit the CSS rules
  • Remove the class that you had attached to the <body> element
  • Add a <script> element to the <body>
  • Write a simple JavaScript command

Objects

Think of your home. It has one front door, and many rooms. In each room there are many things. Perhaps in your bedroom there is a bookcase with shelves and many books. To identify the first book on the second shelf in your bedroom, you could say:

home.bedroom.bookcase.shelves[2].books[1]

You can take this book and do things with it: read it, write in it, count its pages, use it as a ping-pong bat...

JavaScript thinks this way. It is an object-oriented programming language. This means that it thinks of things as objects which can:

  • Contain other objects (your home contains your bedroom)
  • Have properties (a book has pages, a page has text)
  • Have methods, or actions which you can do with the object (you can read() a book or count() its pages)

The document Object

Open a new tab in your browser and type about:blank in the address bar. This will create an empty window. The browser will automatically create the simplest possible HTML page. You are now going to use JavaScript to change this page.

Press Ctrl-Shift-I (or ⌘-Shift-I on Macintosh, to open the Inspector window in your browser. You will see a Console where you can type JavaScript commands and expressions.

For JavaScript in a browser, the equivalent of "home" is the document object. Everthing you see on a web page in a browser is a property of the document object.

In the Console, type:

document.body.innerText = "Hello World"
The Inspector window in Mozilla Firefox and Google Chrome
Figure 8. The Inspector window in Mozilla Firefox and Google Chrome. The Console is at the bottom of the window.

What do you see in the main browser window? You've just used JavaScript to change the HTML content of the <body> element on this page.

In the Console, type:

document.body.style = "background:black;color:white;font-size:16vw"

How does the content in the main window change? You've just used JavaScript to change the CSS for the <body> element.

Using the Inspector window in Firefox
Figure 9. Using the Inspector window in Firefox

Exploring the Inspector Window

In the Inspector window, you can see both the HTML content and the CSS rule that you have just created. You can edit the CSS rule. Click on the color tokens, and change the color of the background and the text. Click on the value for the font-size and use the up- and down-arrow keys to change the value. Double-click on the words "Hello world" to select them, then enter new text.

Take your time and explore the possibilities.

Adding JavaScript to your web page

To add CSS rules to your page, you first added a <style> element. To add JavaScript to your page, you need to add a <script> element. In Mozilla Thimble, edit your page so that it looks like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        text-align: center;
      }
      h1 {
        opacity: 0;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

Events, listeners and functions

Each time you interact with a web page, JavaScript generates an event. When you click with a mouse, you generate first a mousedown event, and then a mouseup event, when you release the mouse button.

document.body.onmouseup is a property of the <body> element that listens for mouseup events.

document.body.classList is a property of the <body> element that lists all the classes that have been attributed to the <body> element. In the last step, you used <body class="foo"> to attribute the foo class to the body.

A function is like a recipe for making cookies: it contains the instructions to make things happen. The command ...onmouseup = function () { ... } tells the browser to use this recipe each time you click on the page.

You will start exploring JavaScript in more detail in Section 3

Before you click on the Preview button, predict:

  • What you will see on the page
  • What will happen when you click on the page
  • Your name will not be visible at first
  • When you click on the page, your name will appear in red

Pseudo-elements

You have used CSS selectors to apply a rule to a complete element. CSS pselectors can also allow you to apply a rule to only part of an element. For instance:

  • The first letter of an element
  • The first line of an element
  • The selected text inside an element

As you will see now, you can also use CSS to add text before or after an element.

In this step, you will:

  • Discover the ::after pseudo-element
  • Create a rule to show three dots after "This game was made by"
  • Create a second rule to remove the dots when you click on the page
  • Change existing rules so that the text "This game was made by" is aligned to the left

Click here for more information about pseudo-elements

Adding a pseudo-class

Edit your index.html page so that it looks like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        text-align: center;
      }
      h1 {
        opacity: 0;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
      p::after {
        content: "..."
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

Click on the Preview button above, and you will see that your text now appears as "This game was made by ..." The three dots create suspense.

Look at the rule with the selector body.clicked h1 and the instructions of the new rule that you have just added. Can you imagine another rule that will make the dots disappear when the <body> tag becomes <body class="clicked">?

body.clicked p::after {
  content: "";
}

Removing the dots

The dots show that there is something missing. When your name appears, you don't want to see the dots any more. Edit your index.html page so that it looks like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        text-align: center;
      }
      h1 {
        opacity: 0;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
      p::after {
        content: "..."
      }
      body.clicked p::after {
        content: ""
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

Now, when you click on the page, your name will appear and the dots will disappear.

Fix for the text-align property

Currently, all text inside the <body> element is centered. But when you remove the dots, the text "This game was made by" shifts to the right. Can you imagine how to fix this?

The simplest solution would be to align the text for the <p> element to the left, rather than in the center. There are two ways you can do this. Here is one:

body {
  text-align: center;
}
p {
  text-align: left;
}

This will align all text in the <body> element in the center, except for text inside <p> elements. Text inside all <p> elements will be aligned to the left.

A simpler solution

Below, you will see a solution that uses less CSS code. The rule for the body has been removed, and the instruction text-align: center; has been moved to the h1 selector. The default setting for text-align is left, so all text in the web page will be aligned to the left, except for the text in <h1> elements.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      h1 {
        text-align: center;
        opacity: 0;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
      p::after {
        content: "..."
      }
      body.clicked p::after {
        content: ""
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

CSS transitions

A professional user interface is smooth. A menu will not appear suddenly; it will slide into the page. An image in a slideshow will fade out while the next image fades in. Changes are not abrupt. Changes are made with transitions.

In this step, you will learn how to create a sequence of transitions using CSS.

In particular, you will:

  • Make your name fade in
  • Make your name change color
  • Write a single CSS instruction for both effects

Adding a transition rule

To make your name fade in slowly, and to change slowly from the default black color to red, edit your index.html file, as shown below.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      h1 {
        text-align: center;
        opacity: 0;
        transition: all 2s;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
      p::after {
        content: "..."
      }
      body.clicked p::after {
        content: ""
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

The new instruction says: "Make a transition that lasts 2 seconds for all properties that change on an <h1> element. The following rule changes the values for both opacity and coloropacity and color......

      body.clicked h1 {
        opacity: 1;
        color: red;
      }

... so both opacity and color take 2 seconds to change. Your name will start black and slowly become red.

Defining a transition for only one property

Perhaps you want to only one property to change slowly and all other properties to change immediately. In this case, you can give the exact name of the property to which the transition will be applied. Can you predict what will happen if you make the change shown below?

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      h1 {
        text-align: center;
        opacity: 0;
        transition: opacity 2s;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
      p::after {
        content: "..."
      }
      body.clicked p::after {
        content: ""
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

The color property changes immediately. As soon as you see your name, it appears in red.

Delaying a transition

You can define two or more transitions, separating them by a comma. If you give two durations (for example 1s 2s, the first time is used for the duration of the transition, and the second time is used to delay the start of the transition.

For example: color 1s 2s will wait for 2 seconds and then make the color change over a period of 1 second.

Edit your index.html file as shown below, click on the Preview button, then click on the page and see what happens.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      h1 {
        text-align: center;
        opacity: 0;
        transition: opacity 2s, color 1s 2s;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
      p::after {
        content: "..."
      }
      body.clicked p::after {
        content: ""
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

To see the transition again, press the rotating arrow Reset button, then click on your page again. Edit the HTML file using different values for the duration of the transition and the duration of the pause before it begins. Experiment. Choose the values that you like best.

font-size

Your game is almost complete. You have one more thing to do, to make everything look good: set the size of the text.

In this step, you will

  • Learn about the font-size property
  • Learn about different units of measurement
  • Choose the best font-size of the <p> and the <h1> element

font-size

Back in step 6: Interactivity, you typed the following command into the Console in the Inspector window:

document.body.style = "background:black;color:white;font-size:16vw"

You will remember that the instruction font-size; 16vw made the text big enough to fit the width of the browser window. The property font-size sets the size of the text. It is clear that 16 refers to a number, but what does vw mean?

Text refers to the content of an HTML element: the letters, words and punctuation. Font refers to the form of the letters. Here are examples of different fonts:

  • This text is shown in the Arial font
  • This text is shown in the Times New Roman font
  • This text is shown in the Courrier New font
  • This text is shown in the Comic Sans MS font, or something similar

As you can see, some fonts are bigger than others. The size of the text depends on the size of the font.

vw

vw is a unit of measurement. 100vw is equal to the width of the viewport. "Viewport" is a technical word for the browser window or the smartphone screen where the HTML file is displayed. So if your browser window is 500 pixels wide, 16vw will be 80 pixels. If you make the window 1000 pixels wide, then 16vw will become 160 pixels. The size of the font will change with the viewport wwidth. The text will always be proportional to the width of the window.

Measurement Units

There are several different measurement units. Each one is useful in different situations. Here are the two most commonly used units:

px
Pixel. 1px is the smallest dot that can be shown on your screen. A 1080p screen will have 1920 × 1080 pixels. The default font-size in a desktop browser is often 16px.

16px
24px
48px
em
Originally this meant "the width of the letter M", but now it means "the height of between the top of one line of text and the top of the next line". The default size of <h1> elements is often 2em. If the default font-size for text is 16px, then the default font-size for <h1> elements will be calculated as 32px.


16px (default)
1em (same as default)
0.5em
2em

Making your text fit the viewport

Your text appears on two lines. You want both lines to be visible on the screen, even if the window is not tall. There are four units of measurement which are relative to the size of the viewport:

vw
1% of the viewport width
vh
1% of the viewport height
vmin
1% of the viewport's minimum dimension
vmax
1% of the viewport's maximum dimension

Which unit do you think will ensure that all your text is visible, in any window of any size?

vmin will ensure that your text is small enough to fit in the viewport. You can choose the biggest number of vmin units that will show your text in the window.

In your index.html file, set the font-size of the body to 16vmin then click the Preview button to check if this is a good value. If not, adjust the value until you are happy with it.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        font-size: 16vmin;
      }
      h1 {
        text-align: center;
        opacity: 0;
        transition: opacity 2s, color 1s 2s;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
      p::after {
        content: "..."
      }
      body.clicked p::after {
        content: ""
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

Trouble-shooting

You will probably find that the size of the text in the <h1> element does not change.

The font-size of the header may appear fixed
Figure 10. The font-size of the header may appear fixed

Can you work out why this is happening?

Remember that CSS rules "cascade". Can you find a CSS rule that sets the size of the <h1> element? (Hint: it is not in the index.html file.)

There are several ways to fix this problem. The easiest is to include a font-size instruction in the rule with the h1 selector:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="style.css">
    <style>
      body {
        font-size: 16vmin;
      }
      h1 {
        font-size: 2em
        text-align: center;
        opacity: 0;
        transition: opacity 2s, color 1s 2s;
      }
      body.clicked h1 {
        opacity: 1;
        color: red;
      }
      p::after {
        content: "..."
      }
      body.clicked p::after {
        content: ""
      }
    </style>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script>
      document.body.onmouseup = function() {
        document.body.classList.add("clicked");
      }
    </script>
  </body>
</html>

Can you find other solutions?

The font-size for <h1> elements is set in the style.css document, which you can see in the column on the left. The index.html file contains a link to the style.css file. You can:

  • Delete the link in the index.html file
  • Delete the line font-size: 32px; in the style.css file

Note that deleting the link will mean that the "Open Sans" and "Merriweather" fonts will not be used; the default font will be used everywhere instead.

File Structure

You have now made a very simple activity, using HTML, CSS and JavaScript. Congratulations! Now you can understand how these three technologies work together to make an interactive web page.

These are three separate technologies, and it is good practice to use a separate file for each of them.

In this step, you will tidy up the file structure of your game.

In particular, you will

  • Create separate folders for CSS files and JavaScript files
  • Create a style.css file
  • Create a script.js file
  • Keep only HTML code in the index.html file

Creating folders in Thimble

Click on the green and white New File icon, and select Add Folder, then name the new folder css. Create another new folder and call it js.

Adding a new folder
Figure 11. Adding a new folder

Moving the style.css file

Hover your mouse over the style.css file name until a context menu arrow appears. Click on this arrow and choose Move To in the menu that appears.

Moving the style.css file
Figure 12. Moving the style.css file ...

A dialog window will open. Select the css folder and then click on OK.

to the css folder
Figure 13. ... to the css folder

Creating a new JavaScript file

Hover over the new js folder name, and click on the contextual menu arrow. Choose New File:

Create a new file in the js folder
Figure 14. Create a new file in the js folder

Moving the CSS code to the css/style.css file

In your index.html file, select everything inside the <style> element. (Do not include the <style></style> tags themselves.) Cut this text and paste it at the end of the css/style.css file.

Cut the text inside the style tag
Figure 15. Cut the text inside the <style> tag

Pou can rearrange the instructions for the body and h1 selectors, so that they are all inside the same set of curly brackets. Your css/style.css file should now look like this:

/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
body {
  background-color: white;
  font-family: "Open Sans", sans-serif;
  padding: 5px 25px;
  font-size: 13vmin;
  margin: 0;
  color: #444;
}
h1 {
  font-family: "Merriweather", serif;
  text-align: center;
  opacity: 0;
  transition: opacity 2s, color 1s 2s;
  font-size: 2em;
}
body.clicked h1 {
  opacity: 1;
  color: red;
}
p::after {
  content: "..."
}
body.clicked p::after {
  content: ""
}

Moving your JavaScript code to the js/script.js file

Now cut the JavaScript code that is inside the <script> element, leaving the <script></script> tags in place. Paste this code into the new js/script.js file.

Cut the text inside the script tag
Figure 16. Cut the text inside the <script> tag

The js/script.js file should now look like this:

document.body.onmouseup = function() {
  document.body.classList.add("clicked");
}

Cleaning up the index.html file

The last step is to tell the index.html file where it can find the new JavaScript file, and where the style.css file has moved to.

Edit your index.html so that it looks like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="css/style.css>
  </head>
  <body>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script src="js/script.js"></script>
  </body>
</html>

Notice that the syntax for linking to the JavaScript file is different from the syntax for linking to the CSS file. Also the position of the links is different.

The link to the CSS file appears before the <body> tag, so that the browser knows how to style the content before it reads the content from the file. The link to the JavaScript file appears after the content of the <body> element, so that all the elements in the body already exist before the JavaScript begins to work on them.

On Windows, the character used to indicate a folder is \; on Macintosh, it is :. HTML is written using the conventions for Unix operating systems, so the character that indicates a folder is /.

Publishing your game

Now your prototype game is finished, and you want your friends to see it. With Mozilla Thimble, it is easy to share your game online and become part of the world-wide open-source community.

In this step, you will:

  • Create an account with Mozilla Thimble
  • Publish your project
  • Share the URL with your friends

Create an account

In the top right corner of the Thimble page, click on Create An Account.

Create a Thimble account
Figure 17. Create a Thimble account

A dialog will open. Enter a unique username, your email address and a strong password. Your password:

  • Must be at least 8 characters long
  • Must contain at least one number
  • Must contain at least one UPPERCASE letter from the Latin alphabet
  • Must contain at least one lowercase letter from the Latin alphabet
  • Can contain Cyrillic letters
  • Should be different from any other password you use with any other site
Enter a unique username, your email address and a password.
Figure 18. Enter a unique username, your email address and a password.

Publish

After you have registered, click on the Publish button. You can fill in the Project Description if you like, then click on the green Publish button.

Publish your project for others to see
Figure 19. Publish your project for others to see

You will see a link that you can copy and send to your friends and family. They will be able to see your project, and remix their own version of it.

Well done! You have joined the open-source community. Sharing your work with others helps everyone learn and create.

Share the link with your friends
Figure 20. Share the link with your friends

Preparing for Section 2

In this first section, you have simply been following instructions carefully. Starting now, you can become more creative. You are ready to develop your own interactive story.

Before the next section, please read The Zenigman Experiment, and use the structure of that story as a model for your own. This first version of your story should have:

  • A title
  • At least 3 paragraphs
  • At least 2 different endings
  • At least 1 paragraph where the reader must make a choice between 2 or more options
  • A picture to illustrate each paragraph
  • A picture for the title page

Your story does not have to be complete. Indeed, your story will probably change a lot as you are working on it. You will get lots of feedback from the people who test your game on ways to make it more intriguing and more exciting. This first version can be a simple outline that can grow into something bigger.

In Section 5, you will be able to add objects, like keys or bad luck items, that your reader can find, and which will affect the story at some time in the future. You might already like to start thinking about how you can use this to make your story more interesting. However, the version of your game that you create in the next section will not include this feature.

Your story can be in English or Russian or any language you choose.

"

If you need inspiration, read the first choose-your-own-story ever written: Un conte à votre façon, by Raymond Queneau, 1967. Perhaps you might like to translate this into Russian.

Your work will be published on Mozilla Thimble or GitHub with a Creative Commons license. This means that any images that you use should also have a Creative Commons license. If you use your own artwork, you will be giving other people the right to reuse and modify your images. If you use artwork created by other people, please make sure that they have explicitly given permission for anyone to reuse and modify their images. You may need to give attribution to the original artist and provide a link to the artist's home page.

Section 2: Layout and Links

Before you go any further, you will need to have a story with:

  • A title
  • At least 3 paragraphs
  • At least 2 different endings
  • At least 1 paragraph where the reader must make a choice between 2 or more options
  • A picture to illustrate each paragraph
  • A picture for the title page

A story is more than just words. The quality of the pictures, the attractiveness of the layout, the simplicity of the user interface — these are all things that can add to the pleasure that people will get from your story game. Now that you have the words of your story, you will want to present it well.

In this section, you will put the first version of your interactive story online.

In particular, you will:

  • Create separate HTML documents for the first pages of your story
  • Create a title page with its own image
  • Create a responsive layout for your interactive story that looks good on any device, in either portrait or landscape mode.
  • Use the layout you have created for the text and images of all the pages in your story

Create a Remix of your project

In the last section, you created a very simple interactive web page. Now, you are going to change that page. By the end of this section, it will have become something very different.

Thimble allows you to create a Remix copy of your project. This step is not essential. However, if you make a Remix copy, at the end of this section, you will be able to compare your two versions, and see how much progress you have made.

In this step, you will:

  • Create a Remix version of your project

Remix

At the top right of the Thimble window, click on your name and choose Your Projects from the contextual menu:

Return to the Your Projects screen
Figure 21. Return to the Your Projects screen

On the Your Projects screen, find the name of your game project and click on the Remix link:

Create a Remix copy of your project
Figure 21. Create a Remix copy of your project

When this new copy of your project opens, change its name, at the top left of the Thimble window:

Rename this Remix version of your project.
Figure 23. Rename this Remix version of your project

If you have published your project, you can share its URL with your friends, and they can create their own Remix. They can also share their Publish links with you, and you can remix their work. The more you share, and the more you look at how other people are working, the more you can learn. The whole community grows stronger.

The first pages

In this step, you will create a simple page template for your story, so that the reader can move from one page to the next.

In particular, you will:

  • Create two new HTML pages
  • Create a hyperlink between them

A new page

Press the New File button, and select Add HTML File from the contextual menu.

Create a new HTML file
Figure 24. Create a new HTML file

Name the file page_001.html.

Rename the new HTML file
Figure 25. Rename the new HTML file

Your pages will appear in alphabetical order in the Files pane. If you do not use leading zeros (00...), then pages 1, 10 and 100 will all appear together before page 2, because the character "1" is alphabetically before "2".

Your new page will look exactly like the original index.html page. Edit the <title> tag in the head and replace the content of the <body> tag with the text that you have prepared for the first page of your story. Your page_001.html page might look something like this:

<!-- page_001.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,
    initial-scale=1">
    <title>The Zenigman Experiment</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <h1>The Zenigman Experiment</h1>
    <p>
      You see an advertisement in a newspaper asking for
      volunteers for a psychological experiment. You go
      to the university and meet the professor and other
      volunteers. Some will play the role of prisoners,
      some will play the role of guards. If you are a
      prisoner, you know a secret. If you are a guard,
      your must discover that secret. What will you
      discover about yourself as you play your role?
    </p>
  </body>
</html>

A second page

Now create a second new HTML page and call it page_002.html. As before, change the title and then use the text that you have prepare for the second page of your story for body. You might want to use more than one <p></p> element to divide your text into paragraphs.

<!-- page_002.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,
    initial-scale=1">
    <title>The Zenigman Experiment</title>
    <link rel="stylesheet"href="css/style.css">
  </head>
  <body>
    <p>"Look at this! A new idea for our holiday! A way
    to have some fun and earn some money!"</p>

    <p>Jessie's finger is pointing at an advertisement
    in the local newspaper. Jessie is a true friend,
    with creative and unusual ideas. It always feels
    good to do new things with Jessie.</p>

    <p>The advertisement says:</p>

  <pre>The University of Watermouth wants volunteers
  for a psychological study. Do our clothes, names
  and titles change the way we see other people?

  Are you available 24 hours a day for the week of
  10 - 16 August? If you are selected, you will
  receive $80 per day. Food, clothing and
  accommodation will be provided.</pre> 
  </body>
</html>

Press the Preview button above and then select first page_001.html and then page_001.html in the Files pane on the left, to see the result of your changes.

Creating a link

People who play your game will not be using the Thimble interface. They will only see what you can see in the Preview pane. You need to provide a way to go from page_001.html to page_001.html inside page_001.html itself.

Edit page_001.html as shown below.

<!-- page_001.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,
    initial-scale=1">
    <title>The Zenigman Experiment</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <h1>The Zenigman Experiment </h1>
    <p>
      You see an advertisement in a newspaper asking for
      volunteers for a psychological experiment. You go
      to the university and meet the professor and other
      volunteers. Some will play the role of prisoners,
      some will play the role of guards. If you are a
      prisoner, you know a secret. If you are a guard,
      your must discover that secret. What will you
      discover about yourself as you play your role? 
    </p>

    <a href="page_002.html">Go to page 2</a>
  </body>
</html>
<

This new <a> element is an anchor tag. The href attribute is a Hypertext REFerence. Its value tells the browser which HTML file to display when you click on it. Use these links to more about the <a> element and <href> attribute.

Testing your link

Click on your page_001.html file in the File pane on the left, and then on the Preview button above, then click on the Go to page 2 link. The contents of page_002.html should now appear in the Preview window.

Congratulations! You've created a link to the next page!

The Title Page Image

When a player launches your game, the first thing they will see will be the title page. This will look different from the rest of the game.

In this step, you will:

  • Upload an image to the Thimble server
  • Add this image to your index.html page, using an <img> element

Upload an image

Before you can add your title page image, you need to upload it to the Thimble server. Click on the New File button at the top left of the Thimble window, and choose Upload A File from the contextual menu that opens.

Upload an image
Figure 26. Upload an image

In the dialog pane that opens, click on the From Your Computer button, then select the image that you have have prepared for your title page.

Choose an image from your hard drive
Figure 27. Choose an image from your hard drive

You should now see the name of your image in the column on the left. If you click on this, you will see your picture in the Thimble Editor pane:

Your uploaded image in the Editor pane
Figure 28. Your uploaded image in the Editor pane

Adding an <img> folder

At the end of the last section, you created separate css and js folders to store your style.css and script.js files. To keep everything tidy, you should keep all your images in an img folder. Click on the New File button again, and choose Add Folder.

Create an img folder
Figure 29. Create an img folder

Name the new folder img:

Naming the folder
Figure 30. Naming the folder "img"

Click on the contextual menu for the picture you uploaded, and select Move To:

Move your uploaded image...
Figure 31. Move your uploaded image...

In the dialog window, select the new img folder, and click on OK.

... to the img folder.
Figure 32. ... to the new img folder.

Displaying the image in your index.html page

Click on the index.html link in the column on the left, to display the text of your web page, and make the changes that are shown below.

  • Instead of picture.png, use the correct name of your own image.
  • Instead of title page image, write your own description of the image.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>The Zenigman Experiment</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <img src="tutorial/img/picture.png" alt="title page image"/>
    <p>This game was made by</p>
    <h1>Me!</h1>
    <script src="js/script.js"></script>
  </body>
</html>

When you click the Preview button above, you should see that your image now appears in the browser window. However, it may be much bigger or smaller than you expected.

Your image in your web page
Figure 33. Your image in your web page

Your image is probably not called picture.png. Use the correct name for your own image. Be sure to use the right case for each letter (UPPERCASE or lowercase). If you don't use exactly the right characters, your image will appear as a broken link and the value of the alt property will be shown instead.

Broken link
Figure 34. If the src property is wrong, the value of the alt property will be shown instead.

The tag for adding an image is <img ... />. This is a self-closing tag. An <img /> tag contains no text, so it doesn't need a closing </img> tag like most other elements.

  • src stands for "source
  • alt stands for "alternative"

Positioning elements

In the last section, you used CSS to:

  • Set the size of text
  • Set the color of text
  • Align text in the center or on the left
  • Create transitions
  • Add dots after a paragraph of text

In the next few steps, you use CSS to change the layout of your tile page. You will edit the HTML and the CSS of your title page to make it look good in a desktop browser and on a smartphone.

In particular, you will learn about:

  • The <div> element
  • The position property
  • The z-index property
  • The width property

Flow

By default, each element in a web page appears in the same order as it appears in the HTML document. For this reason, the <img> element appears first, then the <p> element and finally the <h1> element. We say that the elements flow on the page, one after the other.

To make your page look good, you want to change the flow. You want the image to be in the background and the text to be in the foreground. There are two steps to make this happen:

  • Place the <img> and the text elements in two different containers, in the HTML file
  • Take the container for the <img> element out of the normal flow of the page, using CSS

The containers you are going to use are <div> elements. div is short for "division". A <div> element can be used to group other elements together.

To break the flow, you will give one of the <div>s an absolute position.

Make the changes shown below in your index.html file:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>The Zenigman Experiment</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <div class="image">
      <img src="tutorial/img/picture.png" alt="title page image"/>
    </div>
    <div class="story">
      <p>This game was made by</p>
      <h1>Me!</h1>
    </div>
    <script src="js/script.js"></script>
  </body>
</html>

When you press the Preview button above, you should see no change. The role of the<div> elements will only become obvious when you change the CSS.

Absolute position

In the left-hand column, click on css/style.css and then make the following change:

/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');

body {
  background-color: white;
  font-family: "Open Sans", sans-serif;
  padding: 5px 25px;
  font-size: 13vmin;
  margin: 0;
  color: #444;
}
h1 {
  font-family: "Merriweather", serif;
  text-align: center;
  opacity: 0;
  transition: opacity 2s, color 1s 2s;
  font-size: 2em;
}
body.clicked h1 {
  opacity: 1;
  color: red;
}
p::after {
  content: "..."
}
body.clicked p::after {
  content: ""
}
div.image {
  position: absolute;
}

Press the Preview button above. What difference do you see?

The text should now appear behind your picture. (If your picture is opaque, the text may seem to have vanished.)

Press here for more information on the position property and the different values it can take.

z-index

Add a new instruction for the <div.image> rule, and Preview your web page again:

...
div.image {
  position: absolute;
  z-index: -1;
}

What difference do you see now when you press Preview?

The picture should now appear behind your text. (If your picture and your text are similar colors, this might not be obvious)

Press here for more information on the z-index property.

Elements in a web page have three-dimensional coordinates: x, y, z. The origin is the top-left corner of the window. Increasing the x coordinate moves an element to the right; increasing the y coordinate moves it down. An element with a higher z-index appears on top of an element with a lower z-index. By default, all elements have a z-index of 0.

Elements which are set to { position: absolute; } appear on top of elements with the default { position: static }. Setting the z-index of <div class="story"> to -1 moves it forwards, so that it is in front of the picture again.

Adjusting the size of the image

Your image is likely to be bigger or smaller than the page. To fix this, add a new CSS rule, as shown below:

...
div.image {
  position: absolute;
  z-index: -1;
}
div.image img {
  width: 100%;
}

Inheritance

How does this work?

The <img> element is a child of the <div class="image"> element, which is in turn a child of the <body> element, which appears in a window of your browser. The window of your browser has a specific width.

The width of each of the other elements (<body>, <div>) expands to fit its contents. If the <img> element is wider than the window, the <div class="image"> element will be as wide as the image, and the <body> element will be as wide as this <div>.

When you set the width of the <img> element to 100%, it looks for its closest parent that has a fixed value for width. In this case, the only parent whose width is fixed is the window, so the <img> element becomes the same width as the window, and the <div> and <body> elements adjust their width to fit around it.

This concept is called inheritance. You inherit characteristics from your parents: your height, the color of your eyes, the shape of your face, and so on. Your parents inherited from their parents, and so on, through all your ancestors. In the same way, HTML elements inherit many CSS properties from their parent elements.

When you change the width of an <img> element, its height will be adjusted automatically.

Outside the Box

Mozilla Thimble makes it easy to see the results of changing your HTML and CSS code. However, there are better ways of seeing how the browser understands your code. Fortunately, Mozilla have made it easy for you to inspect your code outside the Thimble environment.

In this step, you will discover how to view your web page directly in your browser, without using Thimble.

In particular, you will:

  • Download your project as a ZIP file
  • Extract the files on your hard drive
  • View your project directly in your browser
  • Use your browser's Developer Tools to inspect your web page
  • Modify your CSS directly in the browser
  • Copy the changes you have made and paste them into your style.css file

Downloading a ZIP file

Click on the New File button at the top left of the Thimble window, and choose Download Files (.ZIP)

Download your project as a ZIP file
Figure 35. Download your project as a ZIP file

Find the file in your Downloads folder on your hard-disk and extract its contents. Open the new folder and double-click on the index.html file. It should open in your browser.

Use the keyboard shortcut Ctrl-Shift-I or ⌘-Shift-I to open the Developer Tools window. Explore the different panels of the window, and choose a layout which is comfortable for you.

Using the Developer Tools panel to inspect the HTML page
Figure 36. Using the Developer Tools panel to inspect the HTML page

Click on the Elements tab and move your cursor over the various elements in the HTML display. You should see a colored overlay in the main browser window, showing you where each element is.

Padding, Borders and Margins

Different colors are used for the overlay. A diagram illustrates the meaning of these colors.

The meaning of the overlay colors
Figure 37. The meaning of the overlay colors

As figure 34 shows, the <body> element has padding (shown in green) all around it. The rule for this padding was added to the original styles.css file by the creators of Thimble.

As you can see in figure 35 below, there is a big margin above and below the <h1> element. This margin is part of the default stylesheet used by your browser; the creators of your browser added it.

The margin above and below the h1 element
Figure 38. The margin above and below the <h1> element

Click here to learn more about padding, borders and margins.

Editing CSS in the Inspector pane

You can edit CSS properties inside the Styles Inspector pane. In the HTML pane, click on the <div class="image"> element, and in the Styles pane, add three new properties, as shown below. You should see that your image is now centered vertically in the browser window.

Edit CSS in the Styles Inspector
Figure 39. Edit CSS in the Styles Inspector

CSS: copy and paste

When your page is looking good, you can copy your new CSS instructions and paste them into the style.css file in the Thimble version of your project. Your style.css file should now look like this:

/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');

body {
  background-color: white;
  font-family: "Open Sans", sans-serif;
  padding: 5px 25px;
  font-size: 13vmin;
  margin: 0;
  color: #444;
}
h1 {
  font-family: "Merriweather", serif;
  text-align: center;
  opacity: 0;
  transition: opacity 2s, color 1s 2s;
  font-size: 2em;
}
body.clicked h1 {
  opacity: 1;
  color: red;
}
p::after {
  content: "..."
}
body.clicked p::after {
  content: ""
}
div.image {
  position: absolute;
  z-index: -1;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}
div.image img {
  width: 100%;
}

The { display: flex; } instruction is extremely powerful. It allows you to create layouts that adapt to every situation. Dave Geddes has made an interactive online game called Flexbox Zombies that will teach you everything you might want to know about this particular technology.

You will learn more about using the flexbox system in your own game in the next few steps.

Flex display

In the last step, you used a flexbox layout to center your image on the page, but without any explanation. In this step, you will use a flexbox layout to place the text neatly on the page, and you will learn how it works.

In particular, you will:

  • Edit the HTML to display your game title and your name
  • Add comments to your CSS file, to stop certain instructions from being used
  • Apply the flex display to the <div class="story"> element
  • Learn about flex-direction
  • Learn about justify-content
  • Learn about align-items

At the end of this step, you can go back to the last step and check that you now understand how it works.

Title and Author

It's time to make some radical changes. Give your game a title. Normally the title is shown in bigger characters than the author's name. Edit your index.html file as shown below, but use your own game title and name instead of the placeholder text:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>Made with Thimble</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <div class="image">
      <img src="tutorial/img/picture.png" alt="title page image"/>
    </div>
    <div class="story">
      <h1>Game Title</p>
      <h2>Author Name</h2>
    </div>
    <script src="js/script.js"></script>
  </body>
</html>

Flex again

In the style.css file, make the following changes:

/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
html {
  height: 100%;
}
body {
  height: 100%;
  background-color: white;
  font-family: "Open Sans", sans-serif;
  /* padding: 5px 25px; */
  font-size: 3vmin;
  margin: 0;
  color: #444;
}
h1, h2 {
  font-family: "Merriweather", serif;
  text-align: center;
  /* opacity: 0;
  transition: opacity 2s, color 1s 2s; */
  font-size: 2em;
}
h2 {
  font-size: 1.5em;
}
/* 
body.clicked h1 {
  opacity: 1;
  color: red;
}
p::after {
  content: "..."
}
body.clicked p::after {
  content: ""
}
*/
div.image {
  position: absolute;
  z-index: -1;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}
div.image img {
  width: 100%;
}
div.story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

Four things to notice

You have made four basic changes:

  1. You have commented out several lines of CSS code
  2. You have changed the font-size for the web page and added a rule for <h2> elements
  3. You have added a new rule for the <div class="story"> element
  4. You have added instructions for { height: 100% } in three different places

Comments

Note that, in a CSS file, the sequence /* ... */ creates a comment. Text inside a comment is ignored. This allows you to:

  • Temporarily stop using certain rules or instructions
  • Add labels to make it easier to find certain rules
  • Explain why certain rules are included

The rules and instructions that are now commented out were used to show the <h1> element after a click. That interactivity will not work any more (but soon you'll be adding a different kind of interaction).

font-size

As you will see shortly, a font-size of 3vmin will allow you to show display about 100 words of text without needing to scroll the text. You can adjust the font-size of the <h1> and <h2> elements to make your title and name fit nicely on the page.

Flexbox display for div.story

The new rule that you have added pushes your title to the top of the page and your name to the bottom. To understand how this rule works, comment out each line in turn and check the Preview to see how the display changes

In Thimble, a quick way comment out or uncomment a line is to place the text insertion caret somewhere in the line and press Ctrl-/ or ⌘-/.

For example: when you comment out the line flex-direction: column;, the game title and your name appear side by side. This is because the default value for flex-direction is row.

By default, flex shows elements in a row
Figure 40. By default, flex shows elements in a row

If you comment out any of the other instructions, your name will appear immediately beneath the title. The reason for this is different in each case.

Commenting out any other instruction shows your name immediately beneath the title
Figure 41. Commenting out any other instruction shows your name immediately beneath the title

Why height is important

Download the ZIP file of your project, as you did in the previous step, extract the contents of the file, then double-click on the index.html document. Open the Developer Tools, and display the CSS rule for div.story. Deselect the height checkbox, then hover your mouse over the <div class="story"> element, as shown in the screenshot below.

When its height is not defined, a flex box is just tall enough to contain its elements
Figure 42. When its height is not defined, a flex box is just tall enough to contain its elements

Click on the height checkbox again to select it, and check the dimensions of the <div class="story"> element again.

height: 100% makes the element as tall as its parent element
Figure 43. height: 100% makes the element as tall as its parent element

When the height of the <div class="story"> element is not set, by default its height will be the height of the elements that it contains. When its height is set to 100%, it becomes as tall as its parent. But what is the height of its parent?

The height of the parent

The parent of the <div class="story"> element is the <body> and its parent is the <html> element.

What happens if you deselect the height checkbox for either the <body> element or the <html> element?

If the height of the <html> element is not set to fill the entire height of the window, and if the height of the <body> element is not set to fill the entire height of the <html> element, then the height of the <div class="story"> element will be set to 100% of zero. In this case, by default, the browser will set its height to the height of the elements that it contains.

Your name will appear at the bottom of the <div class="story"> element ... immediately beneath the title.

The display property

Disabling the instruction display: flex; has the same effect for a different reason. By default, the browser will display a <div> element as a block, and inside a block the child elements are simply shown one after the other. Explicitly setting display: flex; overrides the default, and allows the flex-direction and justify-content properties to take effect.

You can see all the possible values for display if your delet the value of the delay property in the Style inspector. A contextual menu will appear to let you choose a new value.

Delete the value of the display property to show a contextual menu of possible values
Figure 44. Delete the value of the display property to show a contextual menu of possible values

Click here to learn more about the display property and its possible values.

justify-content

The justify-content property tells the browser how to arrange the different elements inside a flexbox container. The value space-between creates an equal amount of space between each element. In this case, there are only two elements (the title and your name), so the space between them pushes one to the top and the other to the bottom.

You can use the same trick you used to find all the values for the display property to discover the possible values for justify-content.

The contextual menu shows all possible values for justify-content
Figure 45. The contextual menu shows all possible values for justify-content

Click here to see an illustration of how the most commonly-used values behave. To learn more in a fun way, you can play David Geddes' Flexbox Zombies.

align-items

In the last step, you also used align-items: center to center your image. The justify-content property places child elements along the axis of the flexbox element (as a row, or as a column). The align-items places them on a line perpendicular to this axis, in the direction that you read (left to right, or top to bottom).

Now that you know about flex-direction can you add an instruction for the div.image rule, to make it more elegant?

The image appears in a column, not a row. For now, the <img> element is the only element in the <div class="image">, but perhaps that will change in the future. It would be more correct to set the flex-direction to column.

div.image {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
}

Aspect Ratio

At this moment, your web page completely fills the browser window. The page looks different if the window is a different shape.

In this step, you will learn how to give the page the same shape and appearance in any window on any device.

In particular, you will:

  • Add a new <div> to act as a container for the image and story divs.
  • Use vh units to make this container <div> fit the window
  • Change the colour of the background
  • Use display: flex; to place the new <div> in the center of the window
  • Use the value relative with the position property, to control the <img> element

Create a container div

In Thimble, edit your index.html file so that it matches the code listing below:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>The Zenigman Experiment</title>
    <link rel="stylesheet" href="css/style.css">
  </head>

  <body>

    <div class="container">

      <div class="image">
        <img src="tutorial/img/picture.png" alt="title page image"/>
      </div>

      <div class="story">
        <h1>Game Title</p>
        <h2>Author Name</h2>
      </div>

    </div>

    <script src="js/script.js"></script>
  </body>
</html>

When you look at your page in the Preview, it should look exactly the same as before.

Creating CSS rules for the container div

In Thimble, edit your style.css file as shown below. (Note that the rules that were commented out have now been removed. You won't be using them any more.)

/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
html {
  height: 100%;
}
body {
  background-color: black;
  font-family: "Open Sans", sans-serif;
  font-size: 3vmin;
  margin: 0;
  color: #444;
  height: 100%;
  display: flex;
  justify-content: center;
}
div.container {
  position: relative;
  display: flex;
  width: 75vh;
  height: 100vh;
}
h1, h2 {
  font-family: "Merriweather", serif;
  text-align: center;
  font-size: 2em;
}
h2 {
  font-size: 1.5em;
}
div.image {
  position: absolute;
  z-index: -1;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-color: white;
}
div.image img {
  width: 100%;
}
div.story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

Centering the container <div>

The group of changes shown in black should already make sense to you. They use the same flexbox technique that you saw in the last two steps for centering the <div class="container"> element inside the <body> element, and they make the <body> black and the background of the title-page image white.

Setting the dimensions of the container

The section in red does something new. It sets the height of the <div.container> element to 100vh, which means 100% of the height of the window.

The instruction width: 75vh; sets the width of the <div.container> to 75 viewport height units, so the width of the div.container will change if you change the height of the window and the aspect ratio of the container will remain constant. (Try it!)

position: relative;

The instruction position: relative; affects the width of your image, when the window is wide. Remember that the <img> element is governed by the following rule:

div.image img {
  width: 100%;
}

This means that it will be as wide as its nearest parent which has a position property. The nearest parent with a position property is <div class="image">, but that element has no width property, so it adopts the width of its parent. If the <div class="container"> has no position property, then the <img> will inherit the width of the <body> element, by default.

When the window is narrow, the flexbox display will limit the width of the <div class="container"> element to the width of the widest text. However, when the window is wide, the flexbox display will respect the width: 75vh instruction, and the <img> will grow to fill the <body> element.

Adding the position: relative; instruction to the <div.container> rule tells the <img> element to limit its width to that of the container.

Media Queries

The screens of smartphones and tablets come in many different shapes and sizes. Some people may want to play your game with the screen vertical (in portrait mode). Some may prefer to use landscape mode. Some people may use a big computer screen. Your game needs to look good on every device.

In this step, you will learn how to create CSS rules that change the layout to fit the user's screen.

In particular, you will:

  • Learn about @media queries
  • Learn about aspect ratios
  • Do some simple arithmetic to calculate the best width and height for your title page
  • Use the same arithmetic to ensure that the font-size is always proportional to the page size

@media queries

Media queries allow you to choose when to apply certain rules. In particular, you can create a media query that will apply extra rules when the window is narrow. To test this, add a new rule to your style.css file:

/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
html {
  height: 100% 
}
body {
  background-color: black;
  font-family: "Open Sans", sans-serif;
  font-size: 3vmin;
  margin: 0;
  color: #444;
  height: 100%; 
  display: flex;
  justify-content: center;
}
div.container {
  position: relative;
  display: flex;
  width: 75vh;
  height: 100vh;
}
h1, h2 {
  font-family: "Merriweather", serif;
  text-align: center;
  font-size: 2em;
}
h2 {
  font-size: 1.5em;
}
div.image {
  position: absolute;
  z-index: -1;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-color: #fff;
}
div.image img {
  width: 100%;
}
div.story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

@media (max-aspect-ratio: 3/4) {

  div.container {
    background-color: #ccf;
  }

}

Note the syntax of this rule. It starts with the word @media and is followed by a condition that appears between parentheses (...). This is followed by a pair of curly brackets { ... }, and inside the curly brackets is a rule for an element.

Test this rule. Change the width of the Preview pane, and watch how the <div.container> changes color.

Your task now is to create instructions for the <div.container> rule that:

  • Set the width of the <div class="container"> to the width of the window
  • Set the height the <div class="container"> to 4/3 of the width of the window

What simple arithmetic calculation do you need to do to find the answer

...

@media (max-aspect-ratio: 3/4) {
  
  div.container {
    height: 133.3333vw;
    width: 100vw;
  }

}

Centering the container vertically

When you change the instructions for the width and height of the <div.container>, it appears at the top of the window. There are two different ways you can center it vertically. Both ways are connected with the flex display. One uses flex-direction and one uses align-items.

Can you find one of the solutions? Can you find both?

...

@media (max-aspect-ratio: 3/4) {
  body {
    flex-direction: column;
  }
  div.container {
    height: 133.3333vw;
    width: 100vw;
  }
}

Or:

body {
  background-color: black;
  font-family: "Open Sans", sans-serif;
  font-size: 3vmin;
  margin: 0;
  color: #444;
  height: 100%; 
  display: flex;
  justify-content: center;
  align-items: center;
}

Keeping the font-size proportional

Here is the instruction that sets the font-size for your title page:

body {
  ...
  font-size: 3vmin;
  ...
}

Can you change this instruction and add a new rule inside the @media query, so that the font-size is always proportional to the page size?

body {
  ...
  font-size: 3vh;
  ...
}
                  
...

@media (max-aspect-ratio: 3/4) {
  body {
    ...
    font-size: 4vw;
  }

  ...
}

/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
html {
  height: 100% 
}
body {
  background-color: black;
  font-family: "Open Sans", sans-serif;
  font-size: 3vh;
  margin: 0;
  color: #444;
  height: 100%; 
  display: flex;
  justify-content: center;
  align-items: center;
}
div.container {
  position: relative;
  display: flex;
  width: 75vh;
  height: 100vh;
}
h1, h2 {
  font-family: "Merriweather", serif;
  text-align: center;
  font-size: 2em;
}
h2 {
  font-size: 1.5em;
}
div.image {
  position: absolute;
  z-index: -1;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-color: #fff;
}
div.image img {
  width: 100%;
}
div.story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

@media (max-aspect-ratio: 3/4) {
  
  body {
    font-size: 4vw;
  }

  div.container {
    height: 133.3333vw;
    width: 100vw;
  }
  
}

Story page layout

If you look at page_001.html now, you will see gray text on a black background. All the CSS changes that you made for the title page have also been applied to the story pages.

In this step, create a different layout for the story pages. This will have two columns: a column for pictures on the left and a column for text on the right.

In particular, you will:

  • Add the <div class="container"> to your story HTML pages
  • Edit the style.css file to show two columns
  • Add a title-page class to the <div class="container"> for your index.html file
  • Adjust the CSS rules and instructions to treat the title page and the story pages differently

Applying the container layout

Add the same <div> elements to your page_001.html file as you did to your index.html file, as shown below. You can add a link to the image for your first page at the same time.

<!-- page_001.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,
    initial-scale=1">
    <title>The Zenigman Experiment</title>
    <link rel="stylesheet" href="css/style.css">
  </head>

  <body>
    <div class="container">

      <div class="image">
        <img src="img/picture_for_page_1.png" />
      </div>

      <div class="story">
        <h1>The Zenigman Experiment </h1>
        <p>
          You see an advertisement in a newspaper asking for
          volunteers for a psychological experiment. You go
          to the university and meet the professor and other
          volunteers. Some will play the role of prisoners,
          some will play the role of guards. If you are a
          prisoner, you know a secret. If you are a guard,
          your must discover that secret. What will you
          discover about yourself as you play your role? 
        </p>

        <a href="page_002.html">Go to page 2</a>
      </div>

    </div>
  </body>
</html>

The text will appear on top of the picture. The link will appear at the bottom of the page.

Creating a two-column layout

To divide the story pages into two columns, one for pictures and one for text, edit the style.css file as shown below.

Note that the text in red is not active yet. Think about what change will be needed to make it active. Which rule makes the layout appear in two columns?

div.container > div {
  width: 50%
}
/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
html {
  height: 100% 
}
body {
  background-color: black;
  font-family: "Open Sans", sans-serif;
  font-size: 3vh;
  margin: 0;
  color: #444;
  height: 100%; 
  display: flex;
  justify-content: center;
  align-items: center;
}
div.container {
  position: relative;
  display: flex;
  width: 133.333vh;
  background-color: white;
  height: 100vh;
}
div.container > div {
  width: 50%
}
h1, h2 {
  font-family: "Merriweather", serif;
  text-align: center;
  font-size: 2em;
}
h2 {
  font-size: 1.5em;
}
div.image {
  /* position: absolute; */
  /* z-index: -1; */
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-color: #fff;
}
div.image img {
  width: 100%;
}
div.story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

body.title-page div.container {
  width: 75vh;
}

@media (max-aspect-ratio: 3/4) {
  
  body {
    font-size: 4vw;
  }

  div.container {
    height: 133.3333vw;
    width: 100vw;
  }
  
}

Preview the page_001.html. You should now see two columns, with the picture on the left. Preview the index.html page. That also has two columns. You will fix this in a moment.

The story page layout has 2 columns
Figure 46. The story page layout has 2 columns

The > sign

One of the new rules has a CSS selector with a new sign: div.container > div. The > sign is a child combinator. This selector selects only <div> elements that are the immediate children of the <div.container> element. It selects only <div.image> and <div.story>, and not any descendants of these child elements.

For now, the <div.story> element has no children that are divs, but that will change in step 24, and those child divs should not be affected by this 50% width rule, so there is a good reason for using the > combinator here.

For more information see the CSS Tricks site.

Customizing the title page

To activate the rule in red in the CSS listing above, you need to add a title-page class to the <body> in the index.html file:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1">
    <title>The Zenigman Experiment</title>
    <link rel="stylesheet" href="css/style.css">
  </head>

  <body  class="title-page">

    <div class="container">

      <div class="image">
        <img src="tutorial/img/picture.png" alt="title page image"/>
      </div>

      <div class="story">
        <h1>Game Title</p>
        <h2>Author Name</h2>
      </div>

    </div>

    <script src="js/script.js"></script>
  </body>
</html>

Preview both the index.html and the page_001.html files, to check that they now have different widths.

Adding a title-page class
Figure 47. Adding a .title-page class.

More adjustments

The title page still appears with two columns. To restore its original appearance, you need to make a few more changes to the style.css file.

...

div.image {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-color: #fff;
}
div.image img {
  width: 100%;
}
div.story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

body.title-page div.container {
  width: 75vh;
  background-color: transparent;
}
body.title-page div.container > div {
  width: 100%;
}
body.title-page div.image {
  position: absolute; 
  z-index: -1; 
}

@media (max-aspect-ratio: 3/4) {

  body {
    font-size: 4vw;
  }

  div.container {
    height: 133.3333vw;
    width: 100vw;
  }

}
Restoring the title page to a single column
Figure 48. Restoring the title page to a single column

Quiz: Finalizing the layout

You now know all the techniques that you need to make the two-column layout look good on any shape of screen. If you can work out the solutions for yourself, you will be proving how much you have understood.

In this step, you will find a number of rules with missing values for you to fill in

To answer correctly, you will need to:

  • Think about numbers and ratios
  • Think about units

Starting wide

Make the Preview pane wide enough to see a band of black background on either side of the <div.container>. Now make the Preview pane narrower until there are no black bands, and the words in the text column start to move.

Your first task is to ensure that the <div.container> keeps its aspect ratio as the window (viewport) gets narrower, and that the text remains the same size in proportion to the size of the <div.container>.

To do this, you will need to add the following @media query to the style.css file, and replace the question marks with numbers or letters.

...

div.story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

@media (max-aspect-ratio: ???) {

  body {
    font-size: ???v?;  
  }

  div.container {
    height: ???v?;
    width: ???v?;
  }

}

body.title-page div.container {
  width: 75vh;
  background-color: transparent;
}

...

Leading questions

Here are some questions to help you find the answers:

max-aspect-ratio

When the flexbox display has enough room, it will use the following instructions to determine the size of the <div.container>:

  div.container {
    ...
    width: 133.333vh;
    height: 100vh;
  }

What is the aspect ratio of the container just before the black bands at the sides disappear?

Units

When the window is wide, the size of the <div.container> is limited by the height. The units used to define the dimensions of the <div.container> are vh — viewport height units.

When the window is narrower than a 4/3 aspect ratio, the size of the div.container is limited by the width. As the width decreases, so should the height.

What units should you use in this case?

font-size

The default font-size is:

body {
    ...
    font-size: 3vh;
    ...
  }

When the aspect ratio is 4/3, how many viewport width units are required to make the same length as 3vh?

width

When the aspect ratio of the window is less than 4/3, the <div.container> will be as wide as the window. How many vw units do you need to measure the width of the window?

width

The <div.container> is 100 units wide, and 3/4 as high as it is wide. How many units is it high?

@media (max-aspect-ratio: 4/3) {

    body {
    font-size: 2.25vw;  
  }

  div.container {
    height: 75vw;
    width: 100vw;
  }

}

Portrait mode

When the viewport is square, its width and its height are equal. If the <div.container> is shown in landscape mode or portrait mode, it will take up exactly the same area.

What @media query can you use to detect when the viewport is square, or narrower than a square?

@media (max-aspect-ratio: 1/1) {
  ...
}

What rule can you make to change the orientation of the <div.container>?

  • What CSS selector do you need?
  • What values will you use for width and height?
@media (max-aspect-ratio: 1/1) {

  div.container {
    width: 75vh;
    height: 100vh
  }

}
When the aspect ratio is 1/1, toggle between landscape and portraite mode
Figure 49. When the aspect ratio is 1/1, toggle between landscape and portraite mode

Dividing the page horizontally

As you can see in figure 49 above, the columns become very narrow in portrait mode. It would be better to place the picture above and the text below.

What flexbox instruction can you use to do this?

@media (max-aspect-ratio: 1/1) {

  div.container {
    flex-direction: column;
    width: 75vh;
    height: 100vh
  }

}
flex-direction: column; puts the picture above the text
Figure 50. flex-direction: column; puts the picture above the text

Full width, half height

As figure 50 above shows, the following rule iss still active:

div.container > div {
  width: 50%
}

That rule makes the <div.image> and <div.story> half the width of the <div.container> element

What rule can you write to override this in portrait mode?

Hint: width: auto; and height: auto; cancel any settings for width or height

  • What CSS selector do you need?
  • What values do you need to give for width and height?
@media (max-aspect-ratio: 1/1) {

  div.container {
    flex-direction: column;
    width: 75vh;
    height: 100vh
  }

  div.container > div {
    width: auto;
    height: 50%;
  }

}
Setting the width and height in portrait mode
Figure 51. Setting the width and height in portrait mode

Oversize Image

You will probably find that your image is now disproportionate. Its size is currently set by this rule:

div.image img {
  width: 100%;
}

You need to use the height of the image and not its width to set its size in portrait mode. Remembering the auto value, can you create a rule that does this?

@media (max-aspect-ratio: 1/1) {

  div.container {
    flex-direction: column;
    width: 75vh;
    height: 100vh
  }

  div.container > div {
    width: auto;
    height: 50%;
  }

  div.image img {
    width: auto;
    height: 100%;
  }

}

Proportionate font-size

The last adjustment that you need to make for the @media (max-aspect-ratio: 1/1) { ... } query is to keep the font-size proportional to the size of the div.container. This problem should be easy, because when the aspect ratio is 1/1 the vw units are identical in size to the vh units.

Add a rule that sets the font-size for portrait mode, when the div.container is the full height of the viewport.

@media (max-aspect-ratio: 1/1) {

  body {
    font-size: 2.25vh;
  }

  div.container {
    flex-direction: column;
    width: 75vh;
    height: 100vh
  }

  div.container > div {
    width: auto;
    height: 50%;
  }

  div.image img {
    width: auto;
    height: 100%;
  }

}

Narrower still

What happens if you make the Preview pane even narrower? The div.container keeps its width and height, and parts of it get cut off.

You need to create one last @media query. It needs to activate when the viewport is narrow.

  • What aspect ratio should activate it?
  • What units should it use to set the height and width of window
  • How many units should it use for width and height?
  • How should it handle font-size?
@media (max-aspect-ratio: 3/4) {

  body {
    font-size: 3vw;
  }

  body.title-page {
    font-size: 4vw;
  }

  body.title-page div.container,
  div.container {
    height: 133.3333vw;
    width: 100vw;
  }

}
/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
html {
  height: 100% 
}
body {
  background-color: black;
  font-family: "Open Sans", sans-serif;
  font-size: 3vh;
  margin: 0;
  color: #444;
  height: 100%; 
  display: flex;
  justify-content: center;
  align-items: center;
}
div.container {
  position: relative;
  display: flex;
  width: 133.333vh;
  background-color: white;
  height: 100vh;
}
div.container > div {
  width: 50%
}
h1, h2 {
  font-family: "Merriweather", serif;
  text-align: center;
  font-size: 2em;
}
h2 {
  font-size: 1.5em;
}
div.image {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-color: #fff;
}
div.image img {
  width: 100%;
}
div.story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

@media (max-aspect-ratio: 4/3) {

  body {
    font-size: 2.25vw;  
  }
  
  div.container {
    height: 75vw;
    width: 100vw;
  }

}

@media (max-aspect-ratio: 1/1) {

  body {
    font-size: 2.25vh;
  }

  div.container {
    flex-direction: column;
    width: 75vh;
    height: 100vh
  }

  div.container > div {
    width: auto;
    height: 50%;
  }

  div.image img {
    width: auto;
    height: 100%;
  }

}

body.title-page {
  font-size: 3vh;
  cursor: pointer !important;
}
body.title-page div.container {
  width: 75vh;
  height: 100vh;
  background-color: transparent;
}
body.title-page div.container > div {
  height: 100%;
  width: 100%;
}
body.title-page div.image {
  position: absolute; 
  z-index: -1; 
}
body.title-page img {
  width: 100%;
  height: auto;
}


@media (max-aspect-ratio: 3/4) {

  body {
    font-size: 3vw;
  }

  body.title-page {
    font-size: 4vw;
  }

  body.title-page div.container,
  div.container {
    height: 133.3333vw;
    width: 100vw;
  }

}

One page, one file

Everything is now in place for you to produce the first version of your story. You're probably eager to create a new HTML file for each page of your story, using the structure that you have just developed for your first two pages, and link them together with hyperlinks.

In the next section, you will discover the Sublime Text application that has tools that will make this process simpler, but learning to use the application takes a little time. Doing everything manually will make you appreciate the value of mastering productivity tools.

In this step, you can:

  • Create a template file
  • Make a copy of the template for every page
  • Paste the text of each page of your story into a separate template file
  • Add the appropriate links to each page
  • Upload your images to the Thimble server
  • Set the src of the <img> element to the appropriate picture for each page
  • Link the index.html title page to the first page of your story

Template

Click on the New File button and create a new HTML file. Name it template.html and paste the following text into it for safe-keeping.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,
                                   initial-scale=1">
    <title>My Story</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <div class="container">

      <div class="image">
        <img src="tutorial/img/picture.png" />
      </div>

      <div class="story">
        <div class="text">
          <p>PageText</p>
        </div>

        <div class="links">
          <a href="page_m.html">Left</a>
          <a href="page_n.html">Right</a>
        </div>
      </div>
    </div>
  </body>
</html>

You can use the same title for all the pages of your story, but the other items shown in red in the HTML listing above will be different for every page.

Page after page

Create a new HTML file for each page in your story, and paste this template text into it. From the story that you have prepared, paste a new page of text in place of the PageText item and ensure that the links are pointing to the right files. Customize the text of each link so that it fits in with the story.

Upload your images to the Thimble server

The fastest way to upload all the images that you want to have in the img folder is to follow these steps:

  • On your hard drive, compress all your images into a ZIP file called img.zip
  • In Thimble, click on the New File button then select Upload File
  • Select your img.zip file from your hard drive. Thimble will upload the ZIP file to the Thimble server, then decompress the file and copy all the images into the img folder.

Thimble will use the name of the ZIP file to decide the name of the destination folder. If you name the ZIP file something other than img.zip the images will end up in a different location.

Linking to the images

For each page_...html file, edit the src value in the <img /> element, taking care to use the right case (UPPERCASE or lowercase) for every character in the image files name.

Link your index.html page to the first page of your story

When you click on the title page, you want to browser to open the first story page. In the last section, a click anywhere on the index.html page activated a JavaScript method. It's easy to modify that method so that it opens the first page of your story instead.

In the file at js/script.js, edit the text as shown below:

document.body.onmouseup = function() {
  window.location.href = "page_001.html";
}

Preparing for Section 3

In Section 3, you will be moving beyond Thimble to using more powerful professional development tools. With these tools, you will discover how to set up and deliver your project so that you and your friends can install your game on the Home Screen of your smartphones.

In this step, you will install a browser and two professional applications for software development.

Specifically, you will:

  • Download and install Google Chrome
  • Download and install a trial version of Sublime Text
  • Download and install Git

Google Chrome

The Android operating system for smartphones and tablets is developed by Google. Google's Chrome browser has a set of free Developer Tools that make it easy to install your game on Android devices. You can download and install Google Chrome by clicking here.

Sublime Text

Sublime Text is a text editor designed for writing code. It helps you see the structure of your code provides you with many shortcuts for doing repetitive tasks.

To install Sublime Text, visit the download page and choose the download that is appropriate for your operating system

Sublime Text is not free software, but it will allow you to use all its features without payment for as long as you want. If you decide that you like using it, please consider buying a license, as a way of thanking the developers of Sublime Text for all the efforts they have made to make your life simpler.

Installing Git

GitHub is a meeting place for the open source community, where ideas are shared, where everyone can benefit from the energy and initiatives of others. A budding programmer like you has everything to gain from joining a community like this.

The Git application itself tracks the progress of your project. It creates a space for you make experiments, to make mistakes, to explore new possibilities without getting lost.

git --version

It's quite possible that git is already installed on your computer. To find out, open a Terminal window and type:

git --version

If all goes well, you should see something like this:

git version 2.7.4

If your version of git is 1.7.9.5 or earlier, or if you see a message like git is not a recognized command, then keep reading. Otherwise, there's nothing more that you need to do.

Installing Git on Windows

The easiest way to install Git on the Windows is to download an installer. When you click on the link, the download should start automatically.

You can launch the installer application and simply click on the Next > button, until you reach the screen Adjusting Your PATH Environment. (See image below). Here, it is best to select the Use Git From The Windows Command Prompt radio button. The Windows Command Prompt uses the Windows-standard / character in path names, which means that you can copy and paste path names from the Explorer windows, or drag files onto the Command Prompt window to paste their paths automatically into the window. Perhaps later, you will prefer to use the Git Bash application: selecting the second radio button, as shown in the image below, will allow you to choose the option you like best.

Figure 53. Choose - Use Git From The Windows Command Prompt

Installing Git on Mac OS X

If git --version tells you command not found: git, then you can download an installer for Git and run the installer

If you are using Mac OS 10.9 (Mavericks) or later, you can download an installer from the git-scm.com site.

  • Double-click on the downloaded file
  • Right-click on the yellow PKG icon and select Open from the contextual menu. (If you simply double-click, Mac OS X may tell you that it cannot be opened.)
  • Click Open in the dialog window
  • Enter the name and password of an admin user, to allow the installation
  • Click through the Continue buttons in the installation dialog
  • Click on Close when the installation is finished
Installing Git on Mac OS X
Figure 54. Installing Git on Mac OS X

Installing Git on a Unix-like system

First check which Linux distribution your system is based on. Wikipedia provides a list. Most Linux systems are Debian-based.

Debian-based linux systems
Open a terminal window. Copy and paste the following into the terminal window and hit Return. You may be prompted to enter your password.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git
Red Hat-based linux systems
Open a terminal. Copy and paste the following into the terminal window and hit Return. You may be prompted to enter your password.
sudo yum upgrade
sudo yum install git

Section 3: Developer tools

Before you continue, please make sure that you have the following applications installed on your computer:

  • Google Chrome
  • Sublime Text
  • Git

If not, please return to the previous step and follow the instructions there.

In this step, you will:

In particular, you will:

  • Create an account on GitHub.com
  • Create a GitHub repository for your game
  • Set up a web site for your game at github.io
  • Use Chrome to run an audit on your game site
  • Modify your game so that it passes all the audit tests
  • Install your game as an app on the home screen of an Android phone

Creating a GitHub account

GitHub.com is a meeting place for the open source community, where ideas are shared, where everyone can benefit from the energy and initiatives of others. A budding programmer like you has everything to gain from joining a community like this.

GitHub also provides, free of charge, web hosting for any project that you want to create. GitHub is in the top 100 most visited web sites, and it has over 28 million registered users. (Mozilla.com is in the top 200). You can be sure that your GitHub site will be easily accessible from anywhere at any time.

The Git application itself tracks the progress of your project. It creates a space for you make experiments, to make mistakes, to explore new possibilities without getting lost. You will be using both Git and your browser to interact with GitHub.

In this step, you will prepare a new home for your project on GitHub.com.

In particular, you will learn:

  • How to create a free GitHub account
  • How to create a Git repository on the GitHub server

Registration

Opening a GitHub account won't take long ... although finding a username that you like and that isn't already taken can be time-consuming. I've used the name "tapslate" in my examples.

Go to the Join GitHub page, and fill in the form.

At the time of writing, Git requires you to use only the characters A-Z, a-z and - (hyphens) for your username and for the names of your projects. Names with other punctuation, special characters, accents or non-Roman letters, like !android_ or Andréa or Андрей, are not permitted.

The first page asks for a username and an email address that are not currently registered on GitHub. It will also ask you to enter a password. At the beginning, at least, you will be typing this username and password often.

Figure 55. Create a personal account on GitHub

On the second page, you can accept the Free plan, which is already chosen as the default. Simply press the Finish Sign Up button.

Figure 56. Choose a free plan

This is the very first time you are visiting GitHub as a registered user, so you now see a screen that ask you some personal details. You can either add your details or skip this page. This information is not essential.

Figure 57. Your personal profile

As a first time user, you now see a screen that suggests that you take the official tour of what Git and GitHub can do for you.

Figure 58. Take the tour?

You might like to take GitHub's own tour now, to learn about the basic Git commands, or you might like to bookmark the Hello World tutorial or the Try Git tutorial so that you can come back to these later.

On the right of the page, you can see a Start A project button. Click on that and a new page will appear, asking you to confirm your email address.

Figure 59. Confirm your email address

When you clicked the Create An Account button (see figure 55), a message was sent to your email address. Open that email and click on the link, to prove that you control that email address. This will re-open the page where you were before. This time, when you click the Start A Project button, you'll find yourself on the Create A New Repository page.

Fill in the Repository Name field, and the optional Description field, then click on the Create Repository button.

Figure 60. Give your project a name

Your new repository

That's all you need to do on the GitHub site for now. You've created an online space to store your game, but you're not quite ready to upload it to GitHub.

You'll find yourself now on a page full of choices and command line code. No worries. There are some other things to do before you can continue here. When you find yourself here again later, you will have a much clearer understanding of what all this means.

Figure 61. Information about how to connect to your repository

Your local repository

Mozilla Thimble allows you to see the effect of the changes in your HTML, CSS and JavaScript code as you are typing. Unfortunately, to give you this immediate feedback, the Thimble site has to limit you in other ways. In order to take advantage of all the features of a web app, you need to "remove the training wheels".

In this step, you will transfer your project to your new GitHub repository, and you will start using the command line to control your computer.

In particular, you will:

  • Download your project from the Thimble site
  • Discover how to use a command-line application
  • Use Git from the command line to create a local git repository for your project on your computer
  • Use Git to push your local repository to the remote repository on GitHub.com

Downloading your project from Thimble

You already downloaded an earlier version of your game in step 18: Outside the Box. The steps here are the same. Click on the New File button at the top left of the Thimble window, and choose Download Files (.ZIP)

Download your project as a ZIP file
Figure 62. Download your project as a ZIP file

Find the file in your Downloads folder on your hard-disk and extract its contents.

Beneath the desktop

You are used to using a Graphical User Interface (GUI) for finding files on your computer. Often this is called the desktop. (On Windows, its official name is Windows Explorer. On Macintosh, it's called the Finder, and on other operating systems it has other names, like Gnome or Unity.)

The desktop GUI is easy to use, but it only lets you do the most common tasks, and it protects you from destroying files accidentally. Like a waiter in a restaurant, the GUI simply takes the orders that you give it with the mouse, and passes these orders on to the "chefs" in the operating system.

Now that you are ready to become a serious programmer, you can start learning how to talk to the operating system directly. For this, you need to use the command line. To use the command line, you need to open a special application. On Macintosh and other Unix-based operating systems, the application is called the Terminal. On Windows, it is called the Command Line prompt. In the rest of this tutorial, I will call use the word Terminal.

Hidden files

Find the Terminal application

Click here for instructions on how to find the Terminal application on your operating system, and further information about how to use it.

Using the command line

On your desktop, navigate to the folder where you have extracted the ZIP file from Thimble. Open your Terminal application and type "cd " followed by a space.

cd means "change directory". "Directory" is another word that means "folder".

As shown in the image below, drag the folder containing your game files onto the Terminal window. This will add the paste the path to this folder into the window.

Drag your project folder onto the command line app to copy the path
Figure . Drag your project folder onto the command line app to copy the path

Now press the Return key. The Terminal now acts like a window into your project folder. All the commands that you will type next will apply to this folder.

Creating a Git repository

In the c

Overview

This tutorial shows you how to create a responsive choose-your-own-adventure game that your friends can download and install on their smartphones.

You can see a demo game here.

You can write your own story, use your own pictures, and create your own problems for the players to solve.

You will be learning to write HTML, CSS and JavaScript. You will also learn how to use GitHub to save and display your work. You don't need any previous knowledge of programming, but an creative mind is a bonus.

HTML

HTML would be the food on your plate. HyperText Markup Language provides the content and the structure of the information in your web page.

A web page that just contains HTML can be informative, and can contain links to other pages.

CSS

CSS would be the way the table is laid and the way the food is presented on your plate. The Cascading Style Sheet takes care of the color, shape and position of the HTML elements. It's what gives the page its style.

A web page that just contains CSS is like a deserted restaurant: neat and decorative surroundings, all prepared for something to happen.

JavaScript

JavaScript would be the animation and conversation. JavaScript is what makes the web page come to life, with interactions, animations, cause and effect.

A web page that just contains JavaScript can create all the HTML and CSS that it needs.

Git

Git would be the event organizer, discreetly ensuring that everything is going to plan.

A web page does not need Git to manage it. When you first start creating web pages they will be simple enough for you to keep all your ideas tidy in your head as you are working. But as your experience and your initiatives grow, you will be happy to have Git to keep track of everything for you. Working with Git right from the beginning, on your first small projects, will give you confidence that you are ready to tackle larger projects.