HTML

This reading accompanies Chapter 2 of your book. That chapter does a nice job of introducing bits of HTML as needed. Read that first and feel free to work through their presentation. Here's an organized summary of what we learned, plus a bit more.

If you don't have Chapter 2, here's a link to a copy of a scan of the chapter. To respect the author's copyright, the link is only valid on-campus or with a password. Ask Scott if you don't have that password.

FEWD Chapter 2

Languages

We learned that web pages are written using three languages

  • HTML, which is the skelton and organs
  • CSS, the skin and clothes. We'll look at that in the next chapter.
  • JavaScript, which defines the behavior. We'll get to that later.

HTML template

Our basic page had the following template:

#!HTML
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Ottergram</title>
    </head>
    <body>
        <header>
            <h1>Ottergram</h1>
        </header>
    </body>
</html>

Tags

We learned the following tags. Look at W3Schools or MDN to learn more.

  • head holds meta information about the document
  • meta tells the browser the character set. More about this much later in the course. We'll always use utf-8
  • title is used for window titles, bookmarks, and is used by search engines. More important than you'd think.
  • body holds all the content
  • header holds headers and related stuff like logos
  • h1 holds the text of a major heading
  • link connects a separate file of CSS rules to an HTML file. The URL of the CSS file is the href attribute.
  • ul is a container for an unordered list (bullet list)
  • li is a container for a list item
  • img is replaced (a replaced element) with an image loaded from a separate file, specified using the src attribute.
  • a demarks a clickable hyperlink

Meaningless Tags

All the tags above have some kind of meaning associated with them. They are for some kind of content. However, HTML also comprises two meaningless tags, span and div. A span demarks some text or other inline information. (Inline content is stuff like text that fills up a line before flowing onto the next line.) A div demarks a big block or division of a document.

These tags are useful for styling and behavior (attaching JavaScript to them).

Chrome Developer

They described the Chrome Developer. This is how we look behind the matrix to see what's really happening.

Some other useful tags:

  • em to emphasize some text. Typically is italic.
  • strong which is like em but more so. Typically is bold.
  • h2 to h6 for different levels of headers
  • p for a paragraph. Can't nest or contain other block elements.
  • br for a line break. Usually avoid this because it can break layouts
  • ol for an ordered (numbered) list

Tags should be properly nested:

<foo> <bar> </bar> </foo>

not

<foo> <bar> </foo> </bar>

Once, it was very popular on the web to have links like this:

  • Click here for apple pie recipes
  • Click here for peach pie recipes
  • Click here for prune pie recipes

It seemed so clever and intuitive, making the clickable text be the word "here." There are two big problems with this, though:

  • Accessibility: Screen-reading software for the blind often will read the text of the links on a page so that the user can easily navigate to other pages. Links like those above read as "here," "here," "here" — useless.
  • Indexing: Search engines pay special attention to the click text on a page, since those are often an important clue about the content of the destination page. The links above don't show what the important words are.

So what do you do instead? Just wrap the link tags around important words:

Accessibility is very important in this class, so keep that in mind.

The ALT Attribute

An IMG tag looks like this:

:::HTML
<img src="url/of/picture.jpeg" alt="picture of something">

You noticed that we added an ALT attribute to the IMG tag that is a small piece of text that can be used in place of the image in certain circumstances. The ALT attribute is an important part of the HTML standard. Perhaps its most important use supports accessibility. Unfortunately, not everyone has good enough vision to see the images that we use in our websites, but that doesn't mean they can't and don't use the Web. Instead, they (typically) have software that reads a web page to them, including links. When the software gets to an IMG tag, it reads the ALT text. If there is no ALT text, it may read the SRC attribute, hoping there's a hint there, but all too often the SRC attribute is something like "../images/DCN87372.jpg" and the visually impaired web user is left to guess.

Therefore, you should always include a brief, useful value for the ALT attribute. If your page is an image gallery, then your ALT text could be a description of the image. However, describing the image is not, in general, the idea. For example, if the image is a link whose target is made clear by the image, then the ALT text should say something like, "Link to ..." so the user will know what to do with it. The sole exception is for images that are just used for formatting, such as blank pictures that fill areas or colorful bullets for bullet lists. In those cases, in fact, it's better to include an ALT attribute that is empty, so that the user doesn't have to listen to the SRC attribute being read. In both cases, the text should be useful for someone who wants to use your site but isn't sighted. It helps to turn off images and view your site to check.

Furthermore, you should avoid having critical information on your website conveyed only in images. There may be times when it is unavoidable, but to the extent that it is possible, we want our websites to be easily usable by all people, including the blind and visually impaired.

Accessibility is important in modern society. We build ramps as well as stairs, we put cutouts in curbs, and we allocate parking spaces for the handicapped. Indeed, most federal and state government websites are legally required to be accessible, and ALT attributes are just one part of that.

In this class, we expect you to always use the ALT attribute. If you find an image or an example where we've forgotten to use one, please bring it to our attention.

For more information, you can read the following

Figures

Now that we know about the img tag, it's useful to know about a semantic tag that can be used with it. We can use figure to surround an img tag, paired with figcaption for the caption text:

:::HTML
<figure>
    <img src="../images/hermione-granger-256.jpeg" alt="Hermione Granger">
    <figcaption>Hermione Granger as played by Emma Watson</figcaption>
</figure>

Here's what it would look like:

Hermione Granger
Hermione Granger as played by Emma Watson

Note that images can be used without figure; a figure is often used as in a book, where the text refers to a figure to provide additional information. Also, the use of figcaption doesn't remove the obligation to provide alt text. Still, this can be a useful tag to know about.

Comments

From the very first computer program, programmers have needed to leave notes in the code to help themselves and others understand what's going on or what the code's purpose is. These notes are called comments. Comments are a part of the program text (they're not written separately, because then, well, they'd get separated), but they are ignored by the computer. Comments aren't about what someone can discover by reading the code, but should cover the background context of the code, or its goal.

Because it's important to get in the habit of putting comments in your HTML code, we will require comments in this course. At this point, you won't have a lot to say, and that's fine. You will start by labeling each file with its name, your name, the date, and any sources you consulted (such as the source code of other web pages). Think of this as signing your work. Later, when you're designing a website with many coordinated pages, you can use comments on a page to talk about how it fits into the overall plan.

Comment Syntax

The HTML comment syntax is a little odd-looking. Here's an example:

<!-- I can say anything I want in a comment.  -->

The syntax starts with a left angle bracket < then an exclamation point and two hyphens, then the comment (anything you want) and ends with two hyphens and a right angle bracket >.

Validation of HTML Code

How can you be sure you've followed every nit-picky rule that the HTML standards committee devised? (The standards committee is the World Wide Web Consortium or W3C.) Even if you have memorized all the rules, checking a page would be tedious and error-prone – perfect for a computer! Fortunately, the W3C created an HTML validator. You can validate by supplying a URL, by uploading a file, or even copy/pasting in some HTML. An HTML validator is an excellent tool to help you debug your HTML code.

Validation also helps with accessibility. One important aspect of accessibility is having the proper HTML syntax for each page in your site. Visitors with accessibility needs will use the alternative browsers and screen readers, and that software will be aided by syntactically correct HTML. Read the following for a longer discussion of why to validate your HTML pages.

Throughout the semester, if you need to validate a web page, you can find the HTML validator and others in the reference page.

Icon Declaring Validation

Once you get your page to validate, you can put some HTML code on your page to give it a seal of approval, declaring that it is valid (and what standard it meets). You will see in lab examples of this strategy.

The very cool thing about this icon is that it is clickable, and clicking it will cause the validator to process your page again. Thus, you can modify your page, upload the changes, and click the icon to re-validate it, making validation very easy. In fact, we suggest that you put the icon on your page before it's valid, and use it during your debugging process.

The snippet of code is just the following, so go ahead and copy/paste it into your pages. The code doesn't use anything we don't know, so read it!

:::HTML
<p>
  <a href="http://validator.w3.org/check?uri=referer">
     <img 
       src="http://cs.wellesley.edu/~cs204/Icons/valid-html5v2.png"
       alt="Valid HTML 5"
       title="Valid HTML 5"  
       height="31" width="88">
  </a> 
</p>

The need for meaningful tags

As we've said, HTML was designed to structure the content of a web page. That explains the existence of tags like <p>, <h1>, <ol>, etc. However, when web developers started creating pages with a lot of content, it became clear that to make better use of the available screen space, a way to organize the page content in bigger chunks was needed. Then, CSS could be used to arrange their position on the page. Therefore, the tag <div> was born (short for division), which is currently the most used (and overused) tag in every webpage. While this seemed to have solved the page layout problem, HTML code became difficult to understand, other computer programs (e.g. search engines) couldn't make sense of all divs in a page, if they wanted to use the organization of the page for inferring the meaning of the content.

HTML5 introduced a series of new tags that have meaningful names and can be used universally to express what the content is about, beyond the existing simple tags. Additionally, to make the pages more alive with different kinds of content, several new tags that allow content to be embedded in a page were also added. In the following, we will give a short summary of some of these tags. Try to make use of them in your pages. They will make your code better and more readable to the programs of the future.

Semantic Tags<

Here is a list of new HTML5 tags that are known as semantic tags, because their names have specific meaning.

Tag Name Short Description
<header> Specifies a header for a document or section.
<footer> Specifies a footer for a document or section.
<section> Defines sections in a document (e.g. chapters).
<nav> Defines a set of navigation links.
<aside> Defines content which is relevant but not central (e.g. callouts, sidebars).
<main> Defines the main content of a page.
<article> Defines independent, self-contained content (e.g., blog post, news story).
<abbr> Indicates an abbreviation or acronym.

<abbr title="United Nations">UN</abbr>

See an example in action in the paragraph below for the word W3C.

<figure> Indicates an figure or other graphical content
<figcaption> A caption inside a figure element

Which Tag to Use?

Given all the tags listed above, along with DIV, you might feel bewildered as to which one to use. Here is a helpful HTML5 sectioning flowchart from html5doctor.com . Click on the image to see a larger version:

HTML5 Sectioning Flowchart

Click on the image to see a larger version

Review of URLs

In class, we learned about two kinds of URLs: relative and absolute:

  • absolute URLs start with a slash (or http or https) and specify the same destination regardless of starting location
  • relative URLs start with a name (or ..) and specify a destination as a series of steps from the starting location

Relative URLs have the advantage that if the starting file and ending file are moved to a different place, but continue to share the same relationship (for example, they are in the same folder), then the relative URL will continue to work after they are moved, while an absolute URL will necessarily break.

Here are the rules for relative URLs:

  1. a bare name, like fred.html is a file or folder in the same folder as the starting point.
  2. a slash means to go down into a folder. So stuff/fred.html means that stuff is a folder in the current folder (by rule 1) and fred.html is inside stuff
  3. a .. means to climb out of a folder and go to the parent folder. So ../fred.html means that fred.html is in the folder above the starting point.

