Web Dev Basics: HTML, CSS, & JavaScript Explained

by Admin 50 views
Web Dev Basics: HTML, CSS, & JavaScript Explained

In this module, we dive into the exciting world of web development, exploring how the internet works and how we can create interactive and visually appealing web applications. Let's break down the key concepts and technologies involved, including HTML, CSS, and JavaScript.

The Internet: A Network of Networks

At its core, the internet is a vast network of interconnected computers that communicate with each other. Think of it as the infrastructure that allows us to send and receive data, represented as zeros and ones. This foundation enables us to build various applications, from simple web pages to complex online services.

Routers: The Traffic Directors of the Internet

Routers are specialized computers equipped with CPUs and memory, designed to forward data across cables or wireless connections. They act as traffic directors, ensuring that data packets reach their intended destinations on the internet. These devices maintain tables that map IP addresses to physical cables, allowing them to efficiently route packets to the next hop in the network.

Protocols: The Language of the Internet

Protocols are sets of standard conventions, like a digital handshake, that computers use to communicate. These conventions dictate the format and order of messages exchanged between devices. For example, specific patterns of zeros and ones are used to instruct a router where to send data. TCP/IP are two essential protocols for transmitting data between computers. In essence, they function like a digital envelope, containing both the sender's and receiver's addresses, ensuring that information reaches the correct destination.

IP Addresses: Unique Identifiers for Computers

IP (Internet Protocol) addresses are unique identifiers assigned to computers connected to the internet. These addresses follow a standardized format, enabling computers to locate and communicate with each other. When a computer sends a packet, it includes the recipient's IP address, allowing routers to forward the packet until it reaches its final destination.

DNS: Translating Domain Names into IP Addresses

The Domain Name System (DNS) is a technology that translates human-readable domain names, such as cs50.harvard.edu, into IP addresses. DNS servers, typically provided by Internet Service Providers (ISPs), perform this translation, allowing users to access websites using memorable names instead of numerical IP addresses.

TCP: Ensuring Reliable Data Delivery

TCP (Transmission Control Protocol) is another crucial protocol that enables a single server, identified by its IP address, to offer multiple services through port numbers. Port numbers are small integers added to the IP address, allowing different applications like HTTP, HTTPS, email, and Zoom to communicate on the same server. TCP also provides a mechanism for retransmitting lost packets, ensuring reliable data delivery.

The internet employs multiple paths for data transmission, with packets potentially traversing different routes through interconnected routers. This redundancy enhances reliability and allows for efficient data delivery.

Large amounts of data, such as images, are divided into smaller packets to ensure fair and efficient routing across the internet. Net neutrality is the principle that all data packets should be treated equally by internet service providers, regardless of their content or source.

TCP also ensures that packets are labeled correctly (e.g., “1 of 2”, “2 of 2”) so that they can be reassembled in the correct order at the destination.

With these protocols and technologies, we can send data from one computer to another and build applications on top of the internet.

Web Development: Building Applications for the Web

The web is an application that runs on the Internet, allowing us to access web pages. Other applications, like Zoom, provide videoconferencing, and email is another application.

HTTP (Hypertext Transfer Protocol) governs how web browsers and web servers communicate using TCP/IP packets. The two primary commands supported by HTTP are GET and POST. GET allows a browser to request a page or file, while POST allows a browser to send data to the server.

A URL (Uniform Resource Locator), or web address, typically follows the format https://www.example.com/.

https indicates the secure version of HTTP, ensuring that data transmitted between the browser and server is encrypted.

example.com is the domain name, with .com being the top-level domain, conventionally indicating a commercial website. Today, there are hundreds of top-level domains, and their restrictions vary.

www is the hostname, conventionally indicating a "world wide web" service, though many modern websites omit it.

The / at the end requests the default file, such as index.html, which the web server will serve in response.

An HTTP request typically starts with:

GET / HTTP / 1.1
Host: www.example.com
...

GET indicates a request for a file, and / indicates the default file. A more specific request might start with GET /index.html.

