DEV Community

Cris Acosta
Cris Acosta

Posted on • Updated on

Create a floating label using Tailwind

So lately Tailwind has created a lot of controversy in the dev community but I am not here to talk about that. I am here to share the knowledge I that stumbled upon from our ever-so-reliable source of the latest news and memes in the tech world - Twitter tech - and that is on how to create floating labels using Tailwind.

Prerequisites:
If you are reading this, it is assumed that you already have the foundational knowledge of HTML and CSS and have dabbled with Tailwind's utility classes. Nevertheless, I will do my best to make this as beginner-friendly as possible.

TL;DR? Just scroll all the way to step 3 for the final code and the demo link.

Let's get started.

First, create our basic form layout and our default styles.

<div class="w-full">
      <div class="text-center">
        <h1 class="text-3xl font-semibold text-gray-900">Sign in</h1>
        <p class="mt-2 text-gray-500">Sign in below to access your account</p>
      </div>
      <div class="mt-5 max-w-md">
        <form action="">
          <div class="relative mt-6">
            <!-- Floating lable will not work -->
            <label for="email" class="absolute left-0 ml-1 -translate-y-3 bg-white px-1 text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-0 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 peer-focus:ml-1 peer-focus:-translate-y-3 peer-focus:px-1 peer-focus:text-sm">EMAIL</label>
          </div>
            <input type="email" class="peer w-full border-b placeholder:text-transparent" placeholder="name" />

          <div class="relative mt-6">
            <input type="password" class="peer w-full border-b placeholder:text-transparent" placeholder="name" />
            <label for="email" class="absolute left-0 ml-1 px-1 -translate-y-3 bg-white text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-0 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 peer-focus:ml-1 peer-focus:-translate-y-3 peer-focus:px-1 peer-focus:text-sm">PASSWORD</label>
          </div>
          <button class="mt-10 w-full rounded-md bg-slate-600 py-2 px-5 text-white">Submit</button>
        </form>
      </div>
    </div>
Enter fullscreen mode Exit fullscreen mode

What's happening here?!

  • peer class marker in the input elements allows you to modify the style of the sibling element that immediately follows it based on its state.
  • To create a floating label we need to make it so that the label text itself is sitting on top of the input element. To achieve that, we create a div element with a relative position to contain the input and label elements and add then a position absolute on the label element.

Second. Create the a pseudo-placeholder with label element.

  • Since we are using the label text as the "pseudo-placeholder", will make the actual input placeholder transparent.
  • Into the label's class attributes, add the peer-placeholder-shown: while input element is not focused e.i the placeholder is still is shown(make sure that you added a placeholder to your input elements) and reset the label's positioning.
<div class="w-full">
      <div class="text-center">
        <h1 class="text-3xl font-semibold text-gray-900">Sign in</h1>
        <p class="mt-2 text-gray-500">Sign in below to access your account</p>
      </div>
      <div class="mt-5 max-w-md">
        <form action="">
          <div class="relative mt-6">
            <input type="email" class="peer w-full border-b placeholder:text-transparent" placeholder="name" />
            <label for="email" class="absolute left-0 ml-1 -translate-y-3 bg-white px-1 text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-0 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 ">EMAIL</label>
          </div>
          <div class="relative mt-6">
            <input type="password" class="peer w-full border-b placeholder:text-transparent" placeholder="name" />
            <label for="email" class="absolute left-0 ml-1 px-1 -translate-y-3 bg-white text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-0 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 ">PASSWORD</label>
          </div>
          <button class="mt-10 w-full rounded-md bg-slate-600 py-2 px-5 text-white">Submit</button>
        </form>
      </div>
    </div>

Enter fullscreen mode Exit fullscreen mode

Third. Add the styles to float up the label element as soon as the input element is in focus using peer-focus: class modifier.


<div class="w-full">
      <div class="text-center">
        <h1 class="text-3xl font-semibold text-gray-900">Sign in</h1>
        <p class="mt-2 text-gray-500">Sign in below to access your account</p>
      </div>
      <div class="mt-5 max-w-md">
        <form action="">
          <div class="relative mt-6">
            <input type="email" class="peer w-full border-b placeholder:text-transparent" placeholder="name" />
            <label for="email" class="absolute left-0 ml-1 -translate-y-3 bg-white px-1 text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-0 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 peer-focus:ml-1 peer-focus:-translate-y-3 peer-focus:px-1 peer-focus:text-sm">EMAIL</label>
          </div>
          <div class="relative mt-6">
            <input type="password" class="peer w-full border-b placeholder:text-transparent" placeholder="name" />
            <label for="email" class="absolute left-0 ml-1 px-1 -translate-y-3 bg-white text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-0 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 peer-focus:ml-1 peer-focus:-translate-y-3 peer-focus:px-1 peer-focus:text-sm">PASSWORD</label>
          </div>
          <button class="mt-10 w-full rounded-md bg-slate-600 py-2 px-5 text-white">Submit</button>
        </form>
      </div>
    </div>

Enter fullscreen mode Exit fullscreen mode

Viola! You got a floating label made with Tailwind!

CAVEAT: The element with the peer marker must always precede the immediate sibling element you want to style based on the state of the immediate former sibling element otherwise it won't work.

<div class="w-full">
      <div class="text-center">
        <h1 class="text-3xl font-semibold text-gray-900">Sign in</h1>
        <p class="mt-2 text-gray-500">Sign in below to access your account</p>
      </div>
      <div class="mt-5 max-w-md">
        <form action="">
          <div class="relative mt-6">
            <!-- Floating lable will not work -->
            <label for="email" class="absolute left-0 ml-1 -translate-y-3 bg-white px-1 text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-0 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 peer-focus:ml-1 peer-focus:-translate-y-3 peer-focus:px-1 peer-focus:text-sm">EMAIL</label>
          </div>
            <input type="email" class="peer w-full border-b placeholder:text-transparent" placeholder="name" />

          <div class="relative mt-6">
            <input type="password" class="peer w-full border-b placeholder:text-transparent" placeholder="name" />
            <label for="email" class="absolute left-0 ml-1 px-1 -translate-y-3 bg-white text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-0 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 peer-focus:ml-1 peer-focus:-translate-y-3 peer-focus:px-1 peer-focus:text-sm">PASSWORD</label>
          </div>
          <button class="mt-10 w-full rounded-md bg-slate-600 py-2 px-5 text-white">Submit</button>
        </form>
      </div>
    </div>

Enter fullscreen mode Exit fullscreen mode

I hope this has been useful to you. Happy coding!

Try it yourself: https://play.tailwindcss.com/0bqZmoeIzx

Follow me on Twitter: [https://twitter.com/developing_Dev]
Credit:
Thanks to Surjith S M ✪
twitter: @surjithctly
for sharing this knowledge on twitter.

Sources:
https://tailwindcss.com/docs/hover-focus-and-other-states
https://tailwindcss.com/docs/hover-focus-and-other-states#disabled

Top comments (0)