Lesson 05
How to Make a Website With HTML and CSS (From a Blank File)
In this lesson
People search for an html website builder and often want the opposite of one: they want to make a website with HTML themselves and stop guessing what the tool is doing. That is what this lesson does. A blank file, a boilerplate explained line by line, four CSS ideas that carry most of the weight, and the page live at the end.
You need a text editor and a browser. That is the entire toolchain. No framework, no build step, nothing to install beyond the editor.
The whole boilerplate, line by line
Here is every line a valid HTML5 document needs, and what each one is for. Type them rather than copying them; the muscle memory is worth ten minutes.
- <!DOCTYPE html> — the first line, and not really a tag. It tells the browser to render in standards mode instead of a legacy quirks mode. Omit it and your CSS misbehaves in ways you will never manage to diagnose.
- <html lang="en"> — wraps everything. The lang attribute tells screen readers which language to pronounce and lets browsers offer translation. Set it to the language you are actually writing in. It costs nothing and it is an accessibility basic.
- <head> — everything inside is information about the page rather than content shown on it.
- <meta charset="utf-8"> — declares the character encoding, and belongs first inside head. This is the line that makes apostrophes and accented letters render as themselves instead of as scrambled symbols.
- <meta name="viewport" content="width=device-width, initial-scale=1" /> — the responsive one-liner. width=device-width matches the viewport to the device width in CSS pixels; initial-scale=1 sets zoom to 100%. Without it, mobile browsers pretend to be a desktop and your media queries do nothing at all.
- <title>Your page name</title> — the browser tab, the bookmark label, and the blue line in search results. Write it for someone with ten tabs open.
- <link rel="stylesheet" href="/style.css"> — connects your stylesheet. Close the head after it.
- <body> — the content. One h1, then h2s, paragraphs, links, images. Everything a visitor actually sees.
That is not a starting point that needs completing. It is a finished, valid document. If you uploaded it right now it would work, and it would already be more standards-compliant than a great many sites in production.
The four CSS ideas that matter first
CSS is enormous. These four carry most of a first site, and you can ignore the rest for a long time.
The box model
Every element is a box: content in the middle, padding inside the border, the border itself, margin outside it. By default width applies only to the content, so adding padding makes the box wider than the number you typed. Set box-sizing to border-box on everything, once, at the top of your stylesheet. Now width means width, and one entire category of confusion disappears.
A max-width container
Text that runs the full width of a monitor is genuinely hard to read — the eye loses its place returning to the start of the next line. Give your content a max-width of roughly 40rem, around 65 characters, with automatic left and right margins to centre it. That single pattern is most of the difference between a page that looks designed and one that looks like a default.
One font stack
You do not need a web font yet. A system font stack uses whatever the visitor's device already has: it loads instantly, costs no bandwidth, and looks native on every platform. Set it once on body and let everything inherit it. Add a real typeface later, when the page is otherwise finished and you can tell whether it improves anything.
One media query
A media query holds rules that only apply at certain screen sizes. Write your narrow-screen layout first as ordinary CSS, then add a single query for wider screens — something like a minimum width of 40rem — containing the changes for desktop. Working in that order means the fallback is always the simple stacked layout, which is exactly what you want when something goes wrong.
Blank file to live page, step by step
- Make a folder. Inside it create two files: index.html and style.css. Lowercase, no spaces, no capital letters anywhere.
- Type the eight boilerplate lines into index.html. Change the title and the lang attribute to yours.
- Write real content in the body — one h1, two or three paragraphs, a link. Real sentences, never placeholder text, because placeholder text hides how the design actually reads.
- Double-click index.html to open it in your browser. That is your website. It is ugly and it is live in the only sense that matters right now.
- Add the four CSS ideas to style.css. Reload after each change. Keep going until the page looks like something you would show a person.
- Switch to a tiny local server once you add images or a second page. Opening files directly uses the file:// protocol, where paths and several browser features behave differently from a real server. Any one-line static server removes that whole class of confusion.
- Put the folder in version control. It is your backup, your history, and on most static hosts it is also the deploy mechanism.
- Push it to a static host, point your domain at it, and let the host issue the certificate. HTTPS is automatic and free everywhere worth using.
Step eight has terms attached, and they are not obvious. Before you choose a free host, read the free-tier limits and prohibited uses covered in the previous lesson — several of the popular free plans forbid commercial sites outright.
The three things that actually trip people up
File paths and filenames
A path like img/photo.png is relative to the page you are currently on. A path like /img/photo.png starts at the site root. The first breaks when you move a page into a subfolder; the second breaks if the site is served from a subdirectory. Pick root-relative paths and be consistent.
Then watch the capitals. Photo.PNG and photo.png are the same file on macOS and Windows and two different files on the Linux server your host runs. That mismatch is one of the top causes of a site that worked perfectly on your computer and 404s the moment it goes online. Lowercase everything and the problem cannot occur.
The viewport meta tag
If your CSS "does not work on mobile", check for the viewport tag before you change a single rule. Nine times out of ten it is simply missing. While you are in there, one firm rule: never set user-scalable=no, and do not clamp maximum-scale. MDN states it plainly — disabling zooming "prevents people experiencing low vision conditions from being able to read and understand page content". WCAG requires a minimum of 2x scaling, and there is no design worth taking that away for.
CSS specificity
When two rules both apply to an element, the more specific selector wins: an ID beats a class, a class beats a plain tag. Only when specificity ties does the rule written later win. That is why your brand-new rule at the bottom of the file appears to do nothing.
The fix is almost never !important. It is writing a simpler selector, or removing the over-specific one that is winning. Keep selectors flat — mostly single classes — and specificity stops being something you have to think about.
What you genuinely do not need yet
No CSS framework. No preprocessor. No bundler. No component library. No JavaScript, on a page whose job is to be read. Each of those is a real tool that solves a real problem — and none of those problems exists on page one. Reaching for them early is the single most common reason people who set out to hand-code a site never publish one.
Where this sits in the course
Hand-coding is one of three routes, and it is the right one for a specific kind of person: someone who wants the site and the understanding at the same time. If you are not sure that is you, the complete guide to how to make a website compares this route honestly against the other two.
Questions from the class
Is an HTML website builder a real category?
Do I need special software or a paid editor?
Why does my page look right locally but break once it is online?
How many pages can I hand-code before it becomes painful?
Before you move on
- Your page has a doctype, a lang attribute, a charset, a viewport tag and a title.
- Zooming still works — no user-scalable=no, no clamped maximum-scale.
- Every filename is lowercase, with no spaces.
- box-sizing is set to border-box, and your content sits in a max-width container.
- You have looked at the page on an actual phone, not a narrow window.
- The folder is in version control before it goes anywhere near a host.
Next up — Lesson 06: How long it takes. Or jump to the complete path.