HTTP / 1.1 indicates that the browser is using version 1.1 of the HTTP protocol.

Host: www.example.com specifies the target domain, as a web server might host multiple websites.

An HTTP response starts with:

HTTP / 1.1 200 OK
Content-Type: text/html
...

The web server responds with the HTTP version and a status code, such as 200 OK, indicating a successful request.

Content-Type: text/html indicates the type of content in the response, such as text, image, or other format.

The remainder of the packet(s) contains the content.

Browsers include developer tools that allow us to view HTTP requests and responses. In Chrome, you can access these tools via View > Developer > Developer Tools. The Network tab displays all requests for text, images, and other data downloaded for individual web pages.

The initial request might return a 301 Moved Permanently status code, redirecting the browser from http://... to https://...

The request and response also include headers or additional data:

Note that the response includes a Location: header indicating the redirect target.

Other HTTP status codes include:

  • 200 OK
  • 301 Moved Permanently
  • 304 Not Modified (indicating the browser can use its cached copy of a resource)
  • 307 Temporary Redirect
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 418 I’m a Teapot (a humorous code)
  • 500 Internal Server Error (indicating an error on the server)
  • 503 Service Unavailable

You can use the command-line tool curl to connect to a URL:

curl -I http://safetyschool.org

This command retrieves the headers from the specified URL.

HTTP requests can also include input for servers, such as q=cats in the URL:

GET / search?q=cats HTTP / 1.1
Host: www.google.com
...

This format is used to pass input to web servers, similar to command-line arguments.

HTML: Structuring Web Pages

HTML (Hypertext Markup Language) is used to format web pages and instruct the browser how to display them. It uses tags and attributes to define the structure and content of the page.

A simple HTML page looks like this:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>
            hello, title
        </title>
    </head>
    <body>
        hello, body
    </body>
</html>

The first line declares that the page follows the HTML standard.

Tags are words enclosed in angle brackets, such as <html> and </html>. The first is the opening tag, and the second is the closing tag. In this case, the tags indicate the beginning and end of the HTML page. The opening tag can also have attributes, such as lang="en", which specifies the page's language as English.

Within the <html> tag, there are two more tags, <head> and <body>, which are like child nodes in a tree. Inside <head> is the <title> tag, whose content appears in a tab or window title in a browser. In <body> is the content of the page itself, which we see in the main view of a browser.

The page above will load in the browser as a data structure, like this tree:

Notice there is a hierarchy mapping each tag and its children. Rectangular nodes are tags, while oval nodes are text.

You can save the code above as an HTML file on your local computer, which would work in a browser, but only for you. With the CS50 IDE, you can create an HTML file and actually make it available on the Internet.

Create hello.html with the code above and start a web server installed in the CS50 IDE with http-server, a program that will listen for HTTP requests and respond with pages or other content.

The CS50 IDE itself is already running on some web server, using ports 80 and 443, so your own web server inside the IDE will have to use a different port, 8080 by default. You will see a long URL, ending in cs50.ws, and if you open that URL, you will see a list of files, including hello.html.

Back in the terminal of your IDE, you will see new lines of text printed by your web server, a log of requests that it is receiving.

Take a look at paragraphs.html.

With the <p> tag, you can indicate that each section of text should be a paragraph.

After saving this file, you will need to refresh the index in the web browser and then open paragraphs.html.

You can add headings with tags that start with h and have levels from 1 to 6 in headings.html.

Also examine list.html, table.html, and image.html to add lists, tables, and images.

You can use the <ul> tag to create an unordered list, like a bulleted list, and <ol> for an ordered list with numbers.

Tables start with a <table> tag and have <tr> tags as rows and <td> tags for individual cells.

For image.html, you can upload an image to the CS50 IDE to include it in your page, as well as use the alt attribute to add alternative text for accessibility.

Looking up documentation or other resources online, you can learn the tags that exist in HTML and how to use them.

You can create links in link.html with the <a> or anchor tag. The href attribute is for a hypertext reference, or simply where the link should take you, and within the tag is the text that should appear as the link.

