Web Application Programming

Andrea De Lorenzo, University of Trieste

Class Schedule

Day Time Room
Monday 09:30am - 11:00am Aula V - Building G
Tuesday 03:00pm - 04:30pm Aula 4C - Building H2 bis
Wednesday 01:00pm - 02:30pm Aula 4C - Building H2 bis

http://delorenzo.inginf.units.it/

Class Format

  • In-person lectures, also recorded
  • Recordings available for about 6 months in the course Team
  • Access to the course Team via code:

2ajhwxg

Communications

Telegram Channel

https://t.me/+lRnU-qwJPP1kMGY0

Prerequisites

  • HTTP (Computer Networks)
  • Java
  • Databases

Programming Today

Some Numbers

Programming Today

Some Numbers:

  1. JavaScript
  2. Python
  3. Java
  4. PHP
  5. C#
  6. TypeScript
  7. CSS
  8. C++
  9. Ruby
  10. C

Course Program

Web Application Programming

Principles, methods, and techniques of web programming



But what does it actually mean?

Course Program

But what does it actually mean?

  • ≠ nstalling or configuring
    • Google Sites
    • Wordpress
    • Joomla
    • Drupal
    • etc.
  • ∞ Platforms and tools

Course Program

Practical Course, a lot of technologies:

Don0t use PHP
  • client side:
    • HTML, CSS, JavaScript
    • Ajax, VueJS
  • server side:
    • Node.js
    • Web Services

In practice: how to create a web application

Software

We will only use products available online, for free:

Teaching Materials

  • These slides, available on the instructor’s website
    (possibly released incrementally)
  • Additional references mentioned in the slides
    • optional
    • mandatory (→ official part of the syllabus))
  • For those who want to explore further:
    • "JavaScript Patterns", di Stoyan Stefanov
    • "JavaScript: The Good Parts", di Douglas Crockford
    • "You Don't Know JS Yet", di Kyle Simpson

Optional Teaching Materials

Programming Books:

  • "The Pragmatic Programmer: From Journeyman to Master", di Andrew Hunt
  • "Clean Code - A Handbook of Agile Software Craftsmanship", di Robert C. Martin
  • "Design Patterns", di Gamma, Helm, Johnson e Vlissides
  • "Refactoring: Improving the Design of Existing Code", di Martin Fowler

Optional Teaching Materials

Design Books:

  • "Design of everyday things", di Don Norman
  • "Designing with the Mind in Mind: Simple Guide to Understanding User Interface Design Guidelines", di Jeff Johnson
  • "Don't make me think. Un approccio di buon senso all'usabilità web e mobile", di Steve Krug
  • Seminario di Mark Miller sul design delle UI

Exam Format

  1. Final practical project (“tesina”), to be submitted three days in advance
  2. Oral exam starting with the presentation of the project

Exam Format

Some details:

  • Individual work
  • Specifications provided by the instructor
  • Specifications change at the beginning of a new course

Web Programming

WARNING!!

The technologies we will see:

Final goal: teach how to fish, rather than give the fish.

Looks simple...

Web Programming

Always evaluate:

  • How many users?
  • Required reliability?
  • Does something already exist that solves the problem?
  • Where will it reside on the server side?
  • Monolithic solution?
  • Modular solution (micro-services)?

HTML

HTML

HyperText Markup Language (HTML)

Language used to describe the content and the structure of the information in a web document

It does not describe the presentation of the information!

web page = web document

Brief History

  • Prehistory: CERN
    • 1991 → HTML (draft) first publicly available description
    • 1993 → HTML+ (draft)
    • 1995 → HTML 2.0
  • Yesterday: W3C
    • 1/1997 → HTML 3.2
    • 12/1997 → HTML 4.0
    • 2000–2001 → XHTML
  • Today: W3C + WHATWG
    • 2008–10/2014 → HTML 5 stable W3C Recommendation since October 2014
    • 12/2017 → HTML 5.2

much more complicated, actually

HTML 5 vs. HTML 4

Important enhancements:

  • one single standard, two possible syntaxes: HTML and XHTML (HTML → <!DOCTYPE html>)
  • new elements useful to make the semantics of the document more explicit: <article>, <section>, <nav>, <aside>
  • new elements useful for integrating multimedia content: <audio>, <video>

Official reference on the differences

To ensure backward compatibility, some things may be allowed for HTML interpreters but not for authors

HTML

The Basics

Very Simple HTML Document

<!DOCTYPE html>
<html>
  <head>
    <title>Hello HTML</title>
  </head>
  <body>
    <p>
      Hello <a href="http://www.units.it">UniTs</a>!<br/>
      We are learning!
    </p>
  </body>
</html>

Elements, Tags, Attributes

  • <title>Hello HTML</title>element
    • <title>start tag
    • Hello HTML → content
    • </title>end tag
  • The start tag can contain attributes:
    <a href="http://www.units.it">UniTs</a>
    • href="http://www.units.it" → attribute
    • href → attribute name
    • http://www.units.it → attribute value

Notes

  • Some elements have no content:
    • <img src="white-dog.png"/>
    • <br/>
    • there is only the start tag
  • Some attributes have no value:
    • <input type="checkbox" checked/>
  • Comments are inserted with <!--...-->:
    • <!--nobody can see this-->

Head and Body

  • <head>head, additional information about the document
  • <body> → informational content of the document

Additional Information

  • <title> → document title
  • <meta name="..." content="...">
    • name="author" → document author
    • name="description" → document description
    • name="keywords" → document keywords ("...,...,...")

From HTML to the Screen

Browser: HTML → DOM tree → screen rendering

Document Object Model (DOM)

Tree representation of the document, in memory

Alternatives to the screen:

  • speech synthesis
  • printer
  • ...

HTML

Rules

Rules

Different levels of correctness:

  • syntactic (HTML) → clear, but "it still works"
  • stylistic (HTML) → few and vague
  • stylistic (representation) → many and vague
  • semantic (HTML) → many, fairly clear

Syntactic Rules (HTML): Nesting

Elements can be nested but not overlapped

  • <p>Example <strong>correct</strong></p> → correct
  • <p>Example <strong>correct</p></strong>invalid

Syntactic Rules (HTML): Attribute Values

Attribute values must be in quotes if they contain spaces

  • <img src="white-dog.png" alt="White dog"/> → correct
  • <img src=white-dog.png alt="White dog"/> → correct
  • <img src="white-dog.png" alt=White dog/>invalid

To avoid mistakes, always use quotes!

Syntactic Rules (HTML): named character references

Special characters with a name:

  • &darr;down arrow (↓)
  • &rationals; → rationals (ℚ)
  • lots more available

Rules:

  • in the text you cannot use &s if s is the name of one of the characters
  • all named character references must end with a semicolon

Syntactic Rules (HTML):
is that all?

There are many more!

What to do?

  • consult the specification
  • use a validator

The Specification

The specification = THE manual = the bible:
HTML5 W3C Recommendation, https://html.spec.whatwg.org/multipage/

What does it contain?

  • which elements exist
  • for each element, nesting rules
  • for each element, which attributes
  • for each attribute, meaning and which values are valid
  • ...

Also as an introduction to HTML

HTML5 W3C Recommendation: extremely detailed manual

Example: start tag? end tag? />?

The start and end tags of certain normal elements can be omitted, as described later

Optional tags

complicated, better to always include the end tag

HTML5 W3C Recommendation: extremely detailed manual

Another example: <em>

The em element

Validator

W3C Validator

Validazione sito UniTS
W3C Validator at www.units.it

… the teacher is familiar with the W3C Validator

Stylistic rules (HTML)

  • Indentation!
  • ...
  • Attributes: always use quotes!
  • Close optional tags

Stylistic rules (representation)

Style → de gustibus?

Usability

Stylistic rules (representation)

Usability

10 usability crimes

they are not only about HTML (HTML ≠ representation)

HTML

HTML Elements

HTML Elements

  • <!-- --> → defines a comment
  • <!DOCTYPE> → defines the document type
  • <a> → defines a hyperlink
  • <abbr> → defines an abbreviation
  • <address> → defines an address element
  • ...

Complete list:

HTML Elements: list

Tag Description
<!--...--> Defines a comment
<!DOCTYPE>  Defines the document type
<a> Defines a hyperlink
<abbr> Defines an abbreviation or an acronym
<acronym> Not supported in HTML5. Use <abbr> instead.
Defines an acronym
<address> Defines contact information for the author/owner of a document
<applet> Not supported in HTML5. Use <embed> or <object> instead.
Defines an embedded applet
<area> Defines an area inside an image-map
<article> Defines an article
<aside> Defines content aside from the page content
<audio> Defines sound content
<b> Defines bold text
<base> Specifies the base URL/target for all relative URLs in a document
<basefont> Not supported in HTML5. Use CSS instead.
Specifies a default color, size, and font for all text in a document
<bdi> Isolates a part of text that might be formatted in a different direction from other text outside it
<bdo> Overrides the current text direction
<big> Not supported in HTML5. Use CSS instead.
Defines big text
<blockquote> Defines a section that is quoted from another source
<body> Defines the document's body
<br> Defines a single line break
<button> Defines a clickable button
<canvas> Used to draw graphics, on the fly, via scripting (usually JavaScript)
<caption> Defines a table caption
<center> Not supported in HTML5. Use CSS instead.
Defines centered text
<cite> Defines the title of a work
<code> Defines a piece of computer code
<col> Specifies column properties for each column within a <colgroup> element 
List of tags on w3schools

Sections

  • article → a piece of independent content; if nested, the inner one is related to the outer one (e.g., a blog post and its comments).
  • section → a grouping of content that is part of a broader piece of content, typically with a heading
  • nav → a section with navigation links
  • aside → a piece of content complementary to its context (e.g., notes, Twitter messages, etc.)

Sections

  • h1, ..., h6 → headings (⚠ do not use for subtitles or taglines!)
  • header → introductory content (e.g., title and navigation)
  • footer → information related to the section (e.g., author, additional links, copyright, etc.)
  • address → contact information (⚠ not for generic addresses)

Sections: questions

  • Is the font of h1 larger than that of h2?
  • Is the vertical spacing between two section elements larger than that after an article?
  • How is the address tag rendered?

Sections: questions

Wrong, you shouldn’t be asking yourself that!

HyperText Markup Language (HTML)

Language used to describe the content and structure of the information in a web document

Not the representation!

Grouping content

<h2>My memoirs</h2>
<p>
  I don’t remember them anymore...
</p>
  • p → paragraph
  • hr → topic change (not needed between sections)
  • pre → preformatted text
  • blockquote → external quotation
  • main → main content of the page, not repeated across the site. ⚠ only one per page!

Grouping content

<h3>Ingredients</h3>
<ul>
  <li>Sicilian pesto</li>
  <li>fusilli</li>
  <li>grated cheese</li>
</ul>
<h3>Preparation</h3>
<ol>
  <li>cook the pasta</li>
  <li>add the pesto</li>
  <li>garnish with cheese to taste</li>
</ol>
  • ulunordered list
  • olordered list
  • lilist item

⚠ must not be placed inside paragraphs!

Line breaks

  • CR+LF ≠ new line
  • brline break, part of the content

br elements must be used only for line breaks that are actually part of the content, as in poems or addresses.

must be used? → semantic correctness (HTML)

