Hands-On Game Development with WebAssembly
上QQ阅读APP看书,第一时间看更新

Defining the CSS

Now that we have some basic HTML, we need to create a new shell.css file. Without any CSS styling, our page looks pretty terrible.

A page without styling will be similar to the one shown as follows:

Figure 2.1: The Hello WebAssembly app without a CSS style

Luckily for us, a little bit of CSS goes a long way to make our web page look presentable. Here is what the new shell.css file we are creating looks like:

body {
margin-top: 20px;
}

.input_box {
width: 20%;
display: inline-block;
}
.em_button {
width: 45%;
height: 40px;
background-color: orangered;
color: white;
border: 2px solid white;
font-size: 20px;
border-radius: 8px;
transition-duration: 0.5s;
}

.em_button:hover {
background-color: orange;
color: white;
border: 2px solid white;
}

.em_input {
width: 45%;
height: 20px;
font-size: 20px;
background-color: darkslategray;
color: white;
padding: 6px;
}

#output {
background-color: darkslategray;
color: white;
font-size: 16px;
padding: 10px;
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
width: 60%;
}

#string_box {
padding-top: 10px;
margin-left: auto;
margin-right: auto;
display: block;
width: 60%;
}

#string_input {
font-size: 20px;
background-color: darkslategray;
color: white;
padding: 6px;
margin-left: 5px;
width: 45%;
float: right;
}

Let me quickly walk through what we need to do to style this page. This book is not a book on CSS, but it does not hurt to cover the topic in a cursory fashion.

  1. The first thing we will do is put a little 20-pixel margin on the page body to put a little bit of space between the browser toolbar and the content on our page:
body {
margin-top: 20px;
}
  1. We have created five input boxes that take up 20% of the browser width each. The boxes on the left and the right have nothing in them, so that the content takes up 60% of the browser width. They are displayed as an inline-block, so that they line up horizontally across the screen. Here is the CSS that makes it happen:
.input_box {
width: 20%;
display: inline-block;
}
  1. We then have a few classes to style our buttons using a class called em_button:
.em_button {
width: 45%;
height: 40px;
background-color: orangered;
color: white;
border: 0px;
font-size: 20px;
border-radius: 8px;
transition-duration: 0.2s;
}

.em_button:hover {
background-color: orange;
}

We have set the button width to take up 45% of the containing element. We set the button height to 40 pixels. We have set the button's color to orangered, and the text color to white. We remove the border by setting its width to 0 pixels. We have set the font size to 20 pixels and given it an 8 pixel border-radius, which provides the button with a rounded look. The last line sets the amount of time it takes to transition to a new color when the user hovers over the button.

After we finish the definition of the em_button class, we define the em_button:hover class, which changes the color of the button when the user hovers over it.

Some versions of Safari require the line   -webkit-transition-duration: 0.2s;  inside the   em_button  class definition to have a transition to the hover state. Without this line, the button would instantly change from orangered to orange in some versions of Safari, rather than transitioning over 200 milliseconds.

The next class we define is for the input elements:

.em_input {
width: 45%;
height: 20px;
font-size: 20px;
background-color: darkslategray;
color: white;
padding: 6px;
}

We have set its height, width, and font-size at the beginning. We set the background color to a darkslategray with white text. We have added 6 pixels of padding so that there is a small space between the font and the edge of the input element.

The # in front of the name of a CSS element styles an ID instead of a class. An ID defines a specific element where a class (preceded by a . in CSS) can be assigned to multiple elements in your HTML. The next bit of CSS styles the textarea that has the ID of output:

#output {
background-color: darkslategray;
color: white;
font-size: 16px;
padding: 10px;
margin-left: auto;
margin-right: auto;
display: block;
width: 60%;
}

The first two lines set the background and text color. We set the font size to 16 pixels and add 10 pixels of padding. The next two lines use the left and right margin to center the textarea:

margin-left: auto;
margin-right: auto;

Setting display: block; puts this element on a line by itself. Setting the width to 60% makes the element take up 60% of the containing element, which, in this case, is the browser's body tag.

Finally, we style the string_box and string_input elements:

#string_box {
padding-top: 10px;
margin-left: auto;
margin-right: auto;
display: block;
width: 60%;
}

#string_input {
font-size: 20px;
background-color: darkslategray;
color: white;
padding: 6px;
margin-left: 5px;
width: 45%;
float: right;
}

The string_box is the box that contains the string button and the string input elements. We pad the top of the box to add some space between the string_box and the textarea above it. margin-left: auto and margin-right: auto center the box. Then, we use display:block and width: 60% to have it take up 60% of the web browser.

For the string_input element, we set the font size and the colors and pad it by 6 pixels. We set a left margin of 5 pixels to put some space on the left between the element and its button. We set it to take up 45% of the width of the containing element, while the float: right style pushes the element to the right side of the containing element.

To build our app, we need to run emcc:

 emcc shell.c -o shell-test.html --shell-file new_shell.html -s NO_EXIT_RUNTIME=1 -s EXPORTED_FUNCTIONS="['_test', '_string_test', '_int_test', '_float_test', '_main']" -s EXTRA_EXPORTED_RUNTIME_METHODS="['cwrap', 'ccall']"

EXPORTED_FUNCTIONS is used to define all of the functions called from JavaScript. They are listed with a preceding _ character. EXTRA_EXPORTED_RUNTIME_METHODS is used to make the cwrap and ccall methods available to the JavaScript inside our shell file. We are not currently using ccall, which is an alternative to cwrap, which we may choose to use in the future.

It is important to remember that you must run WebAssembly apps using a web server, or with emrun. If you would like to run your WebAssembly app using emrun, you must compile it with the --emrun flag. The web browser requires a web server to stream the WebAssembly module. If you attempt to open an HTML page that uses WebAssembly in a browser directly from your hard drive, that WebAssembly module will not load.

Now that we have added some CSS styling, we have a much nicer looking app:

Figure 2.2: The Hello WebAssembly app with a CSS style

In the next section, we will discuss HTML5 web game development.