使用 CSS 实现浮动标签

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您的旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费额度!

您可能已经看到这种模式在流行。 它是一个输入,看起来像是带有占位符文本,但当您单击/点击该输入时,该文本会让路,让您在其中输入。 我认为它相当聪明。 Brad Frost 有 一篇关于它的非常好的文章,详细介绍了优缺点等等。

我看到过许多演示都涉及 JavaScript。 几天前,我在 Nest.com 结账时,看到了他们使用这种技术的方法,我想到了一个无需 JavaScript 就可以实现该方法的方法。 所以我们在这里。

以下是 Nest.com 的外观

这是我的看法

它不像 Nest 的那样性感,因为标签向上滑动时文本会逐渐消失。 当然,可以使用一些 JavaScript 实现,但我们将在本文中坚持使用纯 CSS。 尽管如此,这仍然可能实现。 我将把这个挑战留给您。

一些快速提醒

您可能考虑执行此操作有两个原因

  1. 它可能会节省空间。 由于输入和标签合并在一起,因此它占用的空间更少。 当输入处于焦点时,您仍然需要同时显示标签和输入,但您可以通过使用输入已经使用的一些空间或仅针对处于焦点的输入暂时扩展该区域来获得该空间。
  2. 它使输入成为一个大按钮。 这并非说输入本身不是按钮,也并非说标签在拥有适当的 for 属性时不是按钮,但一个大的矩形可以告诉您它想要的东西,您只需点击/点击它,这感觉有点好。 特别是在移动设备上,这可能是一种不错的体验。

我认为,通常情况下,始终可见的标签可能“更好”——但这是一个聪明的想法,如果做得正确,可能会在某些情况下有用。 这也总是存在搞砸并影响可访问性的风险,因此请小心。 这种模式的一个缺点是:我们不能在标签之外使用 placeholder,这可能会有所帮助(例如,标签为“电话号码”,占位符提示为“(555) 555-5555”)。

技巧 (1/3) – 标签即占位符

有一个 <div> 包含 <label><input> (无论如何都需要这样做,因为表单中的输入需要位于块级元素中),它具有相对定位。 这允许在其中使用绝对定位,这意味着我们可以将标签和输入定位在彼此之上。 如果我们这样做,将输入放在上面,但使用透明背景,您将能够看到下面的标签,同时仍然可以单击它。

<div>
  <input id="name" name="name" type="text" required>
  <label for="name">Your Name</label>
</div>
form > div {
  position: relative;
}
form > div > label {
  position: absolute;
}

技巧 (2/3) – :focus 状态和相邻同级组合器

<label><input> 的源代码顺序在这里关系不大,因为它们在语义上与 for 属性绑定在一起。但如果我们将输入放在前面,这意味着我们可以利用它的 :focus 状态和相邻同级组合器 (+) 来影响标签的焦点状态。 类似于 复选框黑客 的概念。

input:focus + label {
  /* do something with the label */
}

您可以对标签执行任何操作。 只需找到一个酷炫的位置将其移动并进行样式设置,使其不会影响在输入中键入。 我的示例有两个可能性:一个是使其变小并移向输入的底部,另一个是将其移到最右侧。

form.go-bottom label {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  transition: 0.2s;
}
form.go-bottom input:focus + label
  top: 100%;
  margin-top: -16px;
}

技巧 (3/3) – :valid 状态

当输入中有实际文本,并且输入再次失去焦点时,看到标签和输入文本重叠在一起会非常奇怪(糟糕)。 幸运的是,CSS 中有一个 :valid 选择器,当输入处于有效状态时,它会在输入上生效。 该有效状态可以是“任何文本”,假设使其有效的唯一条件是具有任何值,这可以通过以下方法实现

<input type="text" required>

然后记住,您能够看到标签的唯一原因是输入具有透明背景。 要隐藏它,我们可以使用不透明背景代替

form input:valid {
  background: white;
}

其余部分只是调整设计细节,直到您满意为止。

更多

这个想法 最初来自 Matt D. Smith,他的设计如下

2018 年更新 - 使用 :placeholder-shown

:placeholder-shown 选择器 在本文最初撰写时并不存在。 Emil Björklund 重新讨论了这个话题,因为它现在已经存在。