### Intro
In this small intro, I will help you understand how to think in TailwindCSS. Weβll go through a small theory intro π€(sorry in advance) and will jump next to a more hands-on π exercise to practice what we learned.
### Why use Tailwind
* **Simple and specific:** Most of the utilities included have specific functionality and donβt add extra styling to them (contrary to Bootstrap).
* **Highly customizable:** Although it has a default configuration, we can simply override it in the `tailwind.config.js` file.
* **Can be optimized:** We can use PurgeCSS in production to remove any classes we donβt use from Tailwind, only loading utilities we use.
* **Easy to write:** As soon as you get used to it, it becomes super fast to write your CSS classes; you can also group classes into components by using `@apply`.
* [other reasons](https://dev.to/joserfelix/why-use-tailwind-css-for-your-next-project-39hp)
### Some comments before we start
* TailwindCSS doesnβt have JavaScript included, it is pure CSS. So if we want to make things dynamic we need to write our own JavaScript.
* I will assume you know the basics of CSS π.
* We wonβt go through the installation of TailwindCSS, for that feel free to check their [installation guide](https://tailwindcss.com/docs/installation).
* File locations are considered for Ruby on Rails.
### Configuration file
TailwindCSS configuration lives in a file called `tailwind.config.js`. In this file, we can customize every TailwindCSS variable.
### How TailwindCSS works
* **Utility Classes:** As with most frameworks, TailwindCSS uses utility classes to style HTML elements; its naming convention is super intuitive (`text-center`, `font-bold`, etc.).
* **Prefixes:** We can add prefixes on different classes to make them work conditionally on different breakpoints or states.
_For example:_ `_hover:font-bold_` _will change the font of the element to bold when hovered._
### Prefixes
**Responsive Design [(see docs)](https://tailwindcss.com/docs/responsive-design)**
On TailwindCSS classes we can add a **breakpoint prefix** which will make it work conditionally at different breakpoints.
**Usage**
```html
<div class="md:w-92 lg:w-40">
[...]
<div class="sm:text-center lg:text-left">
```
### Hover, Focus & other states
As with the **responsive design**, we can use prefixes to style different states of our elements.
**Usage**
```html
<button class="bg-purple-600 hover:bg-purple-800">
Sign up
</button>
```
### Utility Classes
Writing **TailwindCSS** utility classes keeps the same structure among most CSS properties. Weβll go through some examples to clarify how the structure works, but feel free to find any specific utility class on their amazing [**documentation**](https://tailwindcss.com/docs).
### Fonts
[**Font Family**](https://tailwindcss.com/docs/font-family) **β** `font-family` **β** `font-{type}`
```html
<p class="font-sans ...">
<p class="font-serif ...">
<p class="font-mono ...">
```
_Note:_ `font-sans`_,_ `font-serif` _and_ `font-mono` _are variables that we can change in our config file to the_ `font-family` _of our choice._
[**Font Size**](https://tailwindcss.com/docs/font-size) **β** `font-size` **β** `text-{size}`
```html
<p class="text-xs ...">The quick brown fox ...</p>
<p class="text-xl ...">The quick brown fox ...</p>
```
[**Font Weight**](https://tailwindcss.com/docs/font-weight) **β** `font-weight` **β** `font-{weight}`
```html
<p class="font-bold ...">The quick brown fox ...</p>
<p class="font-thin ...">The quick brown fox ...</p>
```
[**Text Align**](https://tailwindcss.com/docs/text-align) **β** `text-align` **β** `text-{alignment}`
```html
<p class="text-left ...">Lorem ipsum dolor sit amet ...</p>
<p class="text-center ...">Lorem ipsum dolor sit amet ...</p>
```
### Container
The `container` class will fix the element width depending on the current breakpoint.
[Container](https://tailwindcss.com/docs/container) **β** `width`
```html
<div class="container">
<!-- ... -->
</div>
```
### Margin & Padding
[**Margin**](https://tailwindcss.com/docs/margin) **β** `margin` **β** `m{direction}-{size}`
```html
<div class="mt-8 ...">mt-8</div>
<div class="m-5 ...">m-5</div>
```
Left + Right β `mx`
Top + Down β `my`
[**Padding**](https://tailwindcss.com/docs/padding) **β** `padding` **β** `p{direction}-{size}`
```html
<div class="pb-3 ...">pb-4</div>
<div class="py-2 ...">py-2</div>
```
Left + Right β `px`
Top + Down β `py`
### Colors
The color class utilities allow us to use the same kind of syntax to style different properties.
`{property}-{color}-{value}`
```html
<p class="text-purple-600 ..."></p>
<button class="bg-green-500 ...">Button</button>
<input class="border-2 border-red-500 ...">
```
### Width and Height
[**Height**](https://tailwindcss.com/docs/height) **β** `height` **β** `h{direction}-{size}`
```html
<div class="h-12 ..."></div>
<div class="h-16 ..."></div>
```
[**Width**](https://tailwindcss.com/docs/width) **β** `width` **β** `w{direction}-{size}`
```html
<div class="w-20 ..."></div>
<div class="w-28 ..."></div>
```
### Display
No rocket science here, just classes that apply different display properties.
`flex` **β** `display: flex`
`inline-block` **β** `display: inline-block`
`hidden` **β** `display: none`
### Creating components [(see more)](https://tailwindcss.com/docs/extracting-components)
Sometimes when repeating classes over and over on the same elements (buttons, avatars, etc.), itβs better to refactor our code creating components that help us to update and reuse our code.
**TailwindCSS** includes the `@apply` directive that extracts common utility patterns to CSS component classes.
```scss
.btn-indigo {
@apply py-2 px-4 bg-indigo-500 text-white font-semibold rounded-lg shadow-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-400 focus:ring-opacity-75;
}
```
```html
<button class="btn-indigo">
Click me
</button>
```
TailwindCSS also recommends wrapping the styles where we use `@apply` with `@layer components { }` so it can recognize that those styles belong to the `components`([performance and organization reasons](https://tailwindcss.com/docs/extracting-components)).
### Enough theory! Letβs create a Components Kitchen Sink
_Note: We will be working on an already created Ruby on Rails app with TailwindCSS using the amazing boilerplate [**_BambooSticks_**](https://github.com/mangotreedev/bamboosticks) π.
![](https://miro.medium.com/max/960/0\*9amlGz6S-PNiOdML.gif)
### Main Header
Letβs start styling our main header.
![](https://miro.medium.com/max/1400/1\*sopu-xi4ZUXH\_10F9Q425g.png)
```html
<h1 class="text-5xl font-semibold text-center">Kitchen Sink</h1>
```
**What utilities did we use?**
* `text-5xl` β `font-size` and `line-height`
* `font-semibold` **β** `font-weight`
* `text-center` β `text-align`
### Container
Now letβs add a simple container so we can center our components later.
![](https://miro.medium.com/max/1400/1\*YLAdzUpYWFKY7HGCWfcxpg.png)
**What new utilities did we use?**
* `container` **β** `max-width` on breakpoint (`sm`, `md`, `lg`, `xl`, `2xl`)
* `mx-auto` **β** `margin-left` and `margin-right`
* `my-3` **β** `margin-top` **and** `margin-bottom`
### Avatars
Letβs now play with some image properties by creating avatars.
![](https://miro.medium.com/max/1400/1\*ILH2hFLQ3cO1zimSii74bA.png)
_Omg those guys are handsome_
**What new utilities did we use?**
* `rounded-full` **β** `border-radius` (same as `border-radius: 50%`) which will make all borders rounded. If the image is a square it will create a circle.
* `h-24` **&** `w-24` **β** `weight` **and** `height`
* `inline-block` **β** `display`
### Buttons
Ok, now letβs do a primary and secondary button.
![](https://miro.medium.com/max/1400/1\*8-6CypmiYOc4hCRQ1CmwvQ.png)
_Both are called Benjamin⦠get it?_
**What new utilities did we use?**
* `px-12` **/** `py-3` **β** `padding-left` **and** `padding-right` **/** `padding-up` **and** `padding-bottom`
* `bg-yellow-400` **β** `background-color`
* `border-yellow-400` **β** `border-color`
* `hover:bg-yellow-300` **β** `background-color` on `:hover`
* `focus:outline-none` **β** `background-color` on `:focus`
* `text-white` **β** `color`
* `rounded` **β** `border-radius`
* `border` **β** `border-width`
* `transition` **β** `transition` (with a transition delay of 150ms)
* `duration-300` **β** `transition-duration`
* `inline-block` **β** `display`
### Banner
![](https://miro.medium.com/max/1400/1\*yV4MBqSo\_nivY0im2JXIqQ.png)
**What new utilities did we use?**
* `bg-cover` **β** `background-size`
* `flex` **β** `display`
* `items-center` **β** `align-items`
* `text-shadow` **β** βThis is a custom class I made, there is no text-shadow utility class on TailwindCSSβ
### Category Card
![](https://miro.medium.com/max/1400/1\*prNSw3p7FxdB8oF0w9hnNA.png)
_This card peels amazingβ¦_
**What new utilities did we use?**
* `justify-center` **β** `justify-content`
* `shadow-xl` **β** `box-shadow`
### Product Card
![](https://miro.medium.com/max/1400/1\*f3dR5udwCj2xrCfmnj1RpA.png)
**What new utilities did we use?**
* `object-cover` **β** `object-fit`
* `flex-col` **β** `flex-direction`
* `p-5` **β** `padding`
* `rounded-l` **β** `border-top-left-radius` and `border-bottom-left-radius`
### Party Card
![](https://miro.medium.com/max/1400/1\*Q-v6AbKY8h0L-YNmWdBWNA.png)
**What new utilities did we use?**
* `rounded-t` **β** `border-top-left-radius` and `border-top-right-radius`
* `w-full` **β** `width: 100%`
* `items-end` **β** `align-items`
### Extracting components
All our refactoring will be in separate files called with the name of the specific component in the folder `app/javascript/stylesheets/components`.
### Buttons
We will extract all the common classes from our buttons in the `.btn` class and create two specific classes (`.btn-main` and `.btn-ghost`) for the different versions of buttons we have.
And we are done! **Congratulations**!
![](https://miro.medium.com/max/996/0\*wSsheHr14rrayAU6.gif)
_ππ»_ [_Link to the Ruby on Rails application with all the components_](https://github.com/nicoproto/tailwindcss-tutorial)