hand Inicio

JSBLOQS.com

Qué puedo hacer por ti?

nochedía

DESARROLLO WEB con
REACT y WORDPRESS

Apúntate a la newsletter (escribo algo de tanto en cuanto)
Wallpaper)

Aprender tailwindCSS con React

1500 palabras
6 minutos
August 21, 2020
cursoscssreact

El framework tailwindcss nos ofrece la posibilidad de definir todos los estilos css inline

Esto que parece restrictivo (y lo es), nos permite entre otras cosas tener un diseño consistente y sobre todo con muy poco mantenimiento

Prólogo

El framework TailwindCSS se define como utility-first, y este es un concepto diferente al de styled-components que tiene sus ventajas y sus inconvenientes

  • El principal inconveniente es que perdemos la encapsulación que conseguimos con styled-components (con la queja recurrente de importar todos los estilos de tailwind en todas las páginas)

  • La principal ventaja es la restricción a la hora de elegir, en lugar de escoger entre todo el repertorio de css lo que hacemos es escoger entre un grupo de clases preestablecidas y que no son semánticas, esto nos permite ser más consistentes

En otras palabras, tailwind nos presiona para que seamos muy minimalistas, mientras que con styled-components al final es fácil generar mucha redundancia con cada componente absolutamente ajustado a las necesidades

  • Lo bueno es que siendo minimalistas tendremos consistencia en la estética y por definición muy poco mantenimiento

  • Lo malo es que si nos despistamos terminaremos con monstruos inline con 20 o más clases (a ver quien entiende y mantiene eso)

En este curso vamos a aprender tailwindcss, vamos allá

  1. Prólogo
  2. Funcionamiento básico de tailwind
  3. Aprendiendo tailwind
  4. Instalando tailwind
  5. Diseñando un bloque de ejemplo

Funcionamiento básico de tailwind

Cómo funciona un framework utility-first?

Fácil, se trata de prescindir de la semántica

En lugar de utilizar nombres semánticos como .estilo_de_mi_formulario vamos a utilizar nombres que describan su función, tipo .ancho_500 .fondo_gris .letra_Lato

Así nos saltamos el paso intermedio de encapsular los estilos en una clase con un nombre irrelevante, para definirlos directamente en el mismo elemento

Y esto lo podemos hacer (sin volvernos locos) porque tailwind nos da una sintaxis breve y un grupo de clases predefinidas que nos limitan y por lo tanto nos obligan a escribir de un modo consistente

Cuando se dice "consistente" es porque en lugar de tener paddings de 10px, de 15px y de 18px pero también de 20px, producto de diseñar cada vez de nuevo cada elemento, tendremos clases que nos darán distancias ya fijadas (que podremos cambiar si queremos, pero que serán comunes para toda nuestra página web), con lo que visualmente tendremos una estética por fuerza más homogénea

El espíritu de tailwind es que no necesitas estar constantemente reinventando los diseños web, ya están todos inventados, tu trabajo sólo es combinarlos a partir de unidades concretas predefinidas

En la práctica

html
<!-- clase semántica -->
<h1 className="mi-componente-de-header">Hey</h1>
<style>
.mi-componente-de-header {
font-size: 1.875rem;
font-weight: 700;
background: #cbd5e0;
}
</style>
<!-- clase utility-first -->
<h1 className="text-3xl font-bold bg-gray-400">Hey</h1>

Si te fijas en la cantidad de código que nos hemos ahorrado verás el porqué tendrás menos mantenimiento con tailwind

Y esto es porque estas clases utility-first ya nos vienen por defecto con tailwind, aunque si los valores no nos gustan podemos definir nuestras propias normas (compartidas para todo el proyecto)

Otro concepto interesante es que ahorrarse el encapsular los estilos en una clase tiene mucho sentido puesto que la gran mayoría de veces esa clase no la reutilizaremos

Y si no necesitamos reutilizarlo, para qué definirlo aparte?