You could set the href as https://www.yale.edu but leave Harvard within the tag, which could mislead users or even trick them into visiting a fake version of some site. Phishing is an act of tricking users, a form of social engineering that includes misleading links.

In search.html, you can create a more complex form that takes user input and sends it to Google's search engine:

<!DOCTYPE html>

<html lang="en">
    <head>
        <title>search</title>
    </head>
    <body>
        <form action="https://www.google.com/search" method="get">
            <input name="q" type="search">
            <input type="submit" value="Search">
        </form>
    </body>
</html>

First, you have a <form> tag that has an action of Google's search URL, with a method of GET.

Within the form, you have an <input>, with the name q, and another <input> with the type of submit. When the second input, a button, is clicked, the form will append the text in the first input to the action URL, ending with search?q=....

Therefore, when you open search.html in your browser, you can use the form to search via Google.

A form can also use a POST method, which doesn't include the form's data in the URL, but somewhere else in the request.

CSS: Styling Web Pages

CSS (Cascading Style Sheets) is used to style the appearance of HTML elements on a web page. It uses properties or key-value pairs, such as color: red;, to define the visual characteristics of elements.

In HTML, there are a few options for including CSS. You can add a <style> tag within the <head> tag, with styles directly inside, or you can link to a styles.css file with a <link> tag within the <head> tag.

You can also include CSS directly in each tag:

<!DOCTYPE html>

<html lang="en">
    <head>
        <title>css</title>
    </head>
    <body>
        <header style="font-size: large; text-align: center;">
            John Harvard
        </header>
        <main style="font-size: medium; text-align: center;">
            Welcome to my homepagel!
        </main>
        <footer style="font-size: small; text-align: center;">
            Copyright &#169; John Harvard
        </footer>
    </body>
</html>

The <header>, <main>, and <footer> tags are like the <p> tags, indicating the sections where the text of your page is.

For each tag, you can add a style attribute, with the value being a list of CSS key-value properties, separated by semicolons. Here, you are setting the font-size for each tag and aligning the text in the center.

Note that you can use &#169;, an HTML entity, as a code to include some symbol on your web page.

You can align the text all at once:

<!DOCTYPE html>

<html lang="en">
    <head>
        <title>css</title>
    </head>
    <body style="text-align: center;">
        <header style="font-size: large;">
            John Harvard
        </header>
        <main style="font-size: medium;">
            Welcome to my home page!
        </main>
        <footer style="font-size: small;">
            Copyright &#169; John Harvard
        </footer>
    </body>
</html>

Here, the style applied to the <body> tag cascades, or applies to its children, so all the internal sections will also have centered text.

To factor out or separate your CSS from the HTML, you can include styles in the <head> tag:

<!DOCTYPE html>

<html lang="en">
    <head>
        <style>

            header
            {
                font-size: large;
                text-align: center;
            }

            main
            {
                font-size: medium;
                text-align: center;
            }

            footer
            {
                font-size: small;
                text-align: center;
            }

        </style>
        <title>css</title>
    </head>
    <body>
        <header>
            John Harvard
        </header>
        <main>
            Welcome to my home page!
        </main>
        <footer>
            Copyright &#169; John Harvard
        </footer>
    </body>
</html>

For each type of tag, you use a type selector to define the style.

You can also use a more specific class selector:

<!DOCTYPE html>

<html lang="en">
    <head>
        <style>

            .centered
            {
                text-align: center;
            }

            .large
            {
                font-size: large;
            }

            .medium
            {
                font-size: medium;
            }

            .small
            {
                font-size: small;
            }

        </style>
        <title>css</title>
    </head>
    <body>
        <header class="centered large">
            John Harvard
        </header>
        <main class="centered medium">
            Welcome to my home page!
        </main>
        <footer class="centered small">
            Copyright &#169; John Harvard
        </footer>
    </body>
</html>

You can define your own CSS class with a . followed by a keyword you choose, so here you create .large, .medium, and .small, each with some property for font size.

Then, in any number of tags in the HTML of your page, you can add one or more of these classes with class="centered large", reusing those styles.