These rules can be combined to yield long relative URLs like ../../africa/botswana.html which is a file in the africa folder that is two folders above this one.

Ottergram

At the end of the chapter, the final page's HTML code is the following:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ottergram</title>
    <link rel="stylesheet" href="stylesheets/styles.css">
  </head>
  <body>
    <header>
      <h1>ottergram</h1>
    </header>
    <ul>
      <li>
        <a href="#">
          <img src="img/otter1.jpg" alt="Barry the Otter">
          <span>Barry</span>
        </a>
      </li>
      <li>
        <a href="#">
          <img src="img/otter2.jpg" alt="Robin the Otter">
          <span>Robin</span>
        </a>
      </li>
      <li>
        <a href="#">
          <img src="img/otter3.jpg" alt="Maurice the Otter">
          <span>Maurice</span>
        </a>
      </li>
      <li>
        <a href="#">
          <img src="img/otter4.jpg" alt="Lesley the Otter">
          <span>Lesley</span>
        </a>
      </li>
      <li>
        <a href="#">
          <img src="img/otter5.jpg" alt="Barbara the Otter">
          <span>Barbara</span>
        </a>
      </li>
    </ul>
  </body>
</html>

You can view that initial version of ottergram in your browser.

Let's take a moment to talk about the HTML.

  • The bulk of the page is a list. Most web pages will not be like that, and indeed, neither will the finished Ottergram.
  • Each list item is a hyperlink with the odd URL of #. That's a fragment identifier, and they use it for an odd reason that we'll talk about below.
  • Each hyperlink is wrapped around an img and a span. The span is essentially the caption of the image. Better semantic markup might have used figure and figcaption.

Fragments

Above, we discussed URLs, but I left something out: fragments. Notice the hyperlink at the beginning of this paragraph. It goes to a particular place on this page. It's able to do so because the destination has an id attribute, and the URL specifies that id after the # character.

In general, a URL looks like https://machine.domain/path/to/file.html#fragment_id

The URLs in Ottergram consist solely of the #, so there's no fragment ID and the filename is missing as well. What that hyperlink does is go to the same page. Try it!

A hyperlink to the same page we are on is not very useful. However, it is clickable. Later, in chapter 6, we're going to write some JavaScript code to hijack the click behavior and do something interesting and useful. For now, we just wanted to create a page with clickable elements. That's what these do.

The End

This is just the beginning of HTML. There's a lot more you could learn, but this will do for now. Title: CS 204 CSS

CSS

Chapter 3 on Styles does a nice job of introducing bits of CSS as needed. Read that first, at least through page 55. Here's an organized summary of what we learned, plus a bit more.

If you don't have Chapter 3, here's a link to a copy of a scan of the chapter. To respect the author's copyright, the link is only valid on-campus or with a password. Ask Scott if you don't have that password.

FEWD Chapter 3

CSS concepts

  • normalize.css removes some of the formatting differences between browsers, making it easier to build consistent websites
  • A CDN is a content delivery network, useful for lots of common files, including jQuery
  • CSS rules, which include
    • selector(s)
    • properties and values

CSS rules

:::CSS
header, footer {
    margin: 0;
    padding: 8px 4px;
    background: cornflowerblue;
    color: inherit;
}

CSS Properties

  • background background colors
  • border an optional box around the element
  • color font colors
  • display how an element is laid out on the page: block stacks vertically, inline is like text. There are other values, like none to act as if the element doesn't exist
  • font-family sets the font for the element
  • font-size sets the size of the font
  • list-style can change or remove the bullets in a bullet list.
  • margin spacing outside the element's border
  • padding spacing between the box and the contents
  • text-align can center text, right-align it and such
  • text-decoration can add or remove underlines and such
  • text-transform can capitalize, lowercase or uppercase text
  • width is the width of the contents of the element, not including any padding, borders or margins. This can be very confusing.

Several of the above are shorthand properties. You can be more specific, like border-left-style

Box Model

The box model is most easily learned by playing with the dev tools, but the idea is simple:

  • block elements work like big boxes that are (by default) stacked vertically on the page
  • they have, outside to inside:
    • margins. These just have widths. They have the background color of the parent block
    • borders. These can have widths, styles, and colors
    • padding. These just have widths, but they take on the background color of this block
    • content. This has width and many other properties

You can use display:block as a declaration to turn a non-block element (like A, IMG or SPAN) into a block element.

Selectors

There are quite a few kinds of selectors available in CSS. Some are used often, some only rarely. Here are some that are simple and very common:

  • tag: style every such tag (e.g. paragraphs <p> or list items <li>) You have to specify one of the existing HTML tags, like p
  • classes: style every element with that class. Make up a class name, say fred and use .fred as the selector. Specify the class with an attribute, like <p class="fred">
  • id: style the (unique) element with that ID. Make up an ID, say george and use #george as the selector. Specify the id with an attribute like <p id="george">

Our book authors advocate avoiding ID. I don't really agree with their reasoning, but their way is fine, too. If something is definitionally unique, I don't see a problem with giving it a unique ID. Furthermore, IDs are the only way to specify a location within a page using a URL. Let's turn to that now.

IDs

This section is not covered in the chapter, or indeed, in the book, as far as I can tell. Still, it's worth re-explaining the href="#" that they used in Chapter 2.

This section is really about URLs. We learned that URLs uniquely specify a single webpage in the world. URLs are even more powerful than that. They can even specify a location within a page. This is done by doing two steps:

First: Giving the location an ID. That's done in HTML with the ID attribute. Any element in HTML can be given an ID, like shown this:

<span id="george">this span is george</span>

This span is george

Second: The absolute URL to specify that location is like http://domain.com/path/to/page.html#id-of-element The # is a special character (called a hash mark, sharp sign, pound sign) separating the URL for the page from the ID of the element (called a fragment).

With relative URLs, you can omit things. So a within-page link to a fragment would just be #id-of-fragment.

Try these two examples, and look at the location box in your browser:

When a web designer wants a link to the current page, they will usually use # as the entire URL, letting everything default. Here's a link to this page.

ID versus Class

If you're confused about the difference between ID and class, you're not alone. Many students have been confused about this.

Here's the key difference: an ID has to be unique, meaning there can be only one element with a particular ID. If we anthropomorphize the elements on our page, an ID is like a Banner ID: there should be only one person with a given ID (barring identity theft).

If we use an ID to identify a place on a page for a URL, we want to specify a single place to go, not multiple places. This reminds me of a short (1:20) clip from Monty Python's Life of Brian: you are all individuals

Classes and IDs are similar in the following ways:

  • we make up a label
  • we apply the label to 1 or more elements
  • we refer to the label from the CSS rules

The difference, of course, is that an ID is a label that can be applied to at most one element, while a class is a label that can be applied to any number of elements.

Interactive Demonstration

I created an interactive selector display that will help show you what elements various selectors pick out. To use it, first, view source just to see the relevant stuff that is going to be picked from. It's not the whole page, just the part with the beige background. The HTML looks something like:

    <h2>this is an h2 header</h2>
    <p id="par1">This paragraph has ID <code>par1</code></p>
    <h2>this is another h2 header</h2>
    <p>this paragraph precedes the list of fruits and veggies</p>
    <ol id="list1">
      <li class="fruit">apple</li>
      <li class="veg">broccoli</li>
      <li class="fruit" data-tag="tough">coconut. this is tough</li>
      <li class="fruit">date</li>
      <li class="veg">endive</li>
      <li class="veg" data-tag="yucky">fennel. this is yucky</li>
      <li class="fruit">"g" fruits
        <ul>
          <li>gooseberry</li>
          <li>grape</li>
          <li>grapefruit</li>
          <li>guava</li>
        </ul>
      </li>
      <li class="veg">horseradish</li>
      <li>tomato</li>
    </ol>
    <p>this paragraph follows the list of fruits and veggies</p>

Take a brief look at the tags, classes, ids, and the overall structure. Then click thorough and try the various selectors.

Summary

  • CSS is how we apply style to our page.
  • It consists of a set of rules
  • Each rule comprises a set of properties and values, like color: red
  • The box model applies to all block elements, such as paragraphs (p), lists (ol and ul), list items (li) and div.
  • In the box model, an element has (from outside to inside):
    • margin. This just has width
    • border. this has a width, style and color
    • padding. this just has width. Its background color is the same as for the content
    • content.
  • each rule also has a selector, which chooses which element(s) to apply the rule to.
  • simple selectors include:
    • tag, like p to apply to all paragraphs. Has to be one of the built-in HTML tags.
    • .class_name to apply to all elements with class='class_name'. We get to make up the class name.
    • #id_name to apply to the sole element with id='id_name'. We get to make up the id name.
  • The difference between classes and ids is that an id has to be unique.

Chapter 4 Supplement

This reading summarizes and expands on the concepts of responsive and flexible layouts that we learned in chapter 4.

Mobile First

We should first design our websites so that they work effectively on small devices, and only later take advantage of greater space. Some rules of thumb:

  • don't lay things out horizontally; stack things vertically
  • give images CSS declarations like width:100% so that they scale to smaller displays
  • don't use table elements and such that might be wider than the display
  • specify widths in percentages when feasible
  • don't specify widths of elements in pixels (or, at least, wide widths) which might result in the dreaded horizontal scrolling

inline-blocks

In the last chapter, we learned about inline elements, like span, that are found in running text and would move around as the browser gets wider and narrower.

We also learned about block elements, which use the box model, can (typically) contain other block elements, and stack vertically on the page.

