Qué hace y ventajas de un preprocesador de estilos CSS

Escrito por picodotdev el .
planeta-codigo web
Enlace permanente Comentarios

Las páginas web están formadas por varios elementos separados, por un lado está el código HTML que forma el contenido de la página con las referencias a elementos externos que use como hojas de estilo CSS, imágenes o archivos JavaScript. Las imágenes son recursos gráficos soportando todos los navegadores los formatos png, jpg para fotos e imágenes vectoriales como svg. Los archivos JavaScript permite incorporar a la página código ejecutable con el propósito de añadir ciertos comportamientos mediante programación. Finalmente, están las hojas de estilo CSS que proporcionan los estilos y cambian el aspecto visual y maquetación de los elementos, el contenido HTML puede ser el mismo pero con una hoja de estilos diferente la visualización muy diferente.

Las hojas de estilos cambian propiedades de visualización de diferentes elementos como tipo de letra, tamaño de texto, formato, color, alineación, bordes, etc… La etiqueta h1 representa el título principal de la página, con el siguiente código se establecen varias propiedades a cada una de las etiquetas.

Siendo las páginas web cada vez más complejas, en gran medida las hojas de estilo también se convierten en más complejas con la aparición de los dispositivos móviles un poco más dado que hay que adaptar la página al tamaño de cada uno de los dispositivos. Por esto se suelen usar toolkits o librerías como Bootstrap con unos estilos elegantes listos para usar sin tener que crearlos desde cero en cada proyecto, proporciona diferentes componentes como layouts, botones, formularios, modales, popovers, barras de progreso, desplegables y algunos más. Sin embargo, aún con Bootstrap suelen ser necesarios escribir algunos estilos adicionales propios de la página.

El preprocesador de estilos CSS

Para facilitar la escritura de hojas de estilos complejas con menor código y más legibles han aparecido preprocesadores de hojas de estilos o css preprocessors con funcionalidades adicionales y una nueva forma de escribir hojas de estilo menos tediosa que el CSS.

Un preprocesador de CSS es un programa que lee un archivo de código fuente en el formato pseudo-código CSS que espera el preprocesador y genera un archivo hoja de estilos en formato CSS que los navegadores entienden, es un compilador que transforma el lenguaje de un archivo a otro en este caso de un código que suele ser similar a CSS a CSS estándar. Uno de los preprocesadores más populares por su simplicidad pero con muchas funciones útiles es less, otro es Sass.

Las ventajas de un preprocesador CSS es que se pueden usar variables que pueden ser utilizadas por ejemplo para aplicar el mismo color a varios elementos sin tener que repetir el color RGB en cada uno de los elementos lo que facilita el mantenimiento de las hojas de estilo. Anidar estilos relativos a un elemento y selectores, realizar operaciones, utilizar funciones, namespaces para agrupar contextos de estilos y mixins para estilos aplicables a varios elementos algunas cosas más pero estas ya mejoran y simplifican significativamente el trabajo con hojas de estilo.

Los preprocesadores CSS facilitan la escritura y mantenimiento de las hojas de estilos con funcionalidades que CSS no tiene pero esto no hace del CSS resultante generado mejor que si estuviese escrito directamente sin utilizar un preprocesador, por ejemplo no conviene crear muchos niveles de anidación ya que el CSS generado será más grande y más costoso de aplicar al navegador. Para desarrollar estilos aplicables a elementos HTML que sean reutilizables y más fácilmente mantenibles hay que emplear alguna de las metodologías más aceptadas que proponen buenas prácticas para la escritura de CSS, algunas de estas metodologías son OOCSS, BEM y SMACSS.

Este es un ejemplo de código fuente en formato del preprocesador Less que muestra varias de las funcionalidades que aporta sobre CSS estándar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Variables
@width: 10px;
@height: @width + 10px;

#header {
  width: @width;
  height: @height;
}

// Mixins
.bordered {
    border-top: dotted 1px black;
    border-bottom: solid 2px black;
}

#menu a {
    color: #111;
    .bordered();
}
  
.post a {
    color: red;
    .bordered();
}

// Nesting
#header {
    color: black;

    .navigation {
      font-size: 12px;
    }

    .logo {
      width: 300px;
    }
}

// Operations
@conversion-1: 5cm + 10mm; // result is 6cm
@conversion-2: 2 - 3cm - 5mm; // result is -1.5cm

@base: 5%;
@filler: @base * 2; // result is 10%
@other: @base + @filler; // result is 15%

// Functions
@base: #f04615;
@width: 0.5;

.class {
  width: percentage(@width); // returns `50%`
  color: saturate(@base, 5%);
  background-color: spin(lighten(@base, 25%), 8);
}