Textual semantics

  • em → the content of the element deserves emphasis
  • strong → the content is important
  • mark → highlighted text for reference (e.g., searched text)
  • s → the content is no longer accurate or relevant
  • sub and sup → subscript and superscript text

Textual Semantics

  • i → different reading (e.g., another language, technical term, etc.)
  • u → text with non-textual annotation (e.g., intentionally incorrect)
  • Authors are encouraged to avoid using the u element where it could be confused for a hyperlink.
  • b → draw attention
    The b element should be used as a last resort when no other element is more appropriate.

Representing Code

  • code → the content is a piece of source code
  • samp → output produced by the code
  • var → a variable
  • kbd → keyboard input... sort of
    • inside samp → the key was pressed by the user and displayed on screen
    • containing a samp tag → a menu was selected
    • containing other kbd → key combination

Example kbd

Please press Ctrl + Shift + R to reload a page.

Please press Ctrl + Shift + R to reload a page.

Example: samp in kbd

To create a new file, choose the menu option FileNew Document .

Don't forget to click the OK button to confirm once you've entered the name of the new file.

To create a new file, choose the menu option FileNew Document.

Don't forget to click the OK button to confirm once you've entered the name of the new file.

Hyperlink

I go to the <a href="http://www.units.it">university</a>
  • a → link (anchor) to another document
  • href="" → location of the other document
    • same site (relative URL) → href="udine.html"
    • different site (absolute URL) → href="http://www.units.it"
    • same document → href="#people"
    • email address → href="mailto:andrea.delorenzo@units.it"

link is something else

Images

<img src="white-dog.jpg" alt="The white dog"/>
  • src → location of the image resource
  • altfallback content: content that is to be used when the external resource cannot be used

Images: atrribute alt

Is alt mandatory?

Except where otherwise specified, the alt attribute must be specified and its value must not be empty; the value must be an appropriate replacement for the image.

One way to think of alternative text is to think about how you would read the page containing the image to someone over the phone, without mentioning that there is an image present.

In some cases, the icon is supplemental to a text label conveying the same meaning. In those cases, the alt attribute must be present but must be empty.

[...] In such cases, the alt attribute may be omitted, but one of the following conditions must be met [...]

“Almost” mandatory to include it, but it can be alt=""

Tables

<table>
  <caption>Line 36 Timetable</caption>
  <thead>
    <tr><th>Hour</th><th>Minute</th></tr>
  </thead>
  <tbody>
    <tr><td>8</td><td>00 15 30 45</td></tr>
    <tr><td>9</td><td>15 45</td></tr>
  </tbody>
</table>
  • caption → title, heading
  • thead; tfoot → column labels; totals, etc. (header, footer)
  • tbody → body (with the values)
  • tr → row (table row)
  • td, th → cell (table data/header cell)

Tables

Do not use them for formatting!

Tables must not be used as layout aids. Historically, some Web authors have misused tables in HTML as a way to control their page layout. This usage is non-conforming, because tools attempting to extract tabular data from such documents would obtain very confusing results. In particular, users of accessibility tools like screen readers are likely to find it very difficult to navigate pages with tables used for layout.

There are a variety of alternatives to using HTML tables for layout, primarily using CSS positioning and the CSS table model.

div and span

The div element has no special meaning at all. It represents its children. It can be used with the class, lang, and title attributes to mark up semantics common to a group of consecutive elements.

→ BLOCK level

The span element doesn't mean anything on its own, but can be useful when used together with the global attributes, e.g. class, lang, or dir. It represents its children.

→ inside a text line

div: example

<article lang="en-US">
  <h1>My use of language and my cats</h1>
  <p>My cat's behavior hasn't changed much since her absence, except
  that she plays her new physique to the neighbors regularly, in an
  attempt to get pets.</p>
  <div lang="en-GB">
    <p>My other cat, coloured black and white, is a sweetie. He followed
    us to the pool today, walking down the pavement with us. Yesterday
    he apparently visited our neighbours. I wonder if he recognises that
    their flat is a mirror image of ours.</p>
    <p>Hm, I just noticed that in the last paragraph I used British
    English. But I'm supposed to write in American English. So I
    shouldn't say "pavement" or "flat" or "colour"...</p>
  </div>
  <p>I should say "sidewalk" and "apartment" and "color"!</p>
</article>

span: example

<code class="lang-c"><span class="keyword">for</span> (<span class="ident">j</span> = 0; <span class="ident">j</span> &lt; 256; <span class="ident">j</span>++) {
  <span class="ident">i_t3</span> = (<span class="ident">i_t3</span> & 0x1ffff) | (<span class="ident">j</span> &lt;&lt; 17);
  <span class="ident">i_t6</span> = (((((((<span class="ident">i_t3</span> >> 3) ^ <span class="ident">i_t3</span>) >> 1) ^ <span class="ident">i_t3</span>) >> 8) ^ <span class="ident">i_t3</span>) >> 5) & 0xff;
  <span class="keyword">if</span> (<span class="ident">i_t6</span> == <span class="ident">i_t1</span>)
    <span class="keyword">break</span>;
}</code>
for (j = 0; j < 256; j++) {
i_t3 = (i_t3 & 0x1ffff) | (j << 17);
i_t6 = (((((((i_t3 >> 3) ^ i_t3) >> 1) ^ i_t3) >> 8) ^ i_t3) >> 5) & 0xff;
if (i_t6 == i_t1)
break;
}

HTML

Global Attributes

id Attribute

id → unique identifier

  • unique across the whole document
  • no spaces: <section id="abstract">

It can be used for:

  • internal links <a href="#abstract">
  • ... to be seen later

Identifiers are opaque strings. Particular meanings should not be derived from the value of the id attribute.

title Attribute

title → descriptive indication

  • <a href="udine.html" title="Info page of the neighboring city">Udine</a>
  • <abbr title="Cascading Style Sheet">CSS</abbr>

Advisory information for the element, such as would be appropriate for a tooltip.

⚠ Warning...

  • Do not consider them tooltips (e.g., on tablets?)
  • Inheritance
  • new line in HTML → actual new line!

lang and translate Attributes

lang → main language of the content

<p lang="it">L'inglese è difficile da pronunciare:
per sempio la parola <span lang="en-UK">Wednesday</span>.</p>
<p lang="de"><span lang="en-UK">Wednesday</span>
ist ein schwieriges Wort auszusprechen.</p>

translate → whether or not this content should be localized

Enumerated values:

  • yes
  • no

Example: code fragments, keyboard input, menus, etc.

class attribute

Value: a set of space-separated names:
<span class="content keyword">if</span>

Authors are encouraged to use values that describe the nature of the content, rather than values that describe the desired presentation of the content

semantic correctness (HTML)

data-* Attribute

          <section data-dog-weight="12.8kg" data-dog-speed="75%">
<h1>White dog</h1>
<p>The white dog is stocky but fast.</p>
</section>
  • what follows data- is the name of the custom attribute
  • private data for the page (or application)
  • CamelCase → camel-case (⚠ uppercase letters not allowed)

dir and style Attributes

dir → text direction

style → appearance of the element, we’ll see later

Semantic Elements – Overview

<header>
<nav>
<section><aside>
<article>
<footer>

article inside section or the other way around?

The article element specifies independent, self-contained content.

The section element defines a section in a document.

Can we use the definition to decide how to nest these elements? No.

In some HTML pages a section will contain an article, and in others an article will contain a section.

HTML Exercise 1

Write a (HTML-only) document about your city or neighborhood.

Content (items):

  • the 3 most famous people/animals
  • or, the 3 most beautiful buildings/places

We will assess the syntactic, semantic, and stylistic correctness of the HTML document.

HTML Exercise 1

Rules:

  • at least 3 items with at least 3 sections
  • use aside, i, em, strong, nav, lang, li
  • each item must include at least 500 characters of text
  • the total document must include at least 5,000 characters of text
  • include at least one internal link

Text Editor

Choose whichever you like, I suggest:

Text Editor – Visual Studio Code

Recommended extensions:

Text Editor – Sublime Text

Recommended packages:

Text Editor – Zed

Features:

  • Lightweight and very fast editor
  • Collaborative editing in real-time
  • Built-in support for multiple languages
  • Modern UI and native performance

Fewer plugins than VS Code or Sublime, but designed for speed and teamwork.

HTML Representation

Representing an HTML document

HyperText Markup Language (HTML)

Language used to describe the content and the structure of the information in a web document

The browser renders the document:
how does it draw it on the screen?

How does it draw it?

  1. HTML
  2. DOM tree
    (in-memory representation)
  3. representation on screen

How?

  • HTML → DOM tree: implicit transformation rules
  • DOM tree → screen: ...

HTML → DOM tree

HTML

<!DOCTYPE html>
<html>
 <head>
  <title>Sample page</title>
 </head>
 <body>
  <h1>Sample page</h1>
  <p>This is a <a href="demo.html">simple</a> sample.</p>
  <!-- this is a comment -->
 </body>
</html>

HTML → DOM tree

DOM tree:

  • DOCTYPE: html
  • html
    • head
      • #text: ⏎␣␣
      • title
        • #text: Sample page
      • #text: ⏎␣
    • #text: ⏎␣
    • body
      • #text: ⏎␣␣
      • h1
        • #text: Sample page
      • #text: ⏎␣␣
      • p
        • #text: This is a
        • a href="demo.html"
          • #text: simple
        • #text: sample.
      • #text: ⏎␣␣
      • #comment: this is a comment
      • #text: ⏎␣⏎

DOM tree: terminology

