![]()
編譯 | 蘇宓
出品 | CSDN(ID:CSDNnews)
多年來,“HTML、CSS 到底算不算是編程語言”一直是前端圈一個頗具爭議的話題。
一邊是工程師堅持認為,它們只是標記與樣式描述工具,不具備傳統意義上的邏輯能力;另一邊則認為,在現代瀏覽器體系下,CSS 已經具備足夠復雜的表達能力,甚至可以完成一些超出“樣式表”范疇的工作。
爭論還沒完全有結論,一個更“實戰化”的例子就出現了。
來自荷蘭的開發者 Niels Leenheer 近日做了一件看起來有點離譜的事:他沒有使用 WebGL,也沒有依賴任何游戲引擎,僅僅依靠最基礎的 HTML 和 CSS,就復刻出了一個“能玩的《DOOM》”。
在這個被稱為 cssDOOM 的項目里,墻壁、地板、木桶、甚至惡魔怪物,都不是傳統意義上的圖形資源,而是通過一個個在三維空間中不斷變形的
標簽構建出來的。JavaScript 只負責游戲邏輯與主循環,而所有畫面的渲染工作,則完全交給 CSS 來完成。
項目地址:https://github.com/NielsLeenheer/cssDOOM
![]()
![]()
Niels Leenheer 是誰?
Niels Leenheer 是一位資深開發者,他最為人熟知的創建了是 HTML5 標準測試網站 HTML5test.com,以及瀏覽器用戶代理解析工具 WhichBrowser。同時,他也是 Fronteers 大會委員會的成員。
此前,他曾完成一項趣味實驗,成功在示波器上運行《Doom》,并借此編寫代碼,從原版游戲 WAD 資源文件中提取地圖數據。
本次 CSS 版《Doom》,正是在該實驗的基礎上迭代開發而來。
![]()
純靠 HTML、CSS,Doom 是怎么實現的?
Niels Leenheer 首先將提取的游戲地圖數據,編譯為由數千個`
`元素構成的靜態場景。
">每一個元素都標注了《Doom》原始坐標參數。
![]()
隨后,瀏覽器的布局與合成系統會接管渲染工作,通過 CSS 的 transform 以及諸如 hypot()、atan2() 等數學函數,把這些元素渲染成定位在三維空間中的對象。
}與其讓 JavaScript 負責完整的三維幾何計算,這個實現選擇了一種更“偷懶”的方式:腳本只傳遞原始的坐標點,以及地板和天花板的高度等參數作為自定義屬性,其余諸如墻體寬度、旋轉角度等三角計算,全部交給 CSS 引擎來完成。
這種分工是有意為之的:游戲核心循環邏輯改編自《毀滅戰士》開源 C 語言代碼,由 JavaScript 負責運行,同時僅向 CSS 開放坐標數據、狀態參數與少量自定義屬性,構成輕量化渲染層。
Niels Leenheer 也曾嘗試把游戲狀態和邏輯完全交給 CSS 來處理,但很快發現并不現實,于是放棄了這一思路,不過渲染路徑依然幾乎完全留在樣式層完成。
整個項目中一個關鍵難點,在于如何把《DOOM》的坐標體系和渲染技巧,適配到瀏覽器的 3D 處理方式上。比如地面,就是通過將
元素繞 X 軸旋轉 90 度來實現的,然后再借助 clip-path 的 polygon(),或更新的 shape() 語法,將其裁剪成任意形狀的扇區多邊形,從而支持復雜輪廓甚至奇偶填充規則。
![]()
在不同區域之間實現無縫紋理鋪設的關鍵,是將背景位置錨定在“世界坐標系”中。例如,如果一個元素在水平和垂直方向分別偏移了 200px 和 400px,那么它的 background-position 就會被設置為 -200px -400px,這樣紋理圖案就能像被連續鋪在一整塊平面上一樣對齊。
場景的移動方式也比較特殊:它并不是通過“攝像機”來移動視角(因為 CSS 本身并沒有真正的攝像機概念),而是通過移動整個“世界”來實現效果。JavaScript 會記錄玩家的位置和角度,并將其存儲在四個自定義屬性中,而 CSS 會對這些數值進行反向計算,使場景朝相反方向移動,同時通過額外的 translate 來補償透視效果,其余部分則交給瀏覽器的渲染系統完成。
敵人和投射物的精靈渲染則依賴“廣告牌(billboard)”技術:CSS 會讓每個 sprite 始終面向觀察者,在需要時通過 scaleX 進行鏡像翻轉,并使用 step() 動畫來推進精靈幀序列,而 JavaScript 只負責更新對應的狀態屬性。
![]()
場景光照、自動門、升降平臺、彈道特效,統統被轉化為可動態變更的樣式狀態問題。區域亮度以級聯自定義屬性存儲,搭配亮度濾鏡統一調暗昏暗區域,無需逐個修改場景元素;游戲大門通過自定義屬性綁定 CSS 過渡動畫,實現抬升開合,腳本僅需切換狀態標簽,動畫播放完全交由瀏覽器原生驅動。
彈藥彈道通過起點、終點坐標與飛行時長定義,CSS 依靠位移動畫完成彈道位移,搭配獨立旋轉屬性,讓投射物始終朝向玩家。
現代布局特性還被巧妙用來實現游戲自適應適配。原版固定寬度的狀態欄,被重構為文檔對象模型獨立組件,彈藥數值、生命值、角色頭像、護甲值、鑰匙道具拆分展示,通過彈性布局自動排版,在窄屏設備上自動換行適配。
觀戰模式則新增一套 CSS 鏡頭邏輯。
跟隨視角利用角度正弦、余弦函數結合計算屬性,測算偏移數值,將鏡頭固定在玩家斜后方與斜上方;視角切換依靠獨立的位移、旋轉屬性,讓第一人稱與第三人稱跟隨視角之間實現絲滑過渡。
性能與畫面精度問題,也暴露了這套純 CSS 方案的固有短板。包含數千個三維變形元素的大型地圖,極易導致移動端蘋果瀏覽器出現畫面卡頓,甚至程序崩潰。
為此,Niels Leenheer 加入視域剔除機制,自動隱藏玩家視野外的幾何模型。
基礎版剔除邏輯由 JavaScript 編寫,遍歷場景元素,根據距離與角度切換隱藏屬性。
Niels Leenheer 還測試了純 CSS 剔除方案:通過樣式參數定義可見性判定,結合延時動畫與關鍵幀規則,利用樣式特性實現元素的自動顯示與隱藏。
![]()
局限性
《Doom》原生渲染的部分核心邏輯,很難直接復刻至 CSS 環境。
原版游戲會將天空紋理以純二維形式,繪制在地圖實體前方的虛擬墻體上;而CSS渲染必須構建完整三維空間,天空圖層需要置于所有景物后方。
這一差異會導致原版被天空遮擋的模型暴露出來,Niels Leenheer 只能額外增加剔除規則,隱藏玩家視角中被天空墻體遮擋的物體。
Niels Leenheer 明確表示,該項目絕非 WebGL、WebGPU 專業圖形渲染方案的替代品,性能瓶頸也客觀存在,但這并非本次開發的核心目的。
他在分享中提到,這項開發旨在突破 CSS 的能力邊界。三角函數運算、自定義屬性動畫、裁剪路徑、SVG濾鏡、錨點定位等成熟商用級 CSS 特性,都被賦予了標準制定者從未設想過的全新用途。
最終成品完整可玩,直觀證明:只要合理運用大量`
`元素與現代 CSS 語法,無需調用任何圖形編程接口,就能在瀏覽器中完整復刻《毀滅戰士》的游戲世界。
長久以來,愛好者不斷挖掘各類低門檻、非常規設備運行《毀滅戰士》的可能性,CSS 只是最新的趣味載體。
也正如 Niels Leenheer 所言,如果說還有什么意義的話,那它至少回答了一個沒人真正問過的問題:CSS 能不能跑《DOOM》?
答案是:可以。確實可以。
來源:https://nielsleenheer.com/articles/2026/css-is-doomed-rendering-doom-in-3d-with-css/
https://www.techspot.com/news/111922-developer-rebuilds-doom-using-only-css-html-turning.html
【活動分享】"48 小時,與 50+ 位大廠技術決策者,共探 AI 落地真路徑。"由 CSDN&奇點智能研究院聯合舉辦的「全球機器學習技術大會」正式升級為「奇點智能技術大會」。2026 奇點智能技術大會將于 4 月 17-18 日在上海環球港凱悅酒店正式召開,大會聚焦大模型技術演進、智能體系統工程、OpenClaw 生態實踐及 AI 行業落地等十二大專題板塊,特邀來自BAT、京東、微軟、小紅書、美團等頭部企業的 50+ 位技術決策者分享實戰案例。旨在幫助技術管理者與一線 AI 落地人員規避選型風險、降低試錯成本、獲取可復用的工程方法論,真正實現 AI 技術的規模化落地與商業價值轉化。這不僅是一場技術的盛宴,更是決策者把握 2026 AI 拐點的戰略機會。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
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.