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
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.
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?
- !DOCTYPE
- html
- head
- body
- meta charset
- meta "viewport"
- title
- link
- h1
- 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.
Compare the image above with the image on the previous page. What differences do you see?
In the image on the previous page:
- The text is centered.
- There are dots after the word "by", but these dots do not appear in the HTML file.
- Me! appears in red.
When you are happy with the new content of your page, you can move on to the next step: 4: Styling your Content.
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.
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.
You have learned to create CSS rules to place all the text in the center and to change the color of the <h1>
element. In the next section, you will learn to use a class to refine your selectors.
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?
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.
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.
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
.
You have seen that rules and instructions "cascade":
- Selectors that use more tags take priority
- When the number of tags is the same, rules that are later in the file take priority
- Selectors that use a
class
take priority, even when they use fewer tags or appear earlier in the file - Specific instructions that are not overridden by a higher priority rule continue to apply.
These ideas are important. Experiment with them. Change the selectors, the order of the rules and the class, and see what happens
In the next section, you will have a problem to solve using CSS rules and a class.
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 orcount()
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"
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.
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
You have learned to use JavaScript to add a class to a specific element, so that the display on the web page changes. In the next two sections, you will learn more CSS tricks to make this interaction more impressive.
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>
Using the ::after
pseudo-element, you have improved the appearance of the page before and after you click on it. In the next section, you will see how to create a transition between the "before" and "after" state of the page.
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 color
...opacity
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.
You have one last step to make your first game look good. In the next step, you will learn how to set the size of the text.
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 often16px
.
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 often2em
. If the defaultfont-size
for text is16px
, then the defaultfont-size
for<h1>
elements will be calculated as32px
.
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.
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 thestyle.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.
Congratulations! Your first interactive game is complete! In the next step, you will tidy your work space to prepare for making a more complex game.
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
.
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.
A dialog window will open. Select the css
folder and then click on OK.
Creating a new JavaScript file
Hover over the new js folder name, and click on the contextual menu arrow. Choose New File:
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.
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.
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 /
.
That's it! Your proof of concept game is finished. In the next step, you will see how to publish it so that your friends can see what you have done today.
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.
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
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.
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.
This is just the beginning. In the next section, you will be able to add your own texts, your own pictures and create your own interactive story. The final step today is to start preparing for the next section.
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:
On the Your Projects screen, find the name of your game project and click on the Remix link:
When this new copy of your project opens, change its name, at the top left of the Thimble window:
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.
Name the file page_001.html
.
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!
Now that you have seen how to create pages for your story and to create links between them, you might want to put all your story pages online right now. However, in the next few steps, you will be creating a layout for your pages, to make them look good on any device. If you wait until you have finished the layout before you create all your pages, you will have less work to do. You add more pages at the end of this section.
In the next step, you will learn to add an image for your title 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.
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.
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:
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.
Name the new folder img
:
Click on the contextual menu for the picture you uploaded, and select Move To:
In the dialog window, select the new img
folder, and click on OK.
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 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.
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 "sourcealt
stands for "alternative"
You have successfully included an image in your web page. In the next step you will see how to make the image and the text look good on your page.
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.
You now know how to place one HTML element on top of another, but all the elements are close together at the top of the page. In the next step you will see how to visualize the area used by each element.
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)
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.
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.
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.
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.
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.
In the next step you will be making changes to the Thimble version of your web page. I recommend that you test the changes first using the Developer Tools, as explained in this step, so that you can use the overlay colors to see how the padding, borders and margins change.
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:
- You have commented out several lines of CSS code
- You have changed the font-size for the web page and added a rule for
<h2>
elements - You have added a new rule for the
<div class="story">
element - 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
.
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.
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.
Click on the height
checkbox again to select it, and check the dimensions of the <div class="story">
element again.
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.
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
.
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%;
}
Your text and your image should now be in the right places, but they move relative to each other when you change the dimensions of the window. In the next steps, you will learn how to create a layout that scales to fit any shape of window on any device.
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 storydiv
s. - 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 theposition
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.
The <div class="container">
element has a 3:4 aspect ratio when the window is wide, but the flexbox display makes it narrower when the window is narrow, and the <div class="container">
continues to be the full height of the window. In the next step, you will see how to limit the height of the <div class="container">
when the aspect ratio of the window is less than 3:4.
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; } }
You have seen how to use conditional rules inside a @media
query. In the next step, you will use the same techniques to modify your page_001.html
page to show an image with your text.
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 yourindex.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 >
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 div
s, but that will change in step 24, and those child div
s 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.
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;
}
}
The two-column layout for the story pages looks good when the window is wide. However, when the window is narrower than 4:3, the text begins to look crushed. In the next step, you will add more @media
queries to finalise the layout.
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
andheight
?
@media (max-aspect-ratio: 1/1) { div.container { width: 75vh; height: 100vh } }
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
}
}
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
andheight
?
@media (max-aspect-ratio: 1/1) {
div.container {
flex-direction: column;
width: 75vh;
height: 100vh
}
div.container > div {
width: auto;
height: 50%;
}
}
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
andheight
? - 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; } }
Your title page and your story pages will now look good on any screen with any dimensions. However, there is one last thing to do before you create all your story pages. In the next step, you will create separate div
s for the text of your story and for the links.
Bundling text and links
In the flexbox display, the instruction justify-content: space-between;
will create an equal amount of space between every paragraph in your text and every link to another page. The layout would look better if the text were kept in one group and the links in another, with space between these two groups.
In this step, you will:
In particular, you will:
- Add two more
div
elements to thediv.story
element - Make the text element scrollable, if its contents are longer than the space available.
- Adjust the CSS so that the borders between the links, the text and the image area are clear
- Add your own classes and rules to improve the look of your text
Modifying the HTML structure
In your page_001.html
file, add two new <div>
elements inside the <div class="story">
element. Place them around the text of your story and around the links at the end. Your file might look something like this:
<!-- 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> <div class="container"> <div class="image"> <img src="tutorial/img/picture_for_page_2.png" /> </div> <div class="story"> <div class="text"> <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> <p class="news">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.</p> </div> <div class="links"> <a href="page_003.html">Go to page 3</a> </div> </div> </body> </html>
The complete CSS
The CSS listing below shows the complete contents of the style.css
file. The text in black defines how the two new <div>
s will appear.
overflow-y: auto;
will make a vertical scroll bar if the text is too long to fit the space availablepadding
puts whitespace around the text in eachdiv
background-color
makes thediv.links
visually distinct from thediv.text
elementborder-top
creates a darker line between the two elements- The
display: block;
instruction in the rule fordiv.links a { ... }
ensures that each link appears on a new line
The text in gold serves to distinguish between the <div.image>
and the <div.text>
areas. The orange rule is a custom tweak to make an excerpt from a newspaper look different. Feel free to add your own classes and rules to your own story, to make the text more appealing.
/* 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: #eef; border-right: 1px solid #ccd; } div.image img { width: 100%; } div.story { display: flex; flex-direction: column; justify-content: space-between; height: 100%; } div.text { overflow-y: auto; padding: 1em; } div.links { padding: 0.5em; background-color: #eee; border-top: 1px solid #ccc; } div.links a { display: block; padding: 0.2em; } p.news { background-color: #fffcf6; padding: 1em; font-family: "Times New Roman", serif; } @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 { border-right: none; border-bottom: 1px solid #ccc; } 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; } }
The final layout
Your story pages should now look something like the image below. Publish your project and test it on as many devices as you can, to make sure that it looks the way you intend it to before you create all the pages for your story.
When you are satisfied with your layout, you can move on to the final step for this section: creating all your pages and linking them together.
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 theimg
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";
}
That's it! You have all the ingredients for a choose-your-own-adventure story. When you have created and linked all your pages, you can Publish your project and share the link with your friends, and find out which choices they make.
A compelling story line is just the beginning. In the remainder of this course, you will learn how to:
- Add logic puzzles to your game
- Add music and sound effects
- Save the player's progress
- Install the game for playing offline
Starting from the next section, you will need to use more powerful tools than Thimble to develop your game and keep track of your progress. The last step in this section is to download these open source tools so that you are ready to begin developing like a professional.
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.
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 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
When you have Sublime Text and Git installed on your computer, you are ready to start Section 3.
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.
On the second page, you can accept the Free plan, which is already chosen as the default. Simply press the Finish Sign Up button.
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.
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.
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.
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.
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.
Congratulations! You've joined the GitHub community and created your first online repository — a permanent home for your game. In the next step, you'll use the Git application to create a local repository and link it to the repository that you have just created on GitHub. Then, with one simple command, you will put your game online on the GitHub site.
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)
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.
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
- Adjust the settings on GitHub.com to create a web site for your game
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.