├── src ├── main.ts ├── style.css └── typescript.svg ├── vite.config.ts ├── .gitignore ├── package.json ├── index.html ├── tsconfig.json ├── LICENSE ├── public └── vite.svg └── Readme.md /src/main.ts: -------------------------------------------------------------------------------- 1 | import "./style.css"; 2 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import tailwindcss from "@tailwindcss/vite"; 3 | export default defineConfig({ 4 | plugins: [tailwindcss()], 5 | }); 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-boiler-css", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "typescript": "~5.9.3", 13 | "vite": "^7.2.2" 14 | }, 15 | "dependencies": { 16 | "@tailwindcss/vite": "^4.1.17", 17 | "tailwindcss": "^4.1.17" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 00-boiler-css 8 | 9 | 10 |
11 |

12 | POR EL PODER DE TAILWIND !!! 13 |

14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 7 | "types": ["vite/client"], 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "verbatimModuleSyntax": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "erasableSyntaxOnly": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Lemoncode 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Hola Tailwind 2 | 3 | ## Vamos a instalar plugins 4 | 5 | Los que recomienda Tailwind: 6 | 7 | https://tailwindcss.com/docs/editor-setup 8 | 9 | vscode-tailwindcss 10 | 11 | Hay otro para ordenar las clases según le gusta a Tailwind :-@ TOC? 12 | 13 | ## El ejemplo 14 | 15 | Tailwind v4 **resetea todos los estilos por defecto**, incluyendo los 16 | tamaños por defecto de los `h1`, `h2`, etc. 17 | 18 | Por eso este HTML: 19 | 20 | ```html 21 |

POR EL PODER DE TAILWIND !!!

22 | ``` 23 | 24 | No se verá grande. Si queremos un tamaño y estilo concreto, **hay que 25 | definirlo usando utility classes**: 26 | 27 | ```diff 28 | -

29 | +

30 | POR EL PODER DE TAILWIND !!! 31 |

32 | ``` 33 | 34 | ### ¿Qué hace cada clase? 35 | 36 | 1. `text-4xl` → Tamaño grande. 37 | 2. `font-bold` → Texto en negrita. 38 | 3. `text-blue-600` → Color azul tono 600. 39 | 40 | Si guardas los cambios y recargas el navegador, verás que el H1 ahora tiene el tamaño, peso y color que le hemos indicado con las utility classes de Tailwind. 41 | 42 | ¿Y esas combinaciones de utility classes de dónde salen? Pues en versiones antiguas de tailwind se genereban TODAS ! y después se hacía un tree-shaking para quedarnos solo con las que usábamos en nuestro proyecto, como lo oyes te tocaba limpiar par ano acabar con un archivo de CSS de varios megas, es decir a partir de Tailwind v4: 43 | 44 | - Tailwind **YA NO genera todas las clases por defecto**. 45 | - Genera **solo las clases que detecta en el código fuente**. 46 | - El escaneo se hace a través de `@source` en tu CSS (no en 47 | `tailwind.config.js`). 48 | 49 | ¿Lo vemos en acción? Vamos a hacer un `npm run build` 50 | 51 | ```bash 52 | npm run build 53 | ``` 54 | 55 | Y en `dist/assets/index-xxxxx.css` verás algo así: 56 | 57 | ```css 58 | @layer utilities { 59 | .text-4xl { 60 | ...; 61 | } 62 | .font-bold { 63 | ...; 64 | } 65 | .text-blue-500 { 66 | ...; 67 | } 68 | .underline { 69 | ...; 70 | } 71 | } 72 | ``` 73 | 74 | > HOSTIS !!! PUES NO, HAY UN MONTON MAS DE CLASES !!! ¿Qué está pasando aquí? Pues mira que "mojonazo" que el plugin está pillando las del Readme.md jajajajaj. Si borramos el contenido del Readme.md y volvemos a hacer un build, veremos que solo quedan las clases que hemos usado en el index.html 75 | 76 | ```css 77 | @layer utilities { 78 | .text-4xl { 79 | font-size: var(--text-4xl); 80 | line-height: var(--tw-leading, var(--text-4xl--line-height)); 81 | } 82 | .font-bold { 83 | --tw-font-weight: var(--font-weight-bold); 84 | font-weight: var(--font-weight-bold); 85 | } 86 | .text-blue-500 { 87 | color: var(--color-blue-500); 88 | } 89 | .underline { 90 | text-decoration-line: underline; 91 | } 92 | } 93 | ``` 94 | 95 | Vamos a hacer una prueba rápida, modificamos el estilo inline del H1 y volvemos a hacer un build: 96 | 97 | ```diff 98 | -

99 | +

100 | ``` 101 | 102 | Si no está el Readme verás que en el CSS generado solo aparecen las clases `text-3xl` y `underline`. 103 | 104 | Bueno vamos a decirl a Tailwind que ignore el Readme.md para no tener estos problemas. 105 | 106 | _./src/styles.css_ 107 | 108 | ```diff 109 | @import "tailwindcss"; 110 | + @source not "../Readme.md"; 111 | ``` 112 | 113 | Aquí le estamos diciendo que ignore el Readme.md a la hora de buscar clases usadas en el proyecto. 114 | 115 | Por defecto Tailwind ignora los archivos que esténen el .gitignore, y algunos otros, más info: 116 | 117 | https://tailwindcss.com/docs/detecting-classes-in-source-files 118 | 119 | ## Configurar estilos por defecto para `

` 120 | 121 | Si no quieres escribir siempre `class="text-3xl underline"`, puedes 122 | añadir estilos globales usando `@apply`. 123 | 124 | _./src/styles.css_ 125 | 126 | ```diff 127 | @import "tailwindcss"; 128 | @source not "../Readme.md"; 129 | 130 | + h1 { 131 | + @apply text-3xl underline; 132 | + } 133 | ``` 134 | 135 | Aquí le estamos diciendo que aplique las clases `text-3xl` y `underline` a todos los H1. 136 | 137 | Vamos a eliminarlo ahora del markup: 138 | 139 | _./index.html_ 140 | 141 | ```diff 142 | -

143 | +

144 | POR EL PODER DE TAILWIND !!! 145 |

146 | ``` 147 | 148 | ### ¿Esto es bueno o malo? 149 | 150 | **Sí y no.** 151 | 152 | - ✔ Sí: HTML más limpio y semántico.\ 153 | 154 | - ✔ No repites clases una y otra vez. 155 | 156 | - ❌ No: si copias un snippet de otro proyecto Tailwind, el resultado 157 | visual será distinto.\ 158 | 159 | - ❌ Se rompe un poco la filosofía "utility-first pura". 160 | 161 | > 🎯 No hay bala de plata.\ 162 | > Depende de si quieres prioridad en legibilidad o en portabilidad. 163 | 164 | Otra opcíon sería definir un _theme_ con los estilos que quieres, un pequeño adelanto (más adelante veremos esto con más detalle). 165 | 166 | _./src/styles.css_ 167 | 168 | ```diff 169 | @import "tailwindcss"; 170 | @source not "../Readme.md"; 171 | 172 | + @theme { 173 | + --h1-size: 2rem; 174 | + --h1-line: 1.2; 175 | + --h1-decoration: underline; 176 | + } 177 | 178 | - h1 { 179 | - @apply text-3xl underline-offset-1; 180 | - } 181 | ``` 182 | 183 | Y en el HTML: 184 | 185 | _./index.html_ 186 | 187 | ```diff 188 | -

189 | +

190 | POR EL PODER DE TAILWIND !!! 191 |

192 | ``` 193 | 194 | ## Aproximaciones 195 | 196 | ¿Qué enfoques tenemos? 197 | 198 | ### Minimalista (100% utility-first, recomendado) 199 | 200 | No uses `h1 { @apply ... }`.\ 201 | Pon siempre clases en el HTML. 202 | 203 | ### Intermedia (la práctica de muchos equipos) 204 | 205 | Define estilos globales para: - `body` - headings - textos base 206 | 207 | Y el resto, con utilities. 208 | 209 | ### Más avanzada 210 | 211 | Define tokens con `@theme` para colores, tipografía, espaciado, etc. 212 | --------------------------------------------------------------------------------