How to render Tailwind CSS in Angular and Storybook

Reading Time: 2 minutes

 201 total views

Introduction

In previous post, we learned how to apply Tailwind CSS to Angular application. However, the Tailwind CSS does not render in Storybook components properly.

It is because we need to install PostCSS add-on to configure PostCSS and add Tailwind to the Storybook.

In this post, we learn how to install storybook PostCSS add-on and create a PostCSS configuration to add Tailwind to Storybook and render their CSS in Storybook components.

Precondition

Angular application must have Tailwind installed before we can proceed to render Tailwind CSS in Storybook.

Install Storybook PostCSS add-on

Storybook recommends to install addon-postcss to project. Let’s install @storybook/addon-postcss as development dependency of the project.

npm install -save-dev @storybook/addon-postcss

Within ./storybook/main.js, append "@storybook/addon-postcss" to addons array

module.exports = {
  "addons": [
     ... existing addons ...
     "@storybook/addon-postcss"
   ]
}

PostCSS Configuration

Create postcss.config.js at root level of the project,

module.exports = {
  plugins: [
    require('autoprefixer'),
  ],
}

Verify the result in the Storbook

npm run storybook
Using PostCSS preset with postcss@7.0.39

indicates PostCSS is loaded to Storybook successfully

Open the storybooks of FoodCard Component

Storybook components render Tailwind CSS property after the configuration

We can use Storybook to visualize the functionality and styling of components.

Final thought

When Storybook components broke and did not render Tailwind CSS, I panicked because I was not sure how to support Tailwind in them. Storybook PostCSS add-on simplifies the configuration and with a few steps, Storybook renders the components with the expected styling.

This is the end of the blog post and I hope you like the content and continue to follow my learning experience in Angular and Storybook.

Resources:

  1. Repo: https://github.com/railsstudent/ng-spanish-menu
  2. Tailwind: https://tailwindcss.com/docs/installation
  3. Storybook Addon PostCSS: https://storybook.js.org/addons/@storybook/addon-postcss

Tailwind CSS in JIT mode with Angular

Reading Time: 3 minutes

 168 total views

Introduction

Tailwind CSS (https://tailwindcss.com/) is a utility-first CSS framework with out-of-the-box classes for UI components.

For example, <p class="pl-2">hello world</> is equivalent to <p style="padding-left: 0.5rem;">hello world</h> and we achieve the effect without writing inline-style or custom class.

However, our components may require one-off style that Tailwind does not support and we cannot justify to include it in theme configuration.

Fortunately, Tailwind enables Just-In-Time (JIT) mode that generates the styles on demand. This feature allows dynamic style such as “w-[200px]” to fix the width of a card to 200px.

This post will show you the installation of Tailwind CSS, enable Just-In-time mode and add dynamic styles to style a div element.

Install Tailwind CSS in Angular

Firstly, we have to install the dependency of tailwind and tailwind plugins into the Angular application.

npm install --save-dev tailwindcss
npm install --save-dev @tailwindcss/forms @tailwindcss/typography
npx tailwindcss init

The npx command generates tailwind.config.js with default values

Enable Just-In-Time mode

Secondly, we have to enable JIT mode of tailwind; therefore, mode: 'jit‘ is added to tailwind.config.js.

module.exports = {
  mode: 'jit',
  content: ["./src/**/*.{html,ts}"],
  darkMode: 'media', // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [
    require('@tailwindcss/typography'),
    require('@tailwindcss/forms'),
  ],
}

Then, we add file path in content array to purge all html and typescript files to maintain small bundle size in production. The last step of configuration is to import typography and forms plugins by require('@tailwindcss/typography') and require('@tailwindcss/forms')

Add Tailwind Base Styles to Angular

It is important to put tailwind directives at the beginning of the global stylesheet, style.scss. These are base styles that are accessible to all UI components of the application.

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

Finally, we are ready to generate on-demand style in our component.

Generate on-demand styles in Angular Component

Our use case is to set the width of food-card component to 300 pixels wide. The html template of food-card component looks like the following:

<div style="display: flex; flex-direction: column; margin-right: 0.5rem; border: 2px solid black; width: 300px;">
      <label name="name" class="item card-row">
        <span class="field">Name:</span>
        <span class="field-text">{{ ordered.name }}</span>
      </label>
      <label class="item card-row" name="description">
        <span class="field">Description:</span>
        <span class="field-text">{{ ordered.description }}</span>
      </label>
</div>

Except width: 300px;, we can substitute the rest with tailwind utility classes.

I don’t believe the width style should be part of the configuration because it is used one time. The just-in-time mode provides the solution we need; w-[300px] generates custom class at run time and changes the width to 300 pixels wide.

After the modification;

<div class="flex flex-col mr-2 border-solid border-2 border-black w-[300px]">
      <label name="name" class="item card-row">
        <span class="field">Name:</span>
        <span class="field-text">{{ ordered.name }}</span>
      </label>
      <label class="item card-row" name="description">
        <span class="field">Description:</span>
        <span class="field-text">{{ ordered.description }}</span>
      </label>
</div>

Verify the result

The final stage is to verify the custom style actually works and the div component has the expected width.

We can open Chrome inspector, hover on the <div> element and inspect its width property. As the image indicates, we have successfully fix the width to 300 pixels.

Final thought

I really like to use Tailwind in Angular because it saves the efforts of authoring custom css classes in SCSS files. After switching to tailwind, I got rid of most of the SCSS files and replaced the styles with the counterpart utility classes. When utility class is unavailable, it is convenient to generate the custom class on the fly with arbitrary value. Authoring UI components can’t get any easier in web development.

This is the end of the blog post and I hope you like the content and continue to follow my learning experience in Angular and other web technologies.

Resources:

  1. Repo: https://github.com/railsstudent/ng-spanish-menu
  2. Tailwind: https://tailwindcss.com/docs/installation

Use CSS to draw diagonal line across of square

Reading Time: < 1 minutes

 102 total views

  1. Create two divs and convert them into flexboxes.
.square {
   position: relative;
   width: 130px;
   height: 130px;
   border: 1px solid black;
   background: red;

   display: flex;
   justify-content: center;
   align-items: center;
}

<div class="square left-diag"></div>
<div class="square right-diag"></div>

2. Add .left-diag:after pseudo element to draw a black dialog line that draws from bottom left to upper right. Sass style is shown below:

.square {
   &.left-diag:after {
     content: "";
     position: absolute;
     z-index: 1;
     border: 1px solid black;
     height: 140%;
     transform: rotate(-45deg);
   }
}

3. Add .right-diag:after pseudo element to draw a black dialog line that draws from bottom right to upper left. Sass style is shown below:

.square {
   &.right-diag:after {
     content: "";
     position: absolute;
     z-index: 1;
     border: 1px solid black;
     height: 140%;
     transform: rotate(45deg);
   }
}

4. Lets refactor the sass styles and group common css properties in a mixin function

@mixin strikethroughDiagonal($rotation) {
  content: "";
  position: absolute;
  z-index: 1;
  border: 1px solid black;
  height: 140%;
  transform: rotate($rotation);
}

.square {
   &.left-diag:after {
     @include strikethroughDiagonal(-45deg); 
   }

   &.right-diag:after {
     @include strikethroughDiagonal(45deg); 
   }
}

Stackblitz repo:

https://stackblitz.com/edit/js-4s7qhi