Example - Learn web development

Example
=======

This the example for a basic payment form for the article How to structure an HTML form.

A payment form
--------------

### HTML

```html
<form method="post">
  <h1>Payment form</h1>
  <p>
    Required fields are followed by
    <strong><span aria-label="required">*</span></strong>.
  </p>
  <section>
    <h2>Contact information</h2>
    <fieldset>
      <legend>Title</legend>
      <ul>
        <li>
          <label for="title\_1">
            <input type="radio" id="title\_1" name="title" value="A" />
            Ace
          </label>
        </li>
        <li>
          <label for="title\_2">
            <input type="radio" id="title\_2" name="title" value="K" />
            King
          </label>
        </li>
        <li>
          <label for="title\_3">
            <input type="radio" id="title\_3" name="title" value="Q" />
            Queen
          </label>
        </li>
      </ul>
    </fieldset>
    <p>
      <label for="name">
        <span>Name: </span>
        <strong><span aria-label="required">*</span></strong>
      </label>
      <input type="text" id="name" name="username" required />
    </p>
    <p>
      <label for="mail">
        <span>Email: </span>
        <strong><span aria-label="required">*</span></strong>
      </label>
      <input type="email" id="mail" name="usermail" required />
    </p>
    <p>
      <label for="pwd">
        <span>Password: </span>
        <strong><span aria-label="required">*</span></strong>
      </label>
      <input type="password" id="pwd" name="password" required />
    </p>
  </section>
  <section>
    <h2>Payment information</h2>
    <p>
      <label for="card">
        <span>Card type:</span>
      </label>
      <select id="card" name="usercard">
        <option value="visa">Visa</option>
        <option value="mc">Mastercard</option>
        <option value="amex">American Express</option>
      </select>
    </p>
    <p>
      <label for="number">
        <span>Card number:</span>
        <strong><span aria-label="required">*</span></strong>
      </label>
      <input type="tel" id="number" name="cardnumber" />
    </p>
    <p>
      <label for="expiration">
        <span>Expiration date:</span>
        <strong><span aria-label="required">*</span></strong>
      </label>
      <input
 type="text"
 id="expiration"
 required="true"
 placeholder="MM/YY"
 pattern="^(0[1-9]|1[0-2])\/([0-9]{2})$" />
    </p>
  </section>
  <section>
    <p><button type="submit">Validate the payment</button></p>
  </section>
</form>
```

### CSS

```css
h1 {
  margin-top: 0;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

form {
  margin: 0 auto;
  width: 400px;
  padding: 1em;
  border: 1px solid #ccc;
  border-radius: 1em;
}

div + div {
  margin-top: 1em;
}

label span {
  display: inline-block;
  text-align: right;
}

input,
textarea {
  font: 1em sans-serif;
  width: 250px;
  box-sizing: border-box;
  border: 1px solid #999;
}

input[type="checkbox"],
input[type="radio"] {
  width: auto;
  border: none;
}

input:focus,
textarea:focus {
  border-color: #000;
}

textarea {
  vertical-align: top;
  height: 5em;
  resize: vertical;
}

fieldset {
  width: 250px;
  box-sizing: border-box;
  border: 1px solid #999;
}

button {
  margin: 20px 0 0 0;
}

label {
  position: relative;
  display: inline-block;
}

p label {
  width: 100%;
}

label em {
  position: absolute;
  right: 5px;
  top: 20px;
}
```

### Result


Example 3 - Learn web development

Example 3
=========

This is the third example that explain how to build custom form widgets.

Change states
-------------

### HTML

```html
<form class="no-widget">
  <select name="myFruit" tabindex="-1">
    <option>Cherry</option>
    <option>Lemon</option>
    <option>Banana</option>
    <option>Strawberry</option>
    <option>Apple</option>
  </select>

  <div class="select" tabindex="0">
    <span class="value">Cherry</span>
    <ul class="optList hidden">
      <li class="option">Cherry</li>
      <li class="option">Lemon</li>
      <li class="option">Banana</li>
      <li class="option">Strawberry</li>
      <li class="option">Apple</li>
    </ul>
  </div>
</form>
```

### CSS

```css
.widget select,
.no-widget .select {
  position: absolute;
  left: -5000em;
  height: 0;
  overflow: hidden;
}

/\* --------------- \*/
/\* Required Styles \*/
/\* --------------- \*/

.select {
  position: relative;
  display: inline-block;
}

.select.active,
.select:focus {
  box-shadow: 0 0 3px 1px #227755;
  outline-color: transparent;
}

.select .optList {
  position: absolute;
  top: 100%;
  left: 0;
}

.select .optList.hidden {
  max-height: 0;
  visibility: hidden;
}

/\* ------------ \*/
/\* Fancy Styles \*/
/\* ------------ \*/

.select {
  font-size: 0.625em; /\* 10px \*/
  font-family: Verdana, Arial, sans-serif;

  box-sizing: border-box;

  padding: 0.1em 2.5em 0.2em 0.5em; /\* 1px 25px 2px 5px \*/
  width: 10em; /\* 100px \*/

  border: 0.2em solid #000; /\* 2px \*/
  border-radius: 0.4em; /\* 4px \*/

  box-shadow: 0 0.1em 0.2em rgb(0 0 0 / 45%); /\* 0 1px 2px \*/

  background: #f0f0f0;
  background: linear-gradient(0deg, #e3e3e3, #fcfcfc 50%, #f0f0f0);
}

.select .value {
  display: inline-block;
  width: 100%;
  overflow: hidden;

  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: top;
}

.select::after {
  content: "▼";
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 2em; /\* 20px \*/
  top: 0;
  right: 0;

  padding-top: 0.1em;

  box-sizing: border-box;

  text-align: center;

  border-left: 0.2em solid #000;
  border-radius: 0 0.1em 0.1em 0;

  background-color: #000;
  color: #fff;
}

.select .optList {
  z-index: 2;

  list-style: none;
  margin: 0;
  padding: 0;

  background: #f0f0f0;
  border: 0.2em solid #000;
  border-top-width: 0.1em;
  border-radius: 0 0 0.4em 0.4em;

  box-shadow: 0 0.2em 0.4em rgb(0 0 0 / 40%);

  box-sizing: border-box;

  min-width: 100%;
  max-height: 10em; /\* 100px \*/
  overflow-y: auto;
  overflow-x: hidden;
}

.select .option {
  padding: 0.2em 0.3em;
}

.select .highlight {
  background: #000;
  color: #ffffff;
}
```

### JavaScript

```js
// -------------------- //
// Function definitions //
// -------------------- //

function deactivateSelect(select) {
  if (!select.classList.contains("active")) return;

  const optList = select.querySelector(".optList");

  optList.classList.add("hidden");
  select.classList.remove("active");
}

function activeSelect(select, selectList) {
  if (select.classList.contains("active")) return;

  selectList.forEach(deactivateSelect);
  select.classList.add("active");
}

function toggleOptList(select, show) {
  const optList = select.querySelector(".optList");

  optList.classList.toggle("hidden");
}

function highlightOption(select, option) {
  const optionList = select.querySelectorAll(".option");

  optionList.forEach((other) => {
    other.classList.remove("highlight");
  });

  option.classList.add("highlight");
}

// ------------- //
// Event binding //
// ------------- //

window.addEventListener("load", () => {
  const form = document.querySelector("form");

  form.classList.remove("no-widget");
  form.classList.add("widget");
});

window.addEventListener("load", () => {
  const selectList = document.querySelectorAll(".select");

  selectList.forEach((select) => {
    const optionList = select.querySelectorAll(".option");

    optionList.forEach((option) => {
      option.addEventListener("mouseover", () => {
        highlightOption(select, option);
      });
    });

    select.addEventListener(
      "click",
      (event) => {
        toggleOptList(select);
      },
      false,
    );

    select.addEventListener("focus", (event) => {
      activeSelect(select, selectList);
    });

    select.addEventListener("blur", (event) => {
      deactivateSelect(select);
    });

    select.addEventListener("keyup", (event) => {
      if (event.key === "Escape") {
        deactivateSelect(select);
      }
    });
  });
});
```

### Result


Example 2 - Learn web development

Example 2
=========

This is the second example that explain how to build custom form widgets.

JS
--

### HTML

```html
<form class="no-widget">
  <select name="myFruit">
    <option>Cherry</option>
    <option>Lemon</option>
    <option>Banana</option>
    <option>Strawberry</option>
    <option>Apple</option>
  </select>

  <div class="select">
    <span class="value">Cherry</span>
    <ul class="optList hidden">
      <li class="option">Cherry</li>
      <li class="option">Lemon</li>
      <li class="option">Banana</li>
      <li class="option">Strawberry</li>
      <li class="option">Apple</li>
    </ul>
  </div>
</form>
```

### CSS