Let’s consider the subtree of the node body (some #text omitted):

  • the node body is the parent of the node h1
  • the nodes p, #comment, ... are sibling of the node h1
  • the nodes h1, p, ... are children of the node body
  • the nodes a, h1, p, ... are descendant of the node body
  • the nodes like body, p, h1, a are elements
  • the nodes #text are text (they have no children!)

DOM tree → screen: informally

For each node of the DOM tree:

  • what should be drawn?
  • where?
  • how?

reading the document: "drawn" → "spoken", "where" → "when"

Imagine you are the browser, or that you have to write the browser program’s code...

DOM tree → screen: formally

Goal: DOM tree → boxes tree

Main transformation rules:

  • each element E of the DOM tree may generate zero or more boxes
  • a box BE of the element E may be child of another box B'E of E or child of a box BEp of Ep, parent of E

What should be drawn?

An element is drawn if and only if all the following conditions are valid:

  • the parent has been drawn (or has no parent)
  • it is not explicitly marked as "not to be drawn"

Where should it be drawn?

Premise: types of boxes

  • block-level boxlike a paragraph
  • line boxlike a line of text
  • inline-level boxlike a word

Types of boxes: content

What they can contain:

  • block-level box
    • block-level boxes
    • line boxes
  • line box
    • inline-level boxes
  • inline-level box
    • text
    • inline-level boxes
    • block-level boxes (e.g., a list inside a strong element)

Where should it be drawn?

Roughly speaking:

  • consecutive block-level boxes are placed one below the other inside the parent block-level box

    They try to fill all the available horizontal space

  • consecutive line boxes are placed one below the other inside the parent block-level box
  • consecutive inline-level boxes are placed side by side inside the parent line-level box

    They only occupy the strictly necessary space

"consecutive" → follows the order of the DOM tree

Block-Level boxes

Non-exhaustive list:

  • p
  • table
  • nav
  • div
  • form
  • main, article, section
  • h1, h2, ...
  • ...ecc.

Inline-Level boxes

Non-exhaustive list:

  • a
  • span
  • em
  • strong
  • input, button, textarea
  • img
  • ...ecc.

Line boxes

And which elements generate Line Boxes?

They are generated automatically!

The rectangular area that contains the boxes that form a line is called a line box.

When several inline-level boxes cannot fit horizontally within a single line box, they are distributed among two or more vertically-stacked line boxes. Thus, a paragraph is a vertical stack of line boxes.

When an inline box exceeds the width of a line box, it is split into several boxes and these boxes are distributed across several line boxes. If an inline box cannot be split (e.g., if the inline box contains a single character, or language specific word breaking rules disallow a break within the inline box, or if the inline box is affected by a white-space value of nowrap or pre), then the inline box overflows the line box.

Example

DOM tree and boxes
Simplification of the transition HTML → boxes

How is it drawn?

We’re missing something:

  • given an element, what type of box does it generate?
  • given an element, how much margin does it have?
  • ...
  • "how is it drawn?"

"box type", "margin", ... → style properties of boxes

Properties and CSS

Cascading Style Sheet (CSS)

A document that specifies which values to assign to which elements’ properties

  • sheet → sheet, document
  • styleproperties related to stylistic representation
  • cascading → we’ll see...

CSS

Cascading Style Sheet (CSS)

A document that specifies which values to assign to which elements’ properties

"the element of type p must correspond to a block-level box with a 1cm margin"

HTML without CSS?

But the browser still displays my page, even though I haven’t provided any CSS!

implicit rules

The CSS rules given in these subsections are, except where otherwise specified, expected to be used as part of the user-agent level style sheet defaults for all documents that contain HTML elements.

In the specification, a CSS follows

CSS

CSS: short history

  • 1996 → CSS 1
  • 1998 → CSS 2
  • 2011 → CSS 2.1
  • (2005) → CSS 3 (still in development)
You don't need to be a programmer or a CS major to understand the CSS specifications. You don't need to be over 18 or have a Bachelor's degree. You just need to be very pedantic, very persistent, and very thorough.

CSS: basic principles

  • Compatibility: forward and backward
  • Complementary to structured documents (HTML and XML)
  • Independent from Vendor/Platform/Device (roughly, cf. printers)
  • Easy maintenance
  • Simple: only one way to achieve an effect
  • Network performance (e.g., I send formatted text instead of images)
  • Flexible: can be defined in multiple places
  • Compatible with other languages (e.g., JS)
  • Accessibility

CSS 3: the "bible"?

Less simple compared to HTML: the specification is modular

As the popularity of CSS grows, so does interest in making additions to the specification. Rather than attempting to shove dozens of updates into a single monolithic specification, it will be much easier and more efficient to be able to update individual pieces of the specification. Modules will enable CSS to be updated in a more timely and precise fashion, thus allowing for a more flexible and timely evolution of the specification as a whole.

For resource constrained devices, it may be impractical to support all of CSS. For example, an aural browser may be concerned only with aural styles, whereas a visual browser may care nothing for aural styles. In such cases, a user agent may implement a subset of CSS. Subsets of CSS are limited to combining selected CSS modules, and once a module has been chosen, all of its features must be supported.

CSS: modular specification

Development status of the specification modules

CSS: definitions

Cascading Style Sheet (CSS)

An ordered list of rules

Rule

  • selector → which elements the rule applies to
  • zero or more declarations → what applies to those elements

Declaration

  • property name
  • property value

does not apply only to HTML documents

CSS syntax

        selector {
          property-name: property-value;
          property-name: property-value;
          ...
        }

        selector { /* comment */
          property-name: property-value;
          property-name: property-value;
          ...
        }

        /* comment */

The specification defines:

  • the syntax of the selector
  • the list of property names
  • for each property, the possible values (syntax)

@ Rule

There are special rules that start with @:
  • @charset
  • @import
  • @namespace
  • @media
  • @viewport
  • ...

But we’ll talk about them later...

CSS syntax

Attention: if the syntax of a rule is incorrect, the browser must ignore the entire rule!

"must ignore" = "the specification recommends that the browser ignore it" → the browser may not ignore...

different from what happens with HTML

CSS syntax

Three levels of correctness:

  • syntactic (CSS) → otherwise it is ignored
  • stylistic (CSS) → indentation, please!
  • stylistic (representation: HTML+CSS)

there is a CSS validator

CSS location

Who defines the style?

  • Author
  • User
  • User agent

CSS location: Author

Where do I specify that I want to use certain rules for a given HTML document d? Three methods:

  • as an external text document linked to d:
    <link rel="stylesheet" type="text/css" href="...">
  • embedded in d, as the content of a style element:
    <style>...</style>
  • inside (inline) d: with only the declaration(s) as the value of a style attribute of the element I want to style (the selector is not needed!):
  • <p style="...">

CSS location: @import

The @import rule allows you to import other style sheets into a CSS code

  • It must be the first line of the CSS file
    • before it, only @charset is allowed
  • The user agent will include the file as if it were written at that point
  • Conditions can be added (e.g., device type, resolution, etc.)

Example: importing a Google Web Font

<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" >

font-family: 'Roboto', sans-serif;

CSS

CSS Cascading

Source

Many methods...

All methods can be used together → they are all applied!

  • Multiple external documents (multiple <link ...>)

    link is also used for other purposes

  • And if multiple rules are in conflict? (rules that specify different values for the same property of one or more elements)
  • And if some property is not defined?

Inheritance

If a property P is not defined for an element E, the element inherits the value of P from its parent (parent of E)

  • For many elements and many properties, the value from the user-agent level style sheet is used

Inheritance → cascading style sheet

Inheritance: property values

How do I compute the value of each property?

Six values for each property...

  1. Declared: explicitly in the code
  2. Inherited (inherited): after applying inheritance
  3. Specified: takes the default if not declared and not inherited
  4. Computed: e.g. "2 times the font size"
  5. Used: after processing the parent (e.g. "10% width")
  6. Actual: impossible requests for the User Agent → 10.9 becomes 11

Inheritance: property values

Examples:

Declared Inherited Specified Computed Used Actual
text-align: left left left left left left
width: (none) (none) auto auto 120px 120px
font-size: 1.2em 1.2em 1.2em 14.1px 14.1px 14px
width: 80% 80% 80% 80% 354.2px 354px

em is the font size → 2em = 2 times the font size.

Inheritance: conflict

What if multiple rules are in conflict?

  1. method (origin)
    1. inline style sheet (style="...", most important)
    2. embedded style sheet (<style>)
    3. external document (<link>)
    4. user level style sheet
    5. user-agent level style sheet (least important)
  2. specificity (we’ll see)
  3. source order (the last one wins)

Inheritance: !important

CSS attempts to create a balance of power between author and user style sheets. By default, rules in an author’s style sheet override those in a user’s style sheet.

!important changes the priority:

  1. User-agent
  2. User
  3. Author

Example:

{ background-color: lightgrey !important; }

Some legitimate use cases for !important

  • You are using a Content Management System (CMS: WordPress, Drupal, ...) and cannot modify the style
  • You want to give a uniform style to the buttons of your site, so you define a generic rule. Then you add a rule with higher specificity that overrides it (we’ll see). In this case !important solves the problem

Some legitimate use cases for !important

.button {
  background-color: #8c8c8c;
  color: white;
  padding: 5px;
  border: 1px solid black;
}

#myDiv a {
  color: red;
  background-color: yellow;
}
.button {
  background-color: #8c8c8c !important;
  color: white !important;
  padding: 5px !important;
  border: 1px solid black !important;
}

#myDiv a {
  color: red;
  background-color: yellow;
}

Default values

Some keywords allow forcing certain behaviors:

  • initial → default value
  • inherit → taken from the parent element
  • ...there are others (unset, revert)

CSS

CSS selectors

Source

Selector

CSS selector

An expression that, when applied to an element, returns a boolean

fselector(E) ∈ {true, false}

The specification describes all the possible functions f

Main selectors

  • * → any element (f*(E) = true, ∀ E)
  • e → elements of type <e>
  • f e → elements of type <e> that are descendants of elements of type <f>
  • e.className → elements of type <e> with class "className"
  • e#idName → elements of type <e> whose id attribute value is equal to "idName"

descendant ≠ child

<img class="photo old" src="..."/> is selected by both img.photo and img.old

Recap: Selectors official names

Official CSS selectors names

  • *universal selector
  • etype selector (e.g., <div>, <p>)
  • .classNameclass selector
  • #idNameID selector

Combination of selectors

Selectors can be "combined":

  • e.c1 f → an <f> that is a descendant of an <e> with class "c1"
  • e f g → a <g> that is a descendant of an <f> that is a descendant of an <e>
  • e * → all descendants of an <e>

The universal selector * can be omitted in certain cases:

  • *.c1=.c1 → any element with class "c1"
  • *#id1=#id1 → any element with id "id1"

Combinators based on relationships

  • e > f → an <f> that is a child of an <e> (child combinator)
  • e + f → an <f> that is immediately preceded by its sibling <e> (adjacent sibling combinator)
  • e ~ f → an <f> that is preceded by its sibling <e> (general sibling combinator)

Attribute selectors

  • e[a] → an <e> with an attribute a
  • e[a="val"] → an <e> with attribute a equal to "val"
  • e[a~="val"] → an <e> with a="v1 v2 v3 ... val ..." (space-separated values)
  • e[a^="val"] → an <e> with a="valrest"
  • e[a$="val"] → an <e> with a="restval"
  • e[a*="val"] → an <e> with a="somethingvalsomething"
  • e[a|="val"] → an <e> with a="val-v2-v3" (values separated by "-")

    f[lang|="en"](<p lang="en-US">) = f[lang|="en"](<p lang="en-UK">) = true

Structural pseudo-classes

Pseudoclasses: classes not explicitly defined, but matching elements present in the HTML

  • e:nth-child(n), e:nth-last-child(n) → an <e> that is the n-th (n-th from the end) child of its parent
  • e:nth-of-type(n), e:nth-last-of-type(n) → an <e> that is the n-th (n-th from the end) child of its parent among children of type <e>
  • e:first-child, e:last-child, e:first-of-type, e:last-of-type
  • e:only-child, e:only-of-type → an <e> that is the only child (without siblings of type e)
  • e:root → the <e> that is the root of the document
  • e:empty → an <e> without children, not even text

nth-child: details

e:nth-child(n): n can be an expression that is a bit more complex:

  • e:nth-child(3) → the third child
  • e:nth-child(even) = e:nth-child(2n) → even children
  • e:nth-child(odd) = e:nth-child(2n+1) → odd children
  • e:nth-child(5n+2) → the 2nd, 7th, 12th, ... child

