10 月 17 日,我在南特 devFest 舉辦了一場題為「突變 HTML 的入侵」的研討會。
根據定義,研討會必須讓參與者參與,我選擇創建一個迷你遊戲作為支持。這是一個線上靜態網站,在 GitHub 上開源 — 因此您可以改進它!
當我說靜態時,我的意思是靜態:儲存庫有一個依賴項,伺服器,負責提供用於本地工作的基本 HTTP 伺服器,並且伺服器本身沒有依賴項。剩下的只是 HTML、CSS 和 JavaScript。
它讓我回歸基本並顯著提高效率;但最重要的是…發現一大堆提示和技巧!
當你開始遊戲時,你將從自訂你的角色開始。此步驟的唯一目標是發現關卡的視覺結構,讓您親自參與遊戲,所選的值將盡快應用於遊戲中的所有角色。鏡像表示。
選擇角色後,訓練等級會讓您熟悉遊戲的非常簡單的機制:需要完成和提交的部分程式碼,即時執行,影響逐漸被變種人入侵的區域!這段程式碼在大多數層級都是傳遞給mutationObserver的選項,但有時也在回調函數中。
如果失敗或成功,模式視窗會通知您。我們來談談這個模態視窗吧!
我在2022 年的Paris Web 上以及南特devFest 的主題“發現“好的HTML”並保存JS 和CSS”中談到了這個問題,
在工作坊中,我在幾個地方使用它:
大多數都是以程式設計方式開啟的,以回應事件。沒有比這更簡單的了:只需檢索對
document.querySelector('dialog').showModal();
但是,為了避免新增不必要的事件偵聽器,有一個例外:使用 HTML onclick 事件處理程序呼叫遊戲規則視窗:
<button type="button" onclick="rules.showModal()">Règles du jeu</button> <dialog> <h5> Aparté : la projection des identifiants HTML en objets globaux </h5> <p>Dans cet exemple, j’invoque l’ouverture de la fenêtre modale avec rules.showModal(), sans avoir défini la variable rules. Comment est-ce possible ? En résumé, tout élément porteur d’un attribut id devient mécaniquement une propriété globale de l’objet window, et devient donc accessible directement par son nom. C’est spécifié sous le joli nom de Named Access on Window Object (en anglais).</p> <p>C’est drôlement pratique, non ? Figurez-vous que c’est aussi un vecteur d’attaque méconnu faisant partie d’un groupe sobrement intitulé DOM clobbering (en anglais). Je vous encourage à parcourir les recommandations de l’OWASP pour mitiger le DOM clobbering (en anglais).</p> <h4> Accessibilité </h4> <p>La méthode showModal() permet d’ouvrir une fenêtre modale, pas une simple boîte de dialogue — en respectant les exigences en matière d’accessibilité : la focus est mécaniquement piégé dedans, la fermeture est possible avec la touche <kbd>Échap</kbd>, etc.</p> <h3> L’arrière-plan </h3> <p>Une fois la fenêtre modale ouverte, on peut s’appliquer à la styler. Là où moult bibliothèques de composants imposent une <div> (voire plusieurs) pour servir d’arrière-plan à la fenêtre, la version native est livrée avec un pseudo-élément ::backdrop qui s’étend naturellement sur tout le viewport et est promue, avec la fenêtre modale, par-dessus le reste de la page dans ce qui est spécifié sous le nom de top layer. <p>Vous n’avez plus qu’à lui appliquer une couleur, une opacité ou que sais-je encore. Dans le jeu, j’ai utilisé une propriété au nom évocateur de backdrop-filter pour appliquer un effet de flou grisé sur l’arrière-plan.<br> </p> <pre class="brush:php;toolbar:false">dialog::backdrop { backdrop-filter: grayscale(50%) blur(.25rem); }
由於沒有掌握遊戲檢視模式,我使用了一些現代 CSS 來設定模式視窗的寬度,使其具有流暢的寬度,但具有最小值和最大值。
dialog { max-inline-size: clamp(50vw, 100%, 67.5rem); }
max-inline-size 屬性是與法語情況下的 max-width 對應的邏輯屬性。夾子()函數是一個小寶石,我已經在圖表(英文)中大量濫用它,以根據值在CSS 中獲取偽布爾值,正如我的會議“給我畫一個圖形(在CSS)”在devFest Nantes 2023、TNT #24 和DevQuest 2024 上給出。
我提到了使用 Esc 鍵關閉模式的功能,但是
這就是為什麼將對話方塊值加入表單提交方法的原因。它不對應於像 get 或 post 這樣的 HTTP 方法,而是對應於 HTML 上下文,並允許您直接關閉父模式視窗。使用起來非常簡單:
<form> <p>Et, pour revenir à du HTML à l’ancienne : saviez-vous qu’un bouton à l’autre bout du DOM peut soumettre un formulaire ? Il suffit de lui indiquer le formulaire à soumettre :<br> </p> <pre class="brush:php;toolbar:false"><button form="fermer">Fermer la fenêtre</button>
現在你已經看到了:它是一個提交類型按鈕,它將提交帶有關閉標識符的表單,它本身將關閉對話框視窗。很漂亮,不是嗎?這個屬性(至少)可以追溯到 2006 年,在 W3C Web Forms 規範(英文)中,其初稿可以追溯到 2004 年。
對於這個工作坊,我需要邪惡的入侵者和裝飾品。顯然沒有時間手工製作插圖,也沒有辦法購買視覺效果。在網路上的搜尋告訴我,我正在尋找的視覺效果類型稱為自上而下的圖塊集,這些小設定和角色通常為 8 位,具有破碎的視角。
透過查看 8 位元視覺效果,我最終將會議材料中的一個老習慣聯繫起來:標題末尾的裝飾性表情符號。該死,但確實如此!表情符號!
表情符號很棒。這些是 Unicode 點,純文字的,而且現在數量非常多,每個版本的 Unicode 中都有大量新功能。甚至還有變體,依序組成!
在我看來,Unicode 序列的最佳範例是字元:中性的Nobody?可以成為男人嗎?還是女人?加入男性 ♂️ 或女性 ♀️ 的 unicode 點,並以零寬度連接符號 ) 分隔。
要獲得消防員 ??,我們只需加一輛消防車 ??對一個人? !老實說,這不是很好嗎?而且我們可以明顯地添加性別和膚色。
因此,第一級允許您個性化英雄的性別和膚色。
該表單僅由兩組單選按鈕組成,每個按鈕都有一個與相關 Unicode 點相對應的值。
document.querySelector('dialog').showModal();
就是這樣:Firefox 用戶不會加載任何內容,其他人會下載一個排版來顯示與 Firefox 相同的內容。下次更好地選擇您的瀏覽器!
正如我準備主題時經常遇到的情況一樣,我遇到了一些瀏覽器限制。碰巧,Safari 和 Epiphany 的引擎 WebKit 在處理 Twemoji-COLR 的色調變體時存在問題。我能夠在他們的 Bugzilla 上開票(英文)。
在遊戲機制中,會顯示部分程式碼(以製作「漏洞碼」),並從 輸入程式碼。和。
對於閱讀和編寫程式碼來說,語法高亮真的很實用而且很有趣!但載入諸如 PrismJS(英文)或highlight.js(英文)之類的腳本對於我來說總是顯得過多,因為附加價值很高。程式碼區塊最終在 DOM 中被砍掉,其中 是或多或少可讀的類別根據其語法角色對文字的每個部分進行切片。簡直難以消化。
但正當我準備本次研討會時,Heikki Lotvonen 發表了一篇令人難以置信的文章:帶有內建語法突出顯示的字體(英文)。在我看來,這是一場小小的革命:排版利用了 OpenType 功能,特別是 COLR 表。不再有 ,為可讀且乾淨的程式碼讓路!
如果您對 OpenType 實作細節感興趣,我鼓勵您閱讀這篇文章。就我而言,我專注於自訂調色板,透過 @font-palette-values(在 MDN 上,英文)和 override-colors 屬性(在 MDN 上,英文)在 CSS 中實現。
這是遊戲的樣子,其中我利用 CSS 自訂屬性來進行顏色管理:
document.querySelector('dialog').showModal();
結果還不錯吧?
這是純粹的漸進式改進:如果您的瀏覽器不支援 COLR 表、@font-palette-values 規則或 override-colors 屬性,您將只擁有預設等寬字體的純文字。
最後一個讓我玩得很開心的點是外星人關卡。外星怪物表情符號?看起來與《太空侵略者》中的飛船非常非常相似。對於一款入侵遊戲來說,這已經很好了。
所以我想假設參考:黑色背景,入侵者向下滾動的動畫,以及......得分計數器。
對於長期從事CSS的人來說,你可能已經聽說過CSS計數器。我們的分數將僅對應於在場的外星人數量。
但是,如果我們的計數器從 1 開始一直到 100(並且知道原始遊戲有一個五位數的計數器),那麼它就不會很優雅,也不會是一個好的引用。幸運的是,CSS 允許我們使用 @counter-style 自訂計數器樣式。
要取得五位計數器,在計數器值之前顯示 0,這裡是使用的聲明:
document.querySelector('dialog').showModal();
這裡,WebKit 也受到限制:在 DOM 中加入元素時,CSS 計數器不會增加。這張票是 Karl Dubost 在 Bugzilla 上開的(英文)。
視覺上引用《太空侵略者》的另一個亮點是明亮的色彩。使用的表情符號帶有我們無法超載的顏色,因此我們必須更改它。這種技術並不新鮮,但非常有用:累積 CSS 過濾器以實現正確的顏色。
這是一個複雜的練習,我感謝 Barrett Sonntag 的過濾器產生器,將黑色轉換為十六進位代碼(在 CodePen 上,英文)。唯一的限制是從黑色開始,這可以透過先應用灰階(100%)亮度(0%)輕鬆解決。
<button type="button" onclick="rules.showModal()">Règles du jeu</button> <dialog> <h5> Aparté : la projection des identifiants HTML en objets globaux </h5> <p>Dans cet exemple, j’invoque l’ouverture de la fenêtre modale avec rules.showModal(), sans avoir défini la variable rules. Comment est-ce possible ? En résumé, tout élément porteur d’un attribut id devient mécaniquement une propriété globale de l’objet window, et devient donc accessible directement par son nom. C’est spécifié sous le joli nom de Named Access on Window Object (en anglais).</p> <p>C’est drôlement pratique, non ? Figurez-vous que c’est aussi un vecteur d’attaque méconnu faisant partie d’un groupe sobrement intitulé DOM clobbering (en anglais). Je vous encourage à parcourir les recommandations de l’OWASP pour mitiger le DOM clobbering (en anglais).</p> <h4> Accessibilité </h4> <p>La méthode showModal() permet d’ouvrir une fenêtre modale, pas une simple boîte de dialogue — en respectant les exigences en matière d’accessibilité : la focus est mécaniquement piégé dedans, la fermeture est possible avec la touche <kbd>Échap</kbd>, etc.</p> <h3> L’arrière-plan </h3> <p>Une fois la fenêtre modale ouverte, on peut s’appliquer à la styler. Là où moult bibliothèques de composants imposent une <div> (voire plusieurs) pour servir d’arrière-plan à la fenêtre, la version native est livrée avec un pseudo-élément ::backdrop qui s’étend naturellement sur tout le viewport et est promue, avec la fenêtre modale, par-dessus le reste de la page dans ce qui est spécifié sous le nom de top layer. <p>Vous n’avez plus qu’à lui appliquer une couleur, une opacité ou que sais-je encore. Dans le jeu, j’ai utilisé une propriété au nom évocateur de backdrop-filter pour appliquer un effet de flou grisé sur l’arrière-plan.<br> </p> <pre class="brush:php;toolbar:false">dialog::backdrop { backdrop-filter: grayscale(50%) blur(.25rem); }
雖然囉嗦,但確實有效!
想想我暫時只討論了 HTML 和 CSS...我不會詳細討論,但在 JavaScript 方面,我對 Web 感到(有點太多)樂趣成分。總結一下:
在所有這一切中,我玩了很多mutationObservers、間隔和計時器、表情符號和隨機值生成。
如果所有這些東西讓您感到好奇,我邀請您訪問 GitHub 上的遊戲儲存庫並用它做您想做的事情!
如果您開始玩遊戲,我邀請您查閱遊戲附帶的幻燈片。隨著您的進步,您會看到每個變種人都有自己的幻燈片。不要前進得太快,因為下一張幻燈片給了答案......
打開你的檢查員!
本文是「Advent of Tech 2024 Onepoint」的一部分,這是 Onepoint 在聖誕節前夕發布的一系列技術文章。
查看 2024 年科技降臨的所有文章。
以上是「突變 HTML 入侵」背後的秘訣的詳細內容。更多資訊請關注PHP中文網其他相關文章!