```css
.widget select,
.no-widget .select {
  position: absolute;
  left: -5000em;
  height: 0;
  overflow: hidden;
}

/\* --------------- \*/
/\* Required Styles \*/
/\* --------------- \*/

.select {
  position: relative;
  display: inline-block;
}

.select.active,
.select:focus {
  box-shadow: 0 0 3px 1px #227755;
  outline: none;
}

.select .optList {
  position: absolute;
  top: 100%;
  left: 0;
}

.select .optList.hidden {
  max-height: 0;
  visibility: hidden;
}

/\* ------------ \*/
/\* Fancy Styles \*/
/\* ------------ \*/

.select {
  font-size: 0.625em; /\* 10px \*/
  font-family: Verdana, Arial, sans-serif;

  box-sizing: border-box;

  padding: 0.1em 2.5em 0.2em 0.5em; /\* 1px 25px 2px 5px \*/
  width: 10em; /\* 100px \*/

  border: 0.2em solid #000; /\* 2px \*/
  border-radius: 0.4em; /\* 4px \*/

  box-shadow: 0 0.1em 0.2em rgb(0 0 0 / 45%); /\* 0 1px 2px \*/

  background: #f0f0f0;
  background: linear-gradient(0deg, #e3e3e3, #fcfcfc 50%, #f0f0f0);
}

.select .value {
  display: inline-block;
  width: 100%;
  overflow: hidden;

  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: top;
}

.select::after {
  content: "▼";
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 2em; /\* 20px \*/
  top: 0;
  right: 0;

  padding-top: 0.1em;

  box-sizing: border-box;

  text-align: center;

  border-left: 0.2em solid #000;
  border-radius: 0 0.1em 0.1em 0;

  background-color: #000;
  color: #fff;
}

.select .optList {
  z-index: 2;

  list-style: none;
  margin: 0;
  padding: 0;

  background: #f0f0f0;
  border: 0.2em solid #000;
  border-top-width: 0.1em;
  border-radius: 0 0 0.4em 0.4em;

  box-shadow: 0 0.2em 0.4em rgb(0 0 0 / 40%);

  box-sizing: border-box;

  min-width: 100%;
  max-height: 10em; /\* 100px \*/
  overflow-y: auto;
  overflow-x: hidden;
}

.select .option {
  padding: 0.2em 0.3em;
}

.select .highlight {
  background: #000;
  color: #ffffff;
}
```

### JavaScript

```js
window.addEventListener("load", () => {
  const form = document.querySelector("form");

  form.classList.remove("no-widget");
  form.classList.add("widget");
});
```

### Result

No JS
-----

### HTML

```html
<form class="no-widget">
  <select name="myFruit">
    <option>Cherry</option>
    <option>Lemon</option>
    <option>Banana</option>
    <option>Strawberry</option>
    <option>Apple</option>
  </select>

  <div class="select">
    <span class="value">Cherry</span>
    <ul class="optList hidden">
      <li class="option">Cherry</li>
      <li class="option">Lemon</li>
      <li class="option">Banana</li>
      <li class="option">Strawberry</li>
      <li class="option">Apple</li>
    </ul>
  </div>
</form>
```

### CSS

```css
.widget select,
.no-widget .select {
  position: absolute;
  left: -5000em;
  height: 0;
  overflow: hidden;
}
```

### Result


Example 4 - Learn web development

Example 4
=========

This is the fourth example that explain how to build custom form widgets.

Change states
-------------

### HTML

```html
<form class="no-widget">
  <select name="myFruit">
    <option>Cherry</option>
    <option>Lemon</option>
    <option>Banana</option>
    <option>Strawberry</option>
    <option>Apple</option>
  </select>

  <div class="select">
    <span class="value">Cherry</span>
    <ul class="optList hidden">
      <li class="option">Cherry</li>
      <li class="option">Lemon</li>
      <li class="option">Banana</li>
      <li class="option">Strawberry</li>
      <li class="option">Apple</li>
    </ul>
  </div>
</form>
```

### CSS

```css
.widget select,
.no-widget .select {
  position: absolute;
  left: -5000em;
  height: 0;
  overflow: hidden;
}

/\* --------------- \*/
/\* Required Styles \*/
/\* --------------- \*/

.select {
  position: relative;
  display: inline-block;
}

.select.active,
.select:focus {
  box-shadow: 0 0 3px 1px #227755;
  outline-color: transparent;
}

.select .optList {
  position: absolute;
  top: 100%;
  left: 0;
}

.select .optList.hidden {
  max-height: 0;
  visibility: hidden;
}

/\* ------------ \*/
/\* Fancy Styles \*/
/\* ------------ \*/

.select {
  font-size: 0.625em; /\* 10px \*/
  font-family: Verdana, Arial, sans-serif;

  box-sizing: border-box;

  padding: 0.1em 2.5em 0.2em 0.5em; /\* 1px 25px 2px 5px \*/
  width: 10em; /\* 100px \*/

  border: 0.2em solid #000; /\* 2px \*/
  border-radius: 0.4em; /\* 4px \*/

  box-shadow: 0 0.1em 0.2em rgb(0 0 0 / 45%); /\* 0 1px 2px \*/

  background: #f0f0f0;
  background: linear-gradient(0deg, #e3e3e3, #fcfcfc 50%, #f0f0f0);
}

.select .value {
  display: inline-block;
  width: 100%;
  overflow: hidden;

  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: top;
}

.select::after {
  content: "▼";
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 2em; /\* 20px \*/
  top: 0;
  right: 0;

  padding-top: 0.1em;

  box-sizing: border-box;

  text-align: center;

  border-left: 0.2em solid #000;
  border-radius: 0 0.1em 0.1em 0;

  background-color: #000;
  color: #fff;
}

.select .optList {
  z-index: 2;

  list-style: none;
  margin: 0;
  padding: 0;

  background: #f0f0f0;
  border: 0.2em solid #000;
  border-top-width: 0.1em;
  border-radius: 0 0 0.4em 0.4em;

  box-shadow: 0 0.2em 0.4em rgb(0 0 0 / 40%);

  box-sizing: border-box;

  min-width: 100%;
  max-height: 10em; /\* 100px \*/
  overflow-y: auto;
  overflow-x: hidden;
}

.select .option {
  padding: 0.2em 0.3em;
}

.select .highlight {
  background: #000;
  color: #ffffff;
}
```

### JavaScript

```js
// -------------------- //
// Function definitions //
// -------------------- //

function deactivateSelect(select) {
  if (!select.classList.contains("active")) return;

  const optList = select.querySelector(".optList");

  optList.classList.add("hidden");
  select.classList.remove("active");
}

function activeSelect(select, selectList) {
  if (select.classList.contains("active")) return;

  selectList.forEach(deactivateSelect);
  select.classList.add("active");
}

function toggleOptList(select, show) {
  const optList = select.querySelector(".optList");

  optList.classList.toggle("hidden");
}

function highlightOption(select, option) {
  const optionList = select.querySelectorAll(".option");

  optionList.forEach((other) => {
    other.classList.remove("highlight");
  });

  option.classList.add("highlight");
}

function updateValue(select, index) {
  const nativeWidget = select.previousElementSibling;
  const value = select.querySelector(".value");
  const optionList = select.querySelectorAll(".option");

  nativeWidget.selectedIndex = index;
  value.innerHTML = optionList[index].innerHTML;
  highlightOption(select, optionList[index]);
}

function getIndex(select) {
  const nativeWidget = select.previousElementSibling;

  return nativeWidget.selectedIndex;
}

// ------------- //
// Event binding //
// ------------- //

window.addEventListener("load", () => {
  const form = document.querySelector("form");

  form.classList.remove("no-widget");
  form.classList.add("widget");
});

window.addEventListener("load", () => {
  const selectList = document.querySelectorAll(".select");

  selectList.forEach((select) => {
    const optionList = select.querySelectorAll(".option");

    optionList.forEach((option) => {
      option.addEventListener("mouseover", () => {
        highlightOption(select, option);
      });
    });

    select.addEventListener("click", (event) => {
      toggleOptList(select);
    });

    select.addEventListener("focus", (event) => {
      activeSelect(select, selectList);
    });

    select.addEventListener("blur", (event) => {
      deactivateSelect(select);
    });
  });
});

window.addEventListener("load", () => {
  const selectList = document.querySelectorAll(".select");

  selectList.forEach((select) => {
    const optionList = select.querySelectorAll(".option");
    const selectedIndex = getIndex(select);

    select.tabIndex = 0;
    select.previousElementSibling.tabIndex = -1;

    updateValue(select, selectedIndex);

    optionList.forEach((option, index) => {
      option.addEventListener("click", (event) => {
        updateValue(select, index);
      });
    });

    select.addEventListener("keyup", (event) => {
      let index = getIndex(select);

      if (event.key === "Escape") {
        deactivateSelect(select);
      }
      if (event.key === "ArrowDown" && index < optionList.length - 1) {
        index++;
      }
      if (event.key === "ArrowUp" && index > 0) {
        index--;
      }

      updateValue(select, index);
    });
  });
});
```

### Result


Example 1 - Learn web development

Example 1
=========

This is the first example of code that explains how to build a custom form widget.

Basic state
-----------

### HTML

```html
<div class="select">
  <span class="value">Cherry</span>
  <ul class="optList hidden">
    <li class="option">Cherry</li>
    <li class="option">Lemon</li>
    <li class="option">Banana</li>
    <li class="option">Strawberry</li>
    <li class="option">Apple</li>
  </ul>
</div>
```

### CSS

