使用 HTML 和 CSS 构建交互式登录表单

2025-05-24

使用 HTML 和 CSS 构建交互式登录表单

Darin Senneff 创建的 Yeti 登录表单非常棒,和他构建的大多数东西一样,一直是我的灵感源泉:

Darin Senneff 的登录表单

以前,我曾使用 HTML、CSS、SVG 和 JavaScript 创建过这个动画登录表单。但由于我使用了纯 CSS 来为 SVG 制作动画(而不是添加GreenSock),而且并非所有浏览器都支持 GreenSock,所以动画效果有些不流畅。

经过几周异常忙碌的工作后,昨天我终于抽出时间进行了一些有趣的开发。我决定尝试使用 HTML 和 CSS 来开发这个交互式表单的另一个版本,完全不使用任何 SVG 或 JavaScript。

如果您想要一个类似的教程,但使用 JavaScript,请不要错过“如何构建交互式表单”系列,其中我将逐步解释如何使用 HTML、CSS 和 JS 构建像这样的表单。

不使用 JavaScript 或 SVG 的限制使其更具挑战性,并看看它是否可行(剧透警告:有点可行,但有一些限制),并在构建它时学习新的东西。

结果如下

第一步是创建一个简单的表单,其中包含我想要的元素,顺序如下:

  • 人物形象(仅需简单的 CSS)
  • 用户名/电子邮件文本字段(标签+输入)
  • 密码文本字段(标签+输入)
  • 显示密码复选框(输入+标签)
  • 提交按钮
  • 忘记密码链接

我拥有了没有动画或交互性的表单的主要结构...然后乐趣就开始了。

组织元素

在我之前的表单中,交互是通过 JavaScript 处理的。没有 JavaScript 意味着我必须使用字段中的信息来制作图像动画……这意味着我必须稍微重构一下代码。

CSS 图像不能再放在顶部了,因为它需要字段的值来更新其状态。即使显示在顶部,它也需要位于代码的底部。为此,我可以尝试使用FlexBoxGrid 等不同的方法。

我选择了 FlexBox - 事后看来,它可能不是最好的选择 - 并使用该order属性对元素进行重新排序。

因此,图像移到了底部,“显示密码”按钮移到了密码顶部。order应用了一些值,我必须调整tabindex元素,使它们的键盘顺序与显示顺序一致(这稍后会引起一些可访问性问题)。

最终订单如下:

  • 用户名/电子邮件文本字段
  • 显示密码复选框
  • 密码文本字段
  • 提交按钮
  • 忘记密码链接
  • 人物形象

动画图像

现在所有元素都已到位,并且 CSS 人物已绘制完毕,我可以为其添加一些动画。

一个简单的方法是让它眨眼:它不依赖于任何其他东西,考虑到眼睛是圆形的,为了模拟眨眼,我们将眼睛的高度从原始值改为 0,然后再改回原始值。像这样(简化):



@keyframes blink {
  0%, 90%, 100% {
    height: 0.625rem;
  }
  95% {
    height: 0;
  }
}

.eyes {
  animation: blink 5s infinite;
}


Enter fullscreen mode Exit fullscreen mode

这很简单。接下来是嘴巴。角色的眼睛里总是带着一丝微笑,但为了表示所有字段都正确,它笑得更灿烂一些。

为了实现这一点,我使用 HTML 验证(见下文)并将其与选择器:valid/结合起来:invalid

嘴巴是元素的底部边框。为了使其更大,我调整了该元素的宽度和高度(以及位置)。代码简化:



.mouth {
  border: 0.125rem solid transparent;
  border-bottom: 0.125rem solid #422;
  border-radius: 50%;
  transition: all 0.5s
}

/* invalid: smile... but not too much */
form:invalid .mouth {
  top: 75%;
  left: 50%;
  width: 25%;
  height: 10%;
}

/* valid: big smile by expanding size */
form:valid .mouth {
  top: 60%;
  left: 50%;
  width: 40%;
  height: 40%;
}


Enter fullscreen mode Exit fullscreen mode

不幸的是,:valid/:invalid伪类不能很好地与 IE 和 Edge 中的表单配合使用......这限制了演示的范围。

一个额外的动画是,当勾选“显示密码”字段时,角色会闭上眼睛。我还可以添加一些更精致的动画(比如让双手上下移动),但我将留待以后改进。

隐藏密码

让文本从普通文本变为星号再变回来是最棘手的功能。我本来可以发誓用 就能实现text-transform,但事实并非如此。

有一个非标准-webkit-text-security属性允许开发者实现这一点。但它只适用于 WebKit 浏览器。这是一个测试,所以我尝试了一下(代码已简化):



/* show the text field as asterisks in normal mode */
input[name="password"] {
  -webkit-text-security: disc;
}

