Rewriting my website in plain HTML and CSS
用純 HTML 和 CSS 重寫我的網站
This week, I decided to rewrite my website using plain HTML and CSS.
When I originally
made it, I used SvelteKit for simplicity. It was a more interesting
project than I was expecting when I started working so I wanted to share
my thoughts on the experience.
這週,我決定使用純 HTML 和 CSS 重寫我的網站。最初建立網站時,我為了簡便起見使用了 SvelteKit。這個專案比我預期中更有挑戰性,因此想分享一下我的心得。
Why? 為什麼?
There are a number of reasons I decided to do the rewrite. One is
that I’m currently unemployed so I have a lot of free time for side
projects. Another is that, as you can see, this website is pretty simple
so I wasn’t gaining a lot from using SvelteKit. I also wanted to move
the site over to Cloudflare Pages so this was an opportune time to make
some changes.
我決定重寫的原因有很多。其中一個原因是我目前失業,有大量時間可以投入副專案。另一個原因是,如你所見,這個網站相當簡單,使用 SvelteKit 並沒有帶來太多好處。此外,我也想將網站遷移到 Cloudflare Pages,所以這是個做出一些變化的絕佳時機。
However, the primary reason I decided to make some changes is that I
find the Javascript bundler and building ecosystem incredibly
aggravating to use. For example, one of the things I set up my old
website to do was build the blog section from the set of Markdown posts.
I assumed this would be easy to do. SvelteKit and Vite allow you to
prerender your website and I had a set of files at build time - I just
needed to add some logic to transform them. Instead, it was
infuriatingly difficult to figure out a way to just get a handle to a
set of files in my tree at build time (let me caveat that I’m not a
frontend dev and maybe I missed something obvious). It took me hours of
Googling and trying out different options to come up with this awful
piece of code that worked to load the contents of a file and give them
to my page:
然而,我決定做出一些變化的主要原因是,我發現 Javascript 的打包器和建置生態系統非常惱人。例如,我之前設定舊網站時,其中一項功能是從 Markdown 文章集建置部落格區段。我原以為這很容易做到。SvelteKit 和 Vite 允許你預渲染網站,而且我在建置時間擁有一組檔案——我只需要添加一些邏輯來轉換它們。然而,要找到一種方法在建置時間取得檔案樹中的一組檔案卻難以置信地困難(讓我先聲明一下,我不是前端開發人員,也許我錯過了某些顯而易見的東西)。我花了數小時搜尋 Google 並嘗試不同的選項,才想出這段糟糕的程式碼,它可以載入檔案內容並將其提供給我的頁面:
import type { PageLoad } from "./$types";
export const load: PageLoad = async ({ params }) => {
const file = await import(
`../../../../lib/assets/posts/${params.slug}.md`
);
return { content: file.default, ...file.metadata };
};
I was tired of dealing with things like this for the tiny amount I
was gaining from using SvelteKit. And so, I finally decided it was time
for a rewrite.
我厭倦了為了使用 SvelteKit 所獲得的微薄好處而處理這些問題。因此,我最終決定是時候重寫了。
How? 如何做?
I think spending too much time on Hacker News gave me the
misconception that writing a website using plain HTML and CSS would be a
relatively well-paved path in 2025. I spent some time looking around for
guides or a “canonical” way of doing this and found that there isn’t
really one. Because of that, I decided to just start from scratch with
an empty directory and go from there. My website is small enough that I
was able to remake a lot of the pages as static HTML.
我想,在 Hacker News 上花太多時間讓我產生了誤解,以為在 2025 年使用純 HTML 和 CSS 撰寫網站會是一條相對平坦的道路。我花了一些時間搜尋指南或「標準」做法,卻發現實際上並不存在。因此,我決定從一個空目錄開始,從頭做起。我的網站很小,我可以將許多頁面重新製作成靜態 HTML。
However, I prefer writing blog posts in Markdown. It’s easier to
write than HTML, I can pull posts out of my existing Obsidian vault, and
I just find it more convenient. Therefore, I needed some kind of script
to turn my Markdown blog posts into HTML content. I investigated some
options for this and found Pandoc.
Pandoc is a universal document converter for converting markup formats.
It provides a library and a CLI for converting documents from Markdown
to HTML (along with many other formats).
然而,我更喜歡使用 Markdown 撰寫部落格文章。它比 HTML 更容易撰寫,我可以從我現有的 Obsidian 資料庫中提取文章,而且我發現它更方便。因此,我需要一些指令碼來將我的 Markdown 部落格文章轉換成 HTML 內容。我研究了一些選項,並找到了 Pandoc。Pandoc 是一個通用的文件轉換器,用於轉換標記格式。它提供了一個函式庫和一個 CLI,用於將文件從 Markdown 轉換為 HTML(以及許多其他格式)。
To write the script, I wanted something as lightweight as possible
but easier to use than a Bash script. This led me to Python and uv. I’ve found that uv basically
abstracts away the Python environment in a way that’s really convenient
for a tiny project like this. Using Python also gave me a free way to
serve my website using the http.server
module. Finally, I
wrote a tiny Makefile so I wouldn’t have to remember the serve
command.
為了撰寫指令碼,我希望它盡可能輕量級,但比 Bash 指令碼更容易使用。這讓我選擇了 Python 和 uv。我發現 uv 基本上以一種非常方便的方式抽象化了 Python 環境,對於像這樣的小型專案來說非常方便。使用 Python 也讓我可以用 http.server
模組免費託管我的網站。最後,我寫了一個小小的 Makefile,這樣我就不用記住執行伺服器的命令了。
Results 成果
The outcome was
not the most revolutionary because my website was really simple
in the first place. But the size of my “compiled” website asset went
from ~356kb to ~88kb. My project tree got a lot simpler and the only
Javascript on the site now is to highlight code. I’m also just happier
about the state of things. I feel like I understand how and why my site
works (where before I understood parts but not the whole mystery).
結果並非革命性的,因為我的網站一開始就非常簡單。但是我的「編譯」網站資產大小從約 356kb 減少到約 88kb。我的專案目錄結構變得簡單許多,網站上唯一的 Javascript 現在是用於程式碼語法標記。而且我對目前的狀況也更滿意了。我覺得我了解我的網站如何以及為什麼運作(之前我雖然了解部分,但整體來說仍然是個謎)。
Before, with SvelteKit 使用 SvelteKit 之前 |
After, with plain HTML 使用純 HTML 之後 |
![]() |
![]() |
Next Steps 接下來的步驟
There are two downsides that I’ve found so far. I’d like to
investigate ways to fix or improve these.
到目前為止,我發現了兩個缺點。我想研究一下如何修復或改進這些問題。
- More code duplication. SvelteKit has a component system so I could
make my navigation bar as a component and reuse it. When I removed it, I
had to duplicate that code in a few places. Luckily the cost was pretty
minor because I only really have four HTML pages. I’m aware that there’s
some way to do this using web components. It’s something I intend to
look into as one of my next side projects.
更多程式碼重複。SvelteKit 有一個組件系統,所以我可以將我的導覽列製作成一個組件並重複使用它。移除它後,我必須在幾個地方複製該程式碼。幸運的是,成本相當低,因為我只有四個 HTML 頁面。我知道可以使用某種方式透過 Web Components 來實現這一點。這是我打算作為下一個副專案研究的事情之一。 - No live reloading. I have to kill the website to rebuild it now. I’m
sure there’s a tool I can find to fix this, or maybe just use something
like FastAPI that has automatic reload. But until I do something about
it, there’s a minor added cost every time I make a change.
沒有即時重新載入。我現在必須關閉網站才能重新建置它。我相信我可以找到一個工具來解決這個問題,或者也許只使用像 FastAPI 這樣具有自動重新載入功能的工具。但在採取行動之前,每次修改都會增加一點額外成本。
Also, I think this repository is now a reasonably good template for
someone who wants to make a simple website with some Markdown blog posts
without using a generator. I was surprised when I started this project
how difficult it was to find a guide about how to write your site
without a framework. Hopefully this can help some other people.
此外,我認為這個程式碼庫現在是一個相當不錯的範本,適用於想要建立一個簡單的網站,並包含一些 Markdown 部落格文章,而無需使用產生器的使用者。開始這個專案時,我驚訝地發現,要找到關於如何在沒有框架的情況下撰寫網站的指南有多麼困難。希望這能幫助其他人。