Building your first smolweb page
2026-03-01 12:05
A simple news article that takes ten seconds to load and eats 50 MB of data. You've seen that. We all have. Mountains of JavaScript, giant CSS frameworks, third-party trackers, custom fonts pulled from remote servers... all of that to display a few paragraphs of text.
The smolweb pushes back against that. The goal is to write small, clean, accessible HTML that works on any device, any browser, any screen, even without CSS or JavaScript. A smolwebsite should load on a smartphone from 2010, work in a text browser like Lynx, and be readable on a Braille display. Not because those are common cases, but because if your page works there, it works everywhere.
This is a hands-on guide for building your first smolweb page. No framework, no build tool, no npm. A text editor and a browser are all you need.
The philosophy in a few lines
A smolwebsite has a few core rules. No element unless it adds real value. Structure comes from HTML, not from styles: the page must be readable without any CSS. JavaScript is allowed, but the page must remain usable without it. No external dependencies: no CDN, no Google Fonts, no remote scripts. Use the right HTML tag for the right content. Think less about visual style and more about discipline.
Step 1: the bare minimum
Create a file called index.html and open it in your text editor:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My smolwebsite</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
That's already a valid, working webpage. Here's what each line does.
<!DOCTYPE html> tells the browser this is HTML5. It must always be the very first line.
<html lang="en"> is the root element. The lang attribute matters: screen readers use it to pronounce content correctly, and search engines use it to understand what language your page is in. Use the ISO 639-1 code for your language (fr, de, es, etc.).
charset=utf-8 prevents browsers from misinterpreting accented characters. UTF-8 covers every language and special character you will ever need. Always declare it.
viewport is one line that makes your page usable on mobile. Without it, a smartphone will try to render your page as a shrunken desktop screen, which makes the text unreadably small.
Open the file in your browser. It already works.
Step 2: filling the <head>
The <head> section contains information about your page, things the browser and search engines need but the reader does not see directly. Here is a complete one:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<meta name="description" content="A page about my hobbies and projects.">
<link href="/style.css" rel="stylesheet" type="text/css">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.png" type="image/png">
<title>My smolwebsite</title>
</head>
Content-Security-Policy: default-src 'self' tells the browser to only load resources from your own server. No external fonts, no remote scripts, no third-party images. It is both a security header and a smolweb commitment in one. As a side effect, if you write <p style="color:red"> directly in your HTML, this header will block it. That is intentional. CSS belongs in a stylesheet.
color-scheme: light dark respects whatever dark or light mode the user has set in their system. The browser will automatically adjust default colors for backgrounds, text, and form controls. Zero extra CSS needed.
About the favicon: browsers look for /favicon.ico on every page request, even when you have not provided one. That is a failed HTTP request on every page load. Provide a favicon once, it gets cached, and the problem disappears.
Step 3: semantic tags
HTML has a tag for every major part of a webpage. Using them correctly costs nothing and gains a lot: better accessibility, cleaner code, and a page that still makes sense when CSS is stripped away.
<body>
<header>
<strong>My smolwebsite</strong>
<nav>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>My first post</h1>
<p>This is the content of my first post.</p>
</article>
<aside>
<p>Related: <a href="another-post.html">Another post</a></p>
</aside>
</main>
<footer>
<p>Published by me under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA</a>.</p>
</footer>
</body>
Here is a quick reference:
| Tag | Used for |
|---|---|
<header> |
Site name, logo, navigation at the top |
<nav> |
Links to other pages of your site |
<main> |
The main content, used once per page |
<article> |
A self-contained piece of content: a post, a story |
<aside> |
Secondary content related to the main article |
<footer> |
Credits, license, bottom links |
Avoid scattering <div> everywhere. A <div> carries no meaning, it is just a box. If an appropriate semantic tag exists, use it.
Step 4: a small stylesheet
Your page must remain readable without CSS, but a small stylesheet can still improve it. Here is one that stays within smolweb principles:
/* style.css */
html {
font-size: 100%; /* Inherit the user's font size preference */
font-family: sans-serif; /* System default, no download required */
max-width: 65ch; /* Comfortable line length for reading */
margin: 0 auto;
padding: 1rem;
}
h1 { font-size: 2rem; }
h2 { font-size: 1.6rem; }
h3 { font-size: 1.2rem; }
small { font-size: 0.8rem; }
nav ul {
list-style: none;
padding: 0;
margin: 0;
}
nav ul li {
display: inline-block;
border-right: 1px solid black;
padding: 2px 10px;
margin: 0;
}
footer {
border-top: 1px solid;
margin-top: 2rem;
padding-top: 1rem;
font-size: 0.8rem;
}
A few things worth explaining here.
font-size: 100% on the html element inherits whatever font size the user has configured in their browser. A lot of people, particularly those with visual impairments, set it larger than the default. Writing font-size: 16px overrides their choice. Using sizes in rem units afterward keeps everything proportional to that base.
max-width: 65ch keeps line lengths around 60 to 70 characters, which is generally considered the most comfortable range for reading.
Skip float. Floated elements force the browser to do extra layout work. Stacking blocks vertically is simpler and lighter.
Skip web fonts entirely. The sans-serif keyword maps to whatever font the user has set as their preferred one in their browser. It loads instantly and costs nothing.
Step 5: things that will trip you up
Inline styles are blocked by your Content-Security-Policy header and break the separation between content and presentation:
<!-- avoid this -->
<p style="color: red; font-weight: bold;">Warning!</p>
<!-- do this instead -->
<p class="warning">Warning!</p>
Misnested tags cause browsers to guess what you meant, and they often guess wrong:
<!-- wrong -->
<b><i>text</b></i>
<!-- right -->
<b><i>text</i></b>
Tables are for data, not for positioning parts of your page. If you are using a table to put your navigation next to your content, that is the wrong tool.
External scripts and stylesheets break the default-src 'self' policy and introduce a dependency on a server you do not control:
<!-- wrong -->
<script src="https://cdn.example.com/jquery.min.js"></script>
<!-- right -->
<script src="/js/myscript.js"></script>
Missing alt attributes on images leave users with broken image icons and screen reader users with nothing:
<!-- wrong -->
<img src="photo.jpg">
<!-- right -->
<img src="photo.jpg" alt="A sunset over the mountains in July 2024">
Step 6: before you publish
Two validators are worth running before putting your page online.
The W3C validator checks that your HTML conforms to the standard. The smolweb validator checks that you are staying within the smolweb HTML subset.
Then do these four quick tests. Open your page in a regular browser. Disable CSS (in Firefox: View > Page Style > No Style) and check that the content is still readable and logically ordered. Try Lynx or w3m in a terminal if you have access to one: a text-only browser is about as demanding a test as you can run. Finally, resize your browser window down to a narrow width and see if the layout stays usable.
The complete template
Copy and adapt from here:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<meta name="description" content="A short description of this page.">
<link href="/style.css" rel="stylesheet" type="text/css">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.png" type="image/png">
<title>Page title - My smolwebsite</title>
</head>
<body>
<header>
<strong>My smolwebsite</strong>
<nav>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>My first post</h1>
<p>Hello! This is my first smolweb page. It's small, fast, and works everywhere.</p>
<p>No framework, no tracker, no bloat. Just HTML.</p>
</article>
</main>
<footer>
<p>Published by me under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a></p>
</footer>
</body>
</html>
A few more things, once you are up and running
Consider adding an RSS feed. Smolweb readers tend to follow sites through RSS rather than social media, and it is not complicated to set up a basic XML file.
Enable HTTPS if your host supports it. Let's Encrypt provides free certificates. You can also use the w. subdomain (like w.yoursite.tld instead of www.yoursite.tld) to signal that your site follows the smolweb guidelines.
When you add images, optimize them before uploading and always write an alt description. Better yet, ask yourself whether the image is necessary at all. Sometimes a sentence says more.
The smolweb is not about building something ugly or retro. It is about building something that loads fast, respects its readers, and will still work ten years from now. Start with the template above, add only what you actually need, and keep it that way.
Further reading:
- smolweb.org - the official guidelines
- HTML for People - a gentle HTML introduction for beginners
- Modern Font Stacks - system font combinations that look great everywhere
- Wiby - a search engine for small, simple websites
Discuss about this post on the Fediverse