Build an input with Icon using TailwindCSS
[00:00] Now, I have built inputs with icons before, but they were missing two things, one of which is quite important. The first thing was I didn't know how easy it is to change the icon color when the user focused the input. The second, and more important one, I didn't know how to focus the input when the user clicked directly on the icon. Previously you had to move the cursor a bit to the right and click on the field itself in order to focus it.
[00:26] Anyway let's get started. I will add the form element, with an input, and then change this
justify-end class to
justify-between so that the form gets pushed to the left and this drop down menu stays on the right. The input name will be "search", the placeholder will be "search talk", autocomplete will be turned off, and we're going to label it "search talk".
[01:01] To style it, we'll do class
px-3 py-2 for padding,
font-semibold to make the text thicker,
placeholder-gray-500 text-black rounded-2xl to make it rounded, I'll disable the border using
border-none, and then use
ring-2 ring-gray-300, and on focus we'll do
focus:ring-gray-500 focus:ring-2. So this will be our basic input.
[01:33] For the icons I mostly use heroicons which comes with an npm package you can install. So I'll do just that; open the terminal and run npm install
@heroicons/vue. Now I can import the icon I want to use, in this case I want to import the search icon, and then register it and use it just like I'd use a regular component. So here I can just say search icon and give it a class
[02:27] In order to place the icon over the input element we'll have to position it as an absolute element but that also means we'll need a relative wrapper to keep it from floating around all over the screen, so let's wrap these two elements into a div and say class relative, and then for the search icon we have
w-5 h-5 absolute and then give it some margin left say
ml-3. Now to center the icon vertically, we can use
flex on the wrapper, so here we'll say
[03:06] And since we are here, we can set the icon color to
text-gray-400 and the reason I'm doing this here instead of doing directly on the icon is because we can now use the
focus-within variant to set the color when a child element is focused, in our case when the input is focused. So we'll do
focus-within, and then
text-gray-600 and now when I focus the field, the color of the icon changes.
[03:41] Moving on, let's add some left padding for the input to stop the icon from overlapping the text so we'll do
pr-3 and then
pl-10. This will move the text to the right.
[03:54] For the last problem, the input doesn't focus if we click directly on the search icon. We need to click slightly through the right or slightly to the left in order to focus it. To fix that we can add the
pointer-events-none class on the icon so we can do
pointer-events-none, and what this does is it tells the browser that this icon should ignore pointer events; it's like the element is not even there. So now if we hover over the icon you'll see the text cursor appearing and when we click, the input gets focused. So that's the only thing we need to do.
[04:34] Finally, let's make the input a bit wider. We can do that by setting
w-full on the input element,
w-full on the form element, and then constraint it using
max-w-md. Also let's add some spacing between the search input and the dropdown menu, and we can do that either by setting individual margin classes for both elements, or by using a space utility on their parent. I prefer the latter, so we'll do
space-x-6, save, and here it is.