Advertisement
  1. Web Design
  2. PostCSS

PostCSS en Profundidad: Pre-procesando con "PreCSS"

Scroll to top
Read Time: 13 min
This post is part of a series called PostCSS Deep Dive.
Using PostCSS for Minification and Optimization
PostCSS Deep Dive: Roll Your Own Preprocessor

() translation by (you can also view the original English article)

En los últimos dos tutoriales hemos visto formas de usar PreCSS, esencialmente como un post-procesador, para mejorar la optimización y compatibilidad entre navegadores en hojas de estilo finalizadas. En este tutorial aprenderás a utilizar PostCSS como un pre-procesador, de la misma manera que usarías Stylus, Sass o LESS.

Hay dos principales maneras en las que puedes emplear PostCSS para pre-procesar.  Una consiste en seleccionar tus propios complementos para añadir la funcionalidad de pre-proceso que deseas y la otra en instalar un paquete de complementos preseleccionados para comenzar inmediatamente.

Comenzaremos por el enfoque más rápido y sencillo, instalando el excelente paquete de complementos PreCSS, creado por Jonathan Neal. En el próximo tutorial, avanzaremos hacia cómo puedes montar tu propio pre-procesador, utilizando sólo las funciones que desees.

Este tutorial asumirá que tienes cierto grado de familiaridad con características comúnmente presentes en pre-procesadores como Stylus, Sass o LESS. Simplemente porque nos centraremos en cómo puedes usar este mismo tipo de características mediante PostCSS, más que en qué hacen realmente esas características. Dicho esto, incluso si nunca has utilizado antes un pre-procesador, este podría ser el lugar perfecto para comenzar.

Probar PreCSS en vivo

En la siguiente sección, recorreremos paso a paso cómo configurar un proyecto Gulp o Grunt para utilizar PreCSS. No obstante, si quieres tomar un atajo (sólo por ahora), puedes alternativamente usar el live demo playground (campo de juego en vivo) para probar el código que ejecutaremos en este tutorial. El código puede escribirse en la ventana izquierda y se compilará y mostrará automáticamente en la ventana derecha.

PreCSS Live Editor (editor en vivo de PreCSS): https://jonathantneal.github.io/precss

Configura tu Proyecto

Lo primero que necesitarás será configurar tu proyecto para usar Gulp o Grunt, según tu preferencia. Si aún no tienes preferencia por uno de ellos, recomiendo usar Gulp dado que necesitarás menos código para lograr el mismo fin.

Puedes leer sobre cómo configurar proyectos Gulp o Grunt para PostCSS en los anteriores tutoriales.

respectivamente.

Sin embargo, si no quieres configurar manualmente tu proyecto desde cero, puedes descargar los archivos fuente adjuntos a este tutorial y extraer el proyecto de arranque para Gulp o Grunt en una carpeta vacía.

Después, utilizando un terminal y estando ubicado en la carpeta, ejecuta el comando npm install.

Instalar PreCSS

Estés usando Gulp o Grunt, instala PreCSS en tu proyecto con el comando:

1
npm install precss --save-dev

Cargarlo como un complemento de Gulp

Si estás utilizando Gulp, añade esta variable bajo las ya existentes en el archivo:

1
var precss = require('precss');

Ahora agrega el nombre de la nueva variable a tu array processors:

1
    var processors = [
2
  	precss
3
	];

Comprueba rápidamente que todo está funcionando, ejecutando el comando gulp css y verificando después que un nuevo archivo "style.css" ha aparecido en la carpeta "dest" de tu proyecto.

Cargarlo como un complemento de Grunt

Si estás usando Grunt, actualiza con el siguiente código el objeto processors, que está anidado en el objeto options:

1
        processors: [
2
          require('precss')()
3
        ]

Comprueba rápidamente que todo funciona, ejecutando el comando grunt postcss y verificando después que un nuevo archivo "style.css" ha aparecido en la carpeta "dest" de tu proyecto.

Ahora tienes instalado y listo para funcionar, todo lo que necesitas para utilizar PreCSS. Esto significa que estamos listos para comenzar a caminar a través de algunas de las capacidades de pre-procesado de PreCSS y de cómo pueden utilizarse.

Pre-procesando vía PreCSS

En general, la sintaxis de PreCSS es más similar a la de Sass. No obstante, usa algunos enfoques únicos que abordaremos según avancemos.

Nota: debido a la sintaxis tipo Sass de PreCSS, descubrirás que te funcionará mejor trabajar con un resaltador de sintaxis Sass en tu editor de código favorito.

