Tailwind CSS has a Peer marker that can play tricks like moving label in and out of the input box of a form according to placeholder's different state, it works magic without any JavaScript coded behind.
A login form with a username and an email fields, e.g. the label for each input field is shown inside the input box initially, when the input box gets focused, the label moves smoothly to the outside of the box.
Note: I used online HTML entity encoder to get the following encoded <form> code
<form action=""
class="relative border-8 border-neutral-900 p-6 rounded-lg grid gap-6 md:flex-1 md:max-w-lg my-4 md:my-12 lg:my-16 bg-white dark:bg-neutral-900">
<h2 id="contact" class="font-bold text-3xl">let's connect!</h2>
<div class="relative">
<input type="text" id="name"
class="peer w-full placeholder-transparent rounded-md border-amber-400 border-4 focus:outline-none focus:ring-0 focus:ring-offset0-0 focus:border-amber-400 "
placeholder="Your Name">
<label for="name"
class="absolute left-3 -top-6 text-amber-400 peer-placeholder-shown:top-2 peer-placeholder-shown:text-neutral-300 peer-focus:-top-6 duration-300">Your
name</label>
</div>
<div class="relative">
<input type="text" id="email"
class="peer w-full placeholder-transparent rounded-md border-amber-400 border-4 focus:outline-none focus:ring-0 focus:ring-offset0-0 focus:border-amber-400 "
placeholder="Your Name">
<label for="email"
class="absolute left-3 -top-6 text-amber-400 peer-placeholder-shown:top-2 peer-placeholder-shown:text-neutral-300 peer-focus:-top-6 duration-300">Email
Address</label>
</div>
</form>
As the code suggests, a previous sibling tag, here is the
<input>
field, has a 'peer' marker, the following
<label>
tag can define some actions based on this 'peer' marker state.
For this example, <label>
tag will change position and color based on if the <input>
field has placeholder shown or not.
Within <input>
tag, there is a placeholder defined, and a 'placeholder-transparent' class is added so that it is invisible to users. Therefore when the page is loaded initially, the placeholder-shown modifier is true. In the <label>
tag, 'peer-placeholder-shown:' state defines how the label is shown in terms of its position and color. This is the position and color a user can see initially when the page is loaded.
Once the <input>
field is in focus state by moving cursor into the <input>
field and click, the 'peer-placeholder-shown' modifier should be false, then the label's position and color will change to '-top-6', with the help of 'duration-300' class, the transition of the label's position is smooth like in an animation. In the meantime, the color of label is updated to 'text-neutral-300' class as well.
For a better UI experience, add 'peer-focus:-top-6' state modifier to make the label move out of the input box once the box is in focus. After a user started to type into the box, the 'placeholder-shown' will turn to be false, the label color should change back to amber-400.
Now, let's see how to add a textarea in the form.
It's mostly the same as input box and its label decorations, except two things that's worth mentioning:
1. Use 'resize-none' to remove the left-bottom corner default resizing button.
2. This one is bit tricky. If textarea beginning and ending tags are in the same line, the placeholder is shown, like this: <textarea></textarea>, which leaves no space in between the tags. If the ending tag is in the next line, then the 'placeholder-shown' state is false, because a newline character is there inside the textarea that prevent the placeholder to be in 'shown' state.
<div class="relative">
<textarea name="content" id="content" cols="20" rows="5" class="peer w-full rounded-md border-amber-400 border-4 focus:outline-none focus:ring-0 focus:ring-offset0-0 focus:border-amber-400 resize-none placeholder-transparent" placeholder="How can we help?"></textarea>
<label for="content" class="absolute left-3 -top-6 text-amber-400 peer-placeholder-shown:top-2 peer-placeholder-shown:text-neutral-300 peer-focus:-top-6 duration-300">How can we help?</label>
</div>
Now, let me add a button with a link tag, the form is all done.
<a href="#"
class="px-6 py-2 bg-amber-400 rounded-md hover:ring-4 ring-neutral-900 ring-offset-4 shadow-lg w-max">Sign Up</a>
This is the form when just loaded up.
This is the form when a user types into the input field.
I find this feature is worth mentioning because at first I had some difficulties to fully understand the mechanism behind this intriguing transition. The main point here is to understand 'peer-placeholder-shown' can be used when the <input>
field has placeholder attribute, then to use its label content as the placeholder content, and to style it as 'peer-placeholder-shown:' defines. By doing so, a beautifully animated floating label can be added to a form purely by Tailwind CSS.