Installation
Setting up Tailwind CSS in a .NET project.
Start by creating a new .NET Blazor project if you don’t have one set up already.
The steps in this guide will work not only for Blazor, but for any .NET Web project.
dotnet new blazor --empty -n my-app
Create a new stylesheet at Styles/main.css
mkdir Styles && touch Styles/main.css
Add an @import
to Styles/main.css
that imports Tailwind CSS.
@import "tailwindcss";
Add a file called Tailwind.targets
at the root of the project.
This file declares MSBuild targets that download the Tailwind CLI, and build the stylesheets as part of dotnet build
.
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- This file exposes the following parameters --> <!-- TailwindVersion: The version of the Tailwind Standalone CLI to download. --> <!-- TailwindDownloadPath: The path to where to download the Tailwind Standalone CLI. This property is optional, and defaults to %LOCALAPPDATA% on Windows, and $XDG_CACHE_HOME on Linux and MacOS. --> <!-- TailwindInputStyleSheetPath: The path to the input stylesheet. --> <!-- TailwindOutputStyleSheetPath: The path to the output stylesheet. --> <!-- TailwindOptimizeOutputStyleSheet: Whether to optimize the output stylesheet. This property is optional, and defaults to false. --> <!-- TailwindMinifyOutputStyleSheet: Whether to minify the output stylesheet. This property is optional, and defaults to false when Configuration is Debug, and true when Configuration is Release. --> <!-- TailwindDownloadUrl: The URL to the Tailwind Standalone CLI. This property is optional, and defaults to downloading the specified version from GitHub. --> <!-- To override these properties, create a PropertyGroup in the csproj file --> <!-- For example: --> <!-- <PropertyGroup> --> <!-- <TailwindVersion>v4.0.14</TailwindVersion> --> <!-- <TailwindInputStyleSheetPath>Styles/main.css</TailwindVersion> --> <!-- <TailwindOutputStyleSheetPath>wwwroot/main.css</TailwindVersion> --> <!-- </PropertyGroup --> <PropertyGroup> <TailwindOptimizeOutputStyleSheet Condition="'$(TailwindOptimizeOutputStyleSheet)' == ''">false</TailwindOptimizeOutputStyleSheet> <TailwindMinifyOutputStyleSheet Condition="$(TailwindMinifyOutputStyleSheet) == '' And '$(Configuration)' == 'Debug'">false</TailwindMinifyOutputStyleSheet> <TailwindMinifyOutputStyleSheet Condition="$(TailwindMinifyOutputStyleSheet) == '' And '$(Configuration)' == 'Release'">true</TailwindMinifyOutputStyleSheet> <!-- The path to where Tailwind should be downloaded to --> <!-- This should be a path that is writable by the current user, as well as one that is accessible in CI/CD pipelines --> <!-- By default, this is set to the local app data folder on Windows, and $XDG_CACHE_HOME on Linux and MacOS --> <!-- On Linux and MacOS, use $XDG_CACHE_HOME or $HOME/.cache --> <TailwindDownloadPath Condition="'$(TailwindDownloadPath)' == '' And ($([System.OperatingSystem]::IsLinux()) Or $([System.OperatingSystem]::IsMacOS()))">$([MSBuild]::ValueOrDefault($([System.Environment]::GetEnvironmentVariable('XDG_CONFIG_HOME')), $([System.IO.Path]::Combine($([System.Environment]::GetEnvironmentVariable('HOME')), '.cache'))))</TailwindDownloadPath> <!-- On Windows, use local app data (%LOCALAPPDATA%) --> <TailwindDownloadPath Condition="'$(TailwindDownloadPath)' == '' And $([System.OperatingSystem]::IsWindows())">$(LOCALAPPDATA)</TailwindDownloadPath> </PropertyGroup> <!-- Validate the parameters before download or building --> <Target Name="ValidateParameters" BeforeTargets="DownloadTailwind; Tailwind"> <!-- Ensure the version is specified --> <Error Condition="'$(TailwindVersion)' == ''" Text="Tailwind version not specified. Please specify the version. For example: <PropertyGroup><TailwindVersion>v4.0.14</TailwindVersion></PropertyGroup>"/> <!-- Ensure the input stylesheet path is specified & the file exists --> <Error Condition="'$(TailwindInputStyleSheetPath)' == ''" Text="Tailwind input stylesheet not specified. Please specify the path to the input stylesheet in the csproj file. For example: <PropertyGroup><TailwindInputStyleSheetPath>Styles/main.css</TailwindInputStyleSheetPath></PropertyGroup>"/> <Error Condition="!Exists('$(TailwindInputStyleSheetPath)')" Text="Tailwind input stylesheet '$(TailwindInputStyleSheetPath)' does not exist. Please specify a path to a stylesheet. For example: <PropertyGroup><TailwindInputStyleSheetPath>Styles/main.css</TailwindInputStyleSheetPath></PropertyGroup>"/> <!-- Ensure the output stylesheet path is specified --> <Error Condition="'$(TailwindOutputStyleSheetPath)' == ''" Text="Tailwind output stylesheet not specified. Please specify the path to the output stylesheet in the csproj file. For example: <PropertyGroup><TailwindOutputStyleSheetPath>Styles/main.css</TailwindOutputStyleSheetPath></PropertyGroup>"/> <!-- Ensure the download path is specified --> <Error Condition="'$(TailwindDownloadPath)' == ''" Text="Tailwind download path not specified. Please specify the download path in the csproj file. For example: <PropertyGroup><TailwindDownloadPath>/tmp</TailwindDownloadPath></PropertyGroup>"/> </Target> <!-- This line supports hot reload by instructing dotnet watch to be aware of modifications to the input stylesheet --> <ItemGroup Condition="Exists('$(TailwindInputStyleSheetPath)')"> <Watch Include="$(TailwindInputStyleSheetPath)"/> </ItemGroup> <Target Name="DownloadTailwind"> <PropertyGroup> <!-- Determine which version of Tailwind to use based on the current OS & architecture --> <TailwindReleaseName Condition="$([System.OperatingSystem]::IsLinux()) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == X64">tailwindcss-linux-x64</TailwindReleaseName> <TailwindReleaseName Condition="$([System.OperatingSystem]::IsLinux()) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == Armv7">tailwindcss-linux-armv7</TailwindReleaseName> <TailwindReleaseName Condition="$([System.OperatingSystem]::IsMacOS()) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == X64">tailwindcss-macos-x64</TailwindReleaseName> <TailwindReleaseName Condition="$([System.OperatingSystem]::IsMacOS()) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == Arm64">tailwindcss-macos-arm64</TailwindReleaseName> <TailwindReleaseName Condition="$([System.OperatingSystem]::IsWindows()) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == X64">tailwindcss-windows-x64.exe</TailwindReleaseName> <TailwindReleaseName Condition="$([System.OperatingSystem]::IsWindows()) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == Arm64">tailwindcss-windows-arm64.exe</TailwindReleaseName> <TailwindDownloadUrl Condition="'$(TailwindDownloadUrl)' == '' And $(TailwindVersion) != 'latest'">https://github.com/tailwindlabs/tailwindcss/releases/download/$(TailwindVersion)/$(TailwindReleaseName)</TailwindDownloadUrl> <TailwindDownloadUrl Condition="'$(TailwindDownloadUrl)' == '' And $(TailwindVersion) == 'latest'">https://github.com/tailwindlabs/tailwindcss/releases/latest/download/$(TailwindReleaseName)</TailwindDownloadUrl> </PropertyGroup> <!-- Download the file --> <DownloadFile DestinationFolder="$([System.IO.Path]::Combine('$(TailwindDownloadPath)', 'Tailwind', '$(TailwindVersion)'))" DestinationFileName="$(TailwindReleaseName)" SourceUrl="$(TailwindDownloadUrl)" SkipUnchangedFiles="true" Retries="3"> <Output TaskParameter="DownloadedFile" PropertyName="TailwindCliPath"/> </DownloadFile> <!-- On unix systems, make the file executable --> <Exec Condition="Exists('$(TailwindCliPath)') And ($([System.OperatingSystem]::IsLinux()) Or $([System.OperatingSystem]::IsMacOS()))" Command="chmod +x '$(TailwindCliPath)'"/> </Target> <!-- When building the project, run the Tailwind CLI --> <!-- This target can also be executed manually. For example, with dotnet watch: `dotnet watch msbuild /t:Tailwind` --> <!-- In order to use hot reload, run both `dotnet watch run` and `dotnet watch msbuild /t:Tailwind` --> <Target Name="Tailwind" DependsOnTargets="DownloadTailwind" BeforeTargets="Build"> <PropertyGroup> <!-- Normalize the paths provided --> <TailwindCliPath>$([MSBuild]::NormalizePath('$(TailwindCliPath)'))</TailwindCliPath> <TailwindInputStyleSheetPath>$([MSBuild]::NormalizePath('$(TailwindInputStyleSheetPath)'))</TailwindInputStyleSheetPath> <TailwindOutputStyleSheetPath>$([MSBuild]::NormalizePath('$(TailwindOutputStyleSheetPath)'))</TailwindOutputStyleSheetPath> <TailwindBuildCommand>"$(TailwindCliPath)" -i "$(TailwindInputStyleSheetPath)" -o "$(TailwindOutputStyleSheetPath)"</TailwindBuildCommand> <!-- Add optimize flag if specified --> <TailwindBuildCommand Condition="'$(TailwindOptimizeOutputStyleSheet)' == 'true'">$(TailwindBuildCommand) --optimize</TailwindBuildCommand> <!-- Add minify flag if specified --> <TailwindBuildCommand Condition="'$(TailwindMinifyOutputStyleSheet)' == 'true'">$(TailwindBuildCommand) --minify</TailwindBuildCommand> </PropertyGroup> <Exec Command="$(TailwindBuildCommand)"/> </Target></Project>
Specify the version and input & output stylesheets, and import the Tailwind.targets
file.
<PropertyGroup> <TailwindVersion>latest</TailwindVersion> <TailwindInputStyleSheetPath>Styles/main.css</TailwindInputStyleSheetPath> <TailwindOutputStyleSheetPath>wwwroot/main.build.css</TailwindOutputStyleSheetPath></PropertyGroup><Import Project="Tailwind.targets" />
Add a reference to the CSS file Tailwind generated to the head
of the Components/App.razor
file.
<link rel="stylesheet" href="@Assets["main.build.css"]"/>
Start using Tailwind’s utility classes to style your content.
<h1 class="text-3xl font-bold underline"> Hello world!</h1>
Build the project and start the application with dotnet run
.
dotnet run