Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Web development

Overview

This chapter on web development primarily covers HTML and CSS, which are the two structural languages for web development. Together they form the underlying structure and style of websites. It also covers React which is the biggest web framework.

HTML

HyperText Markup Language or HTML is an XML based language for declaring the structure of a website. It looks like this.

<body>
  <h1>Hello World!</h1>
  <p class="my-subtitle">This is an introduction example for programming in HTML</p>
</body>

HTML consists of elements which are surrounded by tags, have attributes and contain content. An element is a “thing” on the page like an article, button, header, text input, etc. in HTML we define an element by using an opening tag and a closing tag. In the above example, the <body> tag tells the computer that everything until </body> is part of the “body” element of the page (which is the displayed content). We also have a <h1> tag which represents a header element and a <p> tag which represents a paragraph element.

An attribute tells the computer something about the element. In our above example, for the paragraph element (<p class="my-subtitle">) we set the class attribute to “my-subtitle” which tells the computer that this paragraph should be styled using the my-subtitle styles (which we would define in CSS). There are many different attributes but id and class are some of the most common.

Lastly the content of an element is whatever is inside the element. In our example, the header element has “Hello World!” as its content. The body element has a header and a paragraph as it’s content (or called its children).

Let’s move on to a more complete example, one that you could open in your web browser. I’ve added comments explaining some of the structure.

<!DOCTYPE html> <!-- Required for Standard HTML -->
<html lang="en">

  <head>
    <!-- The <head> element contains the metadata for the page
         things like the charset (encoding), page title (displayed
         in the URL bar), styles, and maybe some scripts.

         Nothing in the head is visible -->

    <meta charset="utf-8">
    <title>An introduction page</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>

  </head>

  <body>
    <!-- The body element is the main displayed element.
         This is where the main content of the website goes. -->

    <h1>Hello World!</h1>
    <p class="my-subtitle">This is a more complete example for programming in HTML</p>
    <button id="click-me">Click me</button>

  </body>

</html>

Overall, HTML is a fairly simple language that lets you declare the structure of the page. It is also deeply integrated with CSS and JS which allows complex apps to be built with it.

CSS

Cascading Style Sheets or CSS is a styling language for HTML. It specifies how the page should look.

/* Anything in this block is applied to h1 elements */
h1 {
  font-size: 20pt;
  font-weight: bold;
}

/* This will apply to any p element. */
p {
  margin-top: 5px;
  margin-bottom: 5px;
}

/* .my-subtitle will apply to any element with class="my-subtitle". */
.my-subtitle {
  margin-top: 2px;
  font-size: 16pt;
  color: gray;
}

In this example, we style our header and our paragraph. Also note that multiple style blocks can apply to a single element. If two blocks contain the same style (like ‘margin-top’) the most “specific” style wins. In general, this means that a style in a class block beats a style in an element block. So for our <p class="my-subtitle">, the .my-subtitle styles will take preference over the p styles. In this case the only conflicting style is margin-top and so margin-top: 2px wins.

JS and the DOM

JavaScript can interact with the HTML using the Document Object Model or the DOM. This is just a (large) set of functions that are used to interact with HTML elements from JavaScript. We can show a simple example with our button.

// This gets a reference to the HTML element
let myBtn = document.getElementById("click-me");

// This tells the browser to run a function when the button is clicked
myBtn.addEventListener("click", () => {
  alert("You clicked me!");
});

Now when you click the button, you will get an alert saying “You clicked me!” This is one of the most basic examples, but there are many functions for listening to events, getting input, adding/removing elements, etc.

React

React is the most popular frontend framework. A framework is a tool or library that makes writing HTML and JavaScript easier or more organized. One of the main issues with HTML is that you can only have one HTML file for one page on a website. This does not scale well to large apps, so you either need to create your elements with JS (annoying and bug prone) or write a very large HTML file (also annoying).

React attempts to solve this problem by allowing you to write HTML code within JS. It also introduces the idea of components which are custom reusable elements that you can use similarly to existing HTML elements.

Here’s a basic example.

// This is a reusable component
function MyButton() {
  // React has a nice way to handle "state" using this function
  // It allows you to update state in JS and have it auto update the HTML
  let [count, setCount] = useState(0);

  return (
    {/* we can use JS variables in our HTML */}
    <button onclick={() => setCount(count + 1)}> Counter: {count} </button>
  )
}

// Here we define a component for the main content
function App() {
  return (
    <>
      <h1>Hello World!</h1>
      <p class="my-subtitle">This is a more complete example for programming in HTML</p>
      {/* Here is our custom component */}
      <MyButton />
    </>
  )
}

This creates a website with a counter that updates every time the button is clicked. This shows most of the main features of React.

One thing to note is that these component functions (MyButton() and App()) can be run by React multiple times which mean they should not have “side effects” which means they shouldn’t update global state or make web requests or anything like that.

// This is a reusable component
function MyButton() {
  let [count, setCount] = useState(0);

  // This is could be run any number of times!
  console.log("MyButton() was called");

  return (
    <button onclick={() => setCount(count + 1)}> Counter: {count} </button>
  )
}

In the above example could output “MyButton() was called” any number of times. In practice, it will likely only update every time the state changes because React needs to update the button text, but that is not guaranteed. If you need to run something once or only when a variable changes you can use useEffect like below.

function MyButton() {
  let [count, setCount] = useState(0);

  useEffect(() => {
    console.log("This will only run once when the component is created");
  }, []); // <-- note the empty array

  useEffect(() => {
    console.log("Count changed. New count: " + count);
  }, [count]); // <-- note the "count" in the array

  return (
    <button onclick={() => setCount(count + 1)}> Counter: {count} </button>
  )
}

Many modern large scale web apps are built with these basic building blocks. Since they are reusable, they can greatly reduce the complexity of codebases.