众所周知,Lingo.dev热爱各种新奇的技术。所以,当我在上一篇文章中看到David 说他很惊讶没有看到"dialog"这个 HTML 元素时,我突然想到------等等,还有这么多 HTML5 元素我们根本不知道!
我们急于拥抱复杂的框架和库,却忽略了 HTML5 中一些最优雅的解决方案。用一个标签就能实现原本需要几十行 JavaScript 才能实现的功能,这其中蕴含着无限的美妙。
最好的代码往往是你无需编写的代码。你有多少次求助于 JavaScript 库来创建模态窗口?或者为可折叠部分编写复杂的 CSS?如果我告诉你,HTML5 已经有原生元素可以实现这些功能,你会怎么想?
这些可不是普通的 HTML 元素,它们会让你不禁想问:"等等,我们一直都可以这样做吗?" 让我们来探索八个你可能没有用到但绝对应该用到的、功能强大的 HTML 元素。
<dialog>
元素:原生模态窗口 想象一下:你正在启动一个新项目,需要添加一个模态对话框。你的第一反应是什么?用 React,找个 UI 库,或者写一堆 JavaScript。我懂------我已经无数次做过同样的事情了。
但 HTML5 有一个专门为此目的而设计的内置元素:
HTML
<dialog id="myDialog">
<h2>This is a Native Dialog</h2>
<p>No JavaScript frameworks required!</p>
<button id="closeDialog">Close</button>
</dialog>
<button id="openDialog">Open Dialog</button>
您仍然需要一些 JavaScript 来处理打开/关闭操作:
JavaScript
const dialog = document.getElementById('myDialog');
document.getElementById('openDialog').addEventListener('click', () => {
dialog.showModal(); // Makes the dialog appear as a modal
});
document.getElementById('closeDialog').addEventListener('click', () => {
dialog.close(); // Closes the dialog
});
浏览器负责处理焦点管理、背景渲染和键盘可访问性。尽管自 2022 年左右以来所有主流浏览器都支持该元素,但与我交流过的大多数开发者从未使用过它。
你可以按照自己想要的方式设计它:
css
dialog {
padding: 20px;
border-radius: 8px;
border: 1px solid #ddd;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
dialog::backdrop {
background-color: rgba(0,0,0,0.6);
}
我已经在生产环境中使用这个库好几年了。主要问题是 iOS Safari 的支持,直到 2023 年才稳定,但现在支持已经很稳定了。对于包含大量交互元素的复杂模态框,你可能仍然需要一个专用的库,但在大多数情况下,原生元素已经足够完美了。
<details>
元素<summary>
:原生手风琴 手风琴面板在网络上随处可见------常见问题解答、产品详情、设置面板等等。大多数开发者会选择 JavaScript 的解决方案,但 HTML5 原生元素可以实现这一点:
HTML
<details>
<summary>Click to expand</summary>
<p>This content can be expanded and collapsed without any JavaScript!</p>
</details>
这就是您所需要的。浏览器会处理切换功能、辅助功能属性和键盘导航。
您可以根据自己的设计系统来设计它:
CSS
details > summary {
list-style: none; /* Removes the default triangle */
}
details > summary::before {
content: '▶';
display: inline-block;
margin-right: 0.5em;
transition: transform 0.2s;
}
details[open] > summary::before {
transform: rotate(90deg);
}
这些元素对于嵌套导航特别有用。我最近在一个文档网站中使用了它们,我们需要三级可折叠导航:
HTML
<details>
<summary>Programming Languages</summary>
<details>
<summary>Frontend</summary>
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</details>
<details>
<summary>Backend</summary>
<ul>
<li>Python</li>
<li>Java</li>
<li>Ruby</li>
</ul>
</details>
</details>
主要的限制在于动画------如果您需要在打开/关闭时实现流畅的动画,则需要添加 JavaScript。但对于许多用例来说,默认行为已经足够了。
<datalist>
元素:原生自动完成 自动完成功能是现代 Web 表单的必备功能。大多数开发人员会寻求第三方解决方案,但 HTML5 内置了此功能:
HTML
<input list="browsers" name="browser" placeholder="Choose a browser">
<datalist id="browsers">
<option value="Chrome">
<option value="Firefox">
<option value="Safari">
<option value="Edge">
</datalist>
这为您提供了一个文本输入,可在您键入时显示建议,并可从列表中选择或输入自定义文本。
一个有趣的用例是创建具有命名颜色的颜色选择器:
HTML
<input type="text" list="colors" placeholder="Choose a color">
<datalist id="colors">
<option value="#FF0000">Red</option>
<option value="#00FF00">Green</option>
<option value="#0000FF">Blue</option>
</datalist>
用户可以输入颜色名称或十六进制代码。添加一些 JavaScript 代码即可显示预览:
JavaScript
const input = document.querySelector('input');
const preview = document.getElementById('colorPreview');
input.addEventListener('input', () => {
preview.style.backgroundColor = input.value;
});
主要的限制在于样式------您无法轻松自定义下拉选项的外观。如果您需要自定义建议的样式,可能仍然需要 JavaScript 解决方案。但对于许多用例来说,原生元素已经足够了。
<meter>
元素:语义测量显示 当显示已知范围内的值时,大多数开发人员会使用带有背景颜色的 div。但 HTML5 有一个专门的元素可以实现这一点:
HTML
<meter value="75" min="0" max="100" low="30" high="70" optimum="80"></meter>
浏览器会根据您设置的阈值来设置样式。如果值处于"低"值范围内,可能会显示为黄色。如果值处于"高"值范围内,可能会显示为橙色。如果值接近"最佳"值,则会显示为绿色。
这对于仪表板特别有用:
HTML
<!-- Disk usage (lower is better) -->
<meter value="75" min="0" max="100" low="70" high="90" optimum="0">75%</meter>
<!-- Battery level (higher is better) -->
<meter value="35" min="0" max="100" low="20" high="60" optimum="100">35%</meter>
<!-- CPU usage (lower is better) -->
<meter value="82" min="0" max="100" low="60" high="80" optimum="0">82%</meter>
该optimum属性表示值越高越好还是越低越好,这会影响颜色。
浏览器支持良好,但样式选项有限。如果您需要高度自定义的外观,可能仍然需要自定义解决方案。但对于仪表板和监控 UI 来说,原生元素效果很好,并且可以向屏幕阅读器传达语义。
<output>
元素:动态计算结果 在构建计算器或交互式表单时,大多数开发人员使用 div 来显示结果。但 HTML5 有一个专门的元素可以实现这一点:
HTML
<form oninput="result.value = parseInt(a.value) + parseInt(b.value)">
<input type="number" id="a" value="0"> +
<input type="number" id="b" value="0"> =
<output name="result" for="a b">0</output>
</form>
for属性在输入和输出之间创建了明确的关系,这有助于屏幕阅读器理解输出是这些特定输入的结果。
去年我在一个副项目中用到了它,做了一个抵押贷款计算器:
HTML
<form id="mortgageCalc">
<div>
<label for="principal">Loan Amount: $</label>
<input type="number" id="principal" value="200000">
</div>
<div>
<label for="rate">Interest Rate: %</label>
<input type="number" id="rate" value="3.5" step="0.1">
</div>
<div>
<label for="term">Loan Term (years):</label>
<input type="number" id="term" value="30">
</div>
<div>
<button type="button" id="calculate">Calculate</button>
</div>
<div>
<p>Monthly Payment: $<output id="payment">954.83</output></p>
<p>Total Interest: $<output id="totalInterest">143,739.01</output></p>
</div>
</form>
主要优势在于语义------屏幕阅读器可以读出该值是计算结果。它也是一个表单元素,因此可以根据需要包含在表单提交中。
<mark>
元素:语义突出显示 在突出显示文本时,大多数开发人员会使用带有背景色的 span。但 HTML5 有一个专门的元素可以实现这一点:
HTML
<p>The <mark>quick brown fox</mark> jumps over the lazy dog.</p>
默认情况下,浏览器采用黄色背景,但您可以自定义它:
CSS
mark {
background-color: #fff9c4;
padding: 2px 4px;
border-radius: 3px;
}
这对于搜索结果特别有用:
JavaScript
const searchTerm = "HTML";
const content = "HTML elements are the building blocks of HTML pages.";
const highlighted = content.replace(
new RegExp(searchTerm, 'gi'),
match => `<mark>${match}</mark>`
);
其优点在于语义意义------屏幕阅读器可以宣布文本被突出显示,让用户更好地理解为什么某些文本脱颖而出。
我发现这在文档站点和知识库中特别有用,突出显示搜索词可以帮助用户快速找到他们正在寻找的内容。
<time>
元素:语义日期和时间 大多数开发人员使用常规文本元素显示日期和时间,但 HTML5 有一个专门的元素用于此:
HTML
<p>The article was published on <time datetime="2025-05-20">May 20, 2025</time>.</p>
该datetime属性允许您以机器可以理解的标准化格式(ISO 8601)指定日期,同时向用户显示人性化的格式。
这对于可以提取准确日期的搜索引擎以及可能想要提供诸如向日历添加事件等功能的浏览器或扩展程序来说非常有用。
您可以将其用于各种日期和时间格式:
HTML
<!-- Just a date -->
<time datetime="2025-05-20">May 20, 2025</time>
<!-- Date and time -->
<time datetime="2025-05-20T14:30:00">2:30 PM on May 20, 2025</time>
<!-- Just a time -->
<time datetime="14:30:00">2:30 PM</time>
<!-- A duration -->
<time datetime="PT2H30M">2 hours and 30 minutes</time>
一个实际应用是相对时间:
HTML
<p>Posted <time datetime="2025-05-18T14:30:00" class="relative-time">2 days ago</time></p>
使用 JavaScript,您可以定期更新这些内容:
JavaScript
function updateRelativeTimes() {
document.querySelectorAll('.relative-time').forEach(el => {
const date = new Date(el.getAttribute('datetime'));
el.textContent = getRelativeTimeString(date);
});
}
// Update every minute
setInterval(updateRelativeTimes, 60000);
此元素对于博客、新闻网站和社交媒体平台尤其有价值,因为准确的日期和时间信息非常重要。
<figure>元素<figcaption>
:语义图像标题 大多数开发人员使用 div 和段落来实现图像标题,但 HTML5 有专门的元素来实现这一点:
HTML
<figure>
<img src="chart.jpg" alt="Sales chart for Q2 2025">
<figcaption>Fig.1 - Company sales increased by 25% in Q2 2025.</figcaption>
</figure>
该<figure>
元素不仅适用于图像 - 它可以用于作为单个单元引用的任何内容:
HTML
<!-- Code snippet with caption -->
<figure>
<pre><code>
function greet(name) {
return `Hello, ${name}!`;
}
</code></pre>
<figcaption>A simple JavaScript greeting function using template literals.</figcaption>
</figure>
<!-- Quote with attribution -->
<figure>
<blockquote>
<p>The best way to predict the future is to invent it.</p>
</blockquote>
<figcaption>--- Alan Kay</figcaption>
</figure>
这些元素对于内容管理系统和博客特别有用,编辑者需要为图像和其他媒体添加标题。
简单的 CSS 设置可以创建一个美观的画廊:
CSS
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
figure {
margin: 0;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
transition: transform 0.3s;
}
figure:hover {
transform: translateY(-5px);
}
figure img {
width: 100%;
height: 200px;
object-fit: cover;
display: block;
}
figcaption {
padding: 10px;
background-color: #f5f5f5;
font-style: italic;
}
主要优点是语义含义------屏幕阅读器可以宣布文本是相关内容的标题,从而提高可访问性。
结论?
拥抱原生 HTML。
我们探索了八个 HTML5 元素,它们为常见的 Web 开发挑战提供了优雅的内置解决方案:
<dialog>
对于原生模态窗口<details>
以及<summary>
可折叠内容<datalist>
用于本机自动完成<meter>
用于语义测量显示<output>
动态计算结果<mark>
用于语义突出显示<time>
用于语义日期和时间<figure>
以及<figcaption>
语义图像标题
这些元素减少了对 JavaScript 的依赖,提高了可访问性,并使您的 HTML 更具语义和意义。
它们并非完美适用于所有用例------构建Lingo.dev通常需要比它们所能提供的更多的自定义或浏览器支持。在没有更好的方案之前,他们仍值得考虑。
参考链接: dev.to/maxprilutsk...
github.com/lingodotdev...
lingo.dev/go/discord