Inputs
Ready to use Tailwind CSS input components with production-ready, copy-paste HTML code. Use them as they are, or as a starting point to build beautiful websites.
Inputs are probably the most used form element in any app or website. We have a solid range here: basic labeled inputs, inputs with hint text or corner hints, error states with red styling, leading and trailing icons, inputs with an inline prefix like a URL slug, a combined input-plus-dropdown, and a few file upload variations including a drag and drop zone. Just wire them up to your form handling.
<div class="mx-auto w-full max-w-xs">
<div>
<label for="email" class="block select-none text-sm font-semibold leading-6 text-gray-900">Email</label>
<input type="email" name="email" id="email" placeholder="[email protected]" autocomplete="email" class="mt-2 w-full rounded-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6" />
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<input type="email" name="email" id="email" placeholder="[email protected]" aria-label="Email" autocomplete="email" class="mt-2 w-full rounded-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6" />
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<label for="email" class="block select-none text-sm/6 font-semibold text-gray-900">Email</label>
<input type="email" name="email" id="email" placeholder="[email protected]" autocomplete="email" aria-describedby="email-description" class="mt-2 w-full rounded-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6" />
<p id="email-description" class="mt-2 text-sm text-gray-500">We don't send spam to our users.</p>
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<div class="flex items-center gap-x-3 justify-between">
<label for="email" class="block select-none text-sm/6 font-semibold text-gray-900">Email</label>
<p id="email-optional" class="text-sm/6 text-gray-500">Optional</p>
</div>
<input type="email" name="email" id="email" placeholder="[email protected]" autocomplete="email" aria-describedby="email-optional" class="mt-2 w-full rounded-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6" />
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<label for="email" class="block select-none text-sm font-semibold leading-6 text-gray-900">Email</label>
<div class="relative mt-2">
<input type="email" name="email" id="email" placeholder="[email protected]" autocomplete="email" aria-invalid="true" aria-describedby="email-error" class="w-full rounded-md border-0 bg-white py-2 pl-3.5 pr-10 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-red-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-red-600 sm:text-sm sm:leading-6" value="name@example" />
<svg aria-hidden="true" class="pointer-events-none absolute right-0 top-1/2 mr-3.5 size-4 -translate-y-1/2 text-red-500" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00094 11.7027H8.00834M8.00094 9.48107C8.66048 8.06942 10.2226 8.17355 10.2226 6.51885C10.2226 5.40802 9.48205 4.29718 8.00094 4.29718C6.85463 4.29718 6.15196 4.96253 5.89281 5.77829M8.00094 14.665C11.6819 14.665 14.6659 11.681 14.6659 7.99996C14.6659 4.31898 11.6819 1.33496 8.00094 1.33496C4.31996 1.33496 1.33594 4.31898 1.33594 7.99996C1.33594 11.681 4.31996 14.665 8.00094 14.665Z" stroke="currentColor" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</div>
<p id="email-error" class="text-sm text-red-600 mt-2">Please enter a valid email address.</p>
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<label for="email" class="block select-none text-sm font-semibold leading-6 text-gray-900">Email</label>
<div class="relative mt-2">
<input type="email" name="email" id="email" placeholder="[email protected]" autocomplete="email" class="w-full rounded-md border-0 bg-white py-2 pl-11 pr-3.5 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6" />
<svg aria-hidden="true" class="pointer-events-none absolute left-0 top-1/2 ml-3.5 size-5 -translate-y-1/2 text-gray-400" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.88867 5.77788L8.39978 9.91116C9.34796 10.6223 10.6516 10.6223 11.5998 9.91116L17.1109 5.77783" stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round" />
<path d="M16.2222 4H3.77778C2.79594 4 2 4.79594 2 5.77778V14.6667C2 15.6485 2.79594 16.4444 3.77778 16.4444H16.2222C17.2041 16.4444 18 15.6485 18 14.6667V5.77778C18 4.79594 17.2041 4 16.2222 4Z" stroke="currentColor" stroke-width="1.67" stroke-linecap="round" />
</svg>
</div>
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<label for="phone" class="block select-none text-sm font-semibold leading-6 text-gray-900">Phone</label>
<div class="relative mt-2">
<input type="tel" name="phone" id="phone" placeholder="+1 (555) 123-4567" autocomplete="tel" class="w-full rounded-md border-0 bg-white py-2 pl-3.5 pr-10 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6" />
<svg aria-hidden="true" class="pointer-events-none absolute right-0 top-1/2 mr-3.5 size-4 -translate-y-1/2 text-gray-400" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00094 11.7027H8.00834M8.00094 9.48107C8.66048 8.06942 10.2226 8.17355 10.2226 6.51885C10.2226 5.40802 9.48205 4.29718 8.00094 4.29718C6.85463 4.29718 6.15196 4.96253 5.89281 5.77829M8.00094 14.665C11.6819 14.665 14.6659 11.681 14.6659 7.99996C14.6659 4.31898 11.6819 1.33496 8.00094 1.33496C4.31996 1.33496 1.33594 4.31898 1.33594 7.99996C1.33594 11.681 4.31996 14.665 8.00094 14.665Z" stroke="currentColor" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</div>
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<label for="website" class="block select-none text-sm font-semibold leading-6 text-gray-900">Website</label>
<div class="mt-2 flex w-full rounded-md shadow-sm">
<div class="shrink-0 rounded-l-md px-3.5 py-2 text-base text-gray-500 ring-1 ring-inset ring-gray-300 sm:text-sm/6">https://</div>
<input type="text" name="website" id="website" placeholder="www.example.com" class="-ml-px w-full flex-1 rounded-r-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6" />
</div>
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<label for="price" class="block select-none text-sm font-semibold leading-6 text-gray-900">Price</label>
<div class="mt-2 flex items-center rounded-md bg-white pl-3.5 shadow-sm ring-1 ring-inset ring-gray-300 has-[input:focus-within]:ring-2 has-[input:focus-within]:ring-inset has-[input:focus-within]:ring-pink-500">
<div class="shrink-0 text-base text-gray-500 sm:text-sm/6">$</div>
<input type="text" name="price" id="price" placeholder="100.00" class="w-full flex-1 border-0 bg-transparent py-2 pl-1 pr-2 text-base text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-0 sm:text-sm sm:leading-6" />
<div class="shrink-0 relative">
<label for="currency" class="sr-only">Currency</label>
<select name="currency" id="currency" class="appearance-none rounded-md border-0 bg-transparent bg-none py-2 pl-3.5 pr-[1.875rem] text-base text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6">
<option value="USD">USD</option>
<option value="GBP">GBP</option>
<option value="EUR">EUR</option>
<option value="JPY">JPY</option>
</select>
<svg class="pointer-events-none absolute right-0 top-1/2 mr-2.5 h-4 w-4 -translate-y-1/2 text-gray-400" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</div>
</div>
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<label for="phone" class="block select-none text-sm font-semibold leading-6 text-gray-900">Phone</label>
<div class="mt-2 flex items-center rounded-md bg-white shadow-sm ring-1 ring-inset ring-gray-300 has-[input:focus-within]:ring-2 has-[input:focus-within]:ring-inset has-[input:focus-within]:ring-pink-500">
<div class="relative shrink-0">
<label for="country" class="sr-only">Country</label>
<select name="country" id="country" class="appearance-none rounded-md border-0 bg-transparent bg-none py-2 pl-3.5 pr-[1.875rem] text-base text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6">
<option value="US">US</option>
<option value="FR">FR</option>
<option value="IT">IT</option>
<option value="DE">DE</option>
</select>
<svg class="pointer-events-none absolute right-0 top-1/2 mr-2.5 h-4 w-4 -translate-y-1/2 text-gray-400" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</div>
<input type="tel" name="phone" id="phone" placeholder="+1 (555) 123-4567" autocomplete="tel" class="w-full flex-1 border-0 bg-transparent py-2 pl-1 pr-3.5 text-base text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-0 sm:text-sm sm:leading-6" />
</div>
</div>
</div>
<div class="mx-auto w-full max-w-md">
<div>
<label for="image-prompt" class="block select-none text-sm font-semibold leading-6 text-gray-900">Image prompt</label>
<div class="mt-2 flex w-full rounded-md shadow-sm">
<input type="text" name="image-prompt" id="image-prompt" placeholder="Describe the image you want to create" class="-mr-px w-full flex-1 rounded-l-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6" />
<button type="button" class="flex shrink-0 items-center gap-x-1 rounded-r-md bg-white px-3.5 py-2 text-sm/6 font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-pink-500">
<svg aria-hidden="true" class="-ml-0.5 size-5" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M10.7666 8.02622C10.8949 7.65497 11.4385 7.65497 11.5668 8.02622L12.3193 10.2054C12.4849 10.6844 12.7639 11.1196 13.1342 11.4766C13.5046 11.8335 13.9561 12.1024 14.4529 12.2619L16.7113 12.9875C17.0962 13.1112 17.0962 13.6355 16.7113 13.7592L14.4517 14.4849C13.955 14.6446 13.5037 14.9137 13.1335 15.2708C12.7634 15.628 12.4846 16.0634 12.3193 16.5425L11.5668 18.7205C11.5392 18.8018 11.4856 18.8726 11.4137 18.9228C11.3419 18.973 11.2554 19 11.1667 19C11.078 19 10.9915 18.973 10.9197 18.9228C10.8478 18.8726 10.7943 18.8018 10.7666 18.7205L10.0142 16.5414C9.84867 16.0625 9.56981 15.6273 9.19968 15.2704C8.82955 14.9134 8.37832 14.6445 7.88173 14.4849L5.62214 13.7592C5.53784 13.7326 5.46444 13.6809 5.41239 13.6116C5.36035 13.5423 5.33233 13.4589 5.33233 13.3734C5.33233 13.2878 5.36035 13.2044 5.41239 13.1351C5.46444 13.0658 5.53784 13.0142 5.62214 12.9875L7.88173 12.2619C8.37832 12.1023 8.82955 11.8333 9.19968 11.4764C9.56981 11.1194 9.84867 10.6843 10.0142 10.2054L10.7666 8.02622ZM6.26023 2.28982C6.27696 2.2411 6.30919 2.19871 6.35233 2.16866C6.39547 2.13861 6.44733 2.12243 6.50054 2.12243C6.55376 2.12243 6.60562 2.13861 6.64876 2.16866C6.6919 2.19871 6.72412 2.2411 6.74085 2.28982L7.1923 3.59708C7.39411 4.17983 7.86773 4.63658 8.472 4.83121L9.82752 5.26658C9.87804 5.28272 9.922 5.31379 9.95316 5.35539C9.98431 5.397 10.0011 5.44701 10.0011 5.49833C10.0011 5.54965 9.98431 5.59967 9.95316 5.64127C9.922 5.68288 9.87804 5.71395 9.82752 5.73008L8.472 6.16546C8.17398 6.26122 7.90317 6.4226 7.68105 6.63681C7.45893 6.85102 7.29159 7.11218 7.1923 7.39959L6.74085 8.70685C6.72412 8.75557 6.6919 8.79796 6.64876 8.82801C6.60562 8.85806 6.55376 8.87423 6.50054 8.87423C6.44733 8.87423 6.39547 8.85806 6.35233 8.82801C6.30919 8.79796 6.27696 8.75557 6.26023 8.70685L5.80878 7.39959C5.70949 7.11218 5.54215 6.85102 5.32003 6.63681C5.09791 6.4226 4.82711 6.26122 4.52909 6.16546L3.17357 5.73008C3.12305 5.71395 3.07909 5.68288 3.04793 5.64127C3.01677 5.59967 3 5.54965 3 5.49833C3 5.44701 3.01677 5.397 3.04793 5.35539C3.07909 5.31379 3.12305 5.28272 3.17357 5.26658L4.52909 4.83121C4.82711 4.73545 5.09791 4.57407 5.32003 4.35986C5.54215 4.14565 5.70949 3.88449 5.80878 3.59708L6.26023 2.28982ZM14.5065 1.10969C14.518 1.07766 14.5396 1.04988 14.5683 1.03022C14.5969 1.01056 14.6312 1 14.6663 1C14.7015 1 14.7358 1.01056 14.7644 1.03022C14.7931 1.04988 14.8146 1.07766 14.8261 1.10969L15.1271 1.98044C15.2613 2.3697 15.5774 2.67457 15.981 2.80395L16.8839 3.0942C16.9171 3.1053 16.9459 3.12612 16.9663 3.15374C16.9867 3.18136 16.9977 3.21442 16.9977 3.24832C16.9977 3.28223 16.9867 3.31529 16.9663 3.34291C16.9459 3.37053 16.9171 3.39134 16.8839 3.40245L15.981 3.6927C15.7821 3.75652 15.6014 3.86417 15.4531 4.00712C15.3049 4.15007 15.1933 4.32438 15.1271 4.51621L14.8261 5.38696C14.8146 5.41899 14.7931 5.44677 14.7644 5.46643C14.7358 5.48609 14.7015 5.49665 14.6663 5.49665C14.6312 5.49665 14.5969 5.48609 14.5683 5.46643C14.5396 5.44677 14.518 5.41899 14.5065 5.38696L14.2055 4.51621C14.1394 4.32438 14.0277 4.15007 13.8795 4.00712C13.7313 3.86417 13.5505 3.75652 13.3516 3.6927L12.4499 3.40245C12.4167 3.39134 12.3879 3.37053 12.3675 3.34291C12.3471 3.31529 12.3362 3.28223 12.3362 3.24832C12.3362 3.21442 12.3471 3.18136 12.3675 3.15374C12.3879 3.12612 12.4167 3.1053 12.4499 3.0942L13.3528 2.80395C13.7564 2.67457 14.0726 2.3697 14.2067 1.98044L14.5065 1.11082V1.10969Z"
fill="currentColor"
/>
</svg>
Generate
</button>
</div>
</div>
</div>
<div class="mx-auto w-full max-w-sm">
<div>
<fieldset>
<legend class="block text-sm/6 font-semibold text-gray-900">Card information</legend>
<div class="mt-2 grid w-full grid-cols-2 rounded-md shadow-sm">
<div class="col-span-2">
<input type="text" name="card-number" id="card-number" placeholder="1234 1234 1234 1234" aria-label="Card number" class="w-full rounded-t-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:relative focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm/6 focus:z-10" />
</div>
<div class="-mt-px">
<input type="text" name="card-expiration-date" id="card-expiration-date" placeholder="MM / YY" aria-label="Expiration date" class="w-full rounded-bl-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:relative focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm/6 focus:z-10" />
</div>
<div class="relative -ml-px -mt-px">
<input type="text" name="card-cvc" id="card-cvc" placeholder="CVC" aria-label="CVC" class="w-full rounded-br-md border-0 bg-white py-2 pl-3.5 pr-14 text-base text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:relative focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm/6" />
<svg aria-hidden="true" class="pointer-events-none absolute right-0 top-1/2 mr-3.5 size-8 -translate-y-1/2" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 7.34739H18V10.1807H1V7.34739Z" fill="#9CA3AF" />
<path d="M18 7.80313H1V6.67419C1.0015 6.35203 1.13516 6.04348 1.37184 5.81578C1.60853 5.58807 1.92908 5.45965 2.26365 5.4585H16.7363C17.0711 5.45965 17.3918 5.58822 17.6286 5.81617C17.8653 6.04411 17.9988 6.35293 18 6.67529V7.80313ZM1 9.01993H18V14.6306C17.9988 14.9529 17.8653 15.2618 17.6286 15.4897C17.3918 15.7177 17.0711 15.8462 16.7363 15.8474H2.26365C1.92888 15.8462 1.60816 15.7177 1.37144 15.4897C1.13472 15.2618 1.0012 14.9529 1 14.6306V9.01993ZM3.55468 13.483H9.10653V12.2651H3.55468V13.483Z" fill="#D1D5DB" />
<rect x="10" y="4.15283" width="9" height="9" rx="4.5" fill="#6b7280" />
<path d="M12.4418 7.24374V10.1528H11.9148V7.75653H11.8977L11.2173 8.19118V7.70823L11.9403 7.24374H12.4418ZM13.1804 10.1528V9.77215L14.1903 8.78209C14.2869 8.68456 14.3674 8.59791 14.4318 8.52215C14.4962 8.44639 14.5445 8.373 14.5767 8.30198C14.6089 8.23096 14.625 8.1552 14.625 8.07471C14.625 7.98285 14.6042 7.90425 14.5625 7.83891C14.5208 7.77262 14.4635 7.72149 14.3906 7.6855C14.3177 7.64952 14.2348 7.63153 14.142 7.63153C14.0464 7.63153 13.9626 7.65141 13.8906 7.69118C13.8187 7.73001 13.7628 7.78541 13.723 7.85738C13.6842 7.92935 13.6648 8.01505 13.6648 8.11448H13.1634C13.1634 7.92982 13.2055 7.76931 13.2898 7.63295C13.3741 7.49658 13.4901 7.39099 13.6378 7.31618C13.7865 7.24137 13.9569 7.20397 14.1491 7.20397C14.3442 7.20397 14.5156 7.24043 14.6634 7.31334C14.8111 7.38626 14.9257 7.48617 15.0071 7.61306C15.0895 7.73995 15.1307 7.88484 15.1307 8.04772C15.1307 8.15662 15.1098 8.26363 15.0682 8.36874C15.0265 8.47385 14.9531 8.59033 14.848 8.71817C14.7438 8.84601 14.5975 9.00084 14.4091 9.18266L13.9077 9.6926V9.71249H15.1747V10.1528H13.1804ZM16.7088 10.1926C16.5043 10.1926 16.3224 10.1576 16.1634 10.0875C16.0052 10.0174 15.8802 9.91988 15.7884 9.79488C15.6965 9.66988 15.6477 9.52546 15.642 9.36164H16.1761C16.1809 9.44024 16.2069 9.50889 16.2543 9.5676C16.3016 9.62537 16.3646 9.67035 16.4432 9.70255C16.5218 9.73474 16.6098 9.75084 16.7074 9.75084C16.8116 9.75084 16.9039 9.73285 16.9844 9.69687C17.0649 9.65993 17.1278 9.6088 17.1733 9.54346C17.2188 9.47812 17.241 9.40283 17.2401 9.3176C17.241 9.22954 17.2183 9.15189 17.1719 9.08465C17.1255 9.01742 17.0582 8.96486 16.9702 8.92698C16.883 8.8891 16.7779 8.87016 16.6548 8.87016H16.3977V8.46391H16.6548C16.7562 8.46391 16.8447 8.44639 16.9205 8.41135C16.9972 8.37632 17.0573 8.32707 17.1009 8.26363C17.1444 8.19923 17.1657 8.1249 17.1648 8.04062C17.1657 7.95823 17.1473 7.88673 17.1094 7.82613C17.0724 7.76457 17.0199 7.71675 16.9517 7.68266C16.8845 7.64857 16.8054 7.63153 16.7145 7.63153C16.6255 7.63153 16.5431 7.64762 16.4673 7.67982C16.3916 7.71202 16.3305 7.75795 16.2841 7.8176C16.2377 7.87632 16.2131 7.94639 16.2102 8.02783H15.7031C15.7069 7.86495 15.7538 7.72196 15.8438 7.59885C15.9347 7.4748 16.0559 7.37821 16.2074 7.30908C16.3589 7.23901 16.5289 7.20397 16.7173 7.20397C16.9115 7.20397 17.08 7.24043 17.223 7.31334C17.367 7.38531 17.4782 7.48238 17.5568 7.60454C17.6354 7.7267 17.6747 7.86164 17.6747 8.00937C17.6757 8.17319 17.6274 8.3105 17.5298 8.4213C17.4332 8.53209 17.3063 8.60454 17.1491 8.63863V8.66135C17.3537 8.68976 17.5104 8.76552 17.6193 8.88863C17.7292 9.01079 17.7836 9.16278 17.7827 9.34459C17.7827 9.50747 17.7363 9.65331 17.6435 9.78209C17.5516 9.90993 17.4247 10.0103 17.2628 10.0832C17.1018 10.1561 16.9171 10.1926 16.7088 10.1926Z" fill="white" />
</svg>
</div>
</div>
</fieldset>
</div>
</div>
<div class="mx-auto w-full max-w-xs">
<div>
<label for="email" class="block select-none text-sm font-semibold leading-6 text-gray-900">Email</label>
<input type="email" name="email" id="email" placeholder="[email protected]" autocomplete="email" value="[email protected]" class="mt-2 w-full rounded-md border-0 bg-white px-3.5 py-2 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-pink-500 sm:text-sm sm:leading-6 disabled:text-gray-500 disabled:bg-gray-50 disabled:ring-gray-200 disabled:cursor-not-allowed" disabled>
</div>
</div>
<div class="mx-auto w-full max-w-sm">
<div>
<label for="upload-file" class="block select-none text-sm font-semibold leading-6 text-gray-900">Upload file</label>
<input type="file" name="upload-file" id="upload-file" class="mt-2 w-full cursor-pointer appearance-none overflow-hidden rounded-md border-0 bg-white pr-3.5 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 file:mr-3.5 file:cursor-pointer file:rounded-l-md file:rounded-r-none file:border-0 file:bg-white file:px-3.5 file:py-2 file:text-sm/6 file:font-semibold file:text-gray-900 file:ring-1 file:hover:bg-gray-50 focus:outline-none file:focus:ring-2 file:focus:ring-pink-500 sm:text-sm/6" />
</div>
</div>
<div class="mx-auto w-full max-w-sm">
<div>
<label for="upload-file" class="block select-none text-sm font-semibold leading-6 text-gray-900">Upload file</label>
<input type="file" name="upload-file" id="upload-file" aria-describedby="file-upload-help" class="mt-2 w-full cursor-pointer appearance-none overflow-hidden rounded-md border-0 bg-white pr-3.5 text-base text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 file:mr-3.5 file:cursor-pointer file:rounded-l-md file:rounded-r-none file:border-0 file:bg-white file:px-3.5 file:py-2 file:text-sm/6 file:font-semibold file:text-gray-900 file:ring-1 file:hover:bg-gray-50 focus:outline-none file:focus:ring-2 file:focus:ring-pink-500 sm:text-sm/6" />
<p id="file-upload-help" class="mt-2 text-sm text-gray-500">SVG, PNG or JPG (max. 1600x900px)</p>
</div>
</div>
<div class="mx-auto w-full max-w-lg">
<div>
<div id="dropzone" class="relative flex min-h-44 w-full flex-col items-center justify-center rounded-xl border-2 border-dashed border-gray-300 px-6 py-4 hover:bg-gray-50">
<svg aria-hidden="true" class="size-8 text-gray-600" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 15V16.2C21 17.8802 21 18.7202 20.673 19.362C20.3854 19.9265 19.9265 20.3854 19.362 20.673C18.7202 21 17.8802 21 16.2 21H7.8C6.11984 21 5.27976 21 4.63803 20.673C4.07354 20.3854 3.6146 19.9265 3.32698 19.362C3 18.7202 3 17.8802 3 16.2V15M17 8L12 3M12 3L7 8M12 3V15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
<label for="upload-file" class="mt-3 text-sm/6 text-gray-900">
Drag and drop or
<span class="font-semibold text-pink-500">Click to upload</span>
<span class="absolute inset-0 cursor-pointer"></span>
</label>
<p id="file-upload-help" class="mt-0.5 text-sm text-gray-500">SVG, PNG or JPG (max. 5MB)</p>
</div>
<input type="file" name="upload-file" id="upload-file" aria-describedby="file-upload-help" class="hidden" multiple />
</div>
</div>
const dropArea = document.querySelector("#dropzone");
const fileInput = document.querySelector("#upload-file");
const allowedTypes = ["image/svg+xml", "image/png", "image/jpeg"];
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB limit
// Prevent default behavior when dragging files
["dragenter", "dragover"].forEach((eventName) => {
dropArea.addEventListener(eventName, (event) => {
event.preventDefault();
dropArea.classList.add("bg-gray-100");
});
});
["dragleave", "drop"].forEach((eventName) => {
dropArea.addEventListener(eventName, () => {
dropArea.classList.remove("bg-gray-100");
});
});
// Handle file drop
dropArea.addEventListener("drop", (event) => {
event.preventDefault();
handleFileUpload(event.dataTransfer.files);
});
// Handle manual file selection
fileInput.addEventListener("change", (event) => {
event.preventDefault();
handleFileUpload(event.target.files);
});
function handleFileUpload(files) {
if (!files.length) return;
const fileArray = Array.from(files);
const validFiles = [];
fileArray.forEach((file) => {
if (!allowedTypes.includes(file.type)) {
alert(`Invalid file type: ${file.name}`);
return;
}
if (file.size > MAX_FILE_SIZE) {
alert(`File too large: ${file.name}`);
return;
}
validFiles.push(file);
console.log("File uploaded:", file.name);
});
// If valid files exist, update file input
if (validFiles.length) {
const dataTransfer = new DataTransfer();
validFiles.forEach((file) => dataTransfer.items.add(file));
fileInput.files = dataTransfer.files;
}
}
Frequently asked questions
-
Basic labeled, without label, with hint text, with corner hint, error state, leading icon, trailing icon, leading text prefix, combined input with trailing dropdown, trailing button, grouped inputs, disabled state, file input, file input with hint, and a drag and drop upload zone.
-
There's a dedicated error state variant that shows a red ring and error message below the input. Apply the same pattern to any input by swapping the ring color to red and adding a small error paragraph underneath.
-
Yes, the drag and drop component includes vanilla JavaScript that handles file drops, validates file type and size, and updates the hidden file input. You still need to handle the actual upload to your server.
-
Yes, there are variants with a trailing dropdown or a leading text prefix combined with the input. They're a single component, no extra JavaScript needed for the layout.
Related Tailwind CSS components
More free, copy-paste Tailwind CSS components to use in your projects.