You can remove the redundancy of centered and apply it only to the <body> tag as well.

Finally, you can take all the CSS properties and move them into another file with the <link> tag:

<!DOCTYPE html>

<html lang="en">
    <head>
        <link href="styles.css" rel="stylesheet">
        <title>css</title>
    </head>
    <body>
        <header class="centered large">
            John Harvard
        </header>
        <main class="centered medium">
            Welcome to my home page!
        </main>
        <footer class="centered small">
            Copyright &#169; John Harvard
        </footer>
    </body>
</html>

Now, one person can work on the HTML, and another can work on the CSS, more independently.

With CSS, you will also rely on references and other resources to figure out how to use the properties as needed.

You can use pseudoselectors, which select certain states:

<!DOCTYPE html>

<html lang="en">
    <head>
        <style>

            #harvard
            {
                color: #ff0000;
            }

            #yale
            {
                color: #0000ff;
            }

            a
            {
                text-decoration: none;
            }

            a:hover
            {
                text-decoration: underline;
            }

        </style>
        <title>link</title>
    </head>
    <body>
        Visit <a href="https://www.harvard.edu/" id="harvard">Harvard</a> or <a href="https://www.yale.edu/" id="yale">Yale</a>.
    </body>
</html>

Here, you are using a:hover to define properties on <a> tags when the user hovers over them.

You also have an id attribute on each <a> tag, to set different colors on each with ID selectors that start with a # in the CSS.

JavaScript: Adding Interactivity to Web Pages

To write code that can be executed in users' browsers, you will use JavaScript. The syntax of JavaScript is similar to that of C and Python for basic constructs:

let counter = 0;

counter = counter + 1;
counter += 1;
counter++;

if(x < y)
{

}

if(x < y)
{

}
else
{

}

if(x < y)
{

}
else if(x > y)
{

}
else
{

}

while(true)
{

}

for(let i = 0; i < 3; i++)
{

}

Note that JavaScript is also loosely typed, with let being the keyword to declare variables of any type.

With JavaScript, you can change the HTML in the browser in real time. You can use <script> tags to include your code directly or from a .js file.

Let's create another form:

<!DOCTYPE html>

<html lang="en">
    <head>
        <script>

            function greet()
            {
                alert('hello, body');
            }

        </script>
        <title>hello</title>
    </head>
    <body>
        <form onsubmit="greet(); return false;">
            <input id="name" type="text">
            <input type="submit">
        </form>
    </body>
</html>

Here, you don't add an action to your form since it will stay on the same page. Instead, you have an onsubmit attribute that will call a function you define in JavaScript and use return false; to prevent the form from actually being submitted anywhere.

Now, if you load this page, you will see hello, body being shown when you submit the form.

Since your input tag, or element, has an ID of name, you can use it in your script:

<script>

    function greet()
    {
        let name = document.querySelector('#name').value;
        alert('hello, ' + name);
    }

</script>

document is a global variable that comes with JavaScript in the browser, and querySelector is another function you can use to select a node in the DOM (Document Object Model), or the tree structure of the HTML page. After selecting the element with the ID of name, you get the value inside the input and add it to your alert.

Note that JavaScript uses single quotes for strings by convention, though double quotes can also be used as long as they match for each string.

You can add more attributes to your form to change the placeholder text, change the button text, disable autocomplete, or focus the input automatically:

<form>
    <input autocomplete="off" autofocus id="name" placeholder="Name" type="text">
    <input type="submit">
</form>

You can also listen for events in JavaScript that occur when something happens on the page. For example, you can listen to the submit event on your form and call the greet function:

<script>

    function greet()
    {
        let name = document.querySelector('#name').value;
        alert('hello, ' + name);
    }

    function listen() {
        document.querySelector('form').addEventListener('submit', greet);
    }

    document.addEventListener('DOMContentLoaded', listen);

</script>

Here, in listen, you pass the function greet by name and do not call it yet. The event listener will call it for you when the event happens.