Other pseudo-classes selectors

  • e:visited, e:link → an <e> that is a link to a visited (unvisited) document (*link pseudo-classes*)
  • e:active, e:hover, e:focus → an <e> in certain states related to user interaction (*user action pseudo-classes*)
  • e:enabled, e:disabled, e:checked → an <e> that is part of the UI and in certain states (*UI element states pseudo-classes*)
  • e:lang(en) → an <e> whose content is in English (*:lang() pseudo-class*)
  • e:target → an <e> that has been targeted by an anchor (URL#anchor) (*:target pseudo-class*)

    http://units.it/bandi.html#scaduti → <section id="scaduti"> is :target

Pseudo-elements selectors

Pseudoelements: elements not explicitly defined, thus generated

  • e::first-line → a generated element representing the first line of text in an <e>
  • e::first-letter → a generated element representing the first letter of an <e>
  • e::before, e::after → a generated element inserted before (after) the content of an <e>
    • commonly used with the content property

Pseudo-elements: example

<p>Nel mezzo di cammin di nostra vita</p>

<p><span::first-letter>N</span>el mezzo di cammin di nostra vita</p>

Negation pseudo-class

  • e:not(selector) → an <e> to which the selector does not apply (only simple selectors allowed, div > div is invalid).

    p:not(:first-child) → all p elements that are not the first child of their parent

Relational pseudo-class

:has()

The :has() CSS pseudo-class represents an element if any of the selectors passed as parameters match at least one element.

  • e:has(selector) → an <e> that is the parent of an element matching the selector
  • can be chained: e:has(f):has(g) or e:has(f, g)

Support is limited to some browsers

Selectors and specificity

Remember? It is one of the mechanisms for resolving inheritance conflicts.

A "number" is generated, composed of three digits, obtained by counting in the selector:

  • ID attributes
  • other attributes or pseudo-classes
  • element names
  • pseudo-elements are ignored

The larger the number, the higher the specificity.

A great example based on Star Wars.

Selector: example

tr:nth-child(even) {
  background-color: #8be9fd; /* we’ll see... */
}
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20

Selector: example

p::first-letter {
  font-size: 200%; /* we’ll see ... */
  color: #8be9fd;  /* this too ... */
}

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique velit eget neque ornare, vitae luctus magna mollis. Donec arcu ligula, tristique et porttitor nec, feugiat et tortor. Suspendisse vel nisi a mauris consectetur hendrerit. Fusce congue leo est, et suscipit massa venenatis vitae. Sed nec molestie nibh. Sed purus tortor, molestie sed justo non, iaculis ultricies orci. Nullam quis quam justo. Nunc finibus aliquet tincidunt. Nunc mattis metus at arcu tristique semper. Vivamus iaculis lacus porttitor, pretium leo tincidunt, euismod nisi. Morbi sodales pharetra ante in congue. Aenean sed erat dui. Aenean eget elementum metus.

Selector: example

figure:has(figcaption) img {
    outline: 10px dashed #8be9fd;
}
With figcaption
MaLe Lab Logo
MaLe Lab Logo
Without figcaption
MaLe Lab Logo

CSS

CSS properties

We will only see a few...

A complete list

Colors

  • color → text color
  • background-color → background color
  • border-color → border color

Values:

  • color: red; → by named color keyword (including extended color keywords)
  • color: #ff0000; → hexadecimal RGB notation
  • color: rgb(255,0,0), color: rgb(100%,0%,0%) → functional RGB notation (integer and percentage values)
  • color: rgba(255,0,0,0.33), color: rgba(100%,0%,0%,0.33) → functional RGBA notation with alpha channel
  • color: transparent;transparent keyword

Backgrounds

  • background-color → background color
  • background-image → background image
  • background-repeat → background-repeat property (repeat, repeat-x, repeat-y, no-repeat)
  • background-attachment → background-attachment property (scroll, fixed, local)
  • background-position → background-position property (keywords, lengths, or percentages)
  • backgroundshorthand property for all background-related properties

Example:

body {
  background-image: url('img_tree.png');
  background-repeat: no-repeat;
  background-position: right top;
}

Fonts

  • font-family → font family name / generic family
  • font-size → absolute-size keyword | relative-size keyword | length | percentage
  • font-weight → font weight (normal, bold, 100–900)
  • font-variant → small-caps variant
  • font-style → normal | italic | oblique
  • fontshorthand property for all font-related properties

Example:

h1 {
  font-family: Helvetica, Verdana, sans-serif;
  font-weight: bold;
  font-size: x-large;
}

font-family: Helvetica, Verdana, sans-serif → the first available one is used

font-family and @font-face

The author may want to use a specific font, but it may not be installed on the user’s system:
font-family: "Fancy Design Font", sans-serif;

@font-face defines a downloadable font resource

@font-face {
  font-family: 'Ubuntu';
  src: local('Ubuntu'),
       local('Ubuntu-Regular'),
       url('http://themes.googleusercontent.com/font?kit=2Q-AW1e_taO6pHwMXcXW5w') format('truetype');
}

h1 { font: "Ubuntu" 10px;}

@font-face is an at-rule

Google Fonts

font-size

font-size: absolute-size keyword | relative-size keyword | length | percentage | inherit

Examples:

font-size: medium;     /* absolute-size keyword */
font-size: large;      /* absolute-size keyword */
font-size: 115%;       /* percentage */
font-size: larger;     /* relative-size keyword */
font-size: 10px;       /* length */
font-size: 0.75cm;     /* length */

CSS length units

Some properties accept a value of type length.

Absolute length units:

in → inches; 1in = 2.54cm
cm → centimeters
mm → millimeters
Q → quarter-millimeters (1Q = 0.25mm)
pt → points; 1pt = 1/72in
pc → picas; 1pc = 12pt
px → reference pixels (CSS pixel)

How does the browser know how many device pixels make up 1cm?

In CSS, absolute units are defined relative to the reference pixel and a standard pixel density; on many screens physical sizes are mapped heuristically.

CSS length units

Relative length units:

em → font size of the element (for font-size, relative to the parent’s font size)
ex → x-height of the element’s font
ch → width of the "0" (zero) glyph in the used font
rem → font size of the root element
lh → computed line height of the element
rlh → line height of the root element
vw → 1% of the viewport’s width
vh → 1% of the viewport’s height
vmin → 1% of the smaller viewport dimension
vmax → 1% of the larger viewport dimension

The unit px is the CSS reference pixel; it’s treated as an absolute unit in CSS specifications.

Text

  • line-height
  • letter-spacing
  • text-align
  • text-decoration
  • text-indent
  • text-transform
  • vertical-align

Examples (more here):

.draft span.note {
  text-transform: uppercase;
}
.draft span.old-version {
  text-decoration: overline;
}

Counters

They behave like variables

  • defined with the property counter-reset: counterName;
  • incremented using the property counter-increment: counterName;
  • Usable in the content property

Example:

body {
 counter-reset: sectionCount;
}
h2::before {
 counter-increment: sectionCount;
 content: "Section " counter(sectionCount) ": ";
}

CSS

CSS Layout

Source

Remember?

DOM tree and boxes
Simplification of the HTML → boxes transition

Display

Defines how the box will be rendered

  • inner display type → what formatting context it creates, and how its descendants will be positioned
  • outer display type → how the box participates in the formatting of its parent

Outer Display Type

There are three possible values

  • block
  • inline
  • run-in → merges with the block that follows it, inserting itself at its beginning (e.g., a dictionary definition).

Inner Display Type

Various options:

  • flow → depends on the Outer Display Type:
    • inline or run-in: generates an inline box
    • block: generates a block
  • flow-root → always creates a Block container
  • ... and many others (table, flex, grid, ruby)

display Property

Summarizes in a single value how to set Inner/Outer Display Type

In short, it determines the type of box that will be generated

  • display: inline → inline flow → inline-level box
  • display: block → block flow → block-level box
  • display: nonedoes not generate a box
  • display: inline-block → inline flow-root → we’ll see later
  • display: flex → block flex → we’ll see later
  • many others

display has a major impact on the representation of a document!

Hiding a box

  • visibility: visible → draws
  • visibility: hidden → does not draw

Warning:

  • visibility: hidden → the box takes up the expected space but is not visible
  • display: none → the box does not exist

Dimensions

We use width and height:

  • do not apply to inline-level boxes (as a first approximation)
  • ... and if the set dimensions exceed the window size?
    • scrollbars appear → ugly!
    • we use max-width

Dimensions

Is it enough to know width and height to calculate the occupied space?

NO!

They refer to the content; you also need to know margin and padding

Margin and padding

Dimensions

But I can cheat:

box-sizing: border-box; → padding and borders are included

Margin and padding

Hint: consider adding it in a * { } block

Positions

How can I move the box?

position property:

  • static → default, follows the normal flow; not affected by top/bottom/right/left and formally not positioned
  • relative → extra properties must be used (top, right, bottom, or left)
    • relative to itself
    • other content will not flow into the freed spaces
    • Example: position: relative; top: -20px; left: 20px; makes the second block overlap the first
      First block
      Second block

Positions

How can I move the box?

position property:

  • fixed → positioned relative to the browser window
    • managed with top, right, bottom, or left
    • the freed space is reused
    • shaky behavior on mobile devices
  • absolute → behaves like fixed but relative to the nearest positioned ancestor
    • Otherwise, it refers to <HTML>

Positions

Example:

nav {
  position: absolute;
  left: 0px;
  width: 200px;
}
section {
  /* position is static by default */
  margin-left: 200px;
}
footer {
  position: fixed;
  bottom: 0;
  left: 0;
  height: 70px;
  background-color: white;
  width: 100%;
}          
Section text 1, possibly very long.
Section text 2, possibly very long.

Floating box

A floating box is shifted in the line to the right or left until it bumps into the edge of its parent box

The rest of the content flows alongside; line boxes are shortened

  • float: left, float: right → it floats
  • float: none → does not float (default)

Ex: style="float: left; width: 200px;height: 100px;margin: 1em;"

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
I’m floating!
Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Cras ac leo purus. Mauris quis diam velit.

Floating box

A floating box can be taller than the containing box; even the lines of the following block-level box are shortened if necessary… how to avoid this?

  • Solution 1: prevent it with clear
    • clear: left, clear: right, clear: both → don’t align with floating boxes on the left and/or right
    • clear: none → allow alignment
  • Solution 2: extend the box with a clearfix
    .clearfix {
      overflow: auto;
      zoom: 1; /* for IE6 */
    }              

float and clear: example

p {clear: left;}
        img {float: left;}
          
Float and clear
Example of float and clear

At what point in the HTML document is the image inserted?

Inline-block box

I want to create a grid of boxes that fills the entire width of the browser: I can do it with

  • float: left → inconvenient, I need to apply clear to the next block
  • display: inline-block (some issues with IE6 and IE7)
I’m an inline block!
I’m an inline block!
I’m an inline block!
I’m an inline block!
I’m an inline block!

And I don’t need any clearing!

Columns

column allows me to split text into columns

        .three-column {
  padding: 1em;
  column-count: 3;
  column-gap: 1em;
}          
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Cras ac leo purus. Mauris quis diam velit.

FlexBox

display: flex; comes with CSS3 → not all browsers handle it well

It has several properties, which can be grouped by applicability:

  • parent (container)
  • children (flex items)
container items

A visual guide

FlexBox - Container

  • flex-direction: row | row-reverse | column | column-reverse

    flex-direction2

FlexBox - Container

  • flex-direction: row | row-reverse | column | column-reverse
  • flex-wrap: nowrap (default) | wrap | wrap-reverse (bottom-top)

FlexBox - Container

  • flex-direction: row | row-reverse | column | column-reverse
  • flex-wrap: nowrap (default) | wrap | wrap-reverse (bottom-top)
  • justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly

    flex-start flex-end center space-between space-around

FlexBox - Container

  • flex-direction: row | row-reverse | column | column-reverse
  • flex-wrap: nowrap (default) | wrap | wrap-reverse (bottom-top)
  • justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly
  • align-items: flex-start | flex-end | center | baseline | stretch (aligns a flex row)
  • align-content: flex-start | flex-end | center | space-between | space-around | stretch (aligns multiple rows)

FlexBox - Children

  • order: <integer> → reorders the content
  • flex: <integer> → how to share the space
    box with flex = 1
    box with flex = 2
  • align-self: overrides the container’s value

Responsive Web Design

Simply put: we make sure our website works well on every device.

  • by rearranging the content
  • possibly using only HTML and CSS
  • JavaScript is not necessarily required
  • often designed with a 12-column grid in mind

ViewPort

The ViewPort is the area of the page visible to the user.

Smartphone & tablet browsers automatically shrink the page to fit the screen: let’s avoid this

<meta name="viewport" content="width=device-width, initial-scale=1.0">

WITHOUT specific ViewPort WITH HTML5 options for ViewPort

Differentiation by media type

You can make certain rules apply only to specific media (or media with certain characteristics):

  • using link:
    <link ... media="screen" href="css1.css">
    <link ... media="print,tty" href="css2.css">
  • using @media:
    @media print {
      /* style sheet for print goes here */
    }

Some media: screen, print, handheld, braille, speech, tty, ...

Grid Layout

We want a layout like this:

Different layouts showing the need for grid layout

How can I switch between the three layouts or create the third one?

Slides inspired by the presentation of Morten Rand-Hendriksen

Grid Layout

Terminology

  • Grid container: the element that contains a grid, set with display: grid;
  • Grid item: descendant of the grid container
  • Grid line: horizontal or vertical line delimiting the grid
    • they are numbered (double numbering: 1...N and -N...-1) Different layouts showing the need for grid layout

Grid Layout

Terminology

  • Grid container: the element that contains a grid, set with display: grid;
  • Grid item: descendant of the grid container
  • Grid line: horizontal or vertical line delimiting the grid
    • they are numbered (double numbering: 1...N and -N...-1)
  • Grid cell: like a table cell
  • Grid area: rectangular area between four lines → one or more cells
  • Grid track: space between two adjacent lines (rows and columns)
  • Grid gap: empty space between two tracks

Grid Layout

How is it used?

  1. Define a grid
  2. Place the elements in the grid

That's it!

Grid Layout

Defining the grid:

  • display: grid;
  • grid-template-columns and grid-template-rows: draw the rows; they take a list of values that specify the distances between rows.

    Units of measurement: em, px, %, fr (fractions), auto (fits content).

main{
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
}
          

Done! The grid items are placed inside (top-bottom, left-right).

Grid Layout

Spanning multiple cells

  • grid-column: x/y; → from vertical line X to Y
  • grid-row: x/y; → from horizontal line X to Y

Problem: working with numbers is tricky, it’s easy to get confused (though you can actually name the lines)

Grid Templates

Using textual descriptions to assign names to the grid container’s cells...

main{
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-areas:
    "title title title"
    "main header header"
    "main sidebar sidebar";
}

...and in the grid items you specify the name

h1{
  grid-area: title;
}

Grid Templates

And the magic happens with media queries...

@media screen and (max-width: 700px) {
  main {
     grid-template-areas:
       "title title title"
       "header header header"
       "main main sidebar";
  }
}

Grid Layout

Some details:

  • grids can be nested without issues;
  • good support across browsers
  • ...if you’re worried, you can use @supports (grid-area: auto){...}

Grid Layout

In practice:

  1. design for mobile first (which also serves as fallback)
  2. extend with grid-templates for other resolutions

Some useful references:

CSS

CSS in different browsers

FlexBox

But does it always work?

NO!

  • CSS3 is still being written
  • several changes over time
  • the name of the property itself changes

And not only that — the problem also applies to other features (e.g., column)

Solution: prefixes

Prefixes

By specification, properties will never start with

  • "-"
  • "_"
.foo {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-orient: horizontal;
  -moz-box-orient: horizontal;
  -webkit-box-direction: normal;
  -moz-box-direction: normal;
  -webkit-flex-direction: row;
  -ms-flex-direction: row;
  flex-direction: row;
}

Tools

Do I always have to do everything manually?

No! I can get help

  • Editor-integrated tools (e.g., Emmet)
  • Online tools (e.g., AutoPrefixer)
  • Offline tools (e.g., Less)
  • Frameworks that solve the problem for me (e.g., Bootstrap)

Bootstrap

One line to rule them all, and in the darkness bind them...

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/[...]" >

Optional: some JavaScript

  • JQuery
  • Popper (popups beside elements)
  • BootstrapJS

It’s worth reading the official guide

Less

A CSS development tool written in JavaScript, usable

  • offline (command line)
  • in JS code
  • client-side (low performance, but handy for development)
    <link rel="stylesheet/less" type="text/css" href="styles.less" />
    <script src="less.js" type="text/javascript"></script> 

Less

  • Variables:
    @red: #FF0000;
    a {color: @red}

    a {color: #ff0000}

  • Nesting:
    div{
     width: 200px;
     p{ font-size: 20px; }
    }

    div{ width: 200px;}

    div p{ font-size: 20px;}

Less

  • Mixins (macros):
    .mixin{
       color: red;
       font-weight:bold;
    }
    
    p{
       font-size:18px;
       .mixin;
    }
            

    .mixin{color: red; font-weight:bold;}

    p{font-size: 18px; color: red; font-weight:bold;}

Less

  • Mixins (macros) - excluded from output:
    .mixin(){
       color: red;
       font-weight:bold;
    }
    
    p{
       font-size:18px;
       .mixin;
    }
            

    p{font-size: 18px; color: red; font-weight:bold;}

Less

  • Mixins (macros) - parametric:
    .mixin(@param){
       color: @param;
       font-weight:bold;
    }
    
    p{
       font-size:18px;
       .mixin(red);
    }

Less

  • Functions:
    • darken(color, percentage)
    • greyscale(color)
    • ...many more

CSS Exercise 1

Using the HTML document from exercise HTML-1, write CSS that renders the document like a medieval illuminated manuscript.

Example illuminated manuscript Example illuminated manuscript Example illuminated manuscript
Representation examples
  • two columns, wide borders
  • the first letter of the first text of the first section must be huge (titles excluded, the rest of the text wraps around the large letter)

CSS Exercise 1 → details

  • No/few changes to the HTML
  • Use Google Web Fonts
  • Navigation bar at the top, aligned to the right
  • If resolution is less than 800px, navbar elements must be centered
  • If resolution is less than 600px,
    • it must have only one column
    • the navigation bar must be a single column
  • If printed, it must have 3cm side margins

CSS Exercise 2

Using the HTML document again: the content of each section must be invisible by default and become visible under some user action.

For example:

  • a checkbox for the selected article
  • hovering over the element linked in the navbar
  • ...

only HTML and CSS

CSS Exercise 3

Some more changes:

  • Add contacts with email addresses and links, then
    • if the link is an email, prepend the character ✉ (\2709)
    • each address must appear in full after the link text, in parentheses
  • If displayed on a screen with resolution 600px or higher, the article must be 21 cm wide, have a white background, and appear raised above a light gray background.
  • If printed, it must have the size of an A5 with 3cm side margins and create a new page for each section@page; some help

only HTML and CSS

Web Programming browser-side

Compiled Code (or Almost)

I can ask the browser to execute compiled code (or code running on a VM)

  • ActiveX → obsolete, Windows only
  • Flash → obsolete
  • Java Applet → limited use (e.g., electronic signature with smart card)
  • WebAssembly → still experimental

Representing an HTML Document

HyperText Markup Language (HTML)

Language used to describe the content and structure of the information in a web document

In reality, the goal of HTML is explicitly broader:

This specification is limited to providing a semantic-level markup language and associated semantic-level scripting APIs for authoring accessible pages on the Web ranging from static documents to dynamic applications.

Scripting

Web Scripting

Execution of the author’s code in the context of the web document

Code? → JavaScript

... but not only

  • SVG scripting
  • TypeScript
  • GO
  • ...

Context

During execution, the code can access the DOM tree, and thus the information within the document

  • read access → retrieve elements, attributes, ... from the DOM tree
  • write access → change attributes, text, structure, ... of the DOM tree

But also external resources (the window, storage, ...)

DOM Write Access

HTML Document → DOM tree → representation

Manipulating the DOM means changing the representation — in real time!

DOM Tree and Scripting

The specification also describes the interface of the various elements:

DOM interface:

  [NamedConstructor=Image(),
   NamedConstructor=Image(in unsigned long width),
   NamedConstructor=Image(in unsigned long width, in unsigned long height)]
  interface HTMLImageElement : HTMLElement {
             attribute DOMString alt;
             attribute DOMString src;
             attribute DOMString useMap;
             attribute boolean isMap;
             attribute unsigned long width;
             attribute unsigned long height;
    readonly attribute unsigned long naturalWidth;
    readonly attribute unsigned long naturalHeight;
    readonly attribute boolean complete;
  };

This is the documentation of the DOM interface for the img element

When Is the Code Executed?

Note:

  • The HTML document is the information
  • The CSS document defines how to represent that information

→ they don’t have a specific “when”...

“When” Is the Code Executed?

It is executed when it is encountered

The browser reads (parses) the HTML document, and when it finds a script, it executes it

How to Include the Script?

Two main methods:

  • Embedded in the document:
    <script type="text/javascript">
      /* do something */
    </script>
  • As an external text file:
    <script type="text/javascript" src="..."></script>

src and Start of Execution

For external scripts, you can specify the defer attribute:

<script type="text/javascript" src="..." defer></script>

→ execution is postponed until the browser reaches the end of the document

for embedded scripts, see onload

defer or not defer?

What’s the difference?

The code can access the DOM...

HTML half-read → DOM only half-complete

Event-Driven Programming

Handler

Association of a piece of code (function) with an event

there’s a click on this button → do these things

the browser reaches the end of the document → do these things

The association can be defined:

  • in the HTML document
    <p onclick="/* piece of code */">click me!</p>
  • in the code: we’ll see later

The JavaScript Language

Introduction

What will we learn?

  • JavaScript: as a language and as a language for the Web
  • Another instance of the “programming language” problem:
    • how to give instructions to a machine with no common sense?
    • the answer is given by humans — it can be imperfect

Brief History

  • 1995: initially called Mocha, released as LiveScript by Netscape
  • 1996: Microsoft created a port called JScript (not fully compatible)
  • 1997: standardization began under Ecma as ECMAScript
  • 2011: became an ISO standard (version 5.1)
  • 2015: ECMAScript 6 (officially ECMAScript 2015)
  • 2017: version 8

Meanwhile:

  • ever-growing popularity
  • increasing use outside the browser

JavaScript Engines

Engine = pair (VM, dialect)

There are many:

  • V8 (in Chrome and Node.js)
  • SpiderMonkey (Firefox, ...)
  • Nitro / JavaScriptCore in Safari
  • ...

Sophisticated: for example, JIT

JavaScript vs Java

  • Similar (not identical) syntax, more relaxed
  • Loose typing
  • Functions are objects!
  • “Silent” exceptions
  • Imperfect, given its history

Syntax

We won’t go into detail

Some peculiarities:

  • keywords: boolean, break, delete, extends, static, ... many unused
  • semicolon: not required, but recommended
  • tolerant toward “spaces”

We’ll see more as we go

Types

5 basic immutable types:

  • numbers
  • strings
  • booleans
  • null
  • undefined

All other values are objects (mutable): arrays, functions, regexes, and objects.

Types and typeof

typeof x is a string which describe the type of x

typeof 1          // → "number"
typeof "a"        // → "string"
typeof true       // → "boolean"
typeof {a: 1}     // → "object"
typeof undefined  // → "undefined"
typeof null       // → ???

Types and typeof: null

typeof null       // → "object"!!!

But why???

In memory: 32 bits per value

  • About 3 bits for the type
    • 000 → object [Null: dato = 0x00]
    • 001 → signed int
    • 010 → double
    • 100 → string
    • 110 → boolean
  • the rest for the data

Types and typeof: null

typeof null       // → "object"!!!

Value decoding (original code):

if (JSVAL_IS_UNDEFINED(v)) {
    type = JSTYPE_UNDEFINED;
} else if (JSVAL_IS_OBJECT(v)) {
    obj = JSVAL_TO_OBJECT(v);
    if (obj [..] clasp == js_FunctionClass)) {
        type = JSTYPE_FUNCTION;
    } else {
        type = JSTYPE_OBJECT;
    }
} else if (JSVAL_IS_NUMBER(v)) {
    type = JSTYPE_NUMBER;
} else if (JSVAL_IS_STRING(v)) {
    type = JSTYPE_STRING;
} else if (JSVAL_IS_BOOLEAN(v)) {
    type = JSTYPE_BOOLEAN;
}
return type;
                  

Types and typeof

typeof x is a string that describes the type of x

typeof 1          // → "number"
typeof "a"        // → "string"
typeof true       // → "boolean"
typeof {a: 1}     // → "object"
typeof undefined  // → "undefined"
typeof null       // → "object"!!!

typeof typeof 44?

There’s a sixth possibility: we’ll see it later.

It would have been better if typeof null returned "null".

typeof and Syntax

Relaxed syntax...

Which ones work, and why?

  1. typeof 1?
  2. typeof(1)?
  3. typeof (1)?

typeof and Syntax

Relaxed syntax...

Which ones work, and why?

  1. typeof 1?
  2. typeof(1)?
  3. typeof (1)?

typeof is an operator, and what is inside the parentheses is an expression to be evaluated.

Immutable Types

Numbers, strings, and booleans are object-like: you can access their methods

(22).toExponential()   // → "2.2e+1"
"job".charAt(2)        // → "b"
true.toLocaleString()  // → "true"

but they are immutable!

Numbers

There is only one number type: float (IEEE 754 Double Precision)

Remember the issues this causes?

Numbers

There is only one number type: float (IEEE 754 Double Precision)

  • operations with decimals behave as floats:
    0.1 + 0.2 == 0.3 /* → false */
  • operations with integers are exact (really safe?)
    9999999999999999 == 10000000000000000 /* → true */

null vs undefined

An identifier refers to:

  • undefined if no value (other than undefined) has been assigned to it
  • null only if it has been explicitly assigned null

Why do both exist? Is there a reason?

  • historical reasons (exceptions came later)
  • a property that exists but has no value can be distinguished from one that doesn’t exist

Objects

An object is a mutable collection of properties.

  • Each property has a name (string) and a value (of any type)
  • Mutable:
    • Property values can be modified
    • Properties can be added or removed

Object literal

Collection of key-value couples comma-separated.

        var simba = {
          name: "simba",
          animalType: "dog",
          legs: 4,
          "sound": "bark",
          collar: {
            material: "leather",
            size: "M"
          }
        };

"animalType", "dog" is a property: "animalType" is the name (string type), "dog" is the value (string type).

The value of the property named "collar" is of type object.

var statement

var simba = {
  name: "simba",
  animalType: "dog",
  legs: 4,
  "sound": "bark"
}
  1. Defines the identifier simba as visible within the scope.
  2. Associates it with (makes it refer to) the object value.

What is the scope? We’ll see.

Accessing Object Property Values

  1. simba.name
  2. simba["name"]

Both expressions access the name property of the object referred to by simba.

The second form is necessary if the property name has certain characteristics, e.g. simba["is cute"].

If simba refers to undefined or null, then a TypeError exception is thrown.

. and [] are refinement operators.

Accessing Property Values: Syntax

Spacing is flexible:

  • simba.name
  • simba["name"]
  • simba .name
  • simba. name
  • simba . name
  • simba ["name"]
  • ...

All are equivalent and syntactically correct.

But not all are stylistically good...

Accessing Object Values

  • Read a property:
    var name = simba.name;
    If it’s not defined, the value is undefined.
  • Add/modify a property:
    simba.nickname = "White dog";
    If it’s not defined, it’s added; otherwise, it’s modified.
  • Remove a property:
    delete simba.nickname;

References

Objects are always passed by reference.

var simba = {
  name: "simba",
  collar: {
    material: "leather",
    size: "M"
  }
};
var whitedog = simba;
var c = whitedog.collar;
delete whitedog.collar;

whitedog.collar? undefined

simba.collar? undefined

c? → Object {material: "leather", size: "M"}

Iterating Over Properties: “Reflection”

var simba = {
  name: "simba",
  legs: 4
};
for (var propName in simba) {
  console.log("simba." + propName + " = " + simba[propName] + ", of type " + (typeof simba[propName]));
}

Functions

A function is an object with two additional hidden properties:

  • the code
  • the context

typeof f returns "function" if f is a function.

Here is the sixth element.

Function Literal

var sum = function(a, b) {
  var c = a + b;
  return c;
}
sum(2,3); /* → 5 */

sum refers to a function object, whose two statements (lines 2 and 3) form its body.

Function Name

var sum = function(a, b) {
  return a + b;
}
sum.name  /* → "" (or the variable name) */

Anonymous function — sum refers to the function.

This is the recommended option.

Why does it have a name property? Who added it? We’ll see.

Function Name

var sum = function summation(a, b) {
  return a + b;
}
sum.name  /* → "summation" */

Named function — sum refers to the function, summation is not a defined identifier.

The name is still useful for:

  • Debugging
  • Recursive functions

Function Name

function summation(a, b) {
  return a + b;
}
summation.name  /* → "summation" */

Named function — summation is defined and refers to the function.

Object or Function?

Functions are objects, i.e. mutable collections of properties!

var sum = function(a, b) {
  return a + b;
}
sum.p = "hello";

Scope

The scope is the region in which identifiers are defined (visible).

In JavaScript, the scope is the function body.

Despite the block syntax (curly braces), the scope is not the block!

Scope

In JavaScript, the scope is the function body.

var maxSumProd = function(a, b) {
  var s = a + b;             /* s is defined */
  var p = a * b;             /* s, p are defined */
  for (var i = 0; i < 4; i++) {
    var c = i;               /* s, p, i, c are defined */
  }
  if (s > p) {               /* s, p, i, c are defined */
    return s;
  } else {
    return p;
  }
};

Different from Java!

Scope and Hierarchy

Scopes are hierarchical: inside a function’s scope, identifiers (except for this and arguments) defined in the outer scope are visible.

var fun = function() {
  var a = 1;
  var b = 2;
  var innerFun = function() {
    var c = a + b;
    return c;
  };
  return innerFun();
};

Global Scope

var defines a variable; if omitted, it implies the global scope.

  • var a;a is defined (but uninitialized) in the local scope
  • var a = 0;a is defined and refers to 0 in the local scope
  • a = 0;
    • if a was defined in a parent scope, it now refers to 0
    • otherwise, it’s defined in the global scope and refers to 0

Global Scope

Watch out!

var calculateTopTenCosts = function() {
  var sum = 0;
  for(top = 0; top < 10; top++) {
    sum += getRankCosts(top);
  }
  return sum;
};
  • var is missing before top in the loop
  • top becomes a global variable (in a browser: the top-level window object)
  • The loop won’t execute (top is not a number)

Block Scope

var declares the variable in the function scope.

And if I want one at the block level?

Since ECMAScript 6 you can use: let

Invoking a Function

There are four Function Invocation Patterns:

  1. Method Invocation
  2. Function Invocation
  3. Apply Invocation
  4. Constructor Invocation

What changes?

  • In addition to declared parameters, each function receives two implicit ones:
    • this
    • arguments
  • this depends on the invocation pattern.

1. Method Invocation

If and only if:

  • the function is the value of an object’s property (method)
  • and it is invoked through that object’s refinement (.)
then:
  • this is the object containing it
  • arguments are the evaluations of the expressions passed in parentheses if fewer arguments are given, the missing ones are undefined

1. Method Invocation

var o = {
  n: 3,
  sum: function(m) {
    return this.n + m;
  },
  dec: function(m) {
    return n - m;
  }
};

o.sum(2)? → 5

o.dec(1)? → error! n undefined

var f = o.sum; f(2)? → NaN

var f = o.sum(); f(2)? f is not a function

Method Invocation and this

this is not optional!

given the same semantics.

2. Function Invocation

When the function is not a property of an object and is invoked directly:

var sum = add(3, 4); // sum is 7
  • The arguments: same as before.
  • this is the global object.
    • What is the global object? It depends on the environment.
    • In a browser, it’s the DOM’s window object.
    • Be careful: it’s not the this of the outer function!

2. Function Invocation

If done correctly, this would refer to the outer function...

var myObject = {
  value: 1,
  double: function() {
    var helper = function() {
      this.value = this.value * 2;
    };
    helper();
  }
}
console.log(myObject.value); /* → 1 */
myObject.double(); /* Method Invocation */
console.log(myObject.value); /* → ?? */

2. Function Invocation

Workaround

var myObject = {
  value: 1,
  double: function() {
    var that = this;
    var helper = function() {
      that.value = that.value * 2;
    };
    helper(); /* Function Invocation */
  }
}
console.log(myObject.value); /* → 1 */
myObject.double(); /* Method Invocation */
console.log(myObject.value); /* → 2 */

3. Apply Invocation

Every function also has an apply method: when called, the first parameter becomes this and the second one becomes arguments.

var sum = function(a, b) {
  return a + b;
};
sum.apply(undefined, [2, 3]); /* → 5 */

[2, 3] is an array literal — we’ll cover that later.

3. Apply Invocation

var myObject = {
  value: 1,
  double: function() {
    var helper = function() {
      this.value = this.value * 2;
    };
    helper.apply(this); /* Apply Invocation */
  }
}
console.log(myObject.value); /* → 1 */
myObject.double(); /* Method Invocation */
console.log(myObject.value); /* → 2 */

4. Constructor Invocation (new)

If a function is called with the keyword new:

  • this is a new object
  • if the return value is not an object, this is returned

The new object has a hidden link to the function’s prototype property.

4. Constructor Invocation

It looks like a constructor, but it can be misused.

By convention (and to avoid misuse), functions intended as constructors start with a capital letter.

4. Constructor Invocation

var Dog = function(name, size) {
  this.name = name;
  this.size = size;
  this.sound = "bark";
  this.makeSound = function() {
    return this.sound;
  }
};

var whiteDog = new Dog("Simba", "M");
var brownDog = new Dog("Gass", "M");

4. Constructor Invocation (Misused)

var Dog = function(name, size) {
  this.name = name;
  this.size = size;
  this.sound = "bark";
  this.makeSound = function() {
    return this.sound;
  }
};

var weirdDog = Dog("Simba", "M");
  • Value of weirdDog? undefined!

Parameters and arguments

  • arguments is a (quasi) array
    • in fact, it’s an object with a length property...
  • arguments may contain more parameters than the function definition:

    function myConcat(separator) {
      var result = '';
      var i;
      for (i = 1; i < arguments.length; i++) {
        result += arguments[i] + separator;
      }
      return result;
    }
    myConcat(', ', 'red', 'orange', 'blue');
    // → "red, orange, blue, "

Parameters and arguments

Their values are linked:

var sum = function(a, b) {
          var c = a + b;
          return c;
        }

a and arguments[0] always share the same value.

Parameters and arguments

var surpriseMe = function (a) {
  console.log(a + " - " + arguments[0]);
  a = 3;
  console.log(a + " - " + arguments[0]);
};

surpriseMe(2)?

2 - 2
3 - 3
                

Parameters and arguments

For non-strict mode functions the array index (defined in 15.4) named data properties of an arguments object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function’s execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. For strict mode functions, the values of the arguments object’s properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.

JavaScript oddities

but luckily there’s Stack Overflow

Default parameters

It used to be done manually:

function multiply(a, b) {
  b = typeof b !== 'undefined' ? b : 1;
  return a * b;
}

...now it can go in the signature (ECMAScript 2015)

function multiply(a, b = 1) {
  return a * b;
}

Rest parameter

Aggregates multiple parameters into an array:

function myConcat(separator, ...values) {
  var result = '';
  var i;
  for (i = 0; i < values.length; i++) {
    result += values[i] + separator;
  }
  return result;
}

myConcat(', ', 'red', 'orange', 'blue');
// → "red, orange, blue, "

Return Value

Functions always have a return value.

  • If the body contains a return statement, then (constructor invocation aside) the return value is whatever is specified there.
  • Otherwise it is undefined.

Execution (obviously) stops when the return statement is reached.

return and whitespace

The syntax of the return statement is “not very tolerant” of line breaks/whitespace

var f = function() {
  return
    {word: "hello"};
}

is equivalent to

var f = function() {
  return undefined;
    {word: "hello"};
}

...

return and whitespace

It is not equivalent to

var f = function() {
  return {word: "hello"};
}

which, in turn, is equivalent to

var f = function() {
  return {
    word: "hello"
  };
}

Scope Convention

By convention: all var statements go at the start of the body:

var fun = function() {
  var a, b, s;
  a = 1;
  b = 2;
  var innerFun = function() {
    var c;
    c = a + b;
    return c;
  }
  s = innerFun();
  return s;
};

Just a convention?

var fun = function() {
  var a = 1;
  var innerFun = function() {
    console.log(a);
  };
  innerFun();
};

fun() /* prints 1: all good */

Just a convention?

var fun = function() {
  var a = 1;
  var innerFun = function() {
    console.log(a);
    var a = 2;
  };
  innerFun();
};

fun() /* prints undefined!!! */

Why?

Variable Hoisting

Internally, JavaScript moves all var declarations to the top of the body:

var fun = function() {
  var a, innerFun;
  a = 1;
  innerFun = function() {
    var a;
    console.log(a); /* local a in scope, it’s undefined */
    a = 2;
  };
  innerFun();
};

fun() /* prints undefined */

Why?

Variable Hoisting

Why?

Because the interpreter does two passes:

For completeness, let’s mention that actually at the implementation level things are a little more complex. There are two stages of the code handling, where variables, function declarations, and formal parameters are created at the first stage, which is the stage of parsing and entering the context. In the second stage, the stage of runtime code execution, function expressions and unqualified identifiers (undeclared variables) are created. But for practical purposes, we can adopt the concept of hoisting, which is actually not defined by ECMAScript standard but is commonly used to describe the behavior.

In fact the specifications don’t say anything about “hoisting” explicitly!

Note: this does not apply to variables defined with let.

Function Hoisting

It also applies to functions, when defined directly (declarations):

function exampleOK() {
  console.log(foo); /* → function’s code */
                    /* (the function itself) */
  foo();            /* → "bar" */
  function foo() {
    console.log('bar');
  };
};

Function Hoisting

It also applies to functions, when defined directly:

function exampleNotOK() {
  console.log(foo); /* → undefined */
  foo(); /* → TypeError: foo is not a function */
  var foo = function() {
    console.log('bar2');
  };
}

Why?

  1. Only the variable foo is hoisted.
  2. The variable receives a value only at line 4.

Closure

How can we expose functionality without exposing internal variables?

Let’s take a counter:

var counter = 0;
function add() {
  counter += 1;
}
add();
add();
add();
  • Does it work? Yes
  • Does the counter increase? Yes
  • Problem: anyone who can call add() can also modify counter.

Closure

What if we put the variable inside the function?

var counter = 0;
function add() {
  var counter;
  counter += 1;
}
add();
add();
add();
  • Does it work? No, at the end counter is 0.
  • We increment an internal variable, but the global one remains visible.

Closure

What if we remove the global variable and just return the value?

function add() {
  var counter;
  counter += 1;
  return counter;
}
add();
add();
add();
  • Does it work? No, in the end counter is 1.
  • The variable is redefined at each call.

Closure

Let’s try nesting functions:

function add() {
  var counter = 0;
  function plus() { counter += 1; }
  plus();
  return counter;
}
  • In JavaScript, all functions have access to the scope in which they are defined.
  • The function plus has access to the enclosing scope, and therefore to counter.
  • Problem: how can we call plus() from outside?

Closure: the solution

A self-invoking function:

var add = (function () {
  var counter = 0;
  return function () {
    counter += 1;
    return counter;
  }
})();
add(); /* 1 */
add(); /* 2 */
add(); /* 3 */
  • Does it work? Yes, the final call returns 3.
  • Can we access counter? No.
  • But how did we do that??

Closure: the solution

var add = (function () {
  var counter = 0;
  return function () {
    counter += 1;
    return counter;
  }
})();
add(); add(); add();
  • add contains the result of a self-invoking function.
  • The self-invoking function runs once: it sets up the counter, returns a function, and is discarded.
  • add is itself a function → it has access to the scope that contains it → it can access counter, which still exists.
  • No one else can access counter.

Closure

We can also create more advanced closures:

var counter = function() {
  var n;
  n = 0;
  return {
    inc: function() {
      n = n + 1;
      return n;
    }
  };
}();
counter.inc();
  • The function referenced by inc is a closure.
  • n is an enclosed variable.

Operators + and types

Some operators also apply to unexpected types: it's useful to know how things work to avoid surprises.

Operator +:

  • if both operands are of type number, it sums the values
  • if both operands are strings, it concatenates them
  • otherwise, as we’ve already seen, it tries to convert operands to strings and concatenate them

often the source of unpleasant issues when reading a number from the DOM

Truthy and Falsy

Every value in JS also has an implicit boolean value:

Falsy
  • false
  • 0 (careful: not "0"!)
  • '' or "" (empty string)
  • null
  • undefined
  • NaN (technically: a number type value)
  • document.all (thanks to Microsoft for this one)
Truthy
...in all other cases

Truthy and Falsy

We can use a function to test it:

function truthyOrFalsy(a) {
    return a ? "truthy" : "falsy";
}
  • truthyOrFalsy(0) → falsy
  • truthyOrFalsy(10 == 5) → falsy
  • truthyOrFalsy(1) → truthy
  • truthyOrFalsy(-1) → truthy
  • truthyOrFalsy({}) → truthy

Mentiroso...

There are some values that are truthy but == false

  • "0" is truthy (non-empty string), but "0" == false:
    1. == → converts the string to a number
    2. 0 == false
    3. "0" == 0
    4. "0" == false
  • Not an isolated case...

== vs ===

Operator ===:

  • true, if operands have the same type and value
  • false, otherwise

Operator ==: tries to perform type conversion

false == undefined /* false */
false == null /* false */
null == undefined /* true */

Goodbye transitivity of equality: better === than == !

Arrays

An array is an object that:

  • has a characteristic literal syntax
  • has predefined methods

Arrays

Arrays are objects

var a = [2, 3, "pippo"];
var a = new Array(2, 3, "pippo"); /* → alternative */
a[0];     /* → 2 */
a[2];     /* → "pippo" */
a["2"];   /* → "pippo" */
a.length; /* → 3 */
a[3];     /* → undefined */

a.addedProperty = "I’m an object";
a.length; /* → 3*/

Other useful methods:

  • slice() → copies a portion of the array,
  • splice() → removes (and replaces) elements,
  • ...

Array: Length

length ≠ upper bound → I can exceed it!

var myArray = [];
myArray.length;     /*  → 0*/
myArray[10000] = "pippo";
myArray.length;     /*  → 10001*/

Adding elements:

numbers[numbers.length] = 'shi';  /*or...*/
numbers.push('go');

Array: removing elements

Assigning a smaller value to length removes the trailing elements.

You can remove any element, but it leaves a hole:

var a = [2, 3, 79];
a.length;     /* → 3 */
delete a[1];
a.length;     /* → 3 */

typeof(a[1]);    /* → "undefined" */

...better to use the splice method

Array: recognition

typeof (array) → "object"

Let’s write our own function:

var is_array = function (value) {
  return value &&
    typeof value === 'object' &&
    typeof value.length === 'number' &&
    typeof value.splice === 'function' &&
    !(value.propertyIsEnumerable('length'));
};
  • is it truthy? not {false, null, undefined, "", 0, NaN}
  • is it an object?
  • does it have a numeric length property?
  • does it have a splice function?
  • would length appear in a for ... in?

Array: sorting

Be careful...

[5, 12, 9, 2, 18, 1, 25].sort(); → [1, 12, 18, 2, 25, 5, 9]

The default behavior is to sort alphabetically!

We must specify a sorting function:

[5, 12, 9, 2, 18, 1, 25].sort(function(a, b){
    return a - b;
});

Array: iteration

Be careful...

var a = [2, 3, 79];
for (var name in a){
  console.log(name)
};
/*output: 0, 1, 2*/

We are iterating over the object’s properties, including any added manually (or by other frameworks)!

Array: iteration

We should use the old-fashioned way:

var a = [2, 3, 79];
for (var i = 0; i < a.length; i += 1) {
  console.log(a[i]);
}
/*output: 2, 3, 79*/

Or use the forEach method:

a.forEach(function(value){
  console.log(value);
});
/*output: 2, 3, 79*/

Memoization

Sometimes I need to reuse already computed results...

var fibonacci = function (n) {
  if (n < 2){
    return n
  } else {
    return fibonacci(n - 1) + fibonacci(n - 2);
  }
};

for (var i = 0; i <= 10; i += 1) {
  console.log('// ' + i + ': ' + fibonacci(i));
}

Inefficient: function called 453 times

Memoization

Let’s use a closure to store previously computed results:

var fibonacci = (function() {
  var memo = [0, 1];
  var fib = function (n) {
    var result = memo[n];
    if (typeof result !== 'number') {
      result = fib(n - 1) + fib(n - 2);
      memo[n] = result;
    }
    return result;
  };
  return fib;
})();

Nice! fibonacci called only 18 times

Class-Based Inheritance

Traditionally (Java, C++, C#) there are two entities: classes and instances.

  • Class: defines the properties and methods of the object it describes, but never represents one. Example: Teacher
  • Instance: materialization of a class. Example: Alberto Bartoli, Eric Medvet, Andrea De Lorenzo

In addition:

  • properties and constructor are defined separately;
  • hierarchy is defined through subclassing an existing class;
  • explicit casting is not required (polymorphism).

Prototype-based Inheritance

JavaScript is loosely-typed: every object derives from another object from which it inherits properties, called its prototype.

How is this achieved?

  • Every constructor function has a prototype property containing the object to be used as prototype in a constructor invocation

    in fact, this property exists in every function; a function becomes a constructor when it is invoked with new

  • The new object has a hidden link to the value of the constructor function’s prototype property: __proto__

Delegation

  • Access for adding/modifying/removing properties uses the hidden link
  • Read access:
    • if the property exists in the object, its value is returned
    • otherwise, if it exists in the prototype, that value is returned
    • otherwise, if it exists in the prototype’s prototype, ...
    • ...
    • otherwise, undefined
  • Write access:
    • creates a new property in the final object → the prototype is not modified.

Example of Prototype-based Inheritance

public class Employee {
   public String name;
   public String dept;
   public Employee () {
      this("", "general");
   }
   public Employee (String name) {
      this(name, "general");
   }
   public Employee (String name, String dept) {
      this.name = name;
      this.dept = dept;
   }
}
function Employee(name="", dept="general") {
  this.name = name;
  this.dept = dept;
}

Example of Prototype-based Inheritance

public class Engineer extends Employee {
  public String machine;
  public Engineer () {
    this("");
  }
  public Engineer (String mach) {
    dept = "engineering";
    machine = mach;
  }
}
function Engineer(mach = "") {
  this.dept = 'engineering';
  this.machine = mach;
}
Engineer.prototype = new Employee;

Example of Prototype-based Inheritance

function Employee(name="", dept="general") {
  this.name = name;
  this.dept = dept;
}
function Engineer(mach = "") {
  this.dept = 'engineering';
  this.machine = mach;
}
Engineer.prototype = new Employee;
var luca = new Engineer("computer");

What are the values of the following expressions:

  • luca.machine → "computer"
  • luca.dept → "engineering"
  • luca.name → ""

Dynamic Inheritance

An object’s prototype is itself an object, so if you

  • add
  • modify
  • remove

a property to/from the prototype, this affects all objects that have that prototype (through delegation).

...
Engineer.prototype = new Employee;
var luca = new Engineer("computer");
Employee.prototype.salary = 100;
luca.salary; /* → 100*/

The Creating Function

  • Creating an object as a literal is equivalent to creating it with a constructor invocation of Object
  • Creating a function as a literal is equivalent to creating it with a constructor invocation of Function

The Creating Function: Objects

Creating an object as a literal is equivalent to creating it with a constructor invocation of Object

var o = new Object();

is equivalent to

var o = {};

and the object can be filled later.

Object.prototype is the prototype object from which both derive.

Literal creation is recommended

The Creating Function: Objects

For example, I can add read-only properties:

var o = new Object();
Object.defineProperty(o, "prop", {
    value: "test",
    writable: false
});

o.prop; /* → "test"*/
o.prop = "Ciao";
o.prop; /* → "test"*/

The Creating Function: Functions

Creating a function as a literal is equivalent to creating it with a constructor invocation of Function

var f = new Function();

is equivalent to

var f = function(){};

but the function cannot be filled later (in its body).

Function.prototype is the object from which both derive (the prototype).

Literal creation is necessary

Dynamic Inheritance

var sum = function(a, b) {
  return a+b;
};
sum.creator;  /* → undefined*/

Function.prototype.creator = "Eric Medvet";

sum.creator;  /* → Eric Medvet (delegation)*/
var prod = function(a, b) {
  return a*b;
}

prod.creator; /* → Eric Medvet (delegation)*/
prod.creator = "Simba";
prod.creator; /* → Simba (no delegation)*/
sum.creator;  /* → Eric Medvet*/

Setting the Prototype

Object.create = function(o) {
  var F = function () {};
  F.prototype = o;
  return new F();
};

var dog = {sound: "bark"};
var coloredDog = Object.create(dog);
coloredDog.sound; /* → bark*/

Setting the Prototype

Object.create = function(o) {
  var F = function () {};
  F.prototype = o;
  return new F();
};
  1. creates a new function and adds it as a property of Object
  2. when create is invoked with argument o
    1. creates a new empty function F
    2. sets its prototype to o
    3. returns the result of new F() (a new object with a hidden link to the prototype property of the creating function, that is o)

Augmenting

Object.create = function(o) {
  ...
};
  1. creates a new function and adds it as a property of Object

Augmenting a base type (Object)

This can also be done with strings, numbers, etc...

String.reverse = function() {
  ...
};

don’t overuse it

Monkey Patching

Adding new functionality to the system library by extending it

Example: we want to add a function to String that capitalizes the first letter

String.prototype.capitalize = function() {
  return this[0].toUpperCase() + this.substr(1);
}
const capitalName = 'jacob'.capitalize(); /* → "Jacob" */

Monkey Patching

It should be avoided!

If other libraries do the same thing, what would happen?

This problem has already occurred in the past: smooshgate

The MooTools library, widely used at the time, had added the flatten function

Array.prototype.flatten = function(){...}

...but in 2019, flatten was introduced into ECMAScript!

Dynamic Inheritance and Primitives

Object.prototype.version = "7.2.11";
"uh".version; /* → 7.2.11*/

Why? Isn’t "uh" a primitive String?

Primitives Coercion

typeof true; /*"boolean"*/
typeof Boolean(true); /*"boolean"*/
typeof new Boolean(true); /*"object"*/
typeof (new Boolean(true)).valueOf(); /*"boolean"*/

typeof "abc"; /*"string"*/
typeof String("abc"); /*"string"*/
typeof new String("abc"); /*"object"*/
typeof (new String("abc")).valueOf(); /*"string"*/

typeof 123; /*"number"*/
typeof Number(123); /*"number"*/
typeof new Number(123); /*"object"*/
typeof (new Number(123)).valueOf(); /*"number"*/

To execute "uh".version, a new String object (wrapper) is created, used only to access the property, and then discarded by the Garbage Collector.

Primitives Coercion

So, can I add properties to primitives?

var primitive = "september";
primitive.vowels = 3;
primitive.vowels; /* → ??*/

Primitives Coercion

So, can I add properties to primitives? NO!

var primitive = "september";
primitive.vowels = 3; /* → create a new wrapper:*/
(new String("september")).vowels = 3;
primitive.vowels;     /*→ create a new wrapper to
                        read the property:*/
(new String("september")).vowels; /* → undefined*/

Primitives Un-Wrapping

Wrappers easily revert to their primitive type:

var Twelve = new Number(12);
var fifteen = Twelve + 3;
fifteen; /*15*/
typeof fifteen; /*"number" (primitive)*/
typeof Twelve; /*"object"; (still object)*/

But it’s still JavaScript:

if (new Boolean(false)) {
  console.log("true");
} else{
  console.log("false");
}

Output?

Primitives Un-Wrapping

Wrappers easily revert to their primitive type:

var Twelve = new Number(12);
var fifteen = Twelve + 3;
fifteen; /*15*/
typeof fifteen; /*"number" (primitive)*/
typeof Twelve; /*"object" (still object)*/

But it’s still JavaScript:

if (new Boolean(false)) {
  console.log("true");
} else{
  console.log("false");
}

Output? → "true", because objects are truthy.

For booleans, use the value: new Boolean(false).valueOf();

Exercise: JS-WordCounter

Create a JavaScript function wordCounter that returns a <word, frequency> "map" computed from the input string.

wordCounter("la mamma di mio figlio è anche mamma di mia figlia"); /* → <"mamma", 2/11>, <"figlio", 1/11>, ...*/

see String.split()

And what if there are punctuation marks? See regular expressions and their literal syntax.

Exercise: JS-Infinite Function

Create a JavaScript function such that:


var f = ...;
f(1)                  /* → 1*/
f()(3)                /* → 3*/
f()()()()("a")        /* → "a"*/
f()...()("x")         /* → "x"*/

var g = f;
f = 33;
g()()()()(f)          /* → 33*/

JavaScript

JavaScript in the Web Context

DOM

Remember?

Document Object Model (DOM)

Tree representation of the document, in memory

Programmatic interface for:

  • Accessing the tree
  • Modifying the structure
  • Modifying the style
  • Modifying the content
Essentially, it connects web pages to scripts or programming languages.

DOM Interfaces

  • Node: provides what’s needed for the tree representation
  • Document: derives from Node, but some properties don’t apply (e.g., a Document has no attributes).
  • Browser:
    • Window: the browser window (or tab) containing the document

      Note: some methods always apply to the window (e.g., window.resizeTo)

    • Navigator: information about the browser
    • History: navigate forward/backward in the browsing history
    • ...

DOM Interfaces - HTML

  • HTMLDocument: extends Document, but with HTML5 many methods/properties are already included in it.
  • HTMLElement: for all types
    • HTMLAnchorElement
    • HTMLParagraphElement
    • HTMLFormElement
    • etc.

Not just HTML! There’s also the entire world of SVG...

Accessing Elements

The document object contains the DOM:

  • document.getElementById("...") → returns the element (HTMLElement) with the specified ID
  • document.getElementsByTagName("...") → returns the elements with the specified tag name ("a", "span", ...); "*" returns all of them
  • document.getElementsByClassName("...") → returns the elements with the specified class (a list of space-separated values)
  • document.querySelectorAll("...") → returns all elements matching the given CSS selector
  • document.querySelector("...") → returns the first element matching the given CSS selector

Creating Elements

  • document.createElement("...") → creates an element of the specified type
  • element.appendChild(child) → adds the element as the last child of the specified element node
  • .innerHTML → reads/sets the HTML code that defines the element’s descendants
var mainSection = document.getElementById("mainSection");
var newP = document.createElement("p");
newP.innerHTML = "this is the <b>new</b> paragraph";
mainSection.appendChild(newP);

Styling Elements

  • element.style → accesses the element’s style attribute → ignores inherited/external styles
    element.style.color = "#ff3300";
    element.style.marginTop = "30px";
  • window.getComputedStyle(element) → returns the computed style for the element

DOM Event Model

There are several ways to bind to events:

  1. HTML Attribute
<button onclick="alert('Hello world!')">

Ugly:

  • Heavier markup → less readable
  • Content and behavior not separated → bugs harder to find

DOM Event Model

There are several ways to bind to events:

  1. HTML Attribute
  2. EventTarget.addEventListener (specifications)
/* Assume myButton is a Button */
myButton.addEventListener('click', function(){
  alert('Hello world');
}, false);

Nice!

Note: not supported in Internet Explorer 6–8, where EventTarget.attachEvent is used instead → it's better to use libraries for maximum compatibility.

DOM Event Model

There are several ways to bind to events:

  1. HTML Attribute
  2. EventTarget.addEventListener (specifications)
  3. DOM element properties
/* Assume myButton is a Button */
myButton.onclick = function(event){
  alert('Hello world');
};

Note: only one handler per element per event.

Event Propagation

There are three phases:

  1. Capture: the event propagates from the most ancestral target (Window) down to the most specific one (e.g., td)
  2. Target: the event reaches its destination and, depending on the event type, either stops or continues with bubble
  3. Bubble: the event propagates back up the tree

Manually stop bubbling propagation:

ev.stopPropagation();

Note: this does not stop the function’s execution.

Exercise: JS-Anagrams

Write an HTML document with an input box and a button: when the user clicks the button, the page shows a list with the first 20 permutations of the word typed into the box.

Hints:

  • input box → input
  • "when the user" → event