Do you need to build a website but never worked with web technologies? Or did you have to admit to yourself that - despite several years of programming experience - you know pretty much nothing about all the web stuff? (This was my situation a few weeks ago.) Then you are who this blog post is aiming at! I’ll try to give you an overview in 10 minutes:
HTML
A basic HTML document looks like this:
The following is important:
The <...>
brackets are called tags and can contain text or
other tags. A tag can have multiple attributes (e.g. ‘name’ and ‘content’ of the 2nd meta tag), which specify
additional properties in a key-value format.
The <html>
tag is the root element of each HTML page.
The <head>
tag contains metadata. Here’s where you import
fonts, CSS style sheets, and so on. You also want to put
any JavaScript that messes with the page’s styling
(for instance for dynamic dark mode) in the head.
The <body>
tag contains <header>
, <main>
, and <footer>
,
which are the elements that are actually displayed in the browser window.
CSS
CSS is used to style the HTML elements. You can either
put it in its own file and import it, or put it right
into the HTML document by using a <style>
tag. Brief reminder:
In both cases, you want to place it in the head section. You apply
styling to specific tags by referencing them with one
of the following selectors:
Type selectors grab all tags of a certain type (in this case <p>
).
Class selectors affect all tags whose class attribute contains a certain class name. Note that tags can have multiple classes, separated by spaces.
ID selectors point to a tag with a certain unique ID.
Pseudo-class selectors are only active for certain states of tags, for instance when the mouse cursor is hovering over a link.
Descendant selectors refer to all tags that are descendants of some other selected tags. In this case, they don’t have to be direct children. Children of children (and further nesting) also works.
Child selectors grab only the direct child.
When you read the codebase of a modern webpage you might also find no CSS at all, and class attributes cluttered with a lot of weird class names instead (which correspond to CSS attributes). This means the website uses a CSS framework called TailwindCSS.
You might also want to have a quick look at the flex and grid layouts.
JavaScript
In addition to displaying HTML files styled with CSS, browsers act as interpreters
for JavaScript, a programming language that you can use to manipulate
the HTML elements dynamically. You can simply include the JavaScript code in an HTML
<script>
tag. Just keep in mind that the browser executes the JS right when
the script tag is encountered. So you likely want to place it at the bottom
of the HTML body, such that the referenced HTML elements already exist on the page!
You have access to other HTML elements via the Document Object Model (DOM) provided
by the browser’s JS runtime. The following is a brief example that grabs a button
from the DOM (document.getElementById(...)
) and registers a function
that adds a paragraph tag with some
text on every button click.
Note that all you have to do is add the new paragraph tag to the
DOM (document
object), and it will be rendered automatically since the browser
keeps the DOM and displayed content in sync.
Architecture and Networking Basics
The client-side application that runs in the browser is often called the frontend of a website. For simple websites that might be already all there is, in the case of more complex web applications the frontend communicates with one or multiple backend APIs, which are just other servers that provide stuff like authentication services, database access, and so on.
The simplest way to understand the networking itself is probably by just looking at a URL:
https://www.test.com/some/resource?key=value&anotherkey=anothervalue#section2
https://www.test.com
just means we use the encrypted version of HTTP
to communicate with the server behind the symbolic hostname test.com
(which is resolved to an IP address using
DNS).
Maybe I should note that this implicitly uses port 80.
/some/resource
is a path/route to a resource the web server provides.
A resource could be anything from a database table to
a simple file.
You can hit that route with 4 main methods:
- GET performs a read operation
- POST creates some data structure
- PUT updates some data structure
- DELETE - you guessed it - deletes some data structure
?key=value&anotherkey=anothervalue
passes search/query parameters in
a key-value format. The first pair is indicated by ’?’ and the following
ones are separated by ’&‘s.
Finally, #section2
is called a fragment and points to a specific
part of a webpage. For instance, if your resource is an HTML file,
the browser would automatically scroll to the HTML element with the
ID ‘section2’.
What about all the fancy frameworks?
Modern websites are usually not built with plain HTML + CSS + JS but use some sort of web framework. The frameworks mostly correspond to different rendering strategies. Here are the most common ones:
The first one - a static website - is not even a rendering strategy
because there is nothing to be rendered.
You have a bunch of HTML, CSS, and JS files, which you place on a web server.
Each route then simply corresponds to a file.
For instance, when you type https://www.test.com/some/route.html
in your browser, it requests the some/route.html
file and
simply displays it.
But writing plain HTML by hand all the time sounds very tedious, doesn’t it? Think about blogs and so on… That’s where Static Site Generators (SGG) come into play. They allow you to write content in a well-suited format such as Markdown and convert it to HTML using some template you provided. The most prominent ones are Hugo, Jekyll, and Gatsby. All of them have a ton of prebuilt template themes available, so you can get a simple website up and running in half an hour.
Even though SSG makes adding content to your website much easier, you still have to deploy on every change. Consequently, these static approaches cannot handle rapidly changing or individualized content. Think about authentication. If you need all that, you might want to render the pages dynamically on your web server at each request. That pattern is called Server Side Rendering (SSR) and is employed by frameworks such as Django, Ruby on Rails, or Laravel, as well as Content Management Systems (CMS) (which allow setup via GUI) like WordPress.
But the problems continue: If you navigate to the About page of this website and back to this blog post, you always get an annoying lag while the browser loads the new page. Not a problem for this blog, but not very professional either. To get those snappy websites with fancy animations, you would have to render the page content not on the server, but on the client using JavaScript. Single Page Applications (SPA) do exactly that. This is the part in which the examples probably start sounding familiar: There are React, Angular, Vue.js, and more modern ones like Svelte.
We’re still not done, though… You’re not simply gaining responsiveness when moving to an SPA, you’re making a trade-off: Firstly, in case the rendering of your website is compute-intensive, rendering it on the browser with JS might be slow. Secondly, your site’s search engine ranking will suffer because the crawlers prefer fully rendered HTML pages with content over a bunch of JavaScript that still has to build the page. So how can we get the best of both worlds? The idea is to initially render what we can on the server, and then switch to client-side rendering afterward to get that smooth user experience. The SPA frameworks usually have some corresponding meta-frameworks that handle this. React has Next.js, Vue.js has Nuxt, and Svelte has SvelteKit. There’s also Astro.js, which by default acts like a static site generator, but lets you opt in to dynamic server-side or client-side rendering for pages (and even single page components) that need it.
So what should you use? Brief reminder: I’m new to web dev myself and mostly have no idea what I’m doing. But I’ve played around with a few of the mentioned frameworks and would recommend the following: If you’re planning to do something static like an academic website, a blog, or a portfolio site, use Astro.js. It feels as simple as the pure SSGs (if you want, you can just pick some theme and start writing content in Markdown), but doesn’t limit you to static sites down the road. If you’re planning on building a full-blown web app with authentication and so on use SvelteKit. As a beginner, at least compared to Next.js (React), it felt way more intuitive and closer to plain HTML + CSS + JS, so I guess the skills would transfer a bit better.
Hosting a Website
If it’s a static website just use GitHub Pages. It’s free, directly integrated into GitHub, and lets you use your own domain if you want to. If you need server-side functionality I don’t really have any hot recommendations. But in case you’re a student it’s a good idea to check out the GitHub student developer pack. You usually can get enough credits from some hosting provider to serve a full web app for free.