传统浏览器中的 HTML 表单

所有 Web 开发者都很快(有时是痛苦地)意识到,Web 对他们来说是一个非常残酷的地方。我们最大的诅咒是传统浏览器。这曾经意味着“Internet Explorer”,但现在有数百万人在使用旧设备,尤其是手机,这些设备既无法更新浏览器也无法更新操作系统。

处理这个“荒野”是工作的一部分。幸运的是,有一些技巧可以帮助你解决传统浏览器引起的大部分问题。如果浏览器不支持 HTML <input> 类型,它不会报错:它只是使用 type=text 的默认值。

了解这些问题

要理解常见的模式,阅读文档会有帮助。如果你正在 MDN 上阅读本文,那么你已经找到了正确的起点。只需检查你想要使用的元素(或 DOM 接口)的支持情况。MDN 为网页中可以使用的大多数元素、属性和 API 提供了兼容性表格。

因为 HTML 表单涉及复杂的交互,所以有一条重要的规则:保持简单,也称为“KISS 原则”。在很多情况下,我们希望表单“更美观”或“具有高级功能”,但构建高效的 HTML 表单并非设计或技术问题。相反,它关乎简洁、直观和易于用户交互。教程《UX For The Masses 上的表单可用性》很好地解释了这一点。

优雅降级是 Web 开发者最好的朋友

优雅降级和渐进增强是开发模式,它们允许你在同时支持各种浏览器的同时构建出色的东西。当你为现代浏览器构建东西,并希望它以某种方式在传统浏览器上也能工作时,你正在执行优雅降级。

让我们看一些与 HTML 表单相关的例子。

HTML 输入类型

所有 HTML 输入类型都可以在所有浏览器中使用,甚至是旧浏览器,因为它们的降级方式是高度可预测的。如果浏览器不知道 <input> 元素的 type 属性值,它将回退到值是 text 的情况。

html
<label for="myColor">
  Pick a color
  <input type="color" id="myColor" name="color" />
</label>
支持的 不支持的
Screen shot of the color input on Chrome for macOS Screen shot of the color input on Firefox for macOS

表单按钮

在 HTML 表单中定义按钮有两种方式

<input>

如果你想使用元素选择器来应用一些 CSS,<input> 元素可能会让事情变得有点困难

html
<input type="button" value="click me" />

如果我们移除所有输入框的边框,我们可以使用全局 CSS revert 值只恢复输入按钮的默认外观。

css
input {
  /* This rule turns off the default rendering for the input types that have a border,
     including buttons defined with an input element */
  border: 1px solid #cccccc;
}
input[type="button"] {
  /* Revert the last border declaration */
  border: revert;
}

限制传统浏览器中的样式

传统浏览器中 HTML 表单的一个大问题是用 CSS 为它们设置样式。正如其他地方所介绍的,你可以声明 appearance: none; 来移除默认样式并在其基础上构建你自己的样式。然而,传统浏览器比现代浏览器更不可能支持本模块前面介绍的样式技术。如果你需要支持传统浏览器,最好让表单控件在传统浏览器中保持无样式。有关检测特定输入类型支持的建议,请参见下一节。

如果你必须修改传统浏览器中表单小部件的默认样式,请定义样式指南以确保所有表单控件之间的一致性,从而不破坏用户体验。你还可以研究一些高难度技术,例如使用 JavaScript 重建小部件,但这可能得不偿失。

特性检测和 Polyfill

CSS 和 JavaScript 是很棒的技术,但重要的是要确保你不会破坏传统浏览器。在使用你所针对的浏览器中未完全支持的功能之前,你应该进行功能检测。

CSS 特性检测

在为替换的表单控件小部件设置样式之前,你可以检查浏览器是否支持你计划使用的功能 @supports

css
@supports (appearance: none) {
  input[type="search"] {
    appearance: none;
    /* restyle the search input */
  }
}

appearance 属性可用于使用平台原生样式显示元素,或者,如使用 none 值所示,移除默认的平台原生样式。

JavaScript 表单输入检测

你可以使用 JavaScript 来检测是否支持特定的输入类型。这是基于我们之前提到的事实——在不支持的浏览器中,所有输入类型都会回退到 <input type="text">

定义一个测试函数。函数体的第一行应该创建一个测试 <input> 元素。接下来,将其 type 属性设置为你想要测试的类型。最后,测试 type 属性值。在不支持该输入类型的浏览器中,最后一行将不起作用,并且 type 将返回为 text。在下面这行中,我们使用否定运算符 (!) 反转了返回值,因为如果 type 不是 text,则该类型受支持,因此我们希望返回 true。完整的函数如下所示

js
function testDatetimeLocalSupport() {
  const testInput = document.createElement("input");
  testInput.setAttribute("type", "datetime-local");
  return testInput.type !== "text";
}

以上例子展示了此类测试的基本思想。然而,与其重新发明轮子,不如使用功能检测库来处理此类测试。

根据测试结果,你可以选择使用 JavaScript 为不受支持的类型构建自定义替代方案,或者不应用为不受支持的类型设置样式的样式表,因为你希望为传统浏览器提供简单的默认样式。

无侵入式 JavaScript

最大的问题之一是 API 的可用性。因此,使用“无侵入式”JavaScript 被认为是最佳实践。它是一种定义了两个要求的开发模式

  • 结构和行为之间严格分离。
  • 如果代码中断,内容和基本功能必须仍然可访问和可用。

无侵入式 JavaScript 的原则(最初由 Peter-Paul Koch 为 dev.opera.com 撰写)很好地描述了这些思想。

注意性能

尽管有些 Polyfill 非常注重性能,但加载额外的脚本会影响应用程序的性能。这对于传统浏览器尤其关键;许多传统浏览器都有非常慢的 JavaScript 引擎,这会使所有 Polyfill 的执行对用户来说很痛苦。性能本身就是一个主题,但传统浏览器对它非常敏感:基本上,它们很慢,它们需要的 Polyfill 越多,它们需要处理的 JavaScript 就越多。因此,与现代浏览器相比,它们的负担是双重的。使用传统浏览器测试你的代码,看看它们的实际表现如何。有时,放弃一些功能比在所有浏览器中都拥有完全相同的功能能带来更好的用户体验。最后提醒一句,请始终考虑最终用户。

总结

正如你所看到的,考虑浏览器和操作系统的默认表单控件外观非常重要。有许多技术可以处理这些问题;然而,掌握所有这些技术超出了本文的范围。基本前提是在着手挑战之前,先考虑修改默认实现是否值得。

如果你阅读了这份HTML 表单指南的所有文章,现在你应该可以轻松使用表单了。如果你发现新的技术或提示,请帮助改进这份指南。