By Leo Rudberg ([email protected]). Written for the Spring 2018 CUNY Hackathon.
Link to this: https://bit.ly/2vTeHy1
.
Follow me on GitHub!
(I will likely schmooze about myself here...)
Unlike my other guides, the setup for this is fairly simple. The only things you need are:
- A web browser (I like Chrome, but Firefox, Edge, Safari, etc. are ok, too)
- A text editor (I like VSCode, but vim, emacs, gedit, Notepad++, etc. are ok, too)
- Optional: git (for mistakes, etc.)
One of my favorite resources for web development is the Mozilla Developer Network, so you may want to open an MDN tab for quick reference.
Once you have everything installed and/or ready to go, create a new directory in your home directory. I've written the commands using bash, which is a terminal available on Mac and Linux (and Windows if you know how to get it), but this should be pretty straightforward without it.
$ cd ~ # go to the home directory
$ mkdir web-hacking # make a `web-hacking` directory in side of your home directory
$ cd web-hacking # go to the web-hacking directory
$ touch index.html # create an empty file called `index.html`
If all goes well, you should be able to navigate to your blank, boring webpage!!!
In Chrome, open a new tab and set the URL to be:
file://<absolute-path-to-web-hacking-directory>/index.html
In order to get the path, you can run the pwd
command in bash, and just copy and paste that after the file://
.
You might think of the Internet/World Wide Web (web) as a maze of tubes and pipes, all filled with memes and such:
But in my opinion, it actually looks like this (albeit slightly more crowded):
I view the web as a bunch of computers all in the same "area" that speak the same "language" (protocol).
Some of these computers are clients (or customers), who wish to access data (e.g. Google, Wikipedia, cat videos). They can access this data by finding the servers who will give it to them. They do this through Domain Name System lookups.
With enough imagination, you can think of the generic fish customers in the foreground as clients who have requested data. Here, Squidward acts as a server that delegates to Spongebob, who actually provides the data the customers want. This is a common practice at Google: frontend servers respond to external humans' (or bots') requests by delegating to backend server, which may control things like databases.
When you look up a website, for example, https://example.com
here's what happens:
- Your browser realizes that you want to make a request to fetch (or GET data.
- Since you didn't provide any other path (like
https://example.com/foo/bar
), your request for data will fetchindex.html
(or whatever the default route handling behavior ofexample.com
is). - Your browser knows that it needs to set up secure communication because it sees the
https://
protocol prefix (https is like http, the vanilla web protocol, but it is safer). - Your browser looks up the actual IP address for example.com (which is just a bunch of unintelligible letters and numbers). The DNS helps accomplish this.
- Once your browser connects with the IP over HTTPS, it fetches the data you wanted. This includes text, images, videos, HTML, CSS, JavaScript, and whatever else the server deems sendable.
- All of the rendering (layouts, styling, JS interpreting and running) happens in your browser once it fetches all of the necessary assets from the server.
(Leo will attempt to answer any/all questions...)
Let's get out web feet wet with writing a simple website using HTML, CSS, and JavaScript -- the standard web technologies.
Let's add some content to our website! Everything on the web is written using a language called Hyper Text Markup Language, also known as HTML. You can read more on HTML on MDN.
The basic structure of HTML is tags:
<some-tag key='value' other-key='other-value'>
<other-tag>...</other-tag>
Some text content!
</some-tag> <!-- This is a comment. -->
Always remember to close your tags!
Let's add some basic setup code to index.html
. A lot of this is just boilerplate necessary to be a good citizen on the
interwebs. Feel free to copy and paste this content:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
</body>
</html>
Now save your changes and refresh the tab with the initial (blank) index.html
.
It should still be blank! But, notice that the page now has a title of Title
. The <title>
tag in the <head>
controls the value of the page title.
You may also have noticed that the <body>
tag has no content.
Change the <title>
to say something else, and put Hello world!
in the <body>
so that it now looks like:
<body>Hello world!</body>
.
Save, refresh, and observe your changes!
<body>
<h1>Hello world, I am a website!</h1>
<h3>Isn't this cool?</h3>
<p>
This is a paragraph. Isn't
<strong>it</strong>
<em>cool</em>?
</p>
<ul>
<li>I am part of a list!</li>
<li>So am I!</li>
</ul>
<div>I am some separated content...</div>
<div>Here is some other content. Right here:
<div>With some child content
<p>OF ITSELF!</p>
</div>
</div>
</body>
</html>
Adding images to our site is pretty easy. First, download (or copy) an image into the folder that index.html
is in. I chose a doge photo named doge.jpg
.
Then add the following:
<div>
<h2>Here's an image:</h2>
<img src='doge.jpg' alt='A cute dog.' />
</div>
<img>
is the tag for images. Since it doesn't have any inner content besides the photo, you don't need a closing tag. We tell the <img>
tag which photo to use via the src
attribute. As a good backup, I also added the alt
attribute, which is useful to describe your photo in case it isn't present. It is also good for accessibility.
Simlar to images, links are also very easy to add:
<div>
<h2>Here's a link:</h2>
<a href='https://google.com/'>I need to look something up...</a>
</div>
The <a>
(anchor) tag allows you to link to other pages (and other content on the same page). By putting in the URL in the href
attribute, users will get directed to the link when they click on it. The text inside the <a>...</a>
is the link text the user sees.
Now, our site has a bunch of really cool content. However, it does not look too great. Let's write some CSS, which is the standard styling language for web development.
CSS goes in it's own block in <head>
and its syntax is totally different than HTML:
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* COOL STYLES GO HERE */
</style>
</head>
A standard CSS rule looks like this:
selector {
property1: value1;
/* (I'm a comment) */
propertyN: valueN;
}
For our purposes, selector
will be just an element (like h2
or a
) or a class, which allows us to give special names to elements like .red-link
or .main-form
.
For thematic styling, you'll want to use CSS properties like color
, background-color
, font-family
, and font-size
. If you are curious about what you have at your disposal, check out MDN or use the Chrome debugger/inspector.
Let's make all of our links pink, with sky blue backgrounds, in a sans-serif font:
<style>
a {
color: pink;
background-color: skyblue;
font-family: sans-serif;
}
</style>
Try modifying the default styling of one of the other types of elements we have on the page!
CSS can also be used for layout. Let's make a halved row using Flexbox. Flexbox makes it really easy to lay out UIs in an intuitive, mobile-friendly way.
First we'll add the HTML:
<div class='container'>
<div class='col-half'>Column A</div>
<div class='col-half'>Column B</div>
</div>
We have a div.container
that will hold the two child columns, each taking up half the parent. Reload the page to see how with just the HTML, we don't have what we want yet.
Now, add these styles:
.container {
display: flex;
width: 100%;
}
.col-half {
width: 50%;
/* So we can see the area controlled by each column. */
border: 1px dotted orange;
}
Reload, and voila! To truly be amazed by Flexbox, try resizing your browser window. You may also be interested in Grid layouts.
If you want to build a site or app, you'll probably want to use a <form>
. HTML forms are a standard element that allow you to capture user input and do things with it, like examine it using JavaScript or send it to a server.
Let's add a simple "Hello user" form with a submit button:
<div>
<h2>My Form</h2>
<form>
<input type='text' name='username' placeholder='Your Name' />
<input type='submit' value='Send name' />
</form>
<!-- TODO: Add a box that says hello to the user! -->
</div>
The form has two <input>
children: one is the actual input where the user will enter their name. The other is a button that will signal that the user wants to submit their name (to whatever system will handle it). Add this code and see that it doesn't really do much yet.
JavaScript (JS) is the standard language that is used for making frontend sites interactive. We'll modify our form HTML and write a little bit of JS code to make our greeter box actually work:
<div>
<h2>My Form</h2>
<form>
<input class='name-input' type='text' name='username' placeholder='Your Name' />
<input type='submit' value='Send name' />
</form>
<div class='greeter-box'>Nothing yet...</div>
</div>
<script>
// This is a useful notice to the JS environment that we don't want to
//do stupid/bad things.
'use strict';
// Assign all of the variables we need.
// Note that `querySelector` uses similar selector strings as CSS does.
const greeterBox = document.querySelector('div.greeter-box');
const form = document.querySelector('form');
const input = document.querySelector('.name-input');
// Assign the listener that responds to submit button clicks.
form.onsubmit = (event) => {
// This stops the page from reloading on submit.
event.preventDefault();
// Get the text from the input.
const text = input.value;
// If there was text in the input...
if (text) {
// Set the content in the greeter box.
greeterBox.textContent = `Hello ${text.trim()}!`;
}
};
</script>
Your HTML file should look like:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
a {
color: pink;
background-color: skyblue;
font-family: sans-serif;
}
.container {
display: flex;
width: 100%;
}
.col-half {
width: 50%;
/* So we can see the area controlled by each column. */
border: 1px dotted orange;
}
.greeter-box {
background-color: black;
color: lime;
font-family: monospace;
}
</style>
</head>
<body>
<h1>Hello world, I am a website!</h1>
<h3>Isn't this cool?</h3>
<p>
This is a paragraph. Isn't
<strong>it</strong>
<em>cool</em>?
</p>
<ul>
<li>I am part of a list!</li>
<li>So am I!</li>
</ul>
<div>I am some separated content...</div>
<div>Here is some other content. Right here:
<div>With some child content
<p>OF ITSELF!</p>
</div>
</div>
<div>
<h2>Here's an image:</h2>
<img src='doge.jpg' alt="A cute dog." />
</div>
<div>
<h2>Here's a link:</h2>
<a href='https://google.com/'>I need to look something up...</a>
</div>
<div class='container'>
<div class='col-half'>Column A</div>
<div class='col-half'>Column B</div>
</div>
<div>
<h2>My Form</h2>
<form>
<input class='name-input' type='text' name='username' placeholder='Your Name' />
<input type='submit' value='Send name' />
</form>
<div class='greeter-box'>Nothing yet...</div>
</div>
<script>
// This is a useful notice to the JS environment that we don't want to
//do stupid/bad things.
'use strict';
// Assign all of the variables we need.
// Note that `querySelector` uses similar selector strings as CSS does.
const greeterBox = document.querySelector('div.greeter-box');
const form = document.querySelector('form');
const input = document.querySelector('.name-input');
// Assign the listener that responds to submit button clicks.
form.onsubmit = (event) => {
// This stops the page from reloading on submit.
event.preventDefault();
// Get the text from the input.
const text = input.value;
// If there was text in the input...
if (text) {
// Set the content in the greeter box.
greeterBox.textContent = `Hello ${text.trim()}!`;
}
};
</script>
</body>
</html>