You first need to listen for the DOMContentLoaded event since the browser reads your HTML file from top to bottom, and the form would not exist until it reads the entire file and loads the content. Therefore, by listening for that event and calling your listen function, you know the form will exist.

You can also use anonymous functions in JavaScript:

<script>

    document.addEventListener('DOMContentLoaded', function() {
        document.querySelector('form').addEventListener('submit', function() {
            let name = document.querySelector('#name').value;
            alert('hello, ' + name);
        });
    });

</script>

You can pass a lambda function with the syntax function(), so here you pass both listeners directly to addEventListener.

Besides submit, there are many other events you can listen to:

  • blur
  • change
  • click
  • drag
  • focus
  • keyup
  • load
  • mousedown
  • mouseover
  • mouseup
  • submit
  • touchmove
  • unload

For example, you can listen to the keyup event and change the DOM as soon as you release a key:

<!DOCTYPE html>

<html lang="en">
    <head>
        <script>

            document.addEventListener('DOMContentLoaded', function() {
                let input = document.querySelector('input');
                input.addEventListener('keyup', function(event) {
                    let name = document.querySelector('#name');
                    if (input.value) {
                        name.innerHTML = `hello, ${input.value}`;
                    }
                    else {
                        name.innerHTML = 'hello, whoever you are';
                    }
                });
            });

        </script>
        <title>hello</title>
    </head>
    <body>
        <form>
            <input autocomplete="off" autofocus placeholder="Name" type="text">
        </form>
        <p id="name"></p>
    </body>
</html>

Note that you can also substitute strings in JavaScript, with ${input.value} inside a string surrounded by backticks, `.

You can also change the style programmatically:

<!DOCTYPE html>

<html lang="en">
    <head>
        <title>background</title>
    </head>
    <body>
        <button id="red">R</button>
        <button id="green">G</button>
        <button id="blue">B</button>
        <script>

            let body = document.querySelector('body');
            document.querySelector('#red').onclick = function() {
                body.style.backgroundColor = 'red';
            };
            document.querySelector('#green').onclick = function() {
                body.style.backgroundColor = 'green';
            };
            document.querySelector('#blue').onclick = function() {
                body.style.backgroundColor = 'blue';
            };

        </script>
    </body>
</html>

After selecting an element, you can use the style property to set the values of CSS properties as well. Here, you have three buttons, each of which with an onclick listener that changes the background color of the <body> element.

Note here that your <script> tag is at the end of your HTML file, so you don't have to listen for the DOMContentLoaded event since the rest of the DOM will have already been read by the browser.

Also, in the developer tools of a browser, you can see the DOM and all the styles applied via the Elements tab:

You can even use this to change a page in your browser after it has loaded by clicking on some element and editing the HTML. But those changes will only be made in your browser, not in your original HTML file or some web page somewhere else.

In size.html, you can set the font size with a dropdown menu via JavaScript, and in blink.html you can make an element “blink” by toggling between visible and hidden.

With geolocation.html, you can ask the browser for a user's GPS coordinates, and with autocomplete.html, you can autocomplete something you type with words from a dictionary file.

Finally, you can use Python to write code that connects to other devices on a local network, such as a light bulb, via an API (Application Programming Interface). Your light bulb's API, in particular, accepts requests on certain URLs:

import os
import requests

USERNAME = os.getenv("USERNAME")
IP = os.getenv("IP")

URL = f"http://{IP}/api/{USERNAME}/lights/1/state"

requests.put(URL, json={"on": False})

With this code, you can use the PUT method to send a message to your light bulb, turning it off.

You use environment variables, values stored somewhere else on your computer, for your username and IP address.

Now, with a bit more logic, you can make your light bulb blink:

import os
import requests
import time

USERNAME = os.getenv("USERNAME")
IP = os.getenv("IP")
URL = f"http://{IP}/api/{USERNAME}/lights/1/state"

while True:
    requests.put(URL, json={"bri": 254, "on": True})
    time.sleep(1)
    requests.put(URL, json={"on": False})
    time.sleep(1)

Next time, you will put together HTML, CSS, JavaScript, Python, and SQL!