```css
/\* --------------- \*/
/\* Required Styles \*/
/\* --------------- \*/

.select {
  position: relative;
  display: inline-block;
}

.select.active,
.select:focus {
  box-shadow: 0 0 3px 1px #227755;
  outline-color: transparent;
}

.select .optList {
  position: absolute;
  top: 100%;
  left: 0;
}

.select .optList.hidden {
  max-height: 0;
  visibility: hidden;
}

/\* ------------ \*/
/\* Fancy Styles \*/
/\* ------------ \*/

.select {
  font-size: 0.625em; /\* 10px \*/
  font-family: Verdana, Arial, sans-serif;

  box-sizing: border-box;

  padding: 0.1em 2.5em 0.2em 0.5em; /\* 1px 25px 2px 5px \*/
  width: 10em; /\* 100px \*/

  border: 0.2em solid #000; /\* 2px \*/
  border-radius: 0.4em; /\* 4px \*/

  box-shadow: 0 0.1em 0.2em rgb(0 0 0 / 45%); /\* 0 1px 2px \*/

  background: #f0f0f0;
  background: linear-gradient(0deg, #e3e3e3, #fcfcfc 50%, #f0f0f0);
}

.select .value {
  display: inline-block;
  width: 100%;
  overflow: hidden;

  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: top;
}

.select::after {
  content: "▼";
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 2em; /\* 20px \*/
  top: 0;
  right: 0;

  padding-top: 0.1em;

  box-sizing: border-box;

  text-align: center;

  border-left: 0.2em solid #000;
  border-radius: 0 0.1em 0.1em 0;

  background-color: #000;
  color: #fff;
}

.select .optList {
  z-index: 2;

  list-style: none;
  margin: 0;
  padding: 0;

  background: #f0f0f0;
  border: 0.2em solid #000;
  border-top-width: 0.1em;
  border-radius: 0 0 0.4em 0.4em;

  box-shadow: 0 0.2em 0.4em rgb(0 0 0 / 40%);

  box-sizing: border-box;

  min-width: 100%;
  max-height: 10em; /\* 100px \*/
  overflow-y: auto;
  overflow-x: hidden;
}

.select .option {
  padding: 0.2em 0.3em;
}

.select .highlight {
  background: #000;
  color: #ffffff;
}
```

### Result for basic state

Active state
------------

### HTML

```html
<div class="select active">
  <span class="value">Cherry</span>
  <ul class="optList hidden">
    <li class="option">Cherry</li>
    <li class="option">Lemon</li>
    <li class="option">Banana</li>
    <li class="option">Strawberry</li>
    <li class="option">Apple</li>
  </ul>
</div>
```

### CSS

```css
/\* --------------- \*/
/\* Required Styles \*/
/\* --------------- \*/

.select {
  position: relative;
  display: inline-block;
}

.select.active,
.select:focus {
  box-shadow: 0 0 3px 1px #227755;
  outline-color: transparent;
}

.select .optList {
  position: absolute;
  top: 100%;
  left: 0;
}

.select .optList.hidden {
  max-height: 0;
  visibility: hidden;
}

/\* ------------ \*/
/\* Fancy Styles \*/
/\* ------------ \*/

.select {
  font-size: 0.625em; /\* 10px \*/
  font-family: Verdana, Arial, sans-serif;

  box-sizing: border-box;

  padding: 0.1em 2.5em 0.2em 0.5em; /\* 1px 25px 2px 5px \*/
  width: 10em; /\* 100px \*/

  border: 0.2em solid #000; /\* 2px \*/
  border-radius: 0.4em; /\* 4px \*/

  box-shadow: 0 0.1em 0.2em rgb(0 0 0 / 45%); /\* 0 1px 2px \*/

  background: #f0f0f0;
  background: linear-gradient(0deg, #e3e3e3, #fcfcfc 50%, #f0f0f0);
}

.select .value {
  display: inline-block;
  width: 100%;
  overflow: hidden;

  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: top;
}

.select::after {
  content: "▼";
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 2em; /\* 20px \*/
  top: 0;
  right: 0;

  padding-top: 0.1em;

  box-sizing: border-box;

  text-align: center;

  border-left: 0.2em solid #000;
  border-radius: 0 0.1em 0.1em 0;

  background-color: #000;
  color: #fff;
}

.select .optList {
  z-index: 2;

  list-style: none;
  margin: 0;
  padding: 0;

  background: #f0f0f0;
  border: 0.2em solid #000;
  border-top-width: 0.1em;
  border-radius: 0 0 0.4em 0.4em;

  box-shadow: 0 0.2em 0.4em rgb(0 0 0 / 40%);

  box-sizing: border-box;

  min-width: 100%;
  max-height: 10em; /\* 100px \*/
  overflow-y: auto;
  overflow-x: hidden;
}

.select .option {
  padding: 0.2em 0.3em;
}

.select .highlight {
  background: #000;
  color: #ffffff;
}
```

### Result for active state

Open state
----------

### HTML

```html
<div class="select active">
  <span class="value">Cherry</span>
  <ul class="optList">
    <li class="option highlight">Cherry</li>
    <li class="option">Lemon</li>
    <li class="option">Banana</li>
    <li class="option">Strawberry</li>
    <li class="option">Apple</li>
  </ul>
</div>
```

### CSS

```css
/\* --------------- \*/
/\* Required Styles \*/
/\* --------------- \*/

.select {
  position: relative;
  display: inline-block;
}

.select.active,
.select:focus {
  box-shadow: 0 0 3px 1px #227755;
  outline-color: transparent;
}

.select .optList {
  position: absolute;
  top: 100%;
  left: 0;
}

.select .optList.hidden {
  max-height: 0;
  visibility: hidden;
}

/\* ------------ \*/
/\* Fancy Styles \*/
/\* ------------ \*/

.select {
  font-size: 0.625em; /\* 10px \*/
  font-family: Verdana, Arial, sans-serif;

  box-sizing: border-box;

  padding: 0.1em 2.5em 0.2em 0.5em; /\* 1px 25px 2px 5px \*/
  width: 10em; /\* 100px \*/

  border: 0.2em solid #000; /\* 2px \*/
  border-radius: 0.4em; /\* 4px \*/

  box-shadow: 0 0.1em 0.2em rgb(0 0 0 / 45%); /\* 0 1px 2px \*/

  background: #f0f0f0;
  background: linear-gradient(0deg, #e3e3e3, #fcfcfc 50%, #f0f0f0);
}

.select .value {
  display: inline-block;
  width: 100%;
  overflow: hidden;

  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: top;
}

.select::after {
  content: "▼";
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 2em; /\* 20px \*/
  top: 0;
  right: 0;

  padding-top: 0.1em;

  box-sizing: border-box;

  text-align: center;

  border-left: 0.2em solid #000;
  border-radius: 0 0.1em 0.1em 0;

  background-color: #000;
  color: #fff;
}

.select .optList {
  z-index: 2;

  list-style: none;
  margin: 0;
  padding: 0;

  background: #f0f0f0;
  border: 0.2em solid #000;
  border-top-width: 0.1em;
  border-radius: 0 0 0.4em 0.4em;

  box-shadow: 0 0.2em 0.4em rgb(0 0 0 / 40%);

  box-sizing: border-box;

  min-width: 100%;
  max-height: 10em; /\* 100px \*/
  overflow-y: auto;
  overflow-x: hidden;
}

.select .option {
  padding: 0.2em 0.3em;
}

.select .highlight {
  background: #000;
  color: #fff;
}
```

### Result for open state


Example 5 - Learn web development

Example 5
=========

This is the last example that explain how to build custom form widgets.

Change states
-------------

### HTML

```html
<form class="no-widget">
  <select name="myFruit">
    <option>Cherry</option>
    <option>Lemon</option>
    <option>Banana</option>
    <option>Strawberry</option>
    <option>Apple</option>
  </select>

  <div class="select" role="listbox">
    <span class="value">Cherry</span>
    <ul class="optList hidden" role="presentation">
      <li class="option" role="option" aria-selected="true">Cherry</li>
      <li class="option" role="option">Lemon</li>
      <li class="option" role="option">Banana</li>
      <li class="option" role="option">Strawberry</li>
      <li class="option" role="option">Apple</li>
    </ul>
  </div>
</form>
```

### CSS

```css
.widget select,
.no-widget .select {
  position: absolute;
  left: -5000em;
  height: 0;
  overflow: hidden;
}

/\* --------------- \*/
/\* Required Styles \*/
/\* --------------- \*/

.select {
  position: relative;
  display: inline-block;
}

.select.active,
.select:focus {
  box-shadow: 0 0 3px 1px #227755;
  outline-color: transparent;
}

.select .optList {
  position: absolute;
  top: 100%;
  left: 0;
}

.select .optList.hidden {
  max-height: 0;
  visibility: hidden;
}

/\* ------------ \*/
/\* Fancy Styles \*/
/\* ------------ \*/

.select {
  font-size: 0.625em; /\* 10px \*/
  font-family: Verdana, Arial, sans-serif;

  box-sizing: border-box;

  padding: 0.1em 2.5em 0.2em 0.5em; /\* 1px 25px 2px 5px \*/
  width: 10em; /\* 100px \*/

  border: 0.2em solid #000; /\* 2px \*/
  border-radius: 0.4em; /\* 4px \*/

  box-shadow: 0 0.1em 0.2em rgb(0 0 0 / 45%); /\* 0 1px 2px \*/

  background: #f0f0f0;
  background: linear-gradient(0deg, #e3e3e3, #fcfcfc 50%, #f0f0f0);
}

.select .value {
  display: inline-block;
  width: 100%;
  overflow: hidden;

  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: top;
}

.select::after {
  content: "▼";
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 2em; /\* 20px \*/
  top: 0;
  right: 0;

  padding-top: 0.1em;

  box-sizing: border-box;

  text-align: center;

  border-left: 0.2em solid #000;
  border-radius: 0 0.1em 0.1em 0;

  background-color: #000;
  color: #fff;
}

.select .optList {
  z-index: 2;

  list-style: none;
  margin: 0;
  padding: 0;

  background: #f0f0f0;
  border: 0.2em solid #000;
  border-top-width: 0.1em;
  border-radius: 0 0 0.4em 0.4em;

  box-shadow: 0 0.2em 0.4em rgb(0 0 0 / 40%);

  box-sizing: border-box;

  min-width: 100%;
  max-height: 10em; /\* 100px \*/
  overflow-y: auto;
  overflow-x: hidden;
}

.select .option {
  padding: 0.2em 0.3em;
}

.select .highlight {
  background: #000;
  color: #ffffff;
}
```

### JavaScript

