整理 | 蘇宓
出品 | CSDN(ID:CSDNnews)
幾年前做前端,HTML、CSS 和 JavaScript 被譽為「前端三劍客」,是很多入坑的開發者逃不開避不掉的技術。其中,HTML 負責搭建架子、CSS 負責視覺美化、JavaScript 則主攻網頁交互,三者缺一不可。
不過最近,一位名叫 Benjamin Aster 的開發者卻玩了波「反套路」—— 他竟然用純 HTML 和 CSS 搞出了一個《我的世界》(Minecraft)克隆版!
沒聽錯,整個項目里一行 JavaScript 都沒有。所有的交互邏輯、動畫效果,全靠這兩位“老將”撐場,但是效果屬實不錯。
正如下圖所示,這款游戲中,3D 方塊可以自由添加和刪除,視角還能旋轉瀏覽,完全不像是沒用 JS 的成果,堪稱魔法。
話不多說,想要體驗的小伙伴不妨試玩一把:https://benjaminaster.com/css-minecraft/
目前,這個項目也已經在 GitHub 上開源:https://github.com/BenjaminAster/CSS-Minecraft
480 行 CSS + 46022 行 HTML,堆出了一個 3D 世界!
那 Benjamin Aster 是怎么做到的呢?
這個問題其實也引起了不少開發者的興趣。英國程序員、Django 框架的作者 Simon Willison 就在看到這個項目后,專門寫了一篇博客,深入解析了這個 0 行 JavaScript、全靠 HTML 和 CSS 撐起來的《我的世界》克隆版背后的技術原理。
簡單來看,這是一個 9x9x9 的世界,可以在其中放置或移除 7 種不同類型的方塊,也可以以 3D 視角旋轉這個世界,從不同角度進行觀察。
讓人意外的是,整個項目僅用480 行 CSS實現:
還有46,022 行 HTML 代碼,只有3.07MB!
核心技術原理
光看這代碼量就像用牙簽拼城堡,這個項目之所以能運作起來,Simon Willison 解釋稱,關鍵技巧是將 標簽與 has() 選擇器組合使用才得以實現。
對此,整個頁面中有35001 個 標簽和5840 個 單選按鈕組成了狀態存儲引擎。
每個方塊的六個面都相當于一個標簽,點擊任意一面,就像觸發了一個隱藏的開關,通過的for
屬性精準「鏈接」到相鄰方塊的狀態。
當你想給方塊換材質時,其實是在切換可見的標簽組。CSS 里的has()
選擇器就像個「大管家」,比如當你選中「石頭」材質的單選按鈕時,它會立刻讓其他材質的方塊「隱身」(display: none
),只留下石頭方塊在界面上顯示。具體實現代碼如下:
.controls:has(
> .block-chooser > .stone > input[type=radio]:checked
) ~ main .cubes-container > .cube:not(.stone) {
display: none;
}
值得一提的是,因為這個項目要生成上萬行 HTML 標簽,比如幾萬個 和 ,用純手寫 HTML 會非常麻煩和冗長。所以在項目里面,作者 Benjamin Aster 使用一種叫做 Pug 語言編寫的 HTML 模板文件,可以通過嵌套結構和循環輕松地批量生成這些標簽,再通過構建工具(比如 pug-cli)編譯成普通 HTML 文件。
下面是這個 Pug 模板的簡化版本(完整代碼詳見:https://github.com/BenjaminAster/CSS-Minecraft/blob/main/index.pug),可以幫助大家理解 HTML 的結構:
//- pug index.pug -w
- const blocks = ["air", "stone", "grass", "dirt", "log", "wood", "leaves", "glass"];
- const layers = 9;
- const rows = 9;
- const columns = 9;
for _, layer in Array(layers) for _, row in Array(rows) for _, column in Array(columns)
- const selectedBlock = layer === layers - 1 ? "grass" : "air"; - const name = `cube-layer-${layer}-row-${row}-column-${column}`;
- const id = `${name}-${blocks[0]}`;
label>
label>
label>
label>
label>
label> div> each block, index in blocks.slice(1) - const id = `${name}-${block}`; - const checked = index === 0;
label>
label>
label>
label>
label>
label> div> //- /each div> //- /for //- /for //- /for div>
因此,對于每一個 9x9x9 = 729 個立方體,都會生成一組共享相同 name 的 8 個 radio 按鈕,例如 cube-layer-0-row-0-column-3 ——意味著這個方塊可以有 8 種狀態(其中 “air” 表示空氣,也就是空白,其余則代表不同的材質類型)。每個方塊有 6 個 label,分別對應它的六個面,這些 label 的 for="" 屬性會指向相鄰位置、當前所選材質類型的下一個方塊。
CSS 動畫玩出 3D 世界旋轉
另一個非常巧妙的設計是這個項目用來實現3D 視圖控制與旋轉的方法。
沒有 JavaScript 的動畫控制,Benjamin 就靠 CSS 動畫來了波「視覺旋轉」。首先,他先定義了一些規則:
.controls:has(.up:active) ~ ma
in .down {
animation-play-state: running;
}
.controls:has(.down:active) ~ main .up {
animation-play-state: running;
}
.controls:has(.clockwise:active) ~ main .clockwise {
animation-play-state: running;
}
.controls:has(.counterclockwise:active) ~ main .counterclockwise {
animation-play-state: running;
}
這些規則意味著,當你按住對應的按鈕(例如 .clockwise),與之關聯的動畫會從暫停狀態變為運行狀態。
接著,Benjamin 又為每種操作都定義了對應的動畫:
.content .clockwise {
animation: var(--animation-duration) linear 1ms paused rotate-clockwise;
}
@keyframes rotate-clockwise {
from {
rotate: y 0turn;
}
to {
rotate: y calc(-1 * var(--max-rotation));
}
}
.content .counterclockwise {
animation: var(--animation-duration) linear 1ms paused rotate-counterclockwise;
}
@keyframes rotate-counterclockwise {
from {
rotate: y 0turn;
}
to {
rotate: y calc(var(--max-rotation));
}
}
當你按住某個按鈕時,動畫從 paused 切換為 running,一旦松開按鈕就會暫停。動畫執行期間,會改變目標元素上的各種 3D 變換屬性,實現空間旋轉。
整個設計巧妙得令人驚嘆,一旦你理解了它的核心技巧,會發現它的實現其實相當優雅而且可讀性強。
最后
隨著 Simon Willison 將這一項目分享出來,也在 Hacker News 引發熱烈討論,網友們紛紛感嘆這簡直是「CSS 黑魔法」:
我完全沒想到 :has() 還能這么用,直接看傻了。
這種項目雖然沒啥生產用途,但絕對讓我重新愛上寫網頁。
這是對 CSS 的精彩‘濫用’,我太喜歡了。
沒多久,項目作者 benjaminaster 也現身 Hacker News 評論區,驚呼:“你們的訪問量實在太猛了,把我的網站擠爆了……我之前用的是 Firebase 的靜態托管服務,因為它完全免費而且配置非常簡單,但現在已經達到了每月 10 GB 的流量上限。我目前已經切換到 Cloudflare,不過 DNS 記錄的更新還需要一點時間。”
在此期間,可使用 GitHub Pages 鏈接訪問項目:https://benjaminaster.github.io/CSS-Minecraft/
Benjamin 還補充說,這個項目其實是他三年前的實驗作品,最初只是想探索純 CSS 的極限表現力,并測試當時剛被瀏覽器支持的 :has() 選擇器。沒想到多年之后,因為一次分享突然爆紅網絡。
為了獲得最佳體驗,他建議使用桌面端瀏覽器訪問,推薦基于 Chromium 的瀏覽器或 Firefox。
項目源碼地址:https://github.com/BenjaminAster/CSS-Minecraft
其中 index.pug 和 main.scss 是主要源碼,其余為編譯后的輸出內容。
演示視頻: https://www.youtube.com/watch?v=OH8-Y9frP5k
整體來看,只用了 480 行 CSS 和 4 萬多行 HTML,就拼出了一個能放方塊、蓋房子、旋轉視角的 3D 世界。它或許不是最實用的作品,但它證明了:挖掘 HTML 和 CSS 的潛力,不一定非得依賴復雜的技術,有時候,只要足夠巧思,也能實現出乎意料的精彩。
參考來源:
https://simonwillison.net/2025/May/26/css-minecraft/
https://news.ycombinator.com/item?id=44100148
2025 全球產品經理大會
2025 年 8 月 15–16 日
北京·威斯汀酒店
2025 全球產品經理大會將匯聚互聯網大廠、AI 創業公司、ToB/ToC 實戰一線的產品人,圍繞產品設計、用戶體驗、增長運營、智能落地等核心議題,展開 12 大專題分享,洞察趨勢、拆解路徑、對話未來。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.