/* if show password is checked, show the actual text */
input[name="show-password"]:checked ~ input[name="password"] {
  -webkit-text-security: none;
}


Enter fullscreen mode Exit fullscreen mode

这确实有效。但在开发表单的所有技巧中,这可能是唯一一个我肯定会用 JavaScript 替换的,因为它大大减少了表单的支持。

颜色和主题

如今,能够改变组件和站点的颜色是一项主要功能……为什么不将它添加到我的演示中呢?

我没有使用颜色、阴影或大小的固定值,而是在更高级别(表单标签)定义CSS 变量并在其中包含的元素中重复使用它们。

对于颜色,我选择了HSL 格式。在 HSL 中,你可以定义颜色的色相、饱和度和亮度,这对于创建阴影非常方便……并且与 CSS 变量和函数结合使用时功能非常强大。

hsl()/函数hsla()允许 CSS 变量和其他函数(尤其是calc())作为参数。因此,我们可以定义默认颜色,并根据不同的状态设置不同的色调。

在这个例子中,我们使用深蓝色作为按钮的背景,而对于悬停状态,我们使用相同颜色的 20% 暗色调:



form {
  /* default color: dark blue in HSL */
  --colorH: 210;
  --colorS: 50%;
  --colorL: 38%;
}

/* the button will be dark blue by default */
form button {
  background: hsl(
                   var(--colorH), 
                   var(--colorS), 
                   var(--colorL)
                 );
}

form button:hover {
  /* 20% darker using calc */
  background: hsl(
                   var(--colorH), 
                   var(--colorS), 
                   calc(var(--colorL) * 0.8)
                 );
}


Enter fullscreen mode Exit fullscreen mode

这是一个屏幕截图,您可以看到改变色调值如何改变表单中使用的调色板:

通过改变变量来改变颜色的屏幕截图

构建表单不需要玩颜色和 HSL,但这很有趣。

表单验证

对于这一点,我没有让自己复杂化:删除所有 JavaScript 验证,并使用标准 HTML5 验证将其委托给浏览器:

  • 该字段是必填项吗?请required为其添加属性。
  • 是邮箱/密码/电话/颜色/等等吗?请使用正确的输入type
  • 它需要遵循特定的结构吗?使用pattern

这只是一个演示。如果是更重要的事情,或者需要投入生产,我会在 HTML 验证的同时使用 JS。但在本例中,目标是避免使用 JavaScript,所以……

浏览器兼容性问题

使用Brave(基于Chrome的浏览器)完成开发后,我发现了一些问题:

  • 显示/隐藏密码(我使用的-webkit-text-security)。
  • IE/Edge 中表单级别的:valid/问题。:invalid

尽管如此,我继续在不同的浏览器上测试,发现了一个新问题。耶!Safari 似乎在动画中使用的单位有问题。通过将 替换为相应的rem单位,问题得到了解决rempx

可访问性问题

说实话,考虑到我当时正在调整 Flex 的排序和样式,我本来没指望登录表单能做到无障碍访问。但经过一些测试后,结果比我最初预想的要好得多。

例如,如果页面加载时没有样式,则登录表单如下所示:

无样式的登录表单

标签文本出现在其字段之后——这很奇怪,但仍然可以理解——而“显示密码”字段出现在该字段之前。这也很常见(毕竟 Senneff 的表单也把它放在了顶部。)

运行自动化可访问性测试的结果也还不错。Wave只发现了三个问题(与 相关tabIndex),而aXe检测到了标签的对比度问题(在静止模式下有效,但在悬停或活动模式下无效)。

运行 WebAIM Wave 的结果

之后,我还尝试与键盘进行交互并使用几个屏幕阅读器(VoiceOverChromeVox)。

Chrome(根据最新的 WebAIM 调查,它是使用最广泛的浏览器)的结果是积极的:按顺序浏览字段,并且即使代码中的顺序与屏幕上的顺序不匹配,屏幕阅读器也能正确读取所有内容。

Safari 不太成功,并且在关注复选框时出现一些问题(这个问题似乎很常见,而且不仅仅出现在我的表单上......但这不是重点。)


我不会在实际生产环境中(完全)使用这个表单,因为有些功能(例如密码显示/隐藏、表单有效性)并非所有浏览器都支持(IE 和 Edge 是主要问题)。不过开发它还是一次不错的尝试。

在此过程中,我练习了一些 FlexBox,使用了一些有趣的选择器和伪类,了解了-webkit-text-security(感谢Chris Coyier 在 CSS-Tricks 上的帖子)......这很好。

文章来源:https://dev.to/alvaromontoro/building-an-interactive-login-form-with-html-and-css-1i2n
PREV
使用 CSS 垂直和水平居中
NEXT
在 CSS 和 HTML 中构建坐标系统