```js
// -------------------- //
// Function definitions //
// -------------------- //

function deactivateSelect(select) {
  if (!select.classList.contains("active")) return;

  const optList = select.querySelector(".optList");

  optList.classList.add("hidden");
  select.classList.remove("active");
}

function activeSelect(select, selectList) {
  if (select.classList.contains("active")) return;

  selectList.forEach(deactivateSelect);
  select.classList.add("active");
}

function toggleOptList(select, show) {
  const optList = select.querySelector(".optList");

  optList.classList.toggle("hidden");
}

function highlightOption(select, option) {
  const optionList = select.querySelectorAll(".option");

  optionList.forEach((other) => {
    other.classList.remove("highlight");
  });

  option.classList.add("highlight");
}

function updateValue(select, index) {
  const nativeWidget = select.previousElementSibling;
  const value = select.querySelector(".value");
  const optionList = select.querySelectorAll(".option");

  optionList.forEach((other) => {
    other.setAttribute("aria-selected", "false");
  });

  optionList[index].setAttribute("aria-selected", "true");

  nativeWidget.selectedIndex = index;
  value.innerHTML = optionList[index].innerHTML;
  highlightOption(select, optionList[index]);
}

function getIndex(select) {
  const nativeWidget = select.previousElementSibling;

  return nativeWidget.selectedIndex;
}

// ------------- //
// Event binding //
// ------------- //

window.addEventListener("load", () => {
  const form = document.querySelector("form");

  form.classList.remove("no-widget");
  form.classList.add("widget");
});

window.addEventListener("load", () => {
  const selectList = document.querySelectorAll(".select");

  selectList.forEach((select) => {
    const optionList = select.querySelectorAll(".option");
    const selectedIndex = getIndex(select);

    select.tabIndex = 0;
    select.previousElementSibling.tabIndex = -1;

    updateValue(select, selectedIndex);

    optionList.forEach((option, index) => {
      option.addEventListener("mouseover", () => {
        highlightOption(select, option);
      });

      option.addEventListener("click", (event) => {
        updateValue(select, index);
      });
    });

    select.addEventListener("click", (event) => {
      toggleOptList(select);
    });

    select.addEventListener("focus", (event) => {
      activeSelect(select, selectList);
    });

    select.addEventListener("blur", (event) => {
      deactivateSelect(select);
    });

    select.addEventListener("keyup", (event) => {
      let index = getIndex(select);

      if (event.key === "Escape") {
        deactivateSelect(select);
      }
      if (event.key === "ArrowDown" && index < optionList.length - 1) {
        index++;
      }
      if (event.key === "ArrowUp" && index > 0) {
        index--;
      }

      updateValue(select, index);
    });
  });
});
```

### Result


Tools for game development - Game development

Tools for game development
==========================

On this page, you can find links to our game development tools articles, which eventually aim to cover frameworks, compilers, and debugging tools.

asm.js

asm.js is a very limited subset of the JavaScript language, which can be significantly optimized and run in an ahead-of-time (AOT) compiling engine for much faster performance than your typical JavaScript performance. This is, of course, great for games.

Emscripten

An LLVM to JavaScript compiler; with Emscripten, you can compile C++ and other languages that can compile to LLVM bytecode into high-performance JavaScript. This is an excellent tool for porting applications to the Web! There is a useful Emscripten tutorial available on the wiki.

Firefox Profiler

The Firefox Profiler lets you profile your code to help figure out where your performance issues are so that you can make your game run at top speed.

Toolchain for developing and debugging games

How does this differ from normal web app debugging? What specialist tools are available? A lot of this is going to be covered by Will in tools, but here we should provide a kind of practical toolchain tutorial for debugging games, with links to Will's stuff:

* Basic tools overview
* Shader editor
* Performance tools (still in production, estimated early 2014)


Publishing games - Game development

Publishing games
================

HTML games have a huge advantage over native in terms of publishing and distribution — you have the freedom of distribution, promotion and monetization of your game on the Web, rather than each version being locked into a single store controlled by one company. You can benefit from the web being truly multiplatform. This series of articles looks at the options you have when you want to publish and distribute your game, and earn something out of it while you wait for it to become famous.

Game distribution
-----------------

So you've followed a tutorial or two and created an HTML game — that's great! Game distribution provides all you need to know about the ways you can distribute your newly created game into the wild — including hosting it yourself online, submitting it to open marketplaces, and submitting it to closed ones like Google Play or the iOS App Store.

Game promotion
--------------

Developing and finishing the game is not enough. You have to let the world know that you have made something interesting available, which people will enjoy playing. There are many Game promotion techniques — many of them free — so even if you're struggling to make a living as an indie dev with zero budget you can still do a lot to let people know about your great new game. Promoting the game helps a lot in monetizing it later on too, so it's important to do it effectively.

Game monetization
-----------------

When you spend your time building, publishing and promoting your game, you will at some point consider earning money out of it. Game monetization is essential to anyone who considers their game development work a serious endeavour on the path to becoming an independent game developer able to make a living, so read on and see what your options are. The technology is mature enough; it's just a matter of choosing the right approach.


Introduction to game development for the Web - Game development

Introduction to game development for the Web
============================================

The modern web has quickly become a viable platform not only for creating stunning, high quality games, but also for distributing those games.

The range of games that can be created is on par with desktop and native OS counterparts. With modern Web technologies and a recent browser, it's entirely possible to make stunning, top-notch games for the Web. And we're not talking about simple card games or multiplayer social games that have in the olden days been done using Flash®. We're talking about 3D action shooters, RPGs, and more. Thanks to massive performance improvements in JavaScript just-in-time compiler technology and new APIs, you can build games that run in the browser (or on HTML5-powered devices) without making compromises.

The HTML game platform
----------------------

You can truly think of the Web as a better target platform for your game. As we like to say, "the Web is the platform." Let's take a look at the core of the Web platform:

| Function | Technology |
| --- | --- |
| **Audio** | Web Audio API |
| **Graphics** | WebGL (OpenGL ES
 2.0)
  |
| **Input** | Touch events,
 Gamepad API, device sensors, WebRTC,
 Full Screen API,
 Pointer Lock API |
| **Language** | JavaScript (or C/C++ using
 Emscripten to
 compile to JavaScript)
  |
| **Networking** | WebRTC and/or
 WebSockets |
| **Storage** | IndexedDB or the "cloud" |
| **Web** | HTML,
 CSS,
 SVG (and much more!)
  |

The business case
-----------------

As a game developer, whether you're an individual or a large game studio, you want to know why it makes sense to target the Web with your next game project. Let's look at how the Web can help you.

1. The reach of the Web is enormous; it's everywhere. Games built with HTML work on smartphones, tablets, PCs and Smart TVs.
2. Marketing and discoverability are improved. You're not limited to promoting your app on someone else's app store. Instead, you can advertise and promote your game all over the Web as well as other media, taking advantage of the Web's inherent linkability and shareability to reach new customers.
3. You have control where it matters: Payments. You don't have to hand over 30% of your revenues to someone else just because your game is in their ecosystem. Instead, charge what you want and use whatever payment processing service you like.
4. Again with more control, you can update your game whenever you want. No waiting breathlessly for approval while someone hidden within another company decides whether your critical bug fix will ship today or tomorrow.
5. Control your analytics! Instead of relying on someone else to make all the decisions about what analytics you need, you can collect your own — or choose the third party that you like the best — to gather information about your sales and your game's reach.
6. You get to manage your customer relationship more closely, in your own way. No more having customer feedback filtered through an app store's limited mechanisms. Engage with your customers the way you want to, without a middleman.
7. Your players can play your game anywhere, anytime. Because the Web is ubiquitous, your customers can check their game's status on their phones, tablets, their home laptops, their work desktops, or anything else.
Web technologies for game developers
------------------------------------

For the tech folks, let's dig into the APIs the Web brings to the table that cater to game developers. Here's a thorough list to give you a taste of what the Web can do for you:

Fetch API

Send and receive any kind of data you want from a Web server like downloading new game levels and artwork to transmitting non-real-time game status information back and forth.

Full Screen API

This simple API lets your game take over the entire screen, thereby immersing the player in action.

Gamepad API

If you want your users to be able to use gamepads or other game controllers to work your game, you'll need this API.

HTML and CSS

Together, these two technologies let you build, style, and lay out your game's user interface. Part of HTML is the `<canvas>` element, which provides one way to do 2D graphics.

HTML audio

The `<audio>` element lets you easily play simple sound effects and music. If your needs are more involved, check out the Web Audio API for real audio processing power!

IndexedDB

A powerful data storage API for maintaining user data on their own computer or device. A great way to save game state and other information locally so it doesn't have to be downloaded every time it's needed. Also useful to help make your game playable even when the user isn't connected to the Web (such as when they're stuck on an airplane for hours on end).

JavaScript

JavaScript, the programming language used on the Web, is blazing fast in modern browsers and getting faster all the time. Use its power to write the code for your game, or look at using technologies like Emscripten or Asm.js to easily port your existing games.

Pointer Lock API

The Pointer Lock API lets you lock the mouse or other pointing device within your game's interface so that instead of absolute cursor positioning you receive coordinate deltas that give you more precise measurements of what the user is doing, and prevent the user from accidentally sending their input somewhere else, thereby missing important action.

SVG (Scalable Vector Graphics)

Lets you build vector graphics that scale smoothly regardless of the size or resolution of the user's display.

Typed Arrays

JavaScript typed arrays give you access to raw binary data from within JavaScript; this lets you manipulate GL textures, game data, or anything else, even if it's not in a native JavaScript format.

Web Audio API

This API for controlling the playback, synthesis, and manipulation of audio from JavaScript code lets you create awesome sound effects as well as play and manipulate music in real time.

