Intro to web development with HTML/CSS/JS


Overview

This is a very brief introduction to programming for the web, focused on the “front end”. We’ll talk about

Resources

First, some resources to go more in depth after this primer.

Tools

You don’t need much to start

For more serious work, you’ll need

A website’s structure

A website is separated into 3 parts:

In the browser

rendering a website. Source: [MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/How_CSS_works)

The HTML/CSS are used to create the DOM, while JavaScript interacts with it.

We can inspect the DOM using Developer tools in any browser, by menu, or right-click > inspect.

Exploring the DOM

Things to notice:

HTML

HyperText Markup Language

<tag-name attribute="value">innerHTML</tag-name>
<tag-name attribute="value" />
<!-- comments -->

Sample HTML Document

Things to note in this document:

What are the semantics?

Why provide semantics?

HTML pre-languages

Writing raw HTML with all the opening and closing tags can be be quite tedious.

CSS

Cascading style sheets describe the appearance of elements.

“Cascading” refers to the way rules/declarations are applied:

Syntax:

selector { property: value; ... }

The whole statement is a “rule”. Each property: value; pair is a “declaration”.

Selectors

Describe the elements in the DOM. There are,

Combinators

Selectors can also be combined to describe where an element falls in the DOM hierarchy.

I read these from right to left: the selected element matches the rightmost selector, the rest describes its place in the DOM Example:

section > p + h1 {
    color: blue;
}

Selects the top-level heading directly adjacent to a paragraph which is the child of a section.

Other selections

Declarations (property: value;)

These describe the way an element is drawn. Different elements can have their own special properties, but no error will be given if a property doesn’t apply.

Common properties include:

You’ll have to look up a reference for all the possibilities.

Box model

It’s worth mentioning the box model for element sizing/spacing.

![box model illustration](/studyGroup/lessons/misc/webdev-intro/img/box-model-standard-small.png)
source: [MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Box_model)

Sites with more complicated layout will often use

* { box-sizing: content-box; },

to make the sizes consistent regardless of borders and padding.

CSS pre-languages

CSS lacks some features that can be very useful/convenient, like

This is good for browser performance, but a pain for developers. There are lots of pre-processors for CSS that add all these features and more

JavaScript (ECMAScript)

JavaScript is the scripting language supported by modern browsers. It’s specified as ECMAScript, the latest standard being ECMAScript 2015 (aka ES6). All modern browsers support ES5.1, and most of ES6

JavaScript is a scripting language with

ES6 adds

Javascript types

There are primitive types:

Then there are notably,

Declaring variables

Variables can be declared with var or let. You’ll probably use var most.

var x = 1;
var s = 'hello world';
var u; // undefined
var f = function() {
    console.log('function f called');
};
var o = {name: 'some object', callMe: f, 1: 'one'}

let is for block-scope which is good for loop variables.

for (let i=0; i<10; i++) {
    console.log(i)
}
console.log(i) // error

Functions

Can be anonymous:

(function() {console.log('hello world')})()

Named throughout current scope (“hoisted”):

foo() // logs "bar"
function foo() { 
    console.log('bar'); 
}

Attached to a variable:

bar() // error
var bar = function () {
    console.log('foo')
}
bar() // logs "foo"

Lexical scope

The scope describes what variables are accessible and their names. In JavaScript, the scope of a variable defined with var is the current function. JS also has a lexical scope, so functions inherit the scope of their parents.

// example of isolating scope with a function
var x = 10;
(function () {
    var x = document.createElement('section');
    x.innerHTML = '<h1>From Demo</h1>';
    x.className = 'slide shown';
    document.getElementById('content').appendChild(x);
})()
console.log(x);

More with scope rules

Variables can become private.

// Example of a closure
var counter = (function() {
    var i = 0;
    return function () {
        return i++;
    };
})();
console.log(counter())
console.log(counter())

More with scope rules

We can make factories

// Bigger example of a closure
var countBy = function(inc) {
    var count = -inc;
    return function() {
        count += inc;
        return count;
    }
};
c = countBy(6);
d = countBy(2);

console.log(c())
console.log(d())
console.log(c())
console.log(d())

Objects

Object properties can be accessed with either . or [].

o.name;
o['callMe']();
o[1]

And properties can always be added/reassigned

f.name = 'asdf';
f.obj = o;

Methods/Calling

Object properties that are methods have a special variable this added to scope.

var f = function (arg1, arg2) {
    arg2 = arg2 || 'earth';
    console.log(`called by ${this.name}`)
    console.log('object', this);
    console.log('arg1', arg1);
    console.log('arg2', arg2);
}
var foo = {name: 'bar', method: f}

The following are equivalent

foo.method('hi');
f.bind(foo)('hi');
f.apply(foo, ['hi');
f.call(foo, 'hi');

Conditional statements

The if/else if/else statement is same as in C

if (condition) {
    codeBlock;
}
else if (condition2)
    statement;
else {
    codeBlock;
}

There is also switch..case, which we’ll see in this app’s code.

Casting in comparison

There are two equalities in JavaScript

Casting also happens for <, <=, etc.

A logical “not” is the operator !, which does cast to booleans. So you can do !!undefined to get true.

Loops

There are while, do...while, and for loops. All follow classic C syntax, but there are special forms of for loops

var shoppingList = ['banana', 'apple', 'bread'];
shoppingList.title = 'My Groceries';

/* This will print the object's properties */
for (let i in shoppingList)
    console.log(i);

/* and this prints the elements in the _iterable_ object */
for (let x of shoppingList)
    console.log(x);

/* for arrays you could still do */
for (let i=0; i<shoppingList.length; i++) {
    console.log(shoppingList[i]);
}

The for...of syntax behaves most like Python’s for...in loop.

Interacting with the DOM

Go over the code for this “app”.

Note:

Classes/Objects

JavaScript is prototype-based. This is different from class-based, but has similar functionality.

Prototype example

function A() {
    this.varA = 'a';
}

function B() {
    A.call(this);
    this.varB = 'b';
}

A.prototype = { foo: 1, bar: function(x) { return this.foo + 1;}};
B.prototype = Object.create(A.prototype);
B.prototype.foo = 3;

a = new A();
b = new B();

a.bar(1);
b.bar(1);

B.prototype.foo = -1;
b.bar(1);

Class syntax

Just a syntactic wrapping of what we covered before.


class C extends B {
    constructor(c) {
        super();
        this.foo = -1;
        this.varC = c;
    };

    get foo() {
        return this._foo;
    };

    set foo(b) {
        this._foo = b;
    };
}

Modules

The current state of modules is a bit complicated because of many players coming up with many solutions. See AMD, CommonJS, RequireJS, Browserify, or home-spun versions.

I won’t be covering those here, because it is so complicated.

However, after all of that, a module is often accessible as an object with the supplied functions as properties. (e.g. marked and hljs in the current site).

Many libraries can be installed with npm.

JavaScript pre-languages