We now know about inline block elements, achieved with display:inline-block. Such elements act like inline elements in terms of filling out the width of their container (moving other inline elements up from the next line until there's no more space), but they act like block elements in that they can contain other block elements.

Note that the default width of a block or inline-block element is 100%, which means that there is never any room left to bring another one up from the next line. So, it only makes sense to use inline-block where you are setting the width (or it's a replaced element, like an img, and so the width is derived from the contents). Like this:

:::CSS
selector {
    display: inline-block;
    width: 20%;  /* five on a line */
    ...
}

New HTML

  • main The main content of a page. Bigger than an article
  • div A meaningless block container. Useful for structuring the page

Flexbox

With Flexbox, there is

  • a container that is limited in size. Presumably takes the whole screen or a portion thereof. Get these with display:flex. Contrast that with a Wikipedia page that is as long as it needs to be
  • a set of flex-items to be displayed, all children of the container. This is automatic.
  • a direction or main axis that the children will be oriented in (horizontally or vertically)
  • a cross axis that is perpendicular to the main axis
  • a specification for what happens with any leftover space in the flex container

Flex containers can be nested, so you have have rows with columns, columns within rows, even rows within rows and columns within columns.

Flex items can grow and shrink. We learned two uses of the flex shorthand property:

  • flex: 0 1 auto means don't grow me, shrink me if needed, and calculate my size from my contents
  • flex: 1 1 auto means grow me as much as possible, shrink me if needed, and calculate my size from my contents

New CSS Properties

Pretty much all of these are related to the new flexbox layout

  • align-items aligning (e.g. centering or stretching) flex-items. If the item doesn't fill the space allocated to it, where does it end up in that space. MDN align-items
  • display:flex to specify an element as a flex container
  • flex how a flex item shrinks or grows
  • flex-direction row or column
  • justify-content what happens with leftover space in a flex container?
  • overflow set what happens when an element's contents is bigger than it is. Scroll? Hide? Show?
  • order what order does this flexitem go in? source order? after others? before others? contents is bigger than it is. Scroll? Hide? Show?
  • text-shadow can add a shadow to some text by reprinting the text in a different color and a small displacement
  • white-space what happens with white space in an element: normal? nowrap?

Absolute and Relative Positioning

Normally, we let the browser figure out where an element should land on the page, based on its size, the size of the container, whether it's a block or inline element, and so forth. This is because the default value of the position CSS property is static. It has two other interesting values:

  • position:relative which allows you to shift the element from its static position
  • position:absolute which allows you to place the element within a Cartesian coordinate system
Here's a sentence in which a single red word has been moved from its usual place.

Here's how that's done. First, the CSS:

:::CSS
.up_and_right {
    position: relative;
    top: -1em;
    left: 2em;
    color:red;
}

Here's the HTML:

:::HTML
Here's a sentence in which a single red
<span class="up_and_right">word</span>
has been moved from its usual place.

In general:

  • The element is shifted vertically using either top or bottom and giving a signed distance by which to move the top or bottom of the element.
  • It's shifted horizontally using either left or right and another signed distance.
  • The starting location is where it would have been if it had been position:static rather than position:relative.
  • Note that other elements don't move as a result of the movement of this one. (There's a gap left in the sentence above, where the word was moved from.)

Position absolute is similar, except that the distances are measured not from the element's static position but in an absolute coordinate system, where the origin of the system is the first non-static ancestor and if no non-static ancestor is found, the browser window.

Therefore, another use of position:relative is to set the coordinate system for its descendants. I like to think of this as "my descendants are positioned relative to me". Here's an example:

pink child
green child
blue child

This is done by:

  • putting position:relative on the ancestor (here the box with gray background)
  • putting position:absolute; top:30px; left:50px on the pink child
  • putting position:absolute; top:-10px; left:-20px on the green child
  • putting position:absolute; bottom:20px; right:30px on the blue child

Use this feature sparingly. Sites where everything is positioned in absolute coordinates are incredibly inflexible. You want a site that is responsive to the size of the browser. Nevertheless, sometimes position:absolute can be useful.

Note that with position:static, elements can never overlap. In particular, text can't overlap. But with position:absolute and position:relative you can do that, if you want.

Flexbox versus Float

Flexbox is relatively new (circa 2014, though proposals go all the way back to 2009). Prior to widespread support for flexbox, web developers used float, which still has some useful features and is still worth knowing about.

Here's a simple example of float, where we get the text to wrap around an image:

Hermione Granger Hermione Granger was indispensable in the Harry Potter series. Harry had the title role, and he was clearly critical to the story, but he did not have exceptional magical skill. His nemesis, Lord Voldemort, was an extraordinary wizard, matched only by Dumbledore. Harry, was good, but no more than good. Hermione, on the other hand, was "the brightest witch of her age" according to Remus Lupin. There was no spell she couldn't do, and her cleverness and foresight saved Harry countless times.

Float causes the floated elements to be

  1. Removed from the flow, so that later stuff moves up on the page, and
  2. shoved back into the page, causing block elements to overlap it and inline elements to wrap around it.

The example above shows the idea. Hermione's picture is floated (to the left in this case) and the paragraph text (inline elements) flows around it.

Centering Block Elements and Text

People love centering, particularly novice designers. Centering moves things away from the edges, which makes it feel more comfortable, without having to decide how much to move it. But there are two kinds of centering. There's centering block elements and centering inline elements like text. Let's start with centering text:

Centering Text

Centering text is pretty easy: just specify text-align:center on its parent element (or, in general, some ancestor, since the setting is inherited.)

You should almost never center lines of text in a paragraph. You get ragged edges left and right, which looks ugly. Also, depending on the font, amount of text and the width of the region, the last line may be weirdly short (and centered). Here's a Tolkien quote:

Do not meddle in the affairs of wizards, for they are subtle and quick to anger.

You probably don't want that single word centered on the second line. But that can happen (and all-too-often does) when you center text and don't have complete control over browser-width, font-size, and the like.

Instead, what you probably want is to have normal, left-aligned text in a box that is itself centered. Let's see how to center boxes.

Centering Blocks

Here's an example of a block element (blue background) centered within its container (red border):

Do not meddle in the affairs of wizards, for they are subtle and quick to anger.

Note that, by default, block elements are width:100% which means that they are as wide as their container will let them be. So, by default, centering is not possible, because there's no extra space to center within. Therefore, to center a block element, you usually have to set its width to something smaller than its normal width. The blue block above is 80% of its container. One exception is IMG elements, since they get their width from the actual image, not from the container. However, pictures are often quite wide, so you typically have to scale them down using a width setting anyhow.

The trick to centering a block element is to set its margin-left and margin-right to auto. Auto margins means to take whatever space is leftover in the container and distribute it equally to the two margins.

The example above used a shorthand: margin:10px auto which means the top and bottom margins are 10px and the left and right are auto.

Galleries with Floating Elements

We often want galleries of elements, where there should be as many on a line as will fit, but fewer if necessary, without any horizontal scrolling. One way to do that is by setting display:inline-block and set the width on the gallery elements, which allows you to put arbitrary content in each element, while still having them fill the line like inline elements.

Another way is to use float:left as shown by W3schools Gallery

Chapter 5 Supplement

This reading summarizes and expands on the concepts of adaptive layouts with media queries that we learned in chapter 5.

Summary

  • standard term is responsive though I agree with their objection
  • viewports:
    • layout viewport: what the developer (and the browser) uses for
  • layout (where elements go and how big they are: think "magazine layout")
    • visual viewport: what the user sees
  • often the visual viewport is narrower than the layout viewport, requiring
    • zooming out
    • scrolling
  • set the layout viewport with this:
:::HTML
<meta name="viewport"
      content="width=device-width, initial-scale=1">
  • media queries using (in CSS) like this:
:::CSS
@media all and (min-width: 768px) {
    selector {
        flex-direction: row;
    }
    /* other CSS rules */
}
  • setting print styles:
:::CSS
@media print {
    body {
        /* Note "pt" (points) not "px" (pixels).
           72.27pt = 1 inch */
        font-size: 12pt "Times New Roman";
    }
    /* other CSS rules */
}

Media Queries

A media query, like all CSS rules, overrides earlier rules. So, the question is, what is the default: the large device or the small device?

Given the primacy of mobile nowadays, it's better to design for small and later make use of larger devices.

Therefore use min-width:

:::CSS
@media all and (min-width: NNNpx) {
    /* rules for large devices */
}

rather than max-width:

:::CSS
@media all and (max-width: NNNpx) {
    /* rules for smaller devices */
}

Breakpoints

What widths make sense to use to call in a different layout? Common values are:

  • 320px smartphones
  • 786px tablets
  • 1024px laptops and desktops

These are called breakpoints where you switch from one layout to another. See Media Queries for Common Device Breakpoints

Of course, those values aren't cast in stone. New devices and pixel densities are always coming out.

JavaScript

CS 111 is a prerequisite for CS 204, so our introduction to JavaScript will compare it to Python. If you skipped CS 111 or have forgotten Python, let me know.

Python versus JavaScript

Finally, there's some practical information on how to run JavaScript

Title: CS 204 How to Run JavaScript

How to Run JavaScript

There are two main ways you will be integrating JavaScript into your HTML code:

  1. Using the script tag
  2. Using an external file

This is very similar to CSS, as you can use the <style> tag or link an external CSS file.

Below is how you would integrate JavaScript into HTML using the <script> tag. The JavaScript code is between the <script> tags. Examine the code below, then switch to the results tab to see it run in action.

Showing another way, below is how you would use an external JavaScript file. Examine the JavaScript and HTML files, then switch to the results tab to see it run in action. In CS 204, we will mostly be using external JavaScript files.

JS Console

It's nice to be able to try little bits of JS code (just as we might try little bits of Python code by running the Python interpreter). Fortunately, every browser has a JS console (interpreter) built-in so it's easy to test little snippets. I do this all the time.

Getting to the console in Chrome on a Mac:

  • At the top bar, go to view > developer > JavaScript Console, or Command-Option-J

Getting to the console in Firefox on a Mac:

  • At the top bar, go to tools > web developer > Web Console, or Command-Option-K

It might look like this:

JavaScript console

If you type any Javascript expressions into the console, it will works as well:

JavaScript console Title: Closures and Namespaces

Closures and Namespaces

This reading is supplemental to Chapter 8 (through page 173), which uses Immediately Invoked Function Expressions (IIFEs) to establish namespaces. This reading also discusses closures, which are briefly described on page 133.

A closure is a special kind of function, and a namespace is a way that a programming language can support separation of code. Consequently, you'll learn more about these concepts in CS 251 (Programming Languages), but they are important, practical concepts that arise naturally in JavaScript code, so we'll learn about them now.

But, before we get to closures, let's review some ideas that you probably remember from prior CS classes, but I want to bring to the top of your mind.

Scope

In JavaScript, variables can be local or global. A global variable can be seen by any code anywhere; local variables can only be seen from a small part of the code. For example, consider the following code:

var glob = 13;

function fred(x) {
    return x+glob;
}

function george(x) {
    x = Math.random();
    glob = Math.random();
    return x+glob;
}

The global variable glob is visible to both functions. (The function names fred and george also go into the global namespace and so are visible to each other. For example, they could invoke each other.)

The local variable x is local to each function. I could simultaneously invoke fred and george with different values for x and nothing would go wrong, because they are different names and therefore different storage locations. Imagine each function is a family, and both families have a child named x (short for Xenophon and Xerxes). Different kids, different storage locations, but the identical names cause no confusion. For the functions, the x variable exists only during the function call and disappears when the function completes.

Other Scopes

There are other scopes in addition to local and global. We actually used these in the Plotting assignment without realizing it. Here's an example; see if you can figure out what it does:

function curve13(max, incr) {
    var xvals = range(max);
    var f = function (x) { return x+incr };
    var yvals = xvals.map(f);
    newPlot(xvals, yvals)
}

Focus on the f function. What is the scope of x? It's local to f, of course. What is the scope of incr? The incr variable is local to curve13 but it is non-local to f. The incr variable refers to the environment that curve13 created.

A variable that is non-local like incr means that f is a closure. We say that f is a "closure over incr".

If a closure is returned from a function, it can continue to refer to its original environment. We did this in the Plotting assignment as well: the functions returned from quadratic and cubic continued to refer to their original environments, which is how they continued to know their coefficient and roots.

What is a Closure?

Formally, a closure is a function plus an environment (you can read more about them in the Wikipedia article on Closures), so to begin getting a handle on them, we start with some more observations about functions.

Functional Programming

The following functions f1 and f2 depend only on their inputs (rather than on some global state information), which makes them easier to understand than the function g1 which depends on some global variable glob. (For example, suppose glob is a string: then the value of g1 is a string, too.)

var f1 = function (x y) { return x + y; };
var f2 = function (x) { return x + 4; };
var g1 = function (x) { return x + glob; };

When we talk about ''functional programming'' in Computer Science, we are thinking about functions like f1 and f2, where calling the functions with the same inputs always yields the same output. The same can't be said of g1. In general, when we say some code is functional, we mean that it depends only on its arguments, not on external state (like glob) or even internal state (its prior history of executions). We'll return to this later.

Function f1 is just the add function; we might call f2 the add4 function. Since functions are first-class objects in JavaScript, we can dynamically create them and return them from functions. So, the following function can create functions like add4:

var makeAdder = function (delta) {
    return function (x) { return x+delta; }
    };
var add4 = makeAdder(4);
alert(add4(3));

Now, what kind of function is add4? It's functional, in the sense that its value only depends on its arguments, not on any global state (certainly none that can change). Yet the code looks nearly the same as g1. What's the difference? The difference is that the glob that g1 refers to is global and can change dynamically, while delta is a lexical variable in the environment of the anonymous function returned by makeAdder. That function includes both the function plus that bit of environment, so it is a closure.

If you think about our earlier discussion of scopes and environments, the environment of the anonymous function returned by makeAdder includes the parameter delta and the delta continues to exist even though makeAdder has returned. It continues to exist because the anonymous function needs it. We say that the anonymous function has closed over the name delta.

An Example: A Shopping Example

Let's see closures in action in a web page. Suppose we have a page that has an item for sale, say apples, and it has an associated button that increments a counter, updates a database, updates the web page and maybe other things. So, you write some code like this:

function updateAppleDatabase(n) {
    console.log("Apple Database updated with "+n);
}

0 Apples

Here's the HTML code:


And here's the JavaScript code:


The event handler function we've written is not functional (it depends on the global variable appleClicks). Nevertheless, the code works fine.

Next, we decide to add additional buttons for bananas, coconuts, dates, eggplants, figs and the rest of the alphabet. Of course, we could copy/paste the code above for each of our grocery items, but copy/paste usually a bad idea. Duplicate code means that if we change our implementation, we have to update all the copies of the original implementation.

Event Handler Maker

But how do we write a generic event handler? We could write a function to make one. While we're at it, we'll make the updateAppleDatabase function more generic.

function groceryClickHandlerMaker(item,outputId) {
    var counter = 0;
    return function () {
         counter++;
         updateDatabase(item,counter);
         $(outputId).html(counter);
         };
}

How do we use the groceryClickHandlerMaker? Here are two examples, where we invoke the groceryClickHandlerMaker function to return a closure that we then attach as the click handler.

0 Bananas

0 Coconuts

Here's the JavaScript code:


Closure Variables

Let's look again at the groceryClickHandlerMaker:

function groceryClickHandlerMaker(item,outputId) {
    var counter = 0;
    return function () {
         counter++;
         updateDatabase(item,counter);
         $(outputId).html(counter);
         };
}

What variables does it close over? It closes over every variable that is not defined within the function. Here there are three:

  1. item
  2. outputId
  3. counter

The first two closure variables won't change ever, so the JavaScript engine can really just substitute the values as static constants. The counter, however, is interesting, because it's updated by the closure invocation, which means that the closure isn't functional in the technical sense of its behavior only depending on its arguments. Its behavior depends on how many times its been executed before.

Namespaces

Some very cool properties of the counter variable used by the click handlers above are that

  1. there are several of these variables, one for each handler
  2. they all have the same name, but
  3. they are all completely unrelated, and
  4. they are all completely private

Think about that last property for a moment: each click handler has its own private state variable. (This should remind you of instance variables in object-oriented programming.) Indeed, each closure has its own private namespace.

What's a namespace? In general, a namespace is a mapping from names (symbols) to values. You can think of the names as variables, as we will here, since in JavaScript we can assign a function to a variable. Namespaces are important in programming because they help us avoid name collisions. For example, many years ago, I was doing some graphics programming and I has some variables that stored the hex codes for various colors:

var red = 0xff0000;
var white = 0xffffff;
var tan = 0xd2b48c;
var teal = 0x00ffff;
...

I also needed to compute the tangent of an angle:

var tan_theta = tan(theta);

I'm embarrassed to admit that it took me hours to understand why the tangent function wasn't working. The problem was a name collision: I had only one namespace, so tan could only have one value.

In JavaScript, the tan function is safely in the Math object and so we say Math.tan to use it. The Math object gives us a kind of namespace. We could create one for Colors very easily in JavaScript using objects:

var Colors = {};
Colors.red = 0xff0000;
Colors.white = 0xffffff;
Colors.tan = 0xd2b48c;
Colors.teal = 0x00ffff;

We can put functions in the object as well, like the tan function is in Math. Suppose we had a function lighten and we didn't want to clutter up the global namespace with it. We could put it in Colors:

Colors.lighten = function (color) { ... };

This technique is very common in JavaScript programming. Another, even more common, is to use functions.

Functions as Namespaces

Let's take a very abstract example so that the details of the code don't confuse the issue. Suppose we want to have a bunch of global variables and functions with short, succinct names for brevity. The functions might be mutually recursive, might refer to the globals, and so forth. After all those definitions, the thing we actually want to do is compute f(1) and insert the result into page . Our code might look like this:


var a = 123;

var b = 456;

var f = function (n) { ... g(a*n); ... };

var g = function (x,y) { ... f(b*x)+f(b*y)...; }

$("#ans").html(f(1));

This code would work, but it would not be good software engineering, because of the potential for namespace conflicts. So, we can just make all these variables be local variables of a new, anonymous function that we will immediately execute.

(function () {

     // code from above

})();

Notice that the function expression is wrapped in parentheses: that's necessary so that it won't be treated as just a top-level function definition. The parenthesized function expression is then followed by a pair of empty parentheses which causes the function to be invoked. This is called an Immediately Invoked Function Expression or IIFE. Wikipedia has more about Immediately Invoked Function Expressions.

Using an IIFE means that no names are added to the global namespace, so the code has no footprint at all. (The footprint of code is the set of names that are added to the global JavaScript namespace.)

Modules, Objects and Methods

This reading is supplemental to Chapter 8 (page 173 to the end).

Many of you are familiar with Python from CS 111. Python has a nice module system in which we can import various helpful modules into our main program. Our code might look like this:

:::Python
import math, cs1graphics

def modifyPicture(pic,angle):
    cs1graphics.adjustY( pic, math.tan(angle) )

Don't worry about the details of the code. I doubt that adjustY exists; I just made it up. The point is that we can use functions that are defined in different modules by using the syntax module.name where the part to the left of the dot is the name of the module (math or cs1graphics) and the part to the right is one of the names that lives in that module.

Moreover, the set of names in each module is separate. If, by coincidence, both modules use the same name, there's no conflict. One could be math.PI and the other could be cs1graphics.PI

Separating sets of names like this is useful in CS, because it reduces the chance of accidental name collisions.

A set of names and values like this is called a namespace. There are lots of kinds of namespaces; a Python module is just one. We'll see a few more.

In fact, Python dictionaries are a kind of namespace, because again they comprise a set of names and values. We look things up and store things under various keys which can be strings or names

:::Python
math2 = dict()
math2['pi'] = 3.2
math2['e'] = 2.71828

colors = dict()
colors['red'] = 0xff0000
colors['tan'] = 0xd2b48c

Indeed, my understanding is that Python's modules are implemented using dictionaries.

JavaScript objects are namespaces

We can do the same thing as Python modules in JavaScript by using objects, which are just like Python dictionaries. They also conveniently give us separate sets of names. For example:

:::JavaScript
math2 = {pi: 3.2,
         e: 2.71828,
         tan: function (angle) { "complex code here"; },
         sqrt: function (num) { "newton's method"; }
         };

colors = {red: 0xFF000,
          green: 0x00FF00,
          black: 0,
          white: 0xFFFFFF,
          tan: 0xd2b48c};
math2.tan != colors.tan;

The above code creates two objects that work just like Python modules: they give us module.name sets of names and the names are distinct, so if, by coincidence the same name is used in both modules, everything is okay.

Inside and Outside

From outside a module, you have to access a value using the dot notation, like math.PI. From inside a module, you can usually use a shorthand that omits the module name. That is, inside the math module, your code can just refer to PI and it means the PI in this module.

In fact, in Python a module doesn't necessarily know its name, and it can be imported as something else. In England, they probably do the following:

:::Python
import math as maths

print(maths.tan(2*maths.PI))

Can we do that in JavaScript? We can, but we will use the function namespace to do it.

What do we mean by a function namespace? A function has an "inside" and an "outside": inside the function, we can refer to local variables, and those are not useable from outside. We'll use a function's local variables for the inside of our module.

:::JavaScript
math2 = (function namespace() {
    var PI = 3.2;

    function area(radius) {
        return PI*radius*radius;
    }

    var mod = {};
    mod.PI = PI;
    mod.area = area;
    return mod;
})();

Title: Forms

Forms

This reading supplements Chapter 9, which introduces forms along with Bootstrap. This reading focusses just on the forms.

Forms are an import part of any website in which the user interacts, such as suppling information or making choices (e.g. menu options).

We will not be covering all aspects of HTML forms. We'll focus on just a handful that are useful in this course. If you want to learn more, there's some additional material at the end, and you're welcome to ask. The most important kinds of inputs we'll learn are:

  • text inputs (a single line of text, such as someone's name or favorite color
  • textareas (longer blocks of text, such as someone's address or blog entry)
  • menus (one of a set of choices, pre-defined by the form's author, such as
  • buttons, which don't so much give input as trigger behavior.

The form tag

HTML has a dedicated tag, form, that is used as a container to package data that might be sent to a web server. In this course, we won't always be submitting the form to a web server, so we will occasionally use form inputs without surrounding them with a form tag, but mostly we will use it. Your book does in Chapter 9.

The attribute method of the element allows the form to either request data from the server (method="GET"), or send data to the server (method="POST"). However, in order for both these operations to happen, the server needs to have some dedicated programs (also known as scripts) that can deal with the form data. At this point, we will not talk about how this happens (we'll postpone this discussion for later in the semester), and only concentrate on the HTML elements that are contained inside the form.

Let's see an example form, and then we'll look at the code that creates it.

Here's the code that creates that form:


As you can see, there's an outer FORM element that wraps up the form inputs. There are input elements that correspond to different places where the user can enter information. Most of the inputs use the INPUT tag, but some use tags like SELECT (for a drop-down menu) and TEXTAREA (for larger blocks of text). The general term is control. Finally, there's a BUTTON input at the end. In a more complete example; clicking this button would send the form data to the web server; this one doesn't do anything.

Form Fields

Let's look at the different input elements (also known as controls). The following table shows the HTML syntax for including different HTML elements in a form. As you will notice, the most common element is <input>, which, based on the value for its attribute type will display a different kind of input. Play with the rendered version of a tag in every row in the table.

Control HTML Rendered Control More Info
text:
<input type="text">
info
number:
<input type="number" min="1" max="120">
info
range:
<input type="range" min="100" max="200">
info
date:
<input type="date">
info
time:
<input type="time">
info
<button type="button">Click me</button>
info
long text:
<textarea rows="2" cols="10"> </textarea>
info
menu:
<select><option>Black <option>White </select>
info

For more information on the form elements and all its fields, consult the W3Schools page on forms.

Let's look at some of the more important controls, and then other aspects of forms.

The input Tag

The input tag is fairly straightforward, but you can specify the type of input you are looking for by using the TYPE attribute. It has many more types, which we are not listing here; consult W3Schools page for input to see the complete list. Here are just a few:

  • text: allows the user to type in a word or phrase
  • password: allows the user to type in a word or phrase, but its value isn't echoed, so no one can look over their shoulder and see it.
  • email: like a text type, but should look like an email address. New with HTML5.
  • date: for entering dates. New with HTML5.
  • time: for entering times. New with HTML5.

Some of these types (such as time, date, number, range, etc.) were introduced in HTML5, which means that not all browser versions are able to support them. For maximum portability, you should stick to type=text. However, sliders like we get with type=range are fun, and we'll use them sometimes.

The SELECT input

To specify a menu, from which the user can choose only one option, you use the SELECT tag inside the form. You specify the NAME of the input in the SELECT tag, and each menu item is specified using the OPTION tag. Here's an example:

<form action="">
  <p>Drink:  <select name="beverage">
      <option value="">choose one</option>
      <option value="Coke">Coca-Cola</option>
      <option value="Pepsi">Pepsi-Cola</option>
      <option>Beer</option>
      <option>Wine</option>
   </select>
</form>

(The closing </option> tag is optional, like a closing </p> tag or </li> tag, but it's best to use it.) Any option can have a separate "value" attribute; if none is specified, the value is the option itself.

Specifying a non-option as the first item in the list helps to tell whether someone has actually made a choice or just overlooked this menu. Making the non-option have a value of the empty string helps with validating the form, which we'll talk about later.

The textarea input

If you want to allow your user to type in a long response, you should define a textarea inside your form. This tag has attributes called ROWS and COLS that let you specify the size of the area.

<textarea name="thoughts" rows="3" cols="40">
A chicken is an egg's way of making another egg
</textarea>

The default value is the region between the beginning and ending tag. Typically, you want the default value to be empty, so put the tags right next to each other, as in this example here:

<textarea name="thoughts" rows="3" cols="40"></textarea>

Don't let even a single space creep in, or the initial value will be a string of one space, and not the empty string. That will affect any code that cares about the default or original value, such as certain kinds of validation

Labels

A form consisting of a bunch of bare boxes would be useless, so how is the user to know what input box means what? That's done with the label tag. There are two ways the label can be used. One option is to wrap both the input and the text in the label:

<label>
    Given Name
    <input type="text" name="givenname">
</label>

<label>
    Family Name
    <input type="text" name="familyname">
</label>

The other is to give the input an ID and reference that ID in a for attribute of the label. The <label> tag still wraps the textual label, but it no longer wraps the control/input.

<label for="givenname">Given Name</label>
<input type="text" name="givenname" id="givenname">

<label for="familyname">Family Name</label>
<input type="text" name="familyname" id="familyname">

The latter is a bit more work, but it is necessary in some cases where the structure of the HTML doesn't allow the input to be a child of the label, as with a table. Your book uses the for/id approach.

Using labels is important for accessibility. More on this below.

Name and Value

When the form gets submitted, the form data gets sent to the server. It gets sent as a set of name/value pairs, which we can think of as like a little table. Here's some data as if from our pizza form:

namevalue
customerHermione
phone555-8888
addrhgranger@hogwarts.ac.uk
sizelarge
due21:00
instructionsplease deliver by owl

Since the fields of a form need to be processed both by Javascript code on the client-side (by the browser) and the scripts on the web server, it is necessary to use the different attributes of these elements to distinguish and access them.

Consequently, the two most important attributes that we will use very frequently are name and value

  • The name attribute is chosen by us, the authors of the form. It is used by Javascript to reference the HTML elements that use it, but most importantly is used by the server to distinguish between the different fields of the submitted form. We will discuss it again later when we talk about submitting the form to the server. In the meantime, it will be good practice to start using it every time we create form fields.
  • The value attribute is the information from the user. It can be typed in by the user, chosen from a menu, or some other way.

Placeholder

Another useful attribute for input controls is placeholder, which can be used to provide a hint or example of the kind of value that should go in a field. For example, this HTML

<input type="text" placeholder="Hermione Granger">

will be rendered like this:

.

Radio Buttons

Radio buttons are used for a set of mutually exclusive options, like the buttons on a car radio, to choose the station.

Important: Radio and checkbox input items should all have the same name, so that they are considered as related. Without the same name, radio buttons will not be mutually exclusive.

HTML Rendered HTML More info
<label for="wbur">WBUR</label>
<input type="radio" name="station" id="wbur">
<label for="wzly">WZLY</label>
<input type="radio" name="station" id="wxly">
info

Try choosing one button and then the other.

Testing Accessibility

Accessibility is a big complex subject, and professional websites have trained developers, automated tools, and human testers to ensure accessibility. All that is outside the scope of this course, but I will introduce three important tools and require you to use them.

  • All HTML must be valid, which means it satisfies the structural rules set out by the WWW consortium (W3C). Valid HTML is important because screen readers and such can do a better job understanding the structure of the page if it follows the rules. Most browsers are much more forgiving, so don't assume that if it looks good in a browser that it's good.

    You can validate your HTML using this website from the W3C: https://validator.nu/. We've done this before in this course.

  • All CSS (see below) must be valid, for similar reasons as the HTML.

    The W3C also provides a CSS validator that works the same way as the HTML validator: https://jigsaw.w3.org/css-validator. Again, we've used this before.

  • Check the page for common accessibility issues with the WAVE, the Web Accessibility Evaluation tool, https://wave.webaim.org/. It's important to note that getting no errors from the WAVE tool doesn't mean your site is accessible — only a person can decide that — but it's a useful tool nevertheless. Not passing the WAVE test is certainly undesirable.

    Like the earlier validators, WAVE can retrieve a publicly hosted page given its URL and evaluate it. It doesn't have a mode where you can copy/paste your code, but there are two browser plugins that will evaluate the page in your browser. In less than 1 minute, I installed the Chrome plug-in, a page, and evaluated it.

Coffeerun From from Chapter 9

Here's the finished code from chapter 9

We'll explore it some, just to look at the form they created. Note:

  1. The controls that they created
  2. The names of those controls
  3. The values of the controls
  4. We'll try submitting the form and observer the name/value pairs in the URL
  5. The coffee input is an ordinary text input
  6. The emailAddress input is an email input (fallback to text if the browser doesn't support email)
  7. The size input is a set of radio buttons
  8. The flavor input is a dropdown menu
  9. The strength input is a range input type, which gives us a fancy slider widget
  10. We'll look at the submit button as well.
  11. We'll adjust the slider and see the numbers in the URL.
  12. We'll look at some of the CSS formatting that we get from Bootstrap.

Topics we didn't cover

  • fieldset and legend
  • checkboxes
  • size of inputs
  • validation
  • others?? Title: Forms and JavaScript

Forms and JavaScript

This reading supplements Chapter 10, which introduces JS code to process data that is entered into forms. We'll look at the following topics:

  • bind (this is from Chapter 8, but re-occurs in Chapter 10)
  • submit handlers
  • preventing defaults
  • jQuery and its pitfall
  • serializing forms
  • resetting forms

Binding this

We saw bind back in Chapter 8, but it rears its ugly head again in Chapter 10.

If you'd like to explore bind with more examples, check out the MDN explanation of bind

If you're not feeling okay about it, please talk to me or to our tutor.

Form Submission

Now let's talk about forms. HTML forms were invented so that a page could collect information from the user and allow it to be packaged up and submitted to a server for some kind of processing. Think about forms on Amazon.com or Ebay.com or any other kind of web application. Think about the customer feedback questionnaires we are constantly being asked to fill out. Even Facebook posts. All of those are forms being submitted to servers.

We can write JavaScript code that gets triggered when a form is submitted. In this chapter, the authors write some sophisticated, abstract code for setting up some general-purpose code for handling form-submission. In this part of the reading, we'll look at more concrete examples, so that the abstract code will make a bit more sense.

Let's start with the following form

Go ahead and fill it out and submit it if you like.

Submit Handlers

The first thing we want to do is add a JS function that will be invoked when the form is submitted. Form submission is a kind of event, so this is a kind of event handler.

What should our function do? For now, let's just alert the user that they submitted the form. A little bit of jQuery will suffice.

:::JavaScript
$("#form2").submit(function () { alert("form submitted!"); });

The jQuery submit method is just a shortcut for using on and the name of the event, which is what your book does:

:::JavaScript
$("#form2").on('submit', function () { alert("form submitted!"); });

Note that the URL changes when you submit this form, with your form data (key/value pairs) appearing in the URL.

Preventing Defaults

Usually, we want to send the data to a server when a form's submit button is clicked (or the user presses enter in a text field), but in this case we don't. We want to prevent the default behavior, so we'll change our event handler to get the event object and use the preventDefault() method:

:::JavaScript
$("#form3").on('submit', function (evt) {
    evt.preventDefault();
    alert("form submitted!");
});

Note that the URL doesn't change with this event handler. Of course, that's because we've prevented the default behavior.

jQuery and its pitfall

What's wrong with the following combination of HTML and CSS and JavaScript?

:::HTML
<form id="form3"> ...</form>
:::CSS
#from3 { border: 1px solid green; }
:::JavaScript
$("#from3").on('submit', function () { alert("submitted"); });

Right; spelling. In CSS, you won't get an error message; it's just a rule that doesn't happen to apply to anything. Similarly, in jQuery, it'll look up everything that matches that selector, and add the given function as a submit handler. Alas, nothing matches that selector, but jQuery doesn't give you an error message. It treats it as an empty set: valid but useless.

Sometimes, jQuery's behavior is exactly what you want, but often, you'd like to know if you've done something wrong. So check the number of matched items:

:::JavaScript
var $form = $("#from3");
if ($form.length === 0) {
    throw new Error("couldn't find form...");
}
$form.on('submit', function () { alert("submitted"); });

(In the code above, we've used a dollar sign in the name of the variable. That's a common but not universal convention for variables that contain jQuery results, since it helps you remember that you can use jQuery methods on the value of that varible. But it's also a little ugly. Your book chooses to use this convention; don't let it bother you.)

In fact, you might even create a higher-level function that will search, check and then add the event handler. Like this:

:::JavaScript
function addFormSubmissionHandler(selector, fn) {
    var $form = $(selector);
    if ($form.length === 0) {
        throw new Error("couldn't find form...");
    }
    $form.on('submit', fn );
}

That's what they've done in this chapter. Actually, they also know that whatever submit handlers they write, they always want to prevent the default behavior of submitting the form, so they do this:

:::JavaScript
function addFormSubmissionHandler(selector, fn) {
    var $form = $(selector);
    if ($form.length === 0) {
        throw new Error("couldn't find form...");
    }
    $form.on('submit', function(evt) {
        evt.preventDefault();
        fn();
     });
}

One important thing to notice about the code above is how a function (fn) is passed in. That function does the rest of the work of the form submission handler. So, you can think of the addFormSubmissionHandler function as:

  1. find the form using a selector
  2. if the selector didn't work, complain
  3. set up a submission handler for that form
  4. the submission handler will do some routine stuff and then,
  5. invoke a function arg to do the specific stuff for this form

Serializing Forms

In general, forms have several inputs and all of them get packaged up and submitted to the server. To do that, the form inputs have to each be converted into strings and those strings have to be concatenated together. That process is called serializing. The key with serializing is that it has to be reversible: all of it has to be done in a way that the server can reverse the process and get back the original set of name/value pairs.

jQuery has a method that will serialize a form for you. It's called, unsurprisingly, .serialize(). You can also get the inputs as an array of objects; that's called .serializeArray(). Each object in the array consists of a single name/value pair from the form. That is, a form asking about pizza preferences:

:::HTML
<form id="pizza">
    <input name="kind">  <!-- e.g. pepperoni or veggie --> 
    <select name="size">
        <option>large (16 inch)</option>
        <option>medium (14 inch)</option>
        <option>personal (12 inch)</option>
    </select>
</form>

Might serialize like this:

:::JavaScript
$("#pizza").serializeArray();
[{name: 'kind', value: 'veggie'},
 {name: 'size', value: 'personal (12 inch)'}]

Check out jQuery .serializeArray to learn more.

In this chapter, they arrange for all form submission handlers to serialize the form into an array, and then collect all the form inputs into a single object. Like this:

:::JavaScript
var data = {};
$(this).serializeArray().forEach(function (item) {
    data[item.name] = item.value;
    });

The earlier pizza form would serialize into an object like this:

:::JavaScript
{kind: 'veggie',
 size: 'personal (12 inch)'}

The form submission handler then invokes the callback function with the form data object as its input. So the overall plan is now:

  1. find the form using a selector
  2. if the selector didn't work, complain
  3. set up a submission handler for that form
  4. the submission handler will do some routine stuff namely
    • prevent the default, and
    • serialize the form into a single object
  5. invoke a function arg with the form data object to do the specific stuff for this form

Here's the code:

:::JavaScript
  FormHandler.prototype.addSubmitHandler = function (fn) {
    console.log('Setting submit handler for form');
    this.$formElement.on('submit', function (event) {
      event.preventDefault();

      var data = {};
      $(this).serializeArray().forEach(function (item) {
        data[item.name] = item.value;
        console.log(item.name + ' is ' + item.value);
      });
      console.log(data);
      fn(data); // invoke the callback with the form data
    });
  };

Re-read the code above keeping the abstract plan in mind.

Bind

They've set up this very abstract code to attach a submission handler to a form with the routine stuff factored from the specific stuff. The code for the specific stuff will be passed in as a callback function. Now they'll use this to attach a submission handler to a form.

Unfortunately, the callback function that they want to use is, in fact, a method. It's the createOrder method of a Truck object. So, they'd like to do the following:

:::JavaScript
var myTruck = new Truck('ncc-1701', new dataStore());
var formHandler = new FormHandler(FORM_SELECTOR);
formHandler.addSubmitHandler( myTruck.createOrder ); // doesn't work

The last line doesn't work. It doesn't work because createOrder is a method, and it needs a value for this. We could do the following:

:::JavaScript
var myTruck = new Truck('ncc-1701', new dataStore());
var formHandler = new FormHandler(FORM_SELECTOR);
formHandler.addSubmitHandler( function (form_data) {
     myTruck.createOrder(form_data);
     });

but it works just as well do to the following:

:::JavaScript
...
var myTruck = new Truck('ncc-1701', new dataStore());
var formHandler = new FormHandler(FORM_SELECTOR);
formHandler.addSubmitHandler( myTruck.createOrder.bind(myTruck) );

The latter is what our book uses. Use whichever technique you understand better. Using bind is also a little more concise, though that's not an important reason.

Grid Systems, Skeleton and Bootstrap

When we have a display device larger than a phone, we often want to switch to a different layout, with different columns and such. For example, we might have a nav bar on the left and a twitter feed to the right in addition to a wide column of main content in the center. We might even have multiple columns of content. To make things neat and orderly, we often have a layout based on a grid. (Typically, you'll see the grid based on 960px, not because that amount matches any device size, but because 960 is divisible in lots of ways.)

For an idea of the theory, please read the Mozilla Developer Network article on grids Fair warning, though, it is long. Stop when you get to Line-based Placement. Our goal is to learn the basic concept and some of the techniques, but not every detail.

In this class, I'm using Skeleton which I like a lot because it's simple and well-documented. However, I acknowledge that many people like Bootstrap, and you're welcome to use that, too. The MDN article used to mention both Skeleton and Bootstrap; but it's been revised.

Form Validation

Chapter 12 on form validation is pretty clear, except that it doesn't explain much about regular expressions.

Regular expressions are a powerful and efficient way to match a pattern against a string. Most civilized programming languages have them available, either built-in or as an easily loaded module.

You should think of regular expressions as a whole new language with its own syntax and grammar. It's not a programming language, but it definitely changes the meaning of different characters. Unfortunately, there are often variations in the regular expression languages from Java to Python to JavaScript and so forth.

The MDN article on regular expressions in JavaScript is good and comprehensive, probably more comprehensive than we need. Read the book chapter first, so you understand the role that regular expressions will play, then read part of the MDN article to learn a bit more. Specifically, read from the beginning, up until it explains the meaning of the decimal point. That will explain all the stuff going on the the chapter.

What is Form Validation?

Later in the course, we'll talk about submitting the form data to a server for more elaborate processing, but before we do that, we should discuss validation. What is form validation? Essentially, it means checking to see that the form has been filled out correctly (as far as we can tell).

Form validation could be used to ensure that someone hasn't overlooked a text input, menu or radio button group, and can check that, for example, the zip code is 5 digits (or 9) and that a telephone number is 10 digits, and that an email address looks like an email address.

Form validation can actually cancel the submission of the form, so that the data never leaves browser. The reason we validate forms is twofold: to give the user immediate feedback that they've missed something, instead of waiting for the server to respond, and to protect the server from having to handle all those invalid forms. Of course, a determined nefarious person can simply disable our form validation JavaScript and hammer our server with invalid forms, but that's rare. The vast majority of invalid forms are just human error.

Obviously, the browser can't tell whether you entered your correct phone number, but it can check that you typed the right number of digits (and only digits). Similarly, it can't check that your spelled your name correctly (and whether your name really is Mickey Mouse), but it can check that you didn't leave that input blank.

With HTML5 and modern web browsers, form validation has gotten a lot easier. In the past, web developers would write JavaScript code that would look at the values in the form to check for bogus values. They wrote libraries and jQuery plug-ins to make the job easier for others.

However, the vast majority of form validation can be done with a few simple things:

  • Add the attribute required to any input that you want to require the user to fill out.
  • Use the fancy new form input types that HTML5 has added, such as:
    • tel, for telephone numbers
    • email, for email addresses
    • date, for just a date (year, month, day)
    • time, for time (hour, minute, seconds)
    • datetime, combining date and time inputs
    • and others

Here's a demonstration:

<form action="/cgi-bin/dump.cgi">
  <p>Username: <input required name="username">
  <select required name="hogwarts_house">
    <option value="">Hogwarts House</option>   
    <option>Gryffindor</option>
    <option>Hufflepuff</option>
    <option>Ravenclaw</option>
    <option>Slytherin</option>
  </select>
  <p>Email address: <input required name="email" type="email">
  <p>Birthday: <input required name="birthday" type="date">
  <p><input type="submit" value="submit form">
</form>

Here's the actual form, so you can change the values of inputs:

Username:

Email address:

Birthday:

Try to submit an incomplete form!

Ajax

Before Ajax, the way that a browser communicated with a server (the "back-end") was typically to submit a form (or get a URL), whereupon the web page was replaced with the response. That replacement can sometimes interrupt a user's experience. Imagine if everytime you clicked "like" on a Facebook page, the entire page was replaced with a new one, even if it looked 99% like the old one.

Ajax is a powerful modern technique whereby a browser page can communicate with a server without having to be replaced by the response. Instead, it's in a kind of "side" conversation going on in parallel (asynchronously) with the browser paying attention to you.

Asynchronous Requests

When we invoke a function, we wait around for the response, like this, and then we can use the result as the argument to other functions:

:::JavaScript
var val = foo(x);
bar(val);
more_work();

That's fine in the context of normal programming, but it doesn't work for lengthy operations. Suppose foo took tens of milliseconds to return. Not only does bar have to wait (it would anyhow), but so does more_work, even if it doesn't depend on foo. More importantly, if the browser has something else to do (such as pay attention to the user), it can't be sitting around waiting for foo to complete.

Instead, we want to use an asynchronous style of programming, where instead of foo returning a value, we pass foo a function that it should invoke on the result. Meanwhile, neither more_work nor the browser will have to wait for foo to complete. Here's the programming style:

:::JavaScript
foo(x, bar);
more_work();

The more_work function and whatever else the browser is doing can execute immediately. Some tens of milliseconds later, once foo is done, foo will arrange to invoke bar.

That's how Ajax works, because the Ajax call starts a network connection to the server and waits for the response:

:::JavaScript
$.post('url', data, func);

The first argument is the URL of the server to send the data to. The second argument is the data, usually as a JavaScript object literal. Finally, the last argument is a callback function that will get invoked with the response from the server. Here's a bit more detail:

function gotit (response) {
    console.log('Got '+response);
}

$.post('url', data, gotit);

In the coffeerun app, they send the data to an application they have running on Heroku.

The .get() method works the same way. In fact, both are wrappers for a general .ajax() method that needs to know what HTTP request you want to make:

:::JavaScript
$.ajax('url', {type: 'get', data: data, success: func});
$.ajax('url', {type: 'post', data: data, success: func});
$.ajax('url', {type: 'delete', data: data, success: func});

LocalStorage

Instead of saving things to a remote server, you can save them in the browser, using localStorage. Note that localStorage is persistent, which means that it will last even if you quit the browser and restart it, even days later. That's not the case with regular JavaScript variables, which live just in that one browser tab and will disappear if the browser tab is closed or re-loaded, let alone restarting the browser.

Setting a value

To store something in the local storage of your browser, any of the following will work:

:::JavaScript
localStorage.fred = 'Fred Weasley';
localStorage['george'] = 'George Weasley';
localStorage.setItem('harry', 'Harry Potter');

To get the values back out, just use the expressions on the left hand side, or the getItem method:

:::JavaScript
console.log(localStorage.fred);
console.log(localStorage['george']);
console.log(localStorage.getItem('harry'));

There are also methods .removeItem which removes a single key, and clear which removes all keys. Title: Inheritance in JavaScript

Inheritance in JavaScript

Object-oriented programming (OOP) has many advantages:

  • data abstraction: objects hide implementation and provide behavior
  • polymorphism: objects can provide similar behavior for different types

In addition, OOP often provides for inheritance. That is, the behavior of a class can be extended or modified in subclasses.

We'll see how all these play out in JavaScript.

A good companion reading to this is the MDN article on Inheritance in JavaScript. The article has some good but different examples.

Data Abstraction

Suppose we are using JavaScript for a 2D computer graphics system. In our system, we're going to have rectangles.

How shall we represent them? We could do any of the following:

  • upper left and lower right corners
  • upper left corner, width and height
  • any two corners
  • center and width and height
  • ...

What if we decide on a representation and change our minds later? Will that affect the users of our system?

What kind of behavior (methods) do we want to support? We might list quite a lot of methods, including drawing it on the screen (which we will not discuss unless you twist my arm). For now, we're only going to provide the area method.

Regardless of how we represent the rectangle internally, how shall we allow the user to construct a rectangle?

For the purposes of this example, suppose we allow the user to give any two corners in the constructor.

Furthermore (switching to the other side of the abstraction barrier), let's suppose that we decide to implement the representation as the upper left and lower right corners.

Here's a JavaScript implementation of rectangles. Please read the code; it's only about 20 lines.

Abstraction Barrier

The client of these rectangle objects only knows that they can report their area. They don't know or care what the internal representation is. This is called an abstraction barrier.

The implementor of these rectangle objects provides a constructor and that behavior (method).

Note that, the implementor might decide that, if clients ask for the area a lot, maybe it would make sense to pre-compute it, or switch to a representation that doesn't require so much computation. The behavior remains the same, but it's now faster and more efficient. We have the freedom to change our representation.

Polymorphism

Suppose that we also want to have circles. They should also support an area method. What will the internal representation be?

  • Center and radius?
  • Top and bottom points?
  • Left and right points?

Here's an implementation of rectangles and circles. Please read the code. The new circle code is only two dozen lines.

Note at the end of that code that we have a list of objects, some of the rectangles and some of the circles. We can compute the area of all of them by using the area method that they both support.

This is called polymorphism: a single interface to entities of different types.

One thing that's great about polymorphism is that we don't have to have a "master" function that knows how to compute the area of all kinds of shapes (and which then needs to be updated if we add a new kind of shape). Instead, the knowledge of how to compute the area of a shape is distributed among the shapes. Each knows how to compute its own area.

Inheritance

What if we have some behavior that is common to both rectangles and circles? Since we are supposing that this a 2D graphics system, maybe each has to keep track of its color (fill mode, stroke width and many other such properties).

We will define a new class called Shape. It will take a color as its argument. We'll also define methods to get and set the color and one to help print a shape, overriding the toString() method that every object inherits from Object, the ancestor of all JavaScript objects.

:::JavaScript
function Shape(color) {
   this.color = color;
}

Shape.prototype.getColor = function () { return this.color; };

Shape.prototype.setColor = function (color) { this.color = color; };

Shape.prototype.toString = function() {
    return "[A "+this.color+" "+this.constructor.name+"]";
};

var s1 = new Shape("red");
console.log("s1 is "+s1.toString());

The constructor property

As you surely noticed, an object can know what function constructed it. For s1 it's the Shape function. Functions have properties like name, which we used here in our toString() method.

Using the constructor name is not common, but it clarifies some of the issues we will discuss next.

Defining Subclasses

We'll redefine our classes for rectangles and circles to use inheritance. In honor of this change, we'll call them Rectangle and Circle.

Both of our Rectangle and Circle classes will inherit from Shape. (Shape will be described as the parent class or sometimes the superclass. Rectangle and Circle will be described as the child class or the subclass.)

Setting up inheritance requires several steps:

  • To properly initialize a new object, we must invoke the parent's constructor from the child's constructor. True, we could assign the color instance variable ourselves, but what if the parent changes the initialization code, say to check the color? Then we'd have to copy those changes to every child: very bad.
  • We have to specify that the child's prototype is an instance of Shape. Since each object inherits instance variables and methods from its prototype chain, we have to make sure that chain is correct.
  • Setting the child's prototype has the unwanted side-effect of changing the constructor property, which we use in the name, so we set it back to the correct value.

Here's a high-level view of creating a subclass:

:::JavaScript
function Rectangle(color,c1,c2) {
    // initialize using superclass
    Shape.call(this,color);
    ...
}

Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle; 

Here we see a good use of the call method that functions have. We invoke the Shape function but we supply a value to use for this (it happens to be the same as the current this) and any additional arguments it needs.

The following file has a complete implementation of these ideas, with rectangles and circles. It also adds Triangles, but it "forgets" to set the prototype and prototype constructor. The result is that triangles don't inherit from Shape, which you can see in the console.log output.

Here's the file: shapes.html

Please read the code; it's not terribly long, and much of it is familiar to you from the earlier examples, so you can focus on the differences.

Notice that one of the cool things about inheritance is code reuse: all the children (grandchildren and further descendants) of Shape get its methods.

The instanceof Operator

There is a special JavaScript operator that will go through the prototype chain for an object to determine whether it inherits from a particular "class". Remember that JavaScript doesn't really have classes; we simulate that with constructor functions, so the constructor functions stand in for classes:

:::JavaScript
// All true
console.log("r1 instanceof Rectangle: "+(r1 instanceof Rectangle));
console.log("r1 instanceof Shape: "+(r1 instanceof Shape));
console.log("r1 instanceof Object: "+(r1 instanceof Object));

// False
console.log("r1 instanceof Circle: "+(r1 instanceof Circle));

New Syntax

In JavaScript/ECMAScript 2015, a new syntax was introduced for defining classes. At the same time, they introduced a new syntax for inheritance, namely the extends keyword to the new class syntax. For a quick introduction, see the following:

One important thing to note is that you must invoke the constructor for the parent class using super(); that invocation is not automatic. You can also use super in method definitions, which is very cool.

Example

The following file re-implements the shapes from above, using the new syntax.

Here's the file: shapes-new.html

With the new syntax, it's impossible to get the prototype chain wrong, so it's a clear winner.

Summary

Many object-oriented languages, such as Java and Python, have classes and objected, with classes being the templates and factories for objects. JavaScript doesn't have this "classical" (as Douglas Crockford, author of JavaScript: The Good Parts, describes it) inheritance system, but instead uses prototype chains. Nevertheless, we can implement this classical OOP inheritance in JavaScript, and many JavaScript libraries do so. For example, Threejs, a library for doing 3D computer graphics in JavaScript.

Galleries and Drop-downs

Our topic for the next class is learning how to do two very common tasks on websites: image galleries (slideshows) and drop-down menus.

There are many solutions for these problems, including fancy transitions between slides and much more. We're going to keep it fairly basic, though.

Rather than write up how to do this, I'm going to defer to two descriptions that are on W3Schools. Let me know whether you find the links below reasonably clear. We will talk about them in class and implement some examples.

Slideshows

A slideshow displays one of a set of images, rotating through them. It has arrows to advance the slideshow or move it backwards, little buttons to indicate where we are in the set and lots of other eye candy.

slideshow

Automatic Slideshows

To have a slideshow automatically advance, it's sufficient to have a function that will manually advance the slideshow, and then have the browser invoke that function every few seconds. That's easily done with the built-in JavaScript setInterval function.

Learn more about setInterval from MDN: setInterval

Clickable Dropdowns

We want to be mobile-friendly and old-fashioned drop-down menus typically drop-down when the mouse is hovered over them. But we can't "hover" on a touch-screen device. Instead, we will click to open/close a drop-down menu. Here's one way:

clickable dropdown

jQuery UI

jQuery itself is a JavaScript library for manipulating the DOM in a convenient way. We've used it many times this semester.

However, there are lots of common user interface (UI) widgets and effects that people commonly want to do that jQuery doesn't do. Fortunately, many of these UI widgets and effects are packaged up in something called jQuery UI.

In this reading, I'll ask you to look at a selection of these. There is nothing particularly special about the ones I've chosen except that I have used most of them in the past and found them helpful and relatively easy to use.

jQuery UI Overall

First, take a few minutes to look over the home page and look at the options:

jqueryui.com

Then, take the time to read the about page: about jQueryUI

Next, I'll ask you to look at several specific items. Each item has a main page with a demo. In fact, it usually has several demos; make sure you study at least the default demo. The demo will have a way to look at the source code of the demo. Please look at the source code.

You'll notice that the source code usually loads quite a few files and other code, such as

  • jquery-ui.css
  • some additional custom CSS
  • some example-specific CSS in a style tag
  • jquery itself
  • jquery UI
  • some example-specific JavaScript, that puts these libraries into action.

So, when you're reading the code, don't neglect to notice all these parts.

You'll see that these jQuery UI features have "API documentation" that shows how they can be customized in a bewildering number of ways. We typically won't be using these customizations; we'll try to stick to the most common cases. You're welcome to look at the API documentation, but I am not asking you to do that on this first reading. Let's get the high-level view down first. Still, it's good to know that if a jQuery UI feature is close to what you want but not quite right, it's probably customizable in the way that you want.

In class, we'll get some more experience with using these.

  • autocomplete Developers should always use this for "state name" when asking for an address.
  • datepicker So easy and useful. We'll use this in the final project as well
  • tabs A nice way to organize a page without having lots of scrolling or switching to other pages. jQuery Mobile is based on this idea.
  • sortable We might use this in the final project

Four features should be enough to get us started, but if there is something else that you see that you think is cool, let me know and we'll see if we can learn about it.

Title: Google Maps

Google Maps

Google Maps is a useful feature to add to many websites and it's (almost) free! Both Google and the W3Schools have nice tutorials and a number of fun examples. We won't read all of them, but a few will be helpful.

API Key

I said Google Maps was almost free. What that means is that Google generously allows you to make queries to their map servers per month for free (it's many thousands), but after that, they will bill you (and the charge is pretty low, $7 per thousand queries, I believe).

Unfortunately, all of that means that in order to use Google Maps, they need to be able to bill you, even if you're just playing around and won't be doing industrial-scale numbers of queries.

This "we need to be able to bill you if we need to" policy, while understandable, is a serious impediment for us. If you have a personal Google account, you can give them a credit card for billing purposes then create an API key and use that.

Unfortunately, the Google accounts that we have thanks to Wellesley College don't allow us to add a credit card. So, I've given my credit card to Google for my personal Google account, and created an API key for that. I can share that with you for educational purposes; just don't cost me any money. :-)

So, when you read these tutorials and they refer to the API key, understand that that is a unique identifier that tells the Maps server who is making the query, so that they can count how many queries you make and, if it gets beyond the free level, can bill you.

Google's Tutorial

First, read this one (longish) web page that is Google's tutorial on adding a Google Map with a Marker

Tutorial

Then, please read through the first two pages of the W3Schools tutorials (linked below). You can just start at the first one and click the big green "next" button on each page.

  1. Maps Intro This is the set up to show a nice, static map, at a place of your choosing (specifying the center given a latitude and longitude. Note that latitude measures north/south location and ranges from -90 (south pole) to +90 (north pole). Longitude measures east/west location and ranges from -180 (middle of the Pacific) to +180 (same as -180) with 0 degrees longitude being Greenwich, England.
  2. Maps Basic This is more information on the basic map, explaining about the map container (a div) and the initialization function. It also shows a demo of four different map types (ROADMAP, SATELLITE, HYBRID, and TERRAIN)

Title: Accessibility

Accessibility

A website is accessible if it can be used effectively by people who have disabilities, such as blindness, deafness, or paraplegia. We've mentioned accessibility many times in this course, and we've made it an important part of the way we build web sites. This reading will cover a lot of what we haven't yet covered, though we won't be able to cover everything we would like to.

Motivation

Overall, the web has been good for accessibility. Because the text is already in computer form, it can be easily processed by a screen reader for the blind (as opposed to print, which would first require optical character recognition). Nevertheless, many modern websites can be frustratingly difficult for people with disabilities.

We can assume that the designers who made the inaccessible websites didn't set out to do so. Most of us see the need and responsibility for building designers to allow for wheelchair ramps and curb cutouts to allow access to public buildings, along with braille signs in elevators and many other accommodations. Furthermore, the Americans with Disabilities Act or ADA requires that many websites be accessible in the same way that public buildings must be accessible. See the website Web Accessibility in Mind for much more information. Much of what is covered in this reading is drawn from that resource. Their materials are copyright © 1999-2016 WebAIM (Web Accessibility in Mind).

The POUR Principles

Having decided to build an accessible website, we have to figure out what that means. First, consider different kinds of disabilities:

  • Visual: people can be blind, have low-vision, be color-blind, and more
  • Auditory: people can be deaf or hard of hearing
  • Motor: people can be unable to use a mouse, be slow or lack fine motor control
  • Cognitive: people can have learning disabilities or poor ability to focus

To make a website accessible, we want to keep four guidelines in mind:

Perceiveable
The information should be accessible by the visitor's working senses, so, for example, information should not be presented solely by sound (a video with narration but no captioning).
Operable
The website shouldn't require the use of a mouse in order to access the information
Understandable
The content is clear, at least to the target audience.
Robust
The website should be accessible to a wide range of assistive technologies

These make the acronym POUR.

Checklist Dozen

These are wonderful principles, but our task in this reading is to see how to achieve them. Let's start with a list of the dozen most important principles. I've copied this list from the WebAIM website, and I've included links to their elaboration on each principle. You're encouraged to go to their site to learn more.

Provide appropriate alternative text
Alternative text provides a textual alternative to non-text content in web pages. It is especially helpful for people who are blind and rely on a screen reader to have the content of the website read to them.
Provide appropriate document structure
Headings, lists, and other structural elements provide meaning and structure to web pages. They can also facilitate keyboard navigation within the page.
Provide headers for data tables
Tables are used online for layout and to organize data. Tables that are used to organize tabular data should have appropriate table headers (the <th> element). Data cells should be associated with their appropriate headers, making it easier for screen reader users to navigate and understand the data table.
Ensure users can complete and submit all forms
Ensure that every form element (text field, checkbox, dropdown list, etc.) has a label and make sure that label is associated to the correct form element using the <label> element. Also make sure the user can submit the form and recover from any errors, such as the failure to fill in all required fields.
Ensure links make sense out of context
Every link should make sense if the link text is read by itself. Screen reader users may choose to read only the links on a web page. Certain phrases like "click here" and "more" must be avoided.
Caption and/or provide transcripts for media
Videos and live audio must have captions and a transcript. With archived audio, a transcription may be sufficient.
Ensure accessibility of non-HTML content, including PDF files, Microsoft Word documents, PowerPoint presentations and Adobe Flash content.
In addition to all of the other principles listed here, PDF documents and other non-HTML content must be as accessible as possible. If you cannot make it accessible, consider using HTML instead or, at the very least, provide an accessible alternative. PDF documents should also include a series of tags to make it more accessible. A tagged PDF file looks the same, but it is almost always more accessible to a person using a screen reader.
Allow users to skip repetitive elements on the page
You should provide a method that allows users to skip navigation or other elements that repeat on every page. This is usually accomplished by providing a "Skip to Main Content," or "Skip Navigation" link at the top of the page which jumps to the main content of the page.
Do not rely on color alone to convey meaning
The use of color can enhance comprehension, but do not use color alone to convey information. That information may not be available to a person who is colorblind and will be unavailable to screen reader users.
Make sure content is clearly written and easy to read
There are many ways to make your content easier to understand. Write clearly, use clear fonts, and use headings and lists appropriately.
Make JavaScript accessible
Ensure that JavaScript event handlers are device independent (e.g., they do not require the use of a mouse) and make sure that your page does not rely on JavaScript to function.
Design to standards
HTML compliant and accessible pages are more robust and provide better search engine optimization. Cascading Style Sheets (CSS) allow you to separate content from presentation. This provides more flexibility and accessibility of your content.

This list does not present all accessibility issues, but by addressing these basic principles, you will ensure greater accessibility of your web content to everyone. You can learn more about accessibility by browsing our articles and resources.

Images

There are generally two kinds of pictures on a website: informative and decorative. If a picture is informative, you must provide some way for a blind user to get equivalent information in a textual form. The usual way to do this is to provide an ALT attribute on the image:

Daniel Radcliffe as Harry Potter
    <img src="../images/harry-potter-thumb.jpeg"
         alt="Daniel Radcliffe as Harry Potter">

Note that this ALT is often incorrectly called an "alt tag" but of course it's an attribute not a tag. The general concept of providing a textual alternative is called "alt text," so that's probably the easiest and best way to describe this. Also, the alt text doesn't say "picture of ..." because that will be clear from the screen reader.

However, sighted people won't (typically) read this alt text. Maybe the text preceding this image says that Daniel Radcliffe plays Harry Potter, but a better way to do this would be to use a FIGURE and a CAPTION:

Daniel Radcliffe as Harry Potter
    <figure>
        <img src="../images/harry-potter-thumb.jpeg" alt="">
        <figcaption>Daniel Radcliffe as Harry Potter</figcaption>
    </figure>

In this case, the screen reader software can use the caption as the ALT text, so we explicitly leave the ALT attribute empty, so that the blind visitor isn't having the same text read twice.

This figure with a caption is now better for both blind and sighted visitors, an example of where accessibility can improve the experience for everyone.

What about other uses of images, say with slideshows and galleries? In most cases, a similar approach will work: if the sighted visitor is expected to get some information from the picture, you should provide that same information in textual form. A gallery of pictures showing the executive board of your club, should have each person described with a caption. If the pictures are somewhat generic, it's reasonable to give a common caption ("picture from our annual soccer game") that will apply to all the pictures in the slideshow.

If a picture is purely decorative (a picture of a soccer ball on the page describing the annual soccer game), the ALT text can be explicitly set to the empty string. Alternatively, you can make the image be a background image using CSS:

   #soccerball {
      width: 240px;
      height: 240px;
      background-image: url(/images/240px-Soccer_ball.svg.png);
   }

   <div id="soccerball"></div>

The advantage of a background image is that, using media queries, you can easily omit these decorative images when the screen size is small.

Videos and Audios

Video and audio elements pose the same issues as still images. Blind visitors won't be able to see your video, so it should have a textual transcript. Deaf visitors won't be able to hear the narration or speakers, so the video should have captioning. This is not always easy or inexpensive. However, there is a benefit that search engines will be able to do a better job with indexing this content if the textual equivalent exists.

We already know that hyperlinks shouldn't have "here" or "more" as the click text. Screen readers often read links out of context, so the link text should stand on its own. However, there's a lot more to know about hyperlinks. Here are just a few items:

  • People expect that links are underlined. Unless the context makes the link obvious (a navigation bar), don't use CSS to remove the default underline
  • An image that is a hyperlink will use the ALT text as the description of the hyperlink.
  • Don't say "link to X" or "go to Y"; the screen reader will indicate that the element is a hyperlink

If you want to learn even more, I suggest Making Accessible Links: 15 Golden Rules for Developers.

Labels for Form Controls

Each form control (input element, such as a text input or a menu) needs to have a label. It can be tempting to omit the labels when you have placeholders and such, but labels are necessary.

Avoid Color

Not everyone sees colors correctly. Color blindness is more common in men than in women, but it does happen in both sexes. Don't use color as the sole means of conveying information. It's fine, for example, to mark the required form inputs with red, but you should also add a bit of text or an asterisk or something. It can be a red asterisk.

Accessible JavaScript

  • don't use mouseover, mouseout and hover, since those are mouse-only
  • use :focus for links that are in focus

Accessible jQuery

Many jQuery methods, such as .hide() and .slideUp() use the CSS setting display:none to achieve the hiding. That method means the resulting content is inaccessible to a screen reader. If you don't want that, a better idea is to add an after-event handler to the jQuery code to display the content but offscreen (or using one of the other techniques for hiding content).

Learning More

Conclusion

Assistive software and hardware are always evolving, as are the CSS techniques that attempt to help them while not hindering other visitors. The main thing is to consider accessibility when you are considering coding some fancy new interface: will it work if the user only has a keyboard? will it work if the user is blind? Will it work if the user has limited motor control? Sometimes, this will mean foregoing that fancy feature, but the goal of making our website for all instead of the lucky few is worth the price.