[Tailwind CSS] From CSS to Tailwind CSS
Tags: webdev, tutorial, tailwindcss, beginners
Published: 2023-03-03 12:02:12

As part of the Micro Frontends series, we developed some micro applications based on Angular (dashboard micro application and heroes micro application). We started from the Angular Tour of Heroes tutorial and until now, we didn't care about anything related to styling.

Check-out the repository for the source code https://github.com/blminami/tour-of-heroes-microfrontends

Today, we're going to add Tailwind CSS to our NX workspace and style the dashboard application. Have a look at the screenshots below (before and after) to see what we want to achieve.

Before

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mi30glv57pb1k2peup87.png)

After


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awuejsp8566ftlh5fgqp.png)


Let's start by running the following command which will add tailwindcss config to the workspace:
```bash
npx nx generate @nrwl/angular:setup-tailwind dashboard-microapp
```

According to the [NX documentation](https://nx.dev/recipes/other/using-tailwind-css-in-react#automated-setup), the command will install the dependencies and add the configuration files. 

```js
// tailwind.config.js

const { createGlobPatternsForDependencies } = require('@nrwl/angular/tailwind');
const { join } = require('path');

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'),
    ...createGlobPatternsForDependencies(__dirname),
  ],
  theme: {
    extend: {
      colors: {
        primary: '#E4B363',
        secondary: '#074F57',
        cordovan: '#c45663',
        'dark-bg': '#242424',
      },
    },
  },
  plugins: [],
};
```

As part of `tailwind.config.js` file, we can extend the default theme by adding custom colors and other properties. For demo purposes, I updated the color palette to include some new colors.

```css
/* dashboard.component.css */

@tailwind base;
@tailwind components;
@tailwind utilities;
```

Also, we have to import TailwindCSS bases style. In order to work in the micro frontend context, the styles have to be added at component level, instead of `styles.css` file.

Now that the configuration is done, we can switch to the html files and use the pre-defined classes to style the components. 

First thing, let's have a look at the `hero-search` component, which exposes the functionality to search a hero by name. 

```html
<div class="flex flex-col items-center mb-4">
  <input
    #searchBox
    id="search-box"
    (input)="search(searchBox.value)"
    placeholder="Search for a hero"
    class="shadow appearance-none border rounded w-2/5 py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
  />
  <ul
    *ngIf="heroes$ | async as heroes; else null"
    class="shadow appearance-none border bg-white rounded w-2/5 py-2 px-3 text-gray-700 leading-tight mt-px cursor-pointer"
  >
    <li *ngFor="let hero of heroes" class="mt-1">
      <a routerLink="/heroes/detail/{{ hero.id }}">
        {{ hero.name }}
      </a>
    </li>
  </ul>
</div>
```

It consists of an input element and a list of heroes that meet the search criteria. We would like to have the 2 elements on separated rows and centered. To achieve it, we add a div container with the following classes `class="flex flex-col items-center mb-4"` which applies flex display, centers the items and add a margin bottom.
Let's also have a look at the input element and the classes `class="shadow appearance-none border rounded w-2/5 py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"`
What we got: an element with shadow, rounded border (border-radius: 0.25rem; /* 4px */), width 40%, vertical and horizontal padding (py-2 px-3) and gray-700 text color.
For more details, check out the [Tailwind documentation](https://tailwindcss.com/docs/installation)

Next, let's give life to our heroes! Instead of displaying boring hero cards, let's have an image, a name and a description of their super powers. We display the top heroes, after all, they deserve some recognition for their powers, right?😄 

In the `in-memory-data.service.ts`, update the heroes array and add the following properties to each object: id, name, description, image. Find the new array of data [here]( https://github.com/blminami/tour-of-heroes-microfrontends/blob/master/libs/core/src/lib/services/in-memory-data.service.ts).
```ts
{
        id: 13,
        name: 'Bombasto',
        description:
          'Telekinesis: The hero can move objects with their mind, allowing them to lift heavy objects or even people',
        image: 'https://i.postimg.cc/3wZMGqn8/11-2-anime-png-picture.png',
},
```

For each hero, we're going to have a container that has rounded corners, box-shadow, cursor pointer and a gradient as background color (you can be creative with the gradients, here is a interesting list of options https://hypercolor.dev/)
`class="rounded flex shadow-lg mb-2 mr-2 bg-gradient-to-br from-gray-200 via-gray-400 to-gray-600 cursor-pointer"`. 
Also, we're going to display the name, image and description of the hero, in 2 different columns.

```html
<div
      *ngFor="let hero of heroes"
      class="rounded flex shadow-lg mb-2 mr-2 bg-gradient-to-br from-gray-200 via-gray-400 to-gray-600 cursor-pointer"
      routerLink="/heroes/detail/{{ hero.id }}"
    >
      <img
        class="object-contain h-52 w-40 self-center"
        [src]="hero.image || defaultImage"
        alt="hero image"
      />
      <div class="px-6 py-4">
        <div class="font-bold text-xl mb-2">{{ hero.name }}</div>
        <p class="text-test text-base">
          {{ hero.description }}
        </p>
      </div>
    </div>
```

Results:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/odkoo6nzkue596kt0us5.png)

Easy-peasy, right? 🥳

✨Check out the [Github repo](https://github.com/blminami/tour-of-heroes-microfrontends) for the entire configuration!

Until next time, thank you for reading! 🐾