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中文网其他相关文章!