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 |
--------------------------------------------------------------------------------