WebGL

Lets you create high-performance, hardware-accelerated 3D (and 2D) graphics from Web content. This is a Web-supported implementation of OpenGL ES 2.0.

WebRTC

The WebRTC (Real-Time Communications) API gives you the power to control audio and video data, including teleconferencing and transmitting other application data back and forth between two users. Want your players to be able to talk to each other while blowing up monsters? This is the API for you.

WebSockets

The WebSocket API lets you connect your app or site to a server to transmit data back and forth in real-time. Perfect for multiplayer gaming action, chat services, and so forth.

Web Workers

Workers give you the ability to spawn background threads running their own JavaScript code, to take advantage of modern, multicore processors.


Anatomy of a video game - Game development

Anatomy of a video game
=======================

This article looks at the anatomy and workflow of the average video game from a technical point of view, in terms of how the main loop should run. It helps beginners to modern game development understand what is required when building a game and how web standards like JavaScript lend themselves as tools. Experienced game programmers who are new to web development could also benefit, too.

Present, accept, interpret, calculate, repeat
---------------------------------------------

The goal of every video game is to **present** the user(s) with a situation, **accept** their input, **interpret** those signals into actions, and **calculate** a new situation resulting from those acts. Games are constantly looping through these stages, over and over, until some end condition occurs (such as winning, losing, or exiting to go to bed). Not surprisingly, this pattern corresponds to how a game engine is programmed.

The specifics depend on the game.

Some games drive this cycle by user input. Imagine that you are developing a *"find the differences between these two similar pictures"*-type game. These games **present** two images to the user; they **accept** their click (or touch); they **interpret** the input as a success, failure, pause, menu interaction, etc.; finally, they **calculate** an updated scene resulting from that input. The game loop is advanced by the user's input and sleeps until they provide it. This is more of a turn-based approach that doesn't demand a constant update every frame, only when the player reacts.

Other games demand control over each of the smallest possible individual timeslices. The same principles as above apply with a slight twist: each frame of animation progresses the cycle and any change in user input is caught at the first available turn. This once-per-frame model is implemented in something called a **main loop**. If your game loops based on time then this will be its authority that your simulations will adhere to.

But it might not need per-frame control. Your game loop might be similar to the *find the differences* example and base itself on input events. It might require both input and simulated time. It might even loop based on something else entirely.

Modern JavaScript — as described in the next sections — thankfully makes it easy to develop an efficient, execute-once-per-frame main loop. Of course, your game will only be as optimized as you make it. If something looks like it should be attached to a more infrequent event then it is often a good idea to break it out of the main loop (but not always).

Building a main loop in JavaScript
----------------------------------

JavaScript works best with events and callback functions. Modern browsers strive to call methods right as they are needed and idle (or do their other tasks) in the gaps. It is an excellent idea to attach your code to the moments that are appropriate for them. Think about whether your function really needs to be called on a strict interval of time, every frame, or only after something else happens. Being more specific with the browser about when your function needs to be called allows the browser to optimize when it is called. Also, it will probably make your job easier.

Some code needs to be run frame-by-frame so why attach that function to anything other than the browser's redraw schedule? On the Web, `window.requestAnimationFrame()` will be the foundation of most well-programmed per-frame main loops. A callback function must be passed in to it when it is called. That callback function will be executed at a suitable time before the next repaint. Here is an example of a simple main loop:

```js
window.main = () => {
  window.requestAnimationFrame(main);

  // Whatever your main loop needs to do
};

main(); // Start the cycle
```

**Note:** In each of the `main()` methods discussed here, we schedule a new `requestAnimationFrame` before performing our loop contents. That is not by accident and it is considered best practice. Calling the next `requestAnimationFrame` early ensures the browser receives it on time to plan accordingly even if your current frame misses its VSync window.

The above chunk of code has two statements. The first statement creates a function as a global variable called `main()`. This function does some work and also tells the browser to call itself next frame with `window.requestAnimationFrame()`. The second statement calls the `main()` function, defined in the first statement. Because `main()` is called once in the second statement and every call of it places itself in the queue of things to do next frame, `main()` is synchronized to your frame rate.

Of course this loop is not perfect. Before we discuss ways to change it, let us discuss what it already does well.

Timing the main loop to when the browser paints to the display allows you to run your loop as frequently as the browser wants to paint. You are given control over each frame of animation. It is also very simple because `main()` is the only function getting looped. A First-Person Shooter (or a similar game) presents a new scene once every frame. You cannot really get more smooth and responsive than that.

But do not immediately assume animations require frame-by-frame control. Simple animations can be easily performed, even GPU-accelerated, with CSS animations and other tools included in the browser. There are a lot of them and they will make your life easier.

Building a better main loop in JavaScript
-----------------------------------------

There are two obvious issues with our previous main loop: `main()` pollutes the `window` object (where all global variables are stored) and the example code did not leave us with a way to *stop* the loop unless the whole tab is closed or refreshed. For the first issue, if you want the main loop to just run and you do not need easy (direct) access to it, you could create it as an Immediately-Invoked Function Expression (IIFE).

```js
/\*
 \* Starting with the semicolon is in case whatever line of code above this example
 \* relied on automatic semicolon insertion (ASI). The browser could accidentally
 \* think this whole example continues from the previous line. The leading semicolon
 \* marks the beginning of our new line if the previous one was not empty or terminated.
 \*/

;(() => {
  function main() {
    window.requestAnimationFrame(main);

    // Your main loop contents
  }

  main(); // Start the cycle
})();
```

When the browser comes across this IIFE, it will define your main loop and immediately queue it for the next frame. It will not be attached to any object and `main` (or `main()` for methods) will be a valid unused name in the rest of the application, free to be defined as something else.

**Note:** In practice, it is more common to prevent the next `requestAnimationFrame()` with an if-statement, rather than calling `cancelAnimationFrame()`.

For the second issue, stopping the main loop, you will need to cancel the call to `main()` with `window.cancelAnimationFrame()`. You will need to pass `cancelAnimationFrame()` the ID token given by `requestAnimationFrame()` when it was last called. Let us assume that your game's functions and variables are built on a namespace that you called `MyGame`. Expanding our last example, the main loop would now look like:

```js
/\*
 \* Starting with the semicolon is in case whatever line of code above this example
 \* relied on automatic semicolon insertion (ASI). The browser could accidentally
 \* think this whole example continues from the previous line. The leading semicolon
 \* marks the beginning of our new line if the previous one was not empty or terminated.
 \*
 \* Let us also assume that MyGame is previously defined.
 \*/

;(() => {
  function main() {
    MyGame.stopMain = window.requestAnimationFrame(main);

    // Your main loop contents
  }

  main(); // Start the cycle
})();
```

We now have a variable declared in our `MyGame` namespace, which we call `stopMain`, that contains the ID returned from our main loop's most recent call to `requestAnimationFrame()`. At any point, we can stop the main loop by telling the browser to cancel the request that corresponds to our token.

```js
window.cancelAnimationFrame(MyGame.stopMain);
```

The key to programming a main loop, in JavaScript, is to attach it to whatever event should be driving your action and pay attention to how the different systems involved interplay. You may have multiple components driven by multiple different types of events. This feels like unnecessary complexity but it might just be good optimization (not necessarily, of course). The problem is that you are not programming a typical main loop. In JavaScript, you are using the browser's main loop and you are trying to do so effectively.

Building a more optimized main loop in JavaScript
-------------------------------------------------

Ultimately, in JavaScript, the browser is running its own main loop and your code exists in some of its stages. The above sections describe main loops which try not to wrestle away control from the browser. These main methods attach themselves to `window.requestAnimationFrame()`, which asks the browser for control over the upcoming frame. It is up to the browser how to relate these requests to their main loop. The W3C spec for requestAnimationFrame does not really define exactly when the browsers must perform the requestAnimationFrame callbacks. This can be a benefit because it leaves browser vendors free to experiment with the solutions that they feel are best and tweak it over time.

Modern versions of Firefox and Google Chrome (and probably others) *attempt* to connect `requestAnimationFrame` callbacks to their main thread at the very beginning of a frame's timeslice. The browser's main thread thus *tries* to look like the following:

1. Start a new frame (while the previous frame is handled by the display).
2. Go through the list of `requestAnimationFrame` callbacks and invoke them.
3. Perform garbage collection and other per-frame tasks when the above callbacks stop controlling the main thread.
4. Sleep (unless an event interrupts the browser's nap) until the monitor is ready for your image (VSync) and repeat.

You can think about developing realtime applications as having a budget of time to do work. All of the above steps must take place every 16-and-a-half milliseconds to keep up with a 60 Hz display. Browsers invoke your code as early as possible to give it maximum computation time. Your main thread will often start workloads that are not even on the main thread (such as rasterization or shaders in WebGL). Long calculations can be performed on a Web Worker or a GPU at the same time as the browser uses its main thread to manage garbage collection, its other tasks, or handle asynchronous events.

While we are on the topic of budgeting time, many web browsers have a tool called *High Resolution Time*. The `Date` object is no longer the recognized method for timing events because it is very imprecise and can be modified by the system clock. High Resolution Time, on the other hand, counts the number of milliseconds since `navigationStart` (when the previous document is unloaded). This value is returned as a decimal number accurate to a thousandth of a millisecond. It is known as a `DOMHighResTimeStamp` but, for all intents and purposes, consider it a floating point number.

**Note:** Systems (hardware or software) that are not capable of microsecond accuracy are allowed to provide millisecond accuracy as a minimum. They should provide 0.001ms accuracy if they are capable of it, however.

This value is not too useful alone, since it is relative to a fairly uninteresting event, but it can be subtracted from another timestamp to accurately and precisely determine how much time elapsed between those two points. To acquire one of these timestamps, you can call `window.performance.now()` and store the result as a variable.

```js
const tNow = window.performance.now();
```

Back to the topic of the main loop. You will often want to know when your main function was invoked. Because this is common, `window.requestAnimationFrame()` always provides a `DOMHighResTimeStamp` to callbacks as an argument when they are executed. This leads to another enhancement to our previous main loops.

```js
/\*
 \* Starting with the semicolon is in case whatever line of code above this example
 \* relied on automatic semicolon insertion (ASI). The browser could accidentally
 \* think this whole example continues from the previous line. The leading semicolon
 \* marks the beginning of our new line if the previous one was not empty or terminated.
 \*
 \* Let us also assume that MyGame is previously defined.
 \*/

;(() => {
  function main(tFrame) {
    MyGame.stopMain = window.requestAnimationFrame(main);

    // Your main loop contents
    // tFrame, from "function main(tFrame)", is now a DOMHighResTimeStamp provided by rAF.
  }

  main(); // Start the cycle
})();
```

Several other optimizations are possible and it really depends on what your game attempts to accomplish. Your game genre will obviously make a difference but it could even be more subtle than that. You could draw every pixel individually on a canvas or you could layer DOM elements (including multiple WebGL canvases with transparent backgrounds if you want) into a complex hierarchy. Each of these paths will lead to different opportunities and constraints.

It is decision… time
--------------------

You will need to make hard decisions about your main loop: how to simulate the accurate progress of time. If you demand per-frame control then you will need to determine how frequently your game will update and draw. You might even want update and draw to occur at different rates. You will also need to consider how gracefully your game will fail if the user's system cannot keep up with the workload. Let us start by assuming that you will handle user input and update the game state every time you draw. We will branch out later.

**Note:** Changing how your main loop deals with time is a debugging nightmare, everywhere. Think about your needs carefully before working on your main loop.

### What most browser games should look like

If your game can hit the maximum refresh rate of any hardware you support then your job is fairly easy. You can update, render, and then do nothing until VSync.

```js
/\*
 \* Starting with the semicolon is in case whatever line of code above this example
 \* relied on automatic semicolon insertion (ASI). The browser could accidentally
 \* think this whole example continues from the previous line. The leading semicolon
 \* marks the beginning of our new line if the previous one was not empty or terminated.
 \*
 \* Let us also assume that MyGame is previously defined.
 \*/

;(() => {
  function main(tFrame) {
    MyGame.stopMain = window.requestAnimationFrame(main);

    update(tFrame); // Call your update method. In our case, we give it rAF's timestamp.
    render();
  }

  main(); // Start the cycle
})();
```

If the maximum refresh rate cannot be reached, quality settings could be adjusted to stay under your time budget. The most famous example of this concept is the game from id Software, RAGE. This game removed control from the user in order to keep its calculation time at roughly 16ms (or roughly 60fps). If computation took too long then rendered resolution would decrease, textures and other assets would fail to load or draw, and so forth. This (non-web) case study made a few assumptions and tradeoffs:

* Each frame of animation accounts for user input.
* No frame needs to be extrapolated (guessed) because each draw has its own update.
* Simulation systems can basically assume that each full update is ~16ms apart.
* Giving the user control over quality settings would be a nightmare.
* Different monitors input at different rates: 30 FPS, 75 FPS, 100 FPS, 120 FPS, 144 FPS, etc.
* Systems that are unable to keep up with 60 FPS lose visual quality to keep the game running at optimal speed (eventually it outright fails, if quality becomes too low.)
### Other ways to handle variable refresh rate needs

Other methods of tackling the problem exist.

One common technique is to update the simulation at a constant frequency and then draw as much (or as little) of the actual frames as possible. The update method can continue looping without care about what the user sees. The draw method can view the last update and when it happened. Since draw knows when it represents, and the simulation time for the last update, it can predict a plausible frame to draw for the user. It does not matter whether this is more frequent than the official update loop (or even less frequent). The update method sets checkpoints and, as frequently as the system allows, the render method draws instants of time around them. There are many ways to separate the update method in web standards:

* Draw on `requestAnimationFrame` and update on a `setInterval()` or `setTimeout()`.
    + This uses processor time even when unfocused or minimized, hogs the main thread, and is probably an artifact of traditional game loops (but it is simple.)
* Draw on `requestAnimationFrame` and update on a `setInterval` or `setTimeout` in a Web Worker.
    + This is the same as above, except update does not hog the main thread (nor does the main thread hog it). This is a more complex solution, and might be too much overhead for simple updates.
* Draw on `requestAnimationFrame` and use it to poke a Web Worker containing the update method with the number of ticks to compute, if any.
    + This sleeps until `requestAnimationFrame` is called and does not pollute the main thread, plus you are not relying on old-fashioned methods. Again, this is a bit more complex than the previous two options, and *starting* each update will be blocked until the browser decides to fire rAF callbacks.

Each of these methods have similar tradeoffs:

* Users can skip rendering frames or interpolate extra ones depending on their performance.
* You can count on all users updating non-cosmetic variables at the same constant frequency minus hiccups.
* Much more complicated to program than the basic loops we saw earlier.
* User input is completely ignored until the next update (even if the user has a fast device).
* The mandatory interpolation has a performance penalty.

A separate update and draw method could look like the following example. For the sake of demonstration, the example is based on the third bullet point, just without using Web Workers for readability (and, let's be honest, writability).

**Warning:** This example, specifically, is in need of technical review.

```js
/\*
 \* Starting with the semicolon is in case whatever line of code above this example
 \* relied on automatic semicolon insertion (ASI). The browser could accidentally
 \* think this whole example continues from the previous line. The leading semicolon
 \* marks the beginning of our new line if the previous one was not empty or terminated.
 \*
 \* Let us also assume that MyGame is previously defined.
 \*
 \* MyGame.lastRender keeps track of the last provided requestAnimationFrame timestamp.
 \* MyGame.lastTick keeps track of the last update time. Always increments by tickLength.
 \* MyGame.tickLength is how frequently the game state updates. It is 20 Hz (50ms) here.
 \*
 \* timeSinceTick is the time between requestAnimationFrame callback and last update.
 \* numTicks is how many updates should have happened between these two rendered frames.
 \*
 \* render() is passed tFrame because it is assumed that the render method will calculate
 \* how long it has been since the most recently passed update tick for
 \* extrapolation (purely cosmetic for fast devices). It draws the scene.
 \*
 \* update() calculates the game state as of a given point in time. It should always
 \* increment by tickLength. It is the authority for game state. It is passed
 \* the DOMHighResTimeStamp for the time it represents (which, again, is always
 \* last update + MyGame.tickLength unless a pause feature is added, etc.)
 \*
 \* setInitialState() Performs whatever tasks are leftover before the main loop must run.
 \* It is just a generic example function that you might have added.
 \*/

;(() => {
  function main(tFrame) {
    MyGame.stopMain = window.requestAnimationFrame(main);
    const nextTick = MyGame.lastTick + MyGame.tickLength;
    let numTicks = 0;

    // If tFrame < nextTick then 0 ticks need to be updated (0 is default for numTicks).
    // If tFrame = nextTick then 1 tick needs to be updated (and so forth).
    // Note: As we mention in summary, you should keep track of how large numTicks is.
    // If it is large, then either your game was asleep, or the machine cannot keep up.
    if (tFrame > nextTick) {
      const timeSinceTick = tFrame - MyGame.lastTick;
      numTicks = Math.floor(timeSinceTick / MyGame.tickLength);
    }

    queueUpdates(numTicks);
    render(tFrame);
    MyGame.lastRender = tFrame;
  }

  function queueUpdates(numTicks) {
    for (let i = 0; i < numTicks; i++) {
      MyGame.lastTick += MyGame.tickLength; // Now lastTick is this tick.
      update(MyGame.lastTick);
    }
  }

  MyGame.lastTick = performance.now();
  MyGame.lastRender = MyGame.lastTick; // Pretend the first draw was on first update.
  MyGame.tickLength = 50; // This sets your simulation to run at 20Hz (50ms)

  setInitialState();
  main(performance.now()); // Start the cycle
})();
```

Another alternative is to do certain things less often. If a portion of your update loop is difficult to compute but insensitive to time, you might consider scaling back its frequency and, ideally, spreading it out into chunks throughout that lengthened period. An implicit example of this was found over at The Artillery Blog for Artillery Games, where they adjust their rate of garbage generation to optimize garbage collection. Obviously, cleaning up resources is not time sensitive (especially if tidying is more disruptive than the garbage itself).

This may also apply to some of your own tasks. Those are good candidates to throttle when available resources become a concern.

Summary
-------

I want to be clear that any of the above, or none of them, could be best for your game. The correct decision entirely depends on the trade-offs that you are willing (and unwilling) to make. The concern is mostly with switching to another option. Fortunately, I do not have any experience with this, but I have heard it is an excruciating game of Whack-a-Mole.

An important thing to remember for managed platforms, like the web, is that your loop may stop execution for significant periods of time. This could occur when the user unselects your tab and the browser sleeps (or slows) its `requestAnimationFrame` callback interval. You have many ways to deal with this situation and this could depend on whether your game is single player or multiplayer. Some choices are:

* Consider the gap "a pause" and skip the time.
    + You can probably see how this is problematic for most multiplayer games.
* You can simulate the gap to catch up.
    + This can be a problem for long drops and/or complex updates.
* You can recover the game state from a peer or the server.
    + This is ineffective if your peers or server are out-of-date too, or they don't exist because the game is single player and doesn't have a server.

Once your main loop has been developed and you have decided on a set of assumptions and tradeoffs which suit your game, it is now just a matter of using your decisions to calculate any applicable physics, AI, sounds, network synchronization, and whatever else your game may require.


Introduction to HTML Game Development - Game development

Introduction to HTML Game Development
=====================================

Advantages
----------

1. Games built with HTML work on smartphones, tablets, PCs and Smart TVs.
2. Advertise and promote your game all over the Web as well as other media.
3. Payments. Charge what you want and use whatever payment processing service you like.
4. Update your game whenever you want.
5. Collect your own analytics!
6. Connect with your customers more closely,
7. Players can play the game anywhere, anytime.
Web Technologies
----------------

Web technologies in game development and their function| **Function** | **Technology** |
| --- | --- |
| **Audio** | Web Audio API |
| **Graphics** | WebGL (OpenGL ES
 2.0)
  |
| **Input** | Touch events,
 Gamepad API, device sensors, WebRTC,
 Full Screen API,
 Pointer Lock API |
| **Language** | JavaScript (or C/C++ using
 Emscripten to
 compile to JavaScript)
  |
| **Networking** | WebRTC and/or
 WebSockets |
| **Storage** | IndexedDB or the "cloud" |
| **Web** | HTML,
 CSS,
 SVG (and much more!)
  |

Fetch API

Send and receive any kind of data you want from a Web server like downloading new game levels and artwork to transmitting non-real-time game status information back and forth.

Full Screen API

Full screen gameplay.

Gamepad API

Use gamepads or other game controllers.

HTML and CSS

Build, style, and lay out your game's user interface.

HTML audio

Easily play simple sound effects and music.

IndexedDB

Store user data on their own computer or device.

JavaScript

 Fast web programming language to write the code for your game.
 To easily port your existing games Emscripten or Asm.js

Pointer Lock API

Lock the mouse or other pointing device within your game's interface.

SVG (Scalable Vector Graphics)

Build vector graphics that scale smoothly regardless of the size or resolution of the user's display.

Typed Arrays

Access raw binary data from within JavaScript; Manipulate GL textures, game data, or anything else.

Web Audio API

Control the playback, synthesis, and manipulation of audio in real time.

WebGL

Create high-performance, hardware-accelerated 3D (and 2D) graphics. OpenGL ES 2.0.

WebRTC

Real-Time Communications to control audio and video data, including teleconferencing and transmitting other application data back and forth between two users like chat.

WebSockets

Connect your app or site to a server to transmit data back and forth in real-time. Perfect for multiplayer gaming action, chat services, and so forth.

Web Workers

Spawn background threads running their own JavaScript code for multicore processors.


Tutorials - Game development

Tutorials
=========

This page contains multiple tutorial series that highlight different workflows for effectively creating different types of web games.

2D breakout game using pure JavaScript

In this step-by-step tutorial you'll implement a simple breakout clone using pure JavaScript. Along the way you will learn the basics of using the `<canvas>` element to implement fundamental game mechanics like rendering and moving images, collision detection, control mechanisms, and winning and losing states.

2D breakout game using Phaser

In this step-by-step tutorial you'll implement the same breakout clone as the previous tutorial series, except that this time you'll do it using the Phaser HTML game framework. This idea here is to teach some of the fundamentals (and advantages) of working with frameworks, along with fundamental game mechanics.

2D maze game with device orientation

This tutorial shows how to create a 2D maze game using HTML, incorporating fundamentals such as collision detection and sprite placement on a `<canvas>`. This is a mobile game that uses the Device Orientation and Vibration **APIs** to enhance the gameplay and is built using the Phaser framework.

2D platform game with Phaser

This tutorial series shows how to create a simple platform game using Phaser, covering fundamentals such as sprites, collisions, physics, collectables, and more.


Techniques for game development - Game development

Techniques for game development
===============================

This page lists essential core techniques for anyone wanting to develop games using open web technologies.

Using async scripts for asm.js

Especially when creating medium to large-sized games, async scripts are an essential technique to take advantage of, so that your game's JavaScript can be compiled off the main thread and be cached for future game running, resulting in a significant performance improvement for your users. This article explains how.

Optimizing startup performance

How to make sure your game starts up quickly, smoothly, and without appearing to lock up the user's browser or device.

Using WebRTC peer-to-peer data channels

In addition to providing support for audio and video communication, WebRTC lets you set up peer-to-peer data channels to exchange text or binary data actively between your players. This article explains what this can do for you, and shows how to use libraries that make this easy.

Audio for Web Games

Audio is an important part of any game — it adds feedback and atmosphere. Web-based audio is maturing fast, but there are still many browser differences to negotiate. This article provides a detailed guide to implementing audio for web games, looking at what works currently across as wide a range of platforms as possible.

2D collision detection

A concise introduction to collision detection in 2D games.

Tilemaps

Tiles are a very popular technique in 2D games for building the game world. These articles provide an introduction to tilemaps and how to implement them with the Canvas API.


Game promotion - Game development

Game promotion
==============

Developing and publishing your game is not enough. You have to let the world know that you have something interesting available that people will enjoy playing. There are many ways to promote your game — most of them being free, so even if you're struggling to make a living as an indie dev with zero budget you can still do a lot to let people know about your great new game. Promoting the game helps a lot when monetizing it later on too, so it's important to do it correctly.

Competitions
------------

Taking part in competitions will not only level up your gamedev skills and let you meet new devs to befriend and learn from — and it will also get you involved in the community. If you make a good game for a competition and win some prizes in the process your game will automatically be promoted by the organizers and other attendees. You'll be rich and famous, or so they say.

Many great games get started as a quick, sloppy demo submitted to a competition. If both the idea and the execution are good enough, you will succeed. Plus competitions generally require games to follow a mandatory theme, so you can get creative around a theme if you are stuck for ideas.

Website and blog
----------------

You should definitely create your own website containing all the information about your games, so people can see what you've worked on. The more information you can include the better — you should include screenshots, description, trailer, press kit, requirements, available platforms, support details and more. You'll get bonus points for allowing your users to directly play your games online — at least in demo form. Also, you should do some work on SEO to allow people to find your games more easily.

You should also blog about everything related to your gamedev activities. Write about your development process, nasty bugs you encounter, funny stories, lessons learned, and the ups and downs of being a game developer. Continually publishing information about your games will help educate others, increase your reputation in the community, and further improve SEO. A further option is to publish monthly reports that summarize all your progress — it helps you see what you've accomplished throughout the month and what's still left to do, and it keeps reminding people that your game is coming out soon — building buzz is always good.

While you can create your website from scratch, there are also tools that can help make the process easier. ManaKeep is a website builder made for indie game developers and provides a great starting point to create your website. Presskit() is a press kit builder that helps you create a press page to share with the media.

Social media
------------

Your social media presence is very important — hashtags can help find friends and allow you to engage with the community and help other devs in need. Honesty is key and you should be authentic, because nobody likes boring press releases or pushy advertisements. When the time comes, your community will help you spread the word about your shiny new game!

Keep an eye on gamers who stream on YouTube and Twitch, engage with Twitter circles and be active on forums such as HTML5GameDevs.com. Share your news and answer questions so that people will value what you're doing and will know that you're trustworthy. Remember to not be too pushy when it comes to telling everyone about your games — you're not a walking advertisement.

Grow your audience by talking to them, sharing tips, offering discounts, giving away prizes in competitions, or just complaining at the weather or buggy browser you have to deal with. Be generous, be yourself and be there for others, and you'll be treated with respect.

Game portals
------------

Using game portals is mostly concerned with monetization, but if you're not planning to sell licenses to allow people to purchase your game and are intending to implement adverts or in-app purchases instead, promoting your game across free portals can be effective.

There are a number of different game portals to which you can send your games for publication. Some portals have their own APIs that allow you to authorize users, save their progress and process in-app purchases. You can also sell a full version of the game from inside your browser demo version, which will be a great move considering high competition, some developers even manage to make full browser versions. Most portals offer revenue share deals or will buy nonexclusive license.

Free portals offer traffic, but only the best ones are popular enough to generate revenues from advertisements on in-app purchases. On the other hand they are a perfect tool to make games visible to a broader audience if you have no budget and limited time.

Press
-----

You can try and reach the press about your game, but bear in mind that they get a tonne of requests like this every single day, so be humble and patient if they don't answer right away, and be polite when talking to them. Be sure to check first if they are dealing with specific genres of games or platforms, so you don't send them something that is not relevant to them in the first place. If you're honest with your approach and your game is good, then you've got more of a chance of success.

If you want to learn more about the etiquette of contacting the press you should definitely check out How To Contact Press - a great guide from Pixel Prospector.

Tutorials
---------

It's good to share your knowledge with other devs — after all you probably learned a thing or two from online articles, so you take the time to pay that knowledge forward. Talking or writing about something you achieved or problems you overcame is something people would be interested it. And you can use your own game as an example, especially in a tutorial when you're showing how to do something you've implemented already. That way everyone benefits — people learn new skills, your game gets promoted, and if you're lucky you can even get paid for writing a tutorial if it's good enough.

There are portals like Tuts+ Game Development which will be more than happy if you write for them - they pay for the content, but not all topic ideas will be accepted. When writing a tutorial remember to focus on delivering something valuable to the reader. They want to learn something - offer your expertise and use your game as a case study. Focus on one aspect and try to explain it throughout and in detail. Also remember to follow up discussion in comments if people have any questions.

If portals you contact are not interested in your content because you don't have any experience yet, try writing tutorials and publish them on your own blog first. It's the easiest way to train your writing skills on your own.

Events
------

If you've gone through all the options listed above you can still find new, creative ways to promote your game — events are another good example. Attending events, both local and global, gives you the ability to meet your fans face to face, as well as other members of the development community. Value the fact that they spent their time seeing you.

### Conferences

There are many conferences where you can give a talk explaining some technical difficulties you overcame, or how you implemented specific APIs; again — use your games as examples for that. It's important to focus on the knowledge part and tone down the marketing — devs are sensitive on this matter and you may end up with an angry crowd if you just try to sell them something.

### Fairs

The other event-related option is fairs (or expos) — at such an event you can get a booth among other devs and promote your game to all the attendees passing by. If you do so, try to be unique and original, so you easily stand from the crowd. Do it the right way and everybody will be talking about you and your game. Having a booth gives you the possibility to interact with your fans directly — besides the promotion part you can also test new builds of your game on regular people and fix any bugs (or incorporate any feedback) they uncover. You can't imagine what people may come up with when playing your game, and what obvious issues you've missed while spending hours polishing it.

Promo codes
-----------

If you're selling the game, then create the ability to distribute promo codes allowing people to access your game for free (or at least a demo or time-limited version), and send them all over the place — to press, YouTubers, as competition prizes, etc. If the game reaches certain people you'll get a free advert to thousands of players. It can boost interest in your game more than anything else if you get lucky.

Fostering the community
-----------------------

You can help community grow and promote yourself and your games at the same time. Sending out weekly newsletters and organizing online competitions or local meetups will show others that you're passionate about what you do and that they can rely on you. Then when you need any help they will be there for you.

Summary
-------

Any way of promoting your game is good. You have a lot of options to chose from with most of them being free, so it's only about your enthusiasm and available time. Sometimes you have to spend more time promoting a game than actually developing it. Remember that it's no use to have the best game in the world if no one knows it exists.

Now lets get on with that monetization part, and earn something for a living.


Game monetization - Game development

Game monetization
=================

When you've spent your time building a game, distributing it and promoting it you should consider earning some money out of it. If your work is a serious endeavour on the path to becoming an independent game developer able to make a living, read on and see what your options are. The technology is mature enough; now it's just about choosing the right approach.

Paid games
----------

The first, most obvious choice that may come to your mind might be selling the games the way it is done for huge AAA titles — with a fixed, up front price. Even though the digital market is key and you don't need to print covers and put your game in a physical store in boxes, to earn decent money on selling your games for a fixed price you have to invest your time and money in marketing. Only the best games will break even or earn more than they cost to make, and you still need a lot of luck for that.

How much you charge for your game depends on the market, quality of your game and a lot of other small factors. An arcade iOS title can be sold for 0.99 USD, but a longer RPG-style desktop game on Steam can cost 20 USD; both prices are OK. You have to follow the market and do your own research — learning from your mistakes quickly is important.

In-app purchases
----------------

Instead of having people pay for your game up front, you can offer a free game with in-app purchases (IAPs.) In this case the game can be acquired without spending a dime — give the game to the players, but offer in-game currency, bonuses or benefits for real money. Specific examples can include bonus levels, better weapons or spells, or refilling the energy needed to play. Designing a good IAP system is an art of its own.

Remember that you need thousands of downloads of your game to make IAPs effective — only a small fraction of players will actually pay for IAPs. How small? It varies, but around one person in every thousand is about average. The more people that play your game, the higher the chance someone will pay, so your earnings heavily depend on your promotion activities.

### Freemium

Games that feature IAPs are often referred to a **freemium** — a freemium game can be acquired and played for free, but you can pay for extra (premium) features, virtual goods or other benefits. The word itself acquired negative connotations after big companies focused on creating games, the main purpose of which was to get as much money from the players as possible instead of delivering a fun experience. The worst cases were when you could use real money to pay for getting advantages over other players, or when they restricted access to the next stages of the game unless the players paid. The term "pay to win" was coined and this approach is disliked by many players and devs. If you want to implement IAPs try to add value to the game with something players will enjoy instead of taking it out and then charging for it.

### Add-ons and DLCs

Add-ons and downloadable content are a good way to provide extra value to an already released game, but remember that you'll have to offer decent, entertaining content to attract people to buy it. A totally new set of levels with new characters, weapons and story is a good material for DLC, but to have enough sales the game itself has to be popular, or else there won't be any players interested in spending their hard-earned money on it.

Advertisements
--------------

Instead of actively selling the games you can also try to get yourself a passive income — showing adverts and relying on previous activities related to promoting your game may benefit, but your game has to be addictive, which isn't as easy as it sounds. You still need to plan it out, and at some point you'll need a bit of luck too. If your game goes viral and people start sharing it, you can get a lot of downloads and money out of adverts.

There are many companies offering advert systems — you sign up and allow them to show adverts in exchange for a percentage of the earnings. Google AdSense is said to be the most effective one, but it's not designed for games and it's a pretty bad practice to use it for that purpose. Instead of risking of having your account closed and all the money blocked try to use the usual, gamedev targeted portals like LeadBolt. They offer easy to implement systems to show the adverts in your games and split the earnings with you.

Video ads are getting more and more popular, especially in the form of a pre-roll — they are shown at the beginning of your game while it's still loading. And on the topic of where to put the advertisements in your game it really depends on you. It should be as subtle as possible to not annoy the players too much, but visible enough to make them click it or at least take notice. Adding adverts between game sessions on game over screens is a popular approach.

Licensing
---------

There's an approach that can work as a monetization model on its own, and that's selling licenses for distribution of your game. There are more and more portals interested in showing your games on their websites. They follow various strategies to earn money via your games, but you don't have to worry about all that as selling the license is usually a one-time deal. You get the money and they can get creative with using your game to make money.

Finding publishers might be hard at first — try to look for them at the HTML5 Gamedevs forums. If you're well known they may reach out to you. Most of the deals are done through emails when talking to a dedicated person on the publisher side. Some publisher websites have that information easily available, while some others are harder to find. When reaching a publisher try to be nice and straight to the point — they are busy people.

### Exclusive licenses

The exclusive license is a type of license for one publisher — you've built a game and you're selling all the rights to it to a single entity along with the rights to redistribute it — Softgames are an example of such a publisher. You can't sell it again in any form while that publisher has the rights — that's why exclusive deals are worth quite a lot of money. How much exactly? It depends on the quality of the game, it's genre, its publisher, and many others, but usually it will be something between 2000 and 5000 USD. Once you've sold an exclusive license you can forget about promoting that particular game as you won't earn more, so go into such a deal only if you're sure it's profitable enough.

### Non-exclusive licenses

This approach is less strict — you can sell a license to multiple publishers. This is the most popular approach as with every new publisher (and they are constantly showing up) you can sell your games on non-exclusive terms. Remember that with this license the publisher can't redistribute it further — it's often called a site-locked deal as they buy the right to publish the game on their own given portal. The usual cost of a non-exclusive license is around 500 USD.

### Subscriptions

There's also an option to get a passive, monthly revenue via a subscription deal. Instead of getting a one-time payment you can get a small amount of money per game, per month — it can be something around 20-50 USD per month, per game. It's normally up to you if you want to get all the money in a lump sum or get it per month. Remember that it can be cancelled, so it's not an indefinitely working solution.

### Ad revenue

You can implement advertisements in your game on your own and try to find the traffic to earn a bit, but you can also do a revenue share deal with a publisher. They will take care of driving the traffic and will split the earnings — usually in a 70/30 or 50/50 deal, collected per month.

Remember that many new, low quality publishers will want to get your game for ad revenue instead of licensing because it will be cheaper for them and you might end up with earnings around 2 USD per game for the whole deal. Be careful when dealing with new publishers — sometimes it's better to lower the license cost for a known one rather than risking fraud with an unknown publisher for more money.

Publishers taking your games for revenue share, and/or licensing may require implementing their own APIs, which could take extra work, so consider that in your rates too.

### Branding

You can sell rights to use your game for branding, or do it yourself. In the first case it's almost like non-exclusive licensing, but the client will usually buy rights for the code and implement their own graphics. In the second case it's like a freelance deal, but you're reusing the code and adding graphics provided by the client, sometimes implementing them as they instruct you. As an example if you've got a game where a player taps items of food, you could change the food to the client's products to give them advertising. Prices in this model vary greatly depending on the brand, client, and amount of work you put in.

Other non-game focused monetization strategies
----------------------------------------------

There are other ways you can earn money when building HTML games, and it doesn't even have to be game-related.

### Selling resources

If you're a graphic designer, you can sell the assets from the games you've created, or something brand new exclusively for that purpose at online shops like Envato Market. It's not much, but if you're a known designer it can be an extra passive stream of income.

### Writing articles and tutorials

It is possible to write articles about your games and even get paid for them. Game promotion and monetization at the same time is a win-win, and if you don't abuse it with too much advertising the readers will enjoy reading them and as well as learning a thing or two. If you focus on sharing the knowledge first and use your games just as the examples it should be OK. Check out Tuts+ Game Development or similar websites for writing opportunities.

### Merchandise

You can sell t-shirts, stickers or other gadgets — some devs make more money from the merchandise than from the games themselves, but it only works on very popular and recognizable games like Angry Birds. Still, it could be another small stream of passive income. The more diversified your earnings are, the better your business stability.

### Donations

When all else fails you can try putting a donate button on your game's page and asking for support from the community. Sometimes it works, but only if the player knows you and feels that it will help you in your situation. That's why carefully managing your community is so important. It worked with the js13kGames competition — every participant got a free t-shirt, and some even gave back a few bucks to help keep it going in years to come.

Summary
-------

There are many ways to earn money — everything that applies to the "normal" AAA gaming world can be, more or less, applied to casual HTML games. You might however also focus on selling licenses, doing branding, or earning on a revenue share basis from the advertisements. It's totally up to you which path you're going to follow.