Forms are an essential part of web development, allowing users to interact with your application by submitting data. Whether it's a login form, a registration form, or a contact form, styling and validating these forms is crucial for a good user experience. In this blog post, we'll explore how to create fully styled forms using Tailwind CSS, a utility-first CSS framework, and how to add validation to ensure the data submitted is correct.
Why Tailwind CSS?
Tailwind CSS is a highly customizable, low-level CSS framework that provides utility classes to build designs directly in your markup. It allows you to create responsive, modern, and fully styled components without writing custom CSS. Tailwind's utility-first approach makes it easy to style forms quickly and consistently.
Setting Up Tailwind CSS
Before we dive into creating forms, let's ensure you have Tailwind CSS set up in your project.
1. Install Tailwind CSS
If you haven't already installed Tailwind CSS, you can do so using npm or yarn:
npm install tailwindcss
2. Configure Tailwind
Generate a tailwind.config.js
file:
npx tailwindcss init
3. Include Tailwind in Your CSS
Create a CSS file (e.g., styles.css
) and include Tailwind's base, components, and utilities:
@tailwind base;
@tailwind components;
@tailwind utilities;
4. Build Your CSS
Use a build tool like PostCSS to process your CSS file:
npx tailwindcss -i ./src/styles.css -o ./dist/output.css --watch
Now you're ready to start building forms with Tailwind CSS!
Creating a Basic Form
Let's start by creating a simple contact form with fields for name, email, and message.
<form class="max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">
<!-- Name Field -->
<div class="mb-4">
<label for="name" class="block text-gray-700 text-sm font-bold mb-2">Name</label>
<input
type="text"
id="name"
name="name"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your name"
/>
</div>
<!-- Email Field -->
<div class="mb-4">
<label for="email" class="block text-gray-700 text-sm font-bold mb-2">Email</label>
<input
type="email"
id="email"
name="email"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your email"
/>
</div>
<!-- Message Field -->
<div class="mb-6">
<label for="message" class="block text-gray-700 text-sm font-bold mb-2">Message</label>
<textarea
id="message"
name="message"
rows="4"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your message"
></textarea>
</div>
<!-- Submit Button -->
<button
type="submit"
class="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
>
Submit
</button>
</form>
Explanation:
-
Container Styling: The form is wrapped in a
div
withmax-w-md
,mx-auto
, andp-6
to center it and add padding. - Input Fields: Each input field is styled with Tailwind's utility classes for width, padding, borders, and focus states.
- Submit Button: The button is styled with a background color, hover effect, and focus ring.
Adding Validation
Validation is crucial to ensure users submit correct data. We'll use HTML5 validation attributes and Tailwind CSS to style validation states.
1. HTML5 Validation Attributes
Add required
and type
attributes to enforce validation:
<input
type="text"
id="name"
name="name"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your name"
/>
<input
type="email"
id="email"
name="email"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your email"
/>
2. Styling Invalid Fields
Tailwind doesn't provide built-in classes for invalid states, but you can use the :invalid
pseudo-class in your CSS:
input:invalid, textarea:invalid {
border-color: #f87171; /* Red border for invalid fields */
}
Alternatively, you can use JavaScript to dynamically add classes for invalid fields.
3. Displaying Validation Messages
Use JavaScript to display custom validation messages:
<div class="mb-4">
<label for="email" class="block text-gray-700 text-sm font-bold mb-2">Email</label>
<input
type="email"
id="email"
name="email"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your email"
/>
<p id="email-error" class="text-red-500 text-sm mt-1 hidden">Please enter a valid email address.</p>
</div>
Add JavaScript to handle validation:
document.querySelector('form').addEventListener('submit', (e) => {
const emailInput = document.getElementById('email');
const emailError = document.getElementById('email-error');
if (!emailInput.checkValidity()) {
e.preventDefault();
emailError.classList.remove('hidden');
} else {
emailError.classList.add('hidden');
}
});
Enhancing the Form with Tailwind Plugins
Tailwind CSS can be extended with plugins to add additional functionality. For example, you can use the @tailwindcss/forms
plugin to style form elements consistently.
1. Install the Plugin
npm install @tailwindcss/forms
2. Add the Plugin to tailwind.config.js
module.exports = {
plugins: [
require('@tailwindcss/forms'),
],
};
3. Use the Plugin
The plugin provides default styles for form elements, making it easier to style inputs, checkboxes, and radio buttons.
Final Example: A Fully Styled and Validated Form
Here's the complete code for a fully styled and validated form:
<form class="max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">
<!-- Name Field -->
<div class="mb-4">
<label for="name" class="block text-gray-700 text-sm font-bold mb-2">Name</label>
<input
type="text"
id="name"
name="name"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your name"
/>
<p id="name-error" class="text-red-500 text-sm mt-1 hidden">Please enter your name.</p>
</div>
<!-- Email Field -->
<div class="mb-4">
<label for="email" class="block text-gray-700 text-sm font-bold mb-2">Email</label>
<input
type="email"
id="email"
name="email"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your email"
/>
<p id="email-error" class="text-red-500 text-sm mt-1 hidden">Please enter a valid email address.</p>
</div>
<!-- Message Field -->
<div class="mb-6">
<label for="message" class="block text-gray-700 text-sm font-bold mb-2">Message</label>
<textarea
id="message"
name="message"
rows="4"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your message"
></textarea>
<p id="message-error" class="text-red-500 text-sm mt-1 hidden">Please enter a message.</p>
</div>
<!-- Submit Button -->
<button
type="submit"
class="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
>
Submit
</button>
</form>
<script>
document.querySelector('form').addEventListener('submit', (e) => {
const nameInput = document.getElementById('name');
const emailInput = document.getElementById('email');
const messageInput = document.getElementById('message');
const nameError = document.getElementById('name-error');
const emailError = document.getElementById('email-error');
const messageError = document.getElementById('message-error');
if (!nameInput.checkValidity()) {
e.preventDefault();
nameError.classList.remove('hidden');
} else {
nameError.classList.add('hidden');
}
if (!emailInput.checkValidity()) {
e.preventDefault();
emailError.classList.remove('hidden');
} else {
emailError.classList.add('hidden');
}
if (!messageInput.checkValidity()) {
e.preventDefault();
messageError.classList.remove('hidden');
} else {
messageError.classList.add('hidden');
}
});
</script>
Conclusion
With Tailwind CSS, creating fully styled and validated forms is a breeze. By leveraging utility classes and HTML5 validation, you can build responsive, accessible, and user-friendly forms without writing custom CSS. Tailwind's flexibility and extensibility make it an excellent choice for modern web development.
Happy coding! 🚀
Top comments (0)