// Importing
@import "library.less";
@import "typo.css";
example.less

Cómo transformar el pseudo-codigo CSS a CSS con un preprocesador

El archivo CSS en formato less hay que compilarlo para producir el archivo CSS que los navegadores entienden. La herramienta para compilar el archivo de estilos en formato less es lessc. Se puede usar directamente en un script Bash o con una herramienta de construcción como npm o a través de webpack.

1
$ npm install --save-dev less
npm-install.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
    "name": "blog-bitix",
    "version": "1.0.0",
    "devDependencies": {
      ...
      "less": "^3.12.2",
      ...
    },
    "scripts": {
      "less-main": "lessc themes/bitix/static/assets/css/main.less themes/bitix/static/assets/css/main.css",
      ...
    },
    "dependencies": {
      "npm": "^6.14.7",
      "npm-check-updates": "^7.0.2"
    }
  }
  
package.json
1
2
3
4
#!/usr/bin/env bash
set -e

npm run less-main
npm-less-main.sh

La hoja de estilos en formato less que genera el código CSS anterior el siguiente. Se observa que los estilos aplicables a _la etiqueta article quedan agrupados en el contexto de article de modo que son fácilmente identificables todos los estilos de cada etiqueta, además algunos colores utilizan variables cuyos valores no hace falta repetir en cada uso junto con el uso de funciones como lighten y darken para generar variaciones del color base indicado.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
@background: white;
@background-page: #F8F8F8;
@color: #222;
@link: rgb(86, 157, 47);
@border: @background-page;

html {
  font-size: 16px;
}

body {
  color: @color;
  font-family: 'PT Serif', 'Times New Roman', Times, serif;
  font-size: 1.2em;
  font-weight: 400;
  margin-bottom: 50px;
  background-color: @background-page;
  background-image: url('/blog-bitix/assets/images/backgrounds/grey.png');
}

...

h1, h2, h3, h4, h5, h6 {
  margin-top: 20px;
  margin-bottom: 10px;
  font-weight: 700;
  clear: both;
}

...

article {
  h1 {
    font-size: 2.6em;
  }

  @media (max-width: 576px) {
    h1 {
      font-size: 1.8em;
    }
  }

  p.information, span.information {
    font-size: 0.9em;
  }

  p.summary {
    font-weight: 700;
  }

  ul.columns {
    columns: 4 12em;
    column-gap: 1em;
  }

  table {
    margin-bottom: 20px;
  }

  blockquote {
    padding: 0 1em;
    color: #6a737d;
    border-left: 0.25em solid #dfe2e5;
  }

  div.logotypes {
    margin-left: 1.5em;
    text-align: right;
    float: right;
    clear: right;
    max-width: 400px;
    min-width: 150px;

    @media (max-width: 576px) {
      width: 125px;
    }

    img, amp-img {
      background-color: white;
      border: 0.5em solid @background;
      border-radius: 0.3em;
      box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.15);
      box-sizing: border-box;

      @media (max-width: 576px) {
        width: 125px;
      }
    }
  }

  ...
}
...
main.less

Y su resultado en formato CSS.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
html {
  font-size: 16px;
}
body {
  color: #222;
  font-family: 'PT Serif', 'Times New Roman', Times, serif;
  font-size: 1.2em;
  font-weight: 400;
  margin-bottom: 50px;
  background-color: #F8F8F8;
  background-image: url('/blog-bitix/assets/images/backgrounds/grey.png');
}

...

h1,
h2,
h3,
h4,
h5,
h6 {
  margin-top: 20px;
  margin-bottom: 10px;
  font-weight: 700;
  clear: both;
}

...

article h1 {
  font-size: 2.6em;
}
@media (max-width: 576px) {
  article h1 {
    font-size: 1.8em;
  }
}
article p.information,
article span.information {
  font-size: 0.9em;
}
article p.summary {
  font-weight: 700;
}
article ul.columns {
  columns: 4 12em;
  column-gap: 1em;
}
article table {
  margin-bottom: 20px;
}
article blockquote {
  padding: 0 1em;
  color: #6a737d;
  border-left: 0.25em solid #dfe2e5;
}
article div.logotypes {
  margin-left: 1.5em;
  text-align: right;
  float: right;
  clear: right;
  max-width: 400px;
  min-width: 150px;
}
@media (max-width: 576px) {
  article div.logotypes {
    width: 125px;
  }
}
article div.logotypes img,
article div.logotypes amp-img {
  background-color: white;
  border: 0.5em solid white;
  border-radius: 0.3em;
  box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.15);
  box-sizing: border-box;
}
@media (max-width: 576px) {
  article div.logotypes img,
  article div.logotypes amp-img {
    width: 125px;
  }
}

...
main.css
Comparte el artículo: