blazor asp.net core y tailwindcss

Blazor en ASP.NET Core + Tailwind CSS

Este tutorial te guía a través de los pasos básicos para configurar Blazor en ASP.NET Core y Tailwind CSS, proporcionándote las herramientas y conocimientos necesarios para comenzar a construir aplicaciones web atractivas y funcionales. Cubriremos desde la configuración del entorno de desarrollo hasta la implementación de una interfaz de usuario básica.

Tailwind CSS, es un framework CSS de utilidades que permite a los desarrolladores diseñar interfaces de usuario de forma rápida y eficiente con clases de utilidad. A diferencia de otros frameworks CSS, Tailwind se centra en ofrecer bloques de construcción de bajo nivel para un diseño personalizado, sin imponer un diseño visual predeterminado.

Primeros pasos

1. Crea el nuevo proyecto de Blazor

Comencemos creando un nuevo proyecto Blazor WebAssembly

* Es necesario tener instalado Node.js y npm CLI

2. Inicializa nuevo proyecto de Node.js

Ejecutamos el comando npm init desde el simbolo de sistema en la raíz del proyecto. Esto inicializará un nuevo proyecto de Node.js, creando un archivo package.json que gestiona las dependencias del proyecto, scripts y otra metadata.

npm init
3. Añadir Tailwind CSS y otros paquetes

En el terminal, ejecuta el siguiente comando:

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

Este comando instala tres paquetes de Node.js en tu proyecto:

  • tailwindcss@latest: Instala la versión más reciente de Tailwind CSS.
  • postcss@latest: Instala la versión más reciente de PostCSS, una herramienta utilizada para transformar estilos CSS con plugins de JavaScript. PostCSS es necesario para procesar los archivos CSS de Tailwind.
  • autoprefixer@latest: Instala la versión más reciente de Autoprefixer, un plugin de PostCSS que añade prefijos automáticos a las reglas CSS para asegurar la compatibilidad con diferentes navegadores.

Al especificar @latest, te aseguras de obtener la versión más reciente de cada paquete.

4. Configurar PostCSS

Creamos postcss.config.js en la raíz de tu proyecto. Este archivo define cómo PostCSS debe procesar tu CSS, incluyendo la utilización de varios plugins como Tailwind CSS y Autoprefixer.

Abre este archivo y configúralo para utilizar Tailwind CSS y Autoprefixer. Aquí tienes un ejemplo básico de cómo podría verse:

module.exports = {
    plugins: {
        tailwindcss: {},
        autoprefixer: {},
    }
}
5. Configurar Tailwind CSS

Ejecuta el comando npx tailwindcss init que se utiliza para inicializar Tailwind CSS en tu proyecto.

npx tailwindcss init

Este comando crea un archivo de configuración de Tailwind, generalmente llamado tailwind.config.js, en la raíz de tu proyecto. Este archivo es donde puedes personalizar tu configuración de Tailwind CSS según las necesidades de tu proyecto.

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./**/*.razor', './**/*.cshtml'],
  theme: {
    extend: {},
  },
  plugins: [],
}

En la carpeta wwwroot, agrega un nuevo archivo CSS y asígnele el nombre app.css. Esto es lo que PostCSS usará para generar el recurso CSS de tu sitio. Aquí agregaremos importaciones de la biblioteca CSS de tailwind:

@tailwind base;
@tailwind components;
@tailwind utilities;
6. Crear CSS con PostCSS CLI

Ahora, necesitamos añadir un script llamado buildcss que pueda automatizar el procesamiento de PostCSS.

{
  "scripts": {
    "buildcss": "postcss wwwroot/css/app.css -o wwwroot/css/app.min.css"
  },
  "dependencies": {
    "postcss-cli": "^11.0.0"
  },
  "devDependencies": {
    "autoprefixer": "^10.4.17",
    "postcss": "^8.4.33",
    "tailwindcss": "^3.4.1"
  }
}

El propósito principal de este script es tomar tu hoja de estilos CSS principal (app.css), procesarla con PostCSS (lo que podría incluir aplicar transformaciones como autoprefixing, minificación, o aplicar utilidades de Tailwind CSS), y luego guardar el resultado en un nuevo archivo (app.min.css), que es una versión optimizada para su uso en producción.

Ahora, puedes ejecutar este script utilizando el comando npm run buildcss en tu terminal.

npm run buildcss

Aquí el nuevo archivo app.min.css :

7. Configuración de eventos posteriores a la compilación

Configura tu proyecto .NET para que, después de que se complete la construcción del mismo, automáticamente ejecute el comando npm run buildcss. Esto es útil para asegurar que tus archivos CSS sean procesados y optimizados cada vez que construyes tu proyecto, manteniendo tus estilos actualizados y optimizados para producción sin necesidad de ejecutar manualmente este paso.

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="npm run buildcss" />
  </Target>
8. Añadir la referencia del archivo CSS generado a la aplicación Blazor
<link rel="stylesheet" href="css/app.min.css" />
9. Por último, podemos añadir componentes

Vamos a probar añadiendo un componente de ejemplo de Tailwind a MainLayout.razor

@inherits LayoutComponentBase

<div class="bg-white">
    <header class="absolute inset-x-0 top-0 z-50">
        <nav class="flex items-center justify-between p-6 lg:px-8" aria-label="Global">
            <div class="flex lg:flex-1">
                <a href="#" class="-m-1.5 p-1.5">
                    <span class="sr-only">Your Company</span>
                    <img class="h-8 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="">
                </a>
            </div>
            <div class="flex lg:hidden">
                <button type="button" class="-m-2.5 inline-flex items-center justify-center rounded-md p-2.5 text-gray-700">
                    <span class="sr-only">Open main menu</span>
                    <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
                    </svg>
                </button>
            </div>
            <div class="hidden lg:flex lg:gap-x-12">
                <a href="#" class="text-sm font-semibold leading-6 text-gray-900">Product</a>
                <a href="#" class="text-sm font-semibold leading-6 text-gray-900">Features</a>
                <a href="#" class="text-sm font-semibold leading-6 text-gray-900">Marketplace</a>
                <a href="#" class="text-sm font-semibold leading-6 text-gray-900">Company</a>
            </div>
            <div class="hidden lg:flex lg:flex-1 lg:justify-end">
                <a href="#" class="text-sm font-semibold leading-6 text-gray-900">Log in <span aria-hidden="true">→</span></a>
            </div>
        </nav>
        <!-- Mobile menu, show/hide based on menu open state. -->
        <div class="lg:hidden" role="dialog" aria-modal="true">
            <!-- Background backdrop, show/hide based on slide-over state. -->
            <div class="fixed inset-0 z-50"></div>
            <div class="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10">
                <div class="flex items-center justify-between">
                    <a href="#" class="-m-1.5 p-1.5">
                        <span class="sr-only">Your Company</span>
                        <img class="h-8 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="">
                    </a>
                    <button type="button" class="-m-2.5 rounded-md p-2.5 text-gray-700">
                        <span class="sr-only">Close menu</span>
                        <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                        </svg>
                    </button>
                </div>
                <div class="mt-6 flow-root">
                    <div class="-my-6 divide-y divide-gray-500/10">
                        <div class="space-y-2 py-6">
                            <a href="#" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50">Product</a>
                            <a href="#" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50">Features</a>
                            <a href="#" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50">Marketplace</a>
                            <a href="#" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50">Company</a>
                        </div>
                        <div class="py-6">
                            <a href="#" class="-mx-3 block rounded-lg px-3 py-2.5 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50">Log in</a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </header>

    <div class="relative isolate px-6 pt-14 lg:px-8">
        <div class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" aria-hidden="true">
            <div class="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]" style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)"></div>
        </div>
        <div class="mx-auto max-w-2xl py-32 sm:py-48 lg:py-56">
            <div class="hidden sm:mb-8 sm:flex sm:justify-center">
                <div class="relative rounded-full px-3 py-1 text-sm leading-6 text-gray-600 ring-1 ring-gray-900/10 hover:ring-gray-900/20">
                    Announcing our next round of funding. <a href="#" class="font-semibold text-indigo-600"><span class="absolute inset-0" aria-hidden="true"></span>Read more <span aria-hidden="true">→</span></a>
                </div>
            </div>
            <div class="text-center">
                <h1 class="text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">Data to enrich your online business</h1>
                <p class="mt-6 text-lg leading-8 text-gray-600">Anim aute id magna aliqua ad ad non deserunt sunt. Qui irure qui lorem cupidatat commodo. Elit sunt amet fugiat veniam occaecat fugiat aliqua.</p>
                <div class="mt-10 flex items-center justify-center gap-x-6">
                    <a href="#" class="rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Get started</a>
                    <a href="#" class="text-sm font-semibold leading-6 text-gray-900">Learn more <span aria-hidden="true">→</span></a>
                </div>
            </div>
        </div>
        <div class="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]" aria-hidden="true">
            <div class="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]" style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)"></div>
        </div>
    </div>
</div>

Compilamos el proyecto y despues ejecutamos el comando dotnet watch run que inicia la aplicación y la observa para reiniciarla automáticamente cada vez que se modifican archivos del código fuente. Si el proyecto no se encuentra en la misma carpeta de que la solución puedes indicarlo con --project

dotnet watch run --project src/8.x

Y el resultado:

Ya tenemos todo listo para continuar añadiendo y probando componentes de tailwind con Blazor.

Código de ejemplo

Blazor + Tailwind CSS Template

1