Y en aquellos casos donde sí queremos reutilizar clases, si utilizamos React la solución es extremadamente elegante (lo vemos más abajo)

Aprendiendo tailwind

Aprender tailwind se reduce a

  • Familiarizarse con las clases existentes
  • Familiarizarse con los archivos que podemos tocar para cambiar los valores por defecto
  • Aprenderse como escribir los valores responsive, los hover, etc

Familiarizarse con las clases existentes

Para el primer punto hay que mirarse la documentación, y aunque al principio pueda parecer confusa lo cierto es que sigue una lógica sencilla y consistente

Un ejemplo lo tenemos con este botón de la documentación oficial

html
<button class="bg-blue-500 text-white font-bold py-2 px-4 rounded">Button</button>

Todas las clases son auto-explicativas excepto quizá las py-2, px-4 y rounded, que si miramos la documentación vemos que se traducen en

css
/* py-2 */
padding-top: 0.5rem;
padding-bottom: 0.5rem;
/* px-4 */
padding-left: 1rem;
padding-right: 1rem;
/* rounded */
border-radius: 0.25rem;

Lo bueno es que es muy fácil acostumbrarse a esta nomenclatura

Lo malo es que es otra nomenclatura que hay que aprender

Cambiando los valores por defecto

Tenemos un archivo central que es tailwind.config.js, y allí podemos cambiar lo que nos plazca (veremos el archivo en sí cuando instalemos la librería más adelante)

La sintaxis es la misma que con theme-ui por lo que si ya lo conoces te sonará todo, y si no lo conoces, luego si lo conoces también te sonará todo

jsx
// tailwind.config.js
module.exports = {
theme: {},
}

Todo lo que pongamos dentro de theme sustituirá los valores por defecto que tengamos

Quizá lo más habitual será el font-size (que al final siempre depende de la tipografía) y los colores (la paleta por defecto, por ejemplo, no incluye grises reales)

jsx
// tailwind.config.js
module.exports = {
theme: {
colors: {
realgrey: '#ccc',
},
},
}

Configurándolo de esta forma tailwind nos dará acceso automáticamente a las clases bg-realgrey, text-realgrey y border-realgrey

No tenemos forma de utilizar ese color directamente, si queremos hacerle tendremos que definir una nueva clase al estilo clásico

css
.btn-blue {
background-color: theme('colors.realgrey');
}

En realidad lo que hemos hecho arriba con tailwind.config.js es sustituir los colores que nos vienen por defecto, y quizá no queremos sustituirlos sino extenderlos, algo muy sencillo

jsx
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
realgrey: '#ccc',
},
},
},
}

De este modo estamos añadiendo el color realgrey (y si ese nombre ya estuviera definido entonces sólo sustituiríamos ese)

Para ver qué valores nos vienen por defecto los tienes aquí, y nada te impide copiar y utilizar ese mismo archivo tu mismo modificándolo directamente

Aparte del theme también podemos modificar otras cosas, como las variants que incluye la variante responsive

Estas variantes lo que hacen es generar las clases correspondientes a esas variantes

jsx
module.exports = {
variants: {
backgroundColor: ['responsive', 'hover'],
},
}

Aquí lo que hacemos es

  • Generar clases para la propiedad backgroundColor que nos servirán para distintas media-queries
  • Generar clases para el estado hover

Generar sólo las que nos interesen nos servirá para reducir el tamaño final del bundle

Del mismo modo también podemos modificar los breakpoints, es decir los valores que utilizaremos para los media-queries

jsx
// tailwind.config.js
module.exports = {
theme: {
screens: {
sm: '640px',
// => @media (min-width: 640px) { ... }
md: '768px',
// => @media (min-width: 768px) { ... }
lg: '1024px',
// => @media (min-width: 1024px) { ... }
xl: '1280px',
// => @media (min-width: 1280px) { ... }
},
},
}

Es decir, que si los valores que nos vienen por defecto no nos gustan, aquí es donde podemos cambiarlos y/o extenderlos, e incluso definir media-queries que no sean mobile-first y tengan el max-width

Lo puedes mirar en la documentación, mientras tanto aquí nos centraremos en utilizar lo que ya nos viene por defecto

Utilizando tailwind

Para utilizar tailwind nada más sencillo que utilizar las clases que ya nos vienen predefinidas

html
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Button</button>

Si te fijas, la clase hover:bg-blue-700 ya nos da pistas de que estamos definiendo una propiedad :hover, que en este caso quiere decir que ese botón cuando esté en hover se le aplique la clase bg-blue-700

No hay ninguna norma que te prohiba utilizar caracteres como el : en un nombre de clase

Y para el responsive?

Imaginemos que queremos modificar el padding de forma responsive

html
<button class="p-2 sm:p-10">Button</button>

Tan sencillo como esto, aquí tenemos definido para todo el mundo el p-2, y para tamaños mayores de 640px aplicaremos la clase p-10

Sólo nos falta saber qué hacer cuando queremos reutilizar parte de las clases, lo hacemos con @apply

html
<!-- original -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Button</button>
<!-- con una clase definida -->
<button class="my-button">Button</button>
<style>
.my-button {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.btn-blue:hover {
@apply bg-blue-700;
}
</style>

Claro está que así pierdes toda la gracia de tailwind, por lo que lo que se aconseja es hacer esta extracción a nivel de componente

jsx
const Button = () => (
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Button</button>
)

Luego verás un ejemplo algo más completo en el código final, pero ya ves cómo podemos reutilizar clases sin perder la elegancia de tailwind

Instalando tailwind

Para instalar tailwind en tu aplicación React (basada en create-react-app) bastaría con instalar el paquete

bash
yarn add tailwindcss

Y luego en tu hoja de estilos central

css
/* purgecss start ignore */
@tailwind base;
@tailwind components;
/* purgecss end ignore */
@tailwind utilities;

Y con esto ya tenemos a tailwind funcionando para nosotros, sin más, aunque lo suyo es crear el archivos de configuración de tailwind para ajustar el funcionamiento de PurgeCSS, integrado en tailwind y que nos sirve para descartar estilos que no estemos utilizando

jsx
// tailwind.config.js
module.exports = {
purge: ['./src/**/*.html', './src/**/*.jsx', './src/**/*.js'],
}

También forma parte de la configuración de purgeCSS los comentarios anteriores en la hoja css (/* purgecss start ignore */), que no es más que decirle a purgeCSS que sólo nos procese las @tailwind utilities (que es lo que nos recomiendan en la documentación)

Ahora podríamos bien importar los estilos de tailwind directamente (pero nos perderemos bastantes cosas), o utilizar la librería para transpilar nuestro tailwind-css a css de verdad

Para hacerlo bastaría con configurar el package.json para que cuando hagamos el start nos compilase el código, y esto lo podemos hacer con el comando tailwindcss que ya nos viene incluido en la librería

json
"scripts": {
"build:style": "tailwindcss build src/styles.css -o transpiled_styles.css",
"start": "npm run build:style && react-scripts start"
}

Pero para que esto funcione en un codesandbox no nos basta con la aplicación habitual sino que necesitamos una aplicación con backend, algo que nos explican aquí y que se "reduce" a instalar precisamente un backend con React

Esto precisamente es lo que haríamos con NextJS, o sin backend con GatsbyJS

Aquí lo que haré será simplemente importar los estilos de tailwind para facilitarme la vida en codesandbox ver cómo funciona

Si quisiésemos instalarlo con Gatsby necesitaríamos configurar también PostCSS, algo que de hecho haremos en la mayoría de los casos

Para Gatsby necesitaríamos instalar el starter y las librerías

bash
gatsby new hello-world https://github.com/gatsbyjs/gatsby-starter-hello-world
yarn add --dev tailwindcss
yarn add gatsby-plugin-postcss

Configurar el plugin postCSS

jsx
// gatsby-config.js
module.exports = {
plugins: ['gatsby-plugin-postcss'],
}

Configurar el postCSS

jsx
// postcss.config.js
module.exports = () => ({
plugins: [require('tailwindcss')],
})

E importar un archivo global css en gatsby-browser.js

js
// gatsby-browser.js
import './src/global.css'

Un archivo que contendrá las bases de tailwind

css
/* ./src/global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

Y ya sólo faltaría la configuración de purgeCSS

jsx
// tailwind.config.js
module.exports = {
purge: ['./src/**/*.js', './src/**/*.jsx', './src/**/*.ts', './src/**/*.tsx'],
}

Lo tienes todo en la documentación, donde también podríamos combinar tailwind con styled-components, algo que si bien tiene ventajas evidentes, me gustaría saber en cuánto augmenta el tamaño de JavaScript a interpretar para el navegador

Diseñando un bloque de ejemplo

Vista la instalación, algo que podemos hacer a nivel local con un simple CRA o aprovechar y utilizar NextJS o GatsbyJS, vamos a ver cómo luce un componente sencillo con un simple ejemplo que tienes en este codesandbox

El package.json (en el codesandbox no podemos ejecutar el tailwindcss por lo que no transpilamos nada)

json
{
"name": "tailwind",
"version": "1.0.0",
"description": "",
"keywords": [],
"main": "src/index.js",
"dependencies": {
"react": "16.12.0",
"react-dom": "16.12.0",
"react-scripts": "3.0.1",
"tailwindcss": "1.0.4"
},
"devDependencies": {},
"scripts": {
"build:style": "tailwindcss build src/styles.css -o transpiled_styles.css",
"start": "npm run build:style && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"browserslist": [">0.2%", "not dead", "not ie <= 11", "not op_mini all"]
}

La configuración de purge

js
// tailwind.config.js
module.exports = {
purge: ['./src/**/*.html', './src/**/*.jsx', './src/**/*.js'],
}

La hoja de estilos donde aprovecho para definir las clases de un background de gradientmagic.com

css
/* styles.css */
/* purgecss start ignore */
@tailwind base;
@tailwind components;
/* purgecss end ignore */
@tailwind utilities;
/* https://www.gradientmagic.com/collection/fracture */
.background {
background-image: linear-gradient(
35deg,
rgba(253, 253, 253, 0.03) 0%,
rgba(253, 253, 253, 0.03) 53%,
rgba(109, 109, 109, 0.03) 53%,
rgba(109, 109, 109, 0.03) 59%,
rgba(228, 228, 228, 0.03) 59%,
rgba(228, 228, 228, 0.03) 66%,
rgba(42, 42, 42, 0.03) 66%,
rgba(42, 42, 42, 0.03) 95%,
rgba(165, 165, 165, 0.03) 95%,
rgba(165, 165, 165, 0.03) 100%
), linear-gradient(
205deg,
rgba(62, 62, 62, 0.03) 0%,
rgba(62, 62, 62, 0.03) 31%,
rgba(200, 200, 200, 0.03) 31%,
rgba(200, 200, 200, 0.03) 41%,
rgba(30, 30, 30, 0.03) 41%,
rgba(30, 30, 30, 0.03) 47%,
rgba(151, 151, 151, 0.03) 47%,
rgba(151, 151, 151, 0.03) 60%,
rgba(95, 95, 95, 0.03) 60%,
rgba(95, 95, 95, 0.03) 100%
), linear-gradient(
30deg,
rgba(7, 7, 7, 0.03) 0%,
rgba(7, 7, 7, 0.03) 19%,
rgba(63, 63, 63, 0.03) 19%,
rgba(63, 63, 63, 0.03) 33%,
rgba(175, 175, 175, 0.03) 33%,
rgba(175, 175, 175, 0.03) 37%,
rgba(244, 244, 244, 0.03) 37%,
rgba(244, 244, 244, 0.03) 60%,
rgba(177, 177, 177, 0.03) 60%,
rgba(177, 177, 177, 0.03) 100%
), linear-gradient(90deg, rgb(162, 162, 162), rgb(229, 229, 229));
}
.background-box1 {
background-image: linear-gradient(
45deg,
rgb(20, 59, 44) 0%,
rgb(20, 59, 44) 62%,
rgb(72, 77, 92) 62%,
rgb(72, 77, 92) 69%,
rgb(124, 94, 140) 69%,
rgb(124, 94, 140) 76%,
rgb(176, 112, 188) 76%,
rgb(176, 112, 188) 88%,
rgb(228, 129, 236) 88%,
rgb(228, 129, 236) 100%
);
}
.background-box2 {
background-image: linear-gradient(
135deg,
transparent 0%,
transparent 21%,
rgba(253, 225, 42, 0.5) 21%,
rgba(253, 225, 42, 0.5) 48%,
transparent 48%,
transparent 95%,
rgba(247, 141, 81, 0.5) 95%,
rgba(247, 141, 81, 0.5) 100%
), linear-gradient(
45deg,
transparent 0%,
transparent 6%,
rgb(253, 225, 42) 6%,
rgb(253, 225, 42) 13%,
rgb(249, 169, 68) 13%,
rgb(249, 169, 68) 32%,
transparent 32%,
transparent 100%
), linear-gradient(90deg, rgb(255, 255, 255), rgb(255, 255, 255));
}

La puerta de entrada de React

jsx
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

Y el componente en sí

jsx
// App.js
import React from 'react'
import './styles.css'
import 'tailwindcss/dist/tailwind.min.css'
export default function App() {
return (
<div className="container fixed mx-auto h-full p-4 background">
<div className="background-box1 text-gray-200 p-4 rounded mb-6 max-w-screen-md">
<H1 attr="font-black">Hello CodeSandbox</H1>
<h2 className="mb-4">Start editing to see some magic happen!</h2>
<Button attr="text-gray-200 bg-blue-800 hover:bg-blue-400">Button</Button>
</div>
<div className="background-box2 text-gray-900 p-4 rounded max-w-screen-md">
<H1 attr="font-normal">Hello CodeSandbox</H1>
<h2 className="mb-4">Start editing to see some magic happen!</h2>
<Button attr="text-gray-200 bg-red-500 hover:bg-gray-500">Button</Button>
</div>
</div>
)
}
const H1 = ({ children, attr }) => (
<h1 className={`${attr} text-4xl sm:text-6xl leading-none mb-2 ${attr}`}>{children}</h1>
)
const Button = ({ children, attr }) => (
<button className={`p-2 rounded transition duration-200 ease-in-out ${attr}`}>{children}</button>
)

Y aquí arriba puedes ver como es muy sencillo integrar clases que utilices en un componente y combinarlas con clases que quieras reutilizar en un componente genérico, todo esto sin perder lo bonito que es escribir en tailwind

El resultado lo tienes en el codesandbox, y aquí abajo tienes un pantallazo

diseño

Como ves, para definir los fontos he utilizado pure css, mientras que para el resto he podido conseguir una estética más que suficiente con lo que me ofrece tailwind

Sin duda es una manera muy agradable de diseñar, mucho menos pesada para la cabeza

Listos!

🙋‍♂️

Qué tal el curso?

👌 Bien 🙌🙌
👍 Bien, pero algunas cosas podrían explicarse mejor 😬
🤷‍♂️ Da por sentadas demasiadas cosas 😒
🤷‍♂️ A ver, hay poca chicha 😬
🤷‍♂️ Los ejemplos no son muy claros 🙇‍♂️
🤷‍♂️ No se entiende, está mal escrito 👎
✍️ Hay errores, revísalo en cuanto puedas 🙏
Enviar Feedback ✍️

Si quieres explorar más cursos y más entradas en el blog, los tienes todos en la página principal, y si el contenido te ha ayudado compártelo entre tus seguidores (con los botones de abajo) por si también les puede interesar 👍

Privacidad
by kuworking.com
[ 2020 >> kuworking ]