Tailwind Handbook - Part II
Tags: tailwindcss, javascript, frontend, beginners
Published: 2024-04-27 15:00:27

## Review

Tailwind CSS is a utility-first CSS framework that provides a set of pre-defined CSS classes. Instead of writing traditional CSS rules, developers assemble layouts and styles directly in HTML using these utility classes. 

In this post, let's go through examples of basic components implemented with the support  of Tailwind CSS. 
For more of the basic details, check out [part I](https://dev.to/lyumotech/tailwind-handbook-part-i-1l2d).

## Building common components

Web applications often feature repeating design patterns: navigation bars, hero sections, card layouts, form elements, and more. Instead of writing the same code repeatedly for each instance, it is a good practice to create reusable components. Using custom reusable components provides the following benefits:
- **Consistency:** Components ensure a unified look and feel across your entire application, avoiding unintentional variations.
- **Efficiency:** Building a component once saves a significant time and effort compared to styling individual elements each time they appear.
- **Maintainability:** Changes to a component's style will make future updates easier and reduce the risk of breaking unrelated elements.

### Basic structure

Before jumping into components' details, let's get familiar with the basic component structure.
Let's assume we want to have a HelloWorld component with only text in it. Here's the example implementation:
```tsx
import React from 'react';

interface HelloWorldProps {
  className?: string; // Allows for optional additional styling
}

const HelloWorld: React.FC<HelloWorldProps> = ({ className }) => {
  return (
    <div className={`font-bold text-2xl text-center ${className}`}>
      Hello World!
    </div>
  );
};

export default HelloWorld;
```
- **TypeScript Interface:** We define an optional `className` prop in case users want to apply additional Tailwind classes for customization.
- **Basic Styling:** The component includes some basic inline styling for font size and centering.
- **JSX Structure:** A simple `<div>` contains the "Hello World!" text. `className` dynamically combines default styles with any provided via the `className` prop.

Now, let's see how this component could be used (without and with some customization):
```html
<HelloWorld />
<HelloWorld className="text-blue-500 underline" />
```

- **Foundation:** While basic, this can be expanded with more elaborate styling, dynamic text content, or interactivity.
- **Customization:** The optional `className` prop allows users to tailor the component's appearance when needed.

Now, let's explore how to build the most common components using Tailwind CSS.
### Navigation bar

**What?**

- A navigation bar is a core element of most websites. It provides users with a clear and structured way to explore different sections of the web page.
- With Tailwind CSS, you'll build navbars using a combination of utility classes for layout, colors, spacing, typography, and potentially interactive behaviors.

**When to Use?**

- Include a navigation bar in almost any website or web application to give users a primary means of orientation.
- The exception might be extremely simple single-page designs (but they would still often have navigation bar, just with navigation to a particular sections on the page).

**Short Implementation Example**

Here's a basic navigation bar example using Tailwind CSS:
```html
<nav className={`flex space-x-8 w-full justify-center`}>
  <a href="#home" className="hover:text-blue-500">
	Home
  </a>
  <a href="#about" className="hover:text-blue-500">
	About
  </a>
  <a href="#services" className="hover:text-blue-500">
	Services
  </a>
  <a href="#contact" className="hover:text-blue-500">
	Contact
  </a>
</nav>
```

**Let's break it down:**

- **`nav` element:**
    - **`flex`:** Turns the `<nav>` element into a flexbox container, allowing flexible arrangement of its children (the navigation links).
    - **`space-x-8`:** Adds consistent horizontal spacing of 8 units (likely based on your `tailwind.config.js` spacing scale) between the navigation links.
    - **`w-full`:** Forces the navigation bar to take up the full available width of its parent container.
    - **`justify-center`:** Centers the navigation links horizontally within the navbar.
- **`a` elements (navigation links)**
    - **`hover:text-blue-500`:** Changes the text color of the links to blue (specific blue shade based on `tailwind.config.js` setup) when the user hovers over them.

**Overall Functionality**
This code creates a horizontal navigation bar with the following characteristics:
- **Full width:** The navigation bar extends across the entire available width of its container.
- **Centered links:** The navigation links are horizontally centered within the bar.
- **Spacing:** Adequate spacing is provided between each navigation link.
- **Hover effect:** The text color of the links changes on hover, providing visual feedback to the user.

> **Note 1:** The specific spacing value (`space-x-8`) and the color (`text-blue-500`) can be customized in the `tailwind.config.js` file or by using different Tailwind utility classes.

> **Note 2:** This is a very basic example. Real-world navigation bars often involve more complexity like dropdowns, responsive adjustments for different screen sizes, and more elaborate styling.
### Hero section

**What?**

- A hero section is a prominent banner-like area often placed at the top of a website. It's designed to grab attention and convey a key message about your product, service, or brand.
- Hero sections typically feature a combination of headings, a call to action (CTA) button, and sometimes background images or videos.

**When to Use?**

- Utilize hero sections on landing pages, homepages, or the top of key content sections to make a strong first impression.
- They are perfect for highlighting your most important value propositions.

**Short Implementation Example**

Here's a simple hero section built with Tailwind CSS:
```html
<section className="bg-gray-900 text-white py-20 text-center">
  <div className="container mx-auto">
	<h1 className="text-4xl font-bold mb-4">Your Product Headline</h1>
	<p className="text-lg mb-8">
	  A short and description of the website.
	</p>
	<a
	  href="#"
	  className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-3 px-6 rounded"
>
	  Get Started Now
	</a>
  </div>
</section>
```

**Let's break it down:**

- **Layout:** `container` and `mx-auto` center content horizontally. `text-center` aligns elements.
- **Colors:** `bg-gray-900` and `text-white` provide a contrasting theme.
- **Spacing:** `py-20` creates vertical padding, `mb-4` and `mb-8` add spacing to elements.
- **Typography:** `text-4xl`, `font-bold`, and `text-lg` size and style text.
- **Button:** `bg-blue-500`, `hover:bg-blue-700`, `text-white`, `font-bold`, `py-3`, `px-6`, and `rounded` style the call-to-action button.

> **Important Note:** Hero sections can become much more visually elaborate. You can improve it by adding background images, gradients, split layouts (text on one side, image on the other), and subtle animations with Tailwind's utility classes.

### Card layouts

**What?**

- Cards are versatile content containers used to present information in a visually organized and digestible way. They often feature an image, title, descriptive text, and sometimes call-to-action elements.
- Tailwind makes it easy to create consistent and flexible card layouts.

**When to Use?**

- Display collections of related content: product listings, blog teasers, team member profiles, testimonials... the possibilities are endless!
- Create grid-like layouts to present information in a scannable format.

**Short Implementation Example**

Here's a basic card layout example using Tailwind CSS:
```html
<div className="bg-white shadow-md rounded-lg p-6">
  <h2 className="text-xl font-bold mb-2">Card Title</h2>
  <p className="text-gray-700">
	Some descriptive text about this card&apos;s content.
  </p>
  <a
	href="#"
	className="inline-block bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mt-4"
>
	Learn More
  </a>
</div>
```

**Let's break it down:**

- **Card Styling:** `bg-white`, `shadow-md`, `rounded-lg`, and `p-6` give individual cards structure and visual definition.
- **Content:** Images, headings (`text-xl`, `font-bold`), text (`text-gray-700`), and a button (`bg-blue-500`, etc.) comprise the card content.

> **Important Note:** Cards can be customized extensively. Try background colors, different image aspect ratios, variations in content structure, and more to tailor them for specific use cases.

Usage Example:
```html
<div className="container mx-auto grid grid-cols-3 gap-6">
  <CardLayout />
  <CardLayout />
  <CardLayout />
  <CardLayout />
</div>
```

- **Layout:** `container`, `mx-auto`, `grid`, `grid-cols-3`, and `gap-6` create a responsive three-column card grid.
### Forms

**What?**

- Forms are essential for collecting user input, ranging from simple contact forms to complex registration or checkout processes.
- Tailwind CSS provides the tools to style beautiful and functional forms while keeping your HTML markup clean.

**When to Use?**

Use forms whenever you need to gather information from users:
- Contact forms
- Login and registration forms
- Survey forms
- Search fields
- Checkout forms
- etc.

**Short Implementation Example**

Here's a simple contact form example built with Tailwind CSS:
```html
<form className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
  <div className="mb-6">
	<label
	  htmlFor="name"
	  className="flex text-gray-700 text-sm font-bold mb-2 justify-start"
>
	  Game&apos;s name
	</label>
	<input
	  className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline focus:border-blue-500"
	  type="text"
	  id="name"
	  name="name"
	/>
  </div>

  <div className="mb-6">
	<label
	  className="flex text-gray-700 text-sm font-bold mb-2 justify-start"
	  htmlFor="description"
>
	  Game&apos;s description
	</label>
	<textarea
	  className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline focus:border-blue-500"
	  id="description"
	  name="description"
	  rows={7}
></textarea>
  </div>

  <div className="flex items-center justify-center">
	<button
	  className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
	  type="submit"
>
	  Submit
	</button>
  </div>
</form>
```

**Let's break it down**

**Overall Form Styling**

- **`bg-white`:** Sets a white background color for the form container.
- **`shadow-md`:** Adds a subtle drop shadow to the form.
- **`rounded`:** Applies a slight rounding to the corners of the form container.
- **`px-8`, `pt-6`, `pb-8`:** Adds padding around the form content for visual spacing (horizontal: 8 units, top: 6 units, bottom: 8 units).
- **`mb-4`:** Adds a bottom margin to the overall form to separate it from subsequent elements.

**Input Fields (`div` containers)**

- **`mb-6`:** Adds a bottom margin to each input group (label, input/textarea) creating spacing between them.

**Labels**

- **`flex`:** Makes the label element a flexbox container.
- **`text-gray-700`:** Sets the label text color to a dark gray.
- **`text-sm`:** Makes the label text smaller.
- **`font-bold`:** Makes the label text bold.
- **`mb-2`:** Adds a bottom margin to the label, creating space between the label and the input field.
- **`justify-start`:** Ensures the label text is left-aligned within its flex container.

**Input and Textarea**

- **`shadow`:** Adds a subtle shadow effect to the input fields.
- **`appearance-none`:** Resets the default browser styling of form inputs.
- **`border`:** Adds a border around the input fields.
- **`rounded`:** Slightly rounds the corners of the input fields.
- **`w-full`:** Forces the input fields to take up the full available width of their container.
- **`py-2`, `px-3`:** Applies padding (vertical: 2 units, horizontal: 3 units) within the input fields.
- **`text-gray-700`:** Sets the input text color to dark gray.
- **`leading-tight`:** Reduces the line-height (spacing between lines) within the input fields.
- **`focus:outline-none`:** Removes the default focus outline when the input fields are selected.
- **`focus:shadow-outline`:** Adds a subtle shadow outline as a focus indicator when the input fields are selected.
- **`focus:border-blue-500`:** Changes the border color to blue when the input fields are in focus.

**Button**

- **`bg-blue-500`:** Sets the background color to blue.
- **`hover:bg-blue-700`:** Changes the background color to a darker blue on hover.
- **`text-white`:** Makes the button text white.
- **`font-bold`:** Makes the button text bold.
- **`py-2`, `px-4`:** Adds padding to the button (vertical: 2 units, horizontal: 4 units).
- **`rounded`:** Rounds the corners of the button.
- **`focus:outline-none`:** Removes the default focus outline.
- **`focus:shadow-outline`:** Adds a shadow outline as a focus indicator.

**Button Alignment**

- **`flex`, `items-center`, `justify-center`:** These classes on the button's container `div` center the button horizontally and vertically.

> **Important Note:** This example focuses only on UI part of the implementation. Interactivity will be covered in the following part of the series.
## Making your designs responsive

One of the core strengths of Tailwind CSS is the ease with which you can create responsive interfaces that adapt to different screen sizes. 
### Breakpoints system in action

- Tailwind comes with a built-in set of breakpoints (sm: 640px, md: 768px, lg: 1024px, xl: 1280px, 2xl: 1536px). These breakpoints mark the widths at which your design might need modifications for optimal display on various devices.
    
- Prefixes like `sm:`, `md:`, `lg:` etc., are used before utility classes to apply styles only at or above the specified breakpoint.

```html
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3"></div>
```

This creates a single-column layout on small screens, switching to two columns on medium screens and above, and three columns on large screens and above.
### Conditional classes

Sometimes, just changing the layout at breakpoints isn't enough. You might need to show or hide elements based on screen size. Tailwind provides special responsive variants to add or remove classes based on breakpoints.

```html
<button class="hidden sm:block">Visible on medium screens and above</button>
```

## Tips for efficient workflow

- **Mobile-First Development:** Start styling for smaller screens and utilize breakpoints to progressively add styles and complexity as the screen size increases. This often leads to leaner code.
- **Customizing Breakpoints:** If needed, you can adjust the default breakpoints or add your own in the `tailwind.config.js` file.
- **Thinking in Components:** When building reusable components, consider their responsiveness alongside their styling.
### Extensions and plugins

Tailwind's extensibility is powerful. Explore plugins like the aspect-ratio plugin to easily maintain proper image/video ratios across screen sizes.

## Conclusion

Tailwind CSS offers a powerful and versatile approach to styling web projects. 

In the next and last part of this series, we'll cover themes customization. Stay tuned!

## Resources

1. https://react.dev/learn
1. https://tailwindcss.com/docs/installation
2. https://www.w3schools.com/css/css_navbar.asp
3. https://www.w3schools.com/tags/tag_section.asp
4. https://www.w3schools.com/html/html_forms.asp
5. https://www.w3schools.com/tags/att_textarea_rows.asp
6. https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/132
7. Some popular UI components libraries:
	1. https://mui.com/
	2. https://daisyui.com/
	3. https://react-spectrum.adobe.com/react-aria/
	4. https://ui.shadcn.com/
	5. https://headlessui.com/
8. https://syntax.fm/show/751/ui-components-shadcn-tailwind-ui-headless-react-aria-radix-ui