Anidamiento

El anidamiento es algo común en los tres principales pre-procesadores (ej.: Stylus, Sass y LESS) y también está presente en PreCSS. El anidamiento en PreCSS se realiza de la misma manera que en Sass y LESS, colocando selectores dentro de las llaves de otros selectores.

La capacidad de utilizar el símbolo & para obtener el selector padre duplicado en el hijo, también funciona en PreCSS de forma similar a otros pre-procesadores.

Prueba añadiendo el siguiente código anidado a tu fichero "src/style.css" :

1
.menu {
2
    width: 100%;
3
	a {
4
		text-decoration: none;
5
	}
6
	&::before {
7
		content: '';
8
	}
9
}

Compila tu CSS con gulp css o grunt postcss y tu fichero "dest/style.css" debería haber evaluado el código anidado, transformándolo en lo siguiente:

1
.menu {
2
    width: 100%;
3
}
4
5
.menu a {
6
	text-decoration: none;
7
}
8
9
.menu::before {
10
	content: '';
11
}

Variables

Las variables son otro tipo de funcionalidad común a todos los pre-procesadores y están incluidas en PreCSS. La única diferencia típica entre cada pre-procesador es la sintaxis para indicar las variables.

  • Las variables LESS comienzan con un símbolo @ y colocan un : antes del valor.
  • Las variables Stylus pueden opcionalmente usar un símbolo $ y situar un signo = antes del valor.
  • Las variables Sass utilizan un símbolo $ y ponen un : antes del valor.

De acuerdo con la tendencia de PreCSS de usar sintaxis parecida a Sass, también coloca un $ delante de la variable y un : antes del valor.

Prueba a usar variables PreCSS añadiendo esto a tu fichero "src/style.css" :

1
$text_color: #232323;
2
3
body {
4
    color: $text_color;
5
}

Tras volver a compilar, deberías ver este código resultante:

1
body {
2
    color: #232323;
3
}

Condicionales

Los condicionales (ej.: la lógica if y else) son una característica muy fuerte tanto en Sass como en Stylus. LESS ofrece los Mixin Guards, pero no aportan el mismo grado de poder. Los condicionales están presentes en PreCSS y siguen la misma sintaxis que Sass, utilizando @if y @else.

Añade este código de ejemplo a tu fichero "src/style.css" :

1
$column_layout: 2;
2
3
.column {
4
    @if $column_layout == 2 {
5
		width: 50%;
6
		float: left;
7
	}	@else {
8
		width: 100%;
9
	}
10
}

En el ejemplo superior, obtenemos un resultado diferente de la clase .column, dependiendo de si queremos una composición de una o dos columnas. Tenemos la variable $column_layout establecida a un valor 2, por lo que deberemos ver como resultado en nuestra clase width: 50%; float: left;.

Compila tu hoja de estilos y deberías ver lo siguiente en tu fichero "dest/style.css" .

1
.column {
2
    width: 50%;
3
    float: left
4
}

Nota: el complemento postcss-advanced-variables que aporta esta función de condicionales es aún bastante nuevo y he encontrado algunos resultados inesperados cuando lo he usado para condicionales más complejos. Sin embargo, estoy seguro de que será actualizado en un futuro cercano.

Existe un complemento alternativo para condicionales llamado postcss-conditionals. Trataremos cómo puedes utilizar ese complemento (si lo eliges) en el siguiente tutorial, "Crear tu propio pre-procesador".

Bucles - @for y @each

Hay dos tipos de bucles disponibles en PreCSS: los @for y los @each. Ambos usan un enfoque similar a Sass. Los bucles "for" te permiten recorrer ciclos a través de un contador numérico, mientras los "each" ofrecen la misma posibilidad, pero a través de un listado de elementos.

Bucles @for

En un bucle @for hay una variable "contadora" que hace el seguimiento de dónde te encuentras dentro del ciclo que recorre el contador numérico, habitualmente establecido como $i. Por ejemplo, cuando recorra de 1 a 3 habrá tres bucles; en el primero $i equivaldrá a 1, en el segundo tendrá un valor de 2 y en el tercero será de 3.

Esta variable contadora $i puede ser interpolada tanto en selectores como en reglas, lo que puede resultar muy útil para tareas como generar reglas nth-of-type() y calcular anchos.

Añade este código a tu fichero "src/style.css" para probar un bucle @for:

1
@for $i from 1 to 3 {
2
    p:nth-of-type($i) {
3
		margin-left: calc( 100% / $i );
4
	}
5
}

Tras la compilación, deberías ver el código ampliado a:

1
p:nth-of-type(1) {
2
    margin-left: calc( 100% / 1 );
3
}
4
5
p:nth-of-type(2) {
6
    margin-left: calc( 100% / 2 );
7
}
8
9
p:nth-of-type(3) {
10
	margin-left: calc( 100% / 3 );
11
}

Nota: los números 1, 2 y 3 han sido insertados dentro de cada uno de los estilos.

Bucles @each

Un bucle @each recorre un ciclo a través de un listado de elementos, en vez de números. Como con los bucles @for, la variable que representa en cada momento el valor de bucle, puede ser insertada en selectores y reglas. Considera que para insertarla en una cadena de texto, necesitas incluir unos paréntesis dentro del nombre de la variable con el formato $(var).

Prueba los bucles @each de PreCSS añadiendo el siguiente código de ejemplo:

1
$social: twitter, facebook, youtube;
2
3
@each $icon in ($social){
4
    .icon-$(icon) {
5
		background: url('img/$(icon).png');
6
	}
7
}

Después de la compilación, deberías ver que se ha generado la siguiente CSS:

1
.icon-twitter {
2
    background: url('img/twitter.png');
3
}
4
5
.icon-facebook {
6
    background: url('img/facebook.png');
7
}
8
9
.icon-youtube {
10
	background: url('img/youtube.png');
11
}

Mixins

La sintaxis para la creación de mixins es un aspecto de PreCSS que difiere ligeramente de Sass.

En Sass, para definir un mixin utilizas la sintaxis @mixin mixin_name($arg1, $arg2) {...} y después lo empleas con @include mixin_name(pass_arg1, pass_arg2);.

En cambio, en PreCSS, defines un mixin con la sintaxis @define-mixin mixin_name $arg1, $arg2 {...} y luego lo aplicas con @mixin mixin_name pass_arg1, pass_arg2;.

Añade este ejemplo a tu fichero "src/style.css" :

1
@define-mixin icon $network, $color {
2
    .button.$(network) {
3
		background-image: url('img/$(network).png');
4
		background-color: $color;
5
	}
6
}
7
8
@mixin icon twitter, blue;
9
10
@mixin icon youtube, red;

Al compilar deberías obtener:

1
.button.twitter {
2
    background-image: url('img/twitter.png');
3
    background-color: blue;
4
}
5
6
.button.youtube {
7
	background-image: url('img/youtube.png');
8
	background-color: red;
9
}

Nota: los argumentos pasados a través del mixin pueden ser interpolados dentro de selectores y cadenas de texto, con el mismo enfoque mencionado anteriormente en los bucles @each; con el formato $(var).

Utilizando @mixin-content

Además de usar mixins de la forma mostrada anteriormente, también pueden aplicarse para emplear bloques de contenido que son enviados al llamar al mixin. Esencialmente es el mismo proceso que al utilizar @content con Sass.

Por ejemplo, modifica el mixin del ejemplo superior, colocando @mixin-content donde quieras que se inserte el bloque de contenido, como en:

1
@define-mixin icon $network, $color {
2
    .button.$(network) {
3
		background-image: url('img/$(network).png');
4
		background-color: $color;
5
		@mixin-content;
6
	}
7
}

Cuando se usa un mixin que integra @mixin-content, debe incluirse con paréntesis, en vez de hacerlo en una sola línea finalizada con ;. En caso contrario fallará al compilar.

Actualiza tu código para que tus llamadas a mixins sean como esta:

1
@mixin icon twitter, blue {
2
    width: 3rem;
3
}
4
5
@mixin icon youtube, red {
6
	width: 4rem;
7
}

Después de compilar, debería producirse el siguiente código - observa la inclusión del contenido width pasado a través de cada uso del mixin.

1
.button.twitter {
2
    background-image: url('img/twitter.png');
3
	background-color: blue;
4
	width: 3rem;
5
}
6
7
.button.youtube {
8
	background-image: url('img/youtube.png');
9
	background-color: red;
10
	width: 4rem;
11
}

Extends

Los extends son parecidos a los mixins, en el sentido en que están diseñados para permitirte reutilizar bloques de código. No obstante, la idea detrás de los extends es crear un conjunto base de código, que sabes que vas a utilizar múltiples veces de la misma forma, para un cierto tipo de elemento. Con posterioridad, podrás extenderte sobre esa base con código adicional no insertado por defecto.

En PreCSS, la sintaxis para definir un extend es @define-extend extend_name {...}.

En tu fichero "src/style.css", define un extend que contenga los estilos base para un botón redondeado, como en:

1
@define-extend rounded_button {
2
    border-radius: 0.5rem;
3
	padding: 1em;
4
	border-width: 0.0625rem;
5
	border-style: solid;
6
}

Este conjunto de estilos por defecto está ahora preparado para ser extendido con código adicional. Por ejemplo, con propiedades como background-color y border-color. Se hace usando la sintaxis @extend extend_name; para importar los estilos base definidos en el extend.

Añade este código de ejemplo, bajo el que acabas de añadir en el paso anterior:

1
.blue_button {
2
    @extend rounded_button;
3
	border-color: #2F74D1;
4
	background-color: #3B8EFF;
5
}
6
7
.red_button {
8
	@extend rounded_button;
9
	border-color: #C41A1E;
10
	background-color: #FF2025;
11
}

Los contenidos completos del extend serán insertados donde se use la línea @extend rounded_button;.

Compila tus estilos y deberías obtener:

1
.blue_button,
2
.red_button {
3
    border-radius: 0.5rem;
4
	padding: 1em;
5
	border-width: 0.0625rem;
6
	border-style: solid;
7
}
8
9
.blue_button {
10
	border-color: #2F74D1;
11
	background-color: #3B8EFF;
12
}
13
14
.red_button {
15
	border-color: #C41A1E;
16
	background-color: #FF2025;
17
}

Considera también que los estilos comunes de .blue_button y .red_button se han combinado por eficiencia.

Imports

El componente utilizado para procesar en línea hojas de estilo mediante @import es el mismo que tratamos en el tutorial previo de esta serie: For Minification and Optimization. Para un resumen sobre su funcionamiento, dirígete a ese tutorial y lee la sección titulada "Inline / Combina ficheros con @import".

En el contexto de utilizar PostCSS como un pre-procesador, los imports resultan aún más útiles, dado que te permiten configurar ficheros parciales ('partials'), algo a lo que ya podrías estar acostumbrado de otras soluciones de pre-proceso. Por ejemplo, podrías configurar una carpeta "partials", dividir tu proyecto en ficheros parciales separados lógicamente y luego importarlos como en:

1
@import "partials/_variables.css";
2
@import "partials/_utilities.css";
3
@import "partials/_mixins.css";
4
@import "partials/_extends.css";

Recapitulemos

Espero que ahora tengas algunas ideas sobre lo poderoso que PostCSS puede ser como pre-procesador, gracias al paquete de complementos PreCSS. Para resumir lo que hemos tratado anteriormente:

  • Puedes probar PreCSS en vivo visitando https://jonathantneal.github.io/precss.
  • El anidamiento en PreCSS funciona de la misma manera que en Sass y LESS.
  • Las variables en PreCSS utilizan la misma sintaxis que en Sass.
  • Los condicionales están presentes en PreCSS, usando la sintaxis @if y @else.
  • También están disponibles los bucles @for y @each.
  • Los mixins en PreCSS se definen con la sintaxis:
    @define-mixin mixin_name $arg1, $arg2 {...}
  • Los mixins en PreCSS se utilizan con la sintaxis:
    @mixin mixin_name pass_arg1, pass_arg2;
  • @mixin-content puede usarse como se emplea @content en Sass
  • Los extends en PreCSS se definen con la sintaxis:
    @define-extend extend_name {...}
  • Los extends, tras definirlos, se utilizan con la sintaxis:
    @extend extend_name;
  • Los @import procesan en línea ficheros CSS externos y son particularmente útiles para usar ficheros parciales ('partials').

En el Próximo Tutorial

PreCSS es un proyecto fantástico que reúne excelentes complementos de extensión del lenguaje y hace que el pre-proceso basado en PostCSS sea muy cercano al "listo para usar". Ofrece casi toda la funcionalidad que la mayoría de usuarios de pre-procesadores pueden esperar y es una forma rápida y sin problemas de poner en marcha la parte pre-procesador de PostCSS.

Utilizar PreCSS es uno de los dos métodos para pre-procesar con PostCSS que mencionamos al inicio de este tutorial. El otro método es configurar tu propio pre-procesador, seleccionando manualmente los complementos para extensión del lenguaje que me mejor se ajustan a tus propios proyectos o estilo de hacer código. La contrapartida es que requiere algo más de configuración, pero a cambio obtienes la libertad de confeccionar un pre-procesador que funciona como tú desees.

Aprederás cómo hacerlo en el próximo tutorial, "Crear Tu Propio Pre-Procesador".

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.