Using container class in Tailwind CSS

The container class sets the max-width of an element to match the min-width of the current breakpoint. This is useful if you’d prefer to design for a fixed set of screen sizes instead of trying to accommodate a fully fluid viewport.

Note that unlike containers you might have used in other frameworks, Tailwind’s container does not center itself automatically and does not have any built-in horizontal padding.

<div class="container mx-auto px-4">
  <!-- ... -->
</div>

References
https://tailwindcss.com/docs/container

Install Tailwind CSS in React

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Add the paths to all of your template files in your tailwind.config.js file.

module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Add the @tailwind directives for each of Tailwind’s layers to your ./src/index.css file.

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

Run your build process with npm run start.

npm run start

References
https://tailwindcss.com/docs/guides/create-react-app

Integrating Tailwind CSS with Blazor

Creating An npm Project

Make sure that you have Node.js and npm CLI tools installed on your machine. Open the root directory of your Blazor Project.

npm init

Adding Tailwind CSS & Other Packages

npm install -D tailwindcss postcss autoprefixer postcss-cli

Configuring PostCSS

As mentioned earlier, POSTCSS will be responsible for transforming the tailwind.css to your own version. Create a new JS file in the root directory of the project and name it postcss.config.js.

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  }
}

Configuring Tailwind CSS

npx tailwindcss init

tailwind.config.js

module.exports = {
content: ["./**/*.html","./**/*.razor"],
theme: {
extend: {},
},
plugins: [],
}

In the wwwroot\css folder add a new CSS file and name it app.css. ( You could name it anything). This is what POSTCSS will use to generate your site’s CSS resource. Here we will be adding imports from the tailwind CSS library.

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

Building CSS With PostCSS CLI

Now, we need to build a script that can automate the postcss processing. Add the highlighted lines to your package.json file. What this script/command does is simple – It takes in app.css as the input and generates an app.min.css file in the same path. The newly generated file contains the complete tailwindcss content.

{
  "name": "blazorwithtailwindcss",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "buildcss": "postcss wwwroot/css/app.css -o wwwroot/css/app.min.css"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^10.2.4",
    "postcss": "^8.2.6",
    "postcss-cli": "^8.3.1",
    "tailwindcss": "^2.0.3"
  }
}
npm run buildcss

This would have generated an app.min.css file in your root directory. You can notice that all the TailwindCSS styles are generated here.

Removing Unused CSS (See Configuring Tailwind CSS instead because purge is obsolete in version 3)

Open up your tailwind.config.js and modify it to match the following.

const colors = require('tailwindcss/colors');
module.exports = {
    purge: {
        enabled: true,
        content: [
            './**/*.html',
            './**/*.razor'
        ],
    },
    darkMode: false, 
    variants: {
        extend: {},
    },
    plugins: [],
}

PS, Make sure that you run the npm run buildcss command every time you make changes in any of the related js or CSS files. (In the next section, we will discuss post-build events that could automate running the npm command every time you build or rebuild the project.)

Configuring Post Build Events

Open your solution file and paste in the following highlighted snippet. This ensures that the dotnet build system runs the npm command once the project is built.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="npm run buildcss" />
  </Target>
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
</Project>

Adding The Stylesheet Reference

Finally, add the referend of the generated CSS file to your Blazor application. Since we have Server Project, you would probably want to add the following snippet to the _Host.cshml file. If you are on a WebAssembly project, Index.html is where you need to add the following.

<link href="~/css/app.min.css" rel="stylesheet" />

Optimizing for Production

npm install -D cssnano

If you’re using Tailwind CLI, you can minify your CSS by adding the --minify flag:

npx tailwindcss -o build.css --minify

If you’ve installed Tailwind as a PostCSS plugin, add cssnano to the end of your plugin list:

postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    cssnano: {preset: 'default'},
  }
}

References
https://codewithmukesh.com/blog/integrating-tailwind-css-with-blazor/
https://tailwindcss.com/docs/installation/using-postcss
https://tailwindcss.com/docs/optimizing-for-production

Absolute Positioning Inside Relative Positioning

A page element with relative positioning gives you the control to absolutely position children elements inside of it.

<div class="row">
  <div
    class="col p-3 mb-2 bg-secondary text-white mx-3 d-flex
    justify-content-center align-items-center rounded shadow-sm position-relative">
    <div class="flex-grow-1 text-center">{{parentName}}</div>
    <div class="spinner-border text-white position-absolute"
         style="right: 5px;"
         role="status" [ngClass]="{invisible:spinnerInvisibility}">
      <span class="sr-only">Loading...</span>
    </div>
  </div>
</div>

Reference
https://css-tricks.com/absolute-positioning-inside-relative-positioning/
https://www.quora.com/What-does-it-mean-when-the-parent-has-position-relative-and-the-child-has-position-absolute-in-CSS
https://css-tricks.com/forums/topic/add-and-overlay-div-in-nested-flex-box-container/

How to make a div 100% height of the browser window

div {
    height:100vh;
}

These units are vh (viewport height), vw (viewport width), vmin (viewport minimum length) and vmax (viewport maximum length).

How is 100vh different to 100%?

<body style="height:100%">
    <div style="height:200px">
        <p style="height:100%; display:block;">Hello, world!</p>
    </div>
</body>

The p tag here is set to 100% height, but because its containing div has 200px height, 100% of 200px becomes 200px, not 100% of the body height. Using 100vh instead means that the p tag will be 100% height of the body regardless of the div height

References
https://stackoverflow.com/questions/1575141/how-to-make-a-div-100-height-of-the-browser-window

animate.css

Dynamically add animations using jQuery with ease:

$('#yourElement').addClass('animated bounceOutLeft');

You can also detect when an animation ends:

$('#yourElement').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', doSomething);

You can change the duration of your animations, add a delay or change the number of times that it plays:

#yourElement {
  -vendor-animation-duration: 3s;
  -vendor-animation-delay: 2s;
  -vendor-animation-iteration-count: infinite;
}

References
https://github.com/daneden/animate.css
https://daneden.github.io/animate.css/

CSS3 Animations

An animation lets an element gradually change from one style to another.

/* The animation code */
@keyframes example {
    from {background-color: red;}
    to {background-color: yellow;}
}

/* The element to apply the animation to */
div {
    width: 100px;
    height: 100px;
    background-color: red;
    animation-name: example;
    animation-duration: 4s;
}
/* The animation code */
@keyframes example {
    0%   {background-color: red;}
    25%  {background-color: yellow;}
    50%  {background-color: blue;}
    100% {background-color: green;}
}
/* The animation code */
@keyframes example {
    0%   {background-color: red; left:0px; top:0px;}
    25%  {background-color: yellow; left:200px; top:0px;}
    50%  {background-color: blue; left:200px; top:200px;}
    75%  {background-color: green; left:0px; top:200px;}
    100% {background-color: red; left:0px; top:0px;}
}

Delay an Animation

div {
    width: 100px;
    height: 100px;
    position: relative;
    background-color: red;
    animation-name: example;
    animation-duration: 4s;
    animation-delay: 2s;
}

Set How Many Times an Animation Should Run

div {
    width: 100px;
    height: 100px;
    position: relative;
    background-color: red;
    animation-name: example;
    animation-duration: 4s;
    animation-iteration-count: 3;
}

use the value “infinite” to make the animation continue for ever

Run Animation in Reverse Direction or Alternate Cycles

div {
    width: 100px;
    height: 100px;
    position: relative;
    background-color: red;
    animation-name: example;
    animation-duration: 4s;
    animation-iteration-count: 3;
    animation-direction: reverse;
}
div {
    width: 100px;
    height: 100px;
    position: relative;
    background-color: red;
    animation-name: example;
    animation-duration: 4s;
    animation-iteration-count: 3;
    animation-direction: alternate;
}

Specify the Speed Curve of the Animation

#div1 {animation-timing-function: linear;}
#div2 {animation-timing-function: ease;}
#div3 {animation-timing-function: ease-in;}
#div4 {animation-timing-function: ease-out;}
#div5 {animation-timing-function: ease-in-out;}

References
http://www.w3schools.com/css/css3_animations.asp