El uso de preprocesadores CSS hace posible que mejoremos nuestro flujo de trabajo, un ejemplo de ello sería que podemos separar el contenido por módulos y aplicar algunos conceptos del enfoque OOCSS, lo que mejoraría nuestro código en cuanto a calidad y rápidez.
OOCSS
Utilizando el enfoque OOCSS es posible diseñar estilos de una manera similar a algún lenguaje de programación. Por lo que antes de describir los cómo funcionan los módulos, haré un breve repaso de algunos elementos que hacen posbible dividir nuestros estilos.
Evitar estilos en cascada
Tomemos por ejemplo este código
a {
color:olive;
text-decoration:none;
}
Parece inofensivo, y en documentos sencillos cumple bien su función. Sin embargo, cuando queremos darle estilo a los enlaces de un menú, por ejemplo, tenemos que sobreescribir algunas reglas, porque de lo contrario al interpretarse los estilos el color no sería el que deseamos.
.menu a{
color:white;
background-color: green;
}
Y para cuando comencemos a diseñar los artíuclos de nuevo modificaremos el estil.
article a{
text-decoration:underline;
}
Y así por cada una de las secciones del documento, de tal manera que tendríamos que preguntarnos qué tan útil resulta declarar estilos globales. En general, en los lenguajes de programación, debemos evitar declararlas y reservar su uso para ocasiones específicas, y parece que lo mismo aplica para el código CSS, por lo que debemos reservar el uso de variables globales salvo en ocasiones especiales, como para aplicar una restauración de estilos, o algunos hacks conocidos.
Si vamos a las causas del problema encontraremos que la función de las etiquetas HTML es establecer relaciones, permitir interacciones o dar un significado a su contenido, pero pueden emplearse en distintos contextos. Por lo que una solución es tratar de establecer el contexto y las relaciones que podrían tener. Un ejemplo sería un menú cuya estructura HTML podría ser la siguiente
<nav class="menu">
<ul>
<li><a href="#">Enlace 1</a></li>
<li><a href="#">Enlace 2</a></li>
</ul>
</nav>
Se trata de una sección de la página hasta cierto punto independiente que realiza una función específica. Si en lugar de declarar reglas globales la ubicamos dentro del contexto en el que se presenta, podemos evitar los estilos en cascada, de tal forma que nuestras reglas quedarían de la siguiente forma:
.menu a { }
.menu li { }
.menu ul ul{ }
Especificidad
Del otro la de las reglas en cascada está la especificidad, que es la suma de declaraciones que tiene una regla, por ejemplo, en el siguiente código:
.menu a {}
#main .menu ul li a { }
La regla que tiene preferencia es la segunda, porque en las hojas de estilo quienes tienen mayor valor son los ids, después la etiquetas y por último las clases. Si queremos declarar una regla con mayor especificidad que la segunda deberiámos incorporar otro id, o escribir !important
al final. La primer regla es suficiente para aplicarse sólo a los enlaces del menú, no es necesario agregar más selectores.
El problema de la especificidad es más común con el uso de los preprocesadores, ya que permiten reglas anidadas y cuando nos damos cuenta terminamos con selectores como el del ejemplo anterior.
Módulos
Como vimos debemos buscar un equilibro a la hora de definir nuestros selectores, no deben ser globales, pero tampoco tan específicos. Tomando en cuenta lo anterior, creo que una forma efectiva para organizar nuestro código sería separar nuestros estilos en pequeños archivos, que corresponden a un contexto, a los cuales podríamos llamar módulos1. Crearíamos un archivo por ejemplo para los artículos, otro para productos, para el footer, etc. Teniendo en cuenta que se trata de secciones de la página que funcionan como una unidad.
Para comenzar crearemos un controlador, el cual además de incluir los módulos, incluirá variables (config) y archivos apoyo (helpers).
/* controller.less */
@import helpers/reset.less
@import config/colors.less
@import config/layout.less
@import modules/menu.less
@import modules/comment.less
Al utilizar un preprocesador tenemos la ventaja de que cada uno de estos import no nos generará un http request, porque se compila antes de publicarse. La estructura de archivos sería como sigue:
- Styles/
-- controller.less
-- Modules/
---- menu.less
---- comments.less
-- Helpers/
---- reset.less
-- Config/
---- layout.less
---- fonts.less
Tanto los archivos helpers como config, merecen una explicación a fondo, pero para consolidar la idea de los módulos, los dejaremos para otra ocaseión.
Estrutura de un módulo
En los módulos incorporamos los tres conceptos que hemos visto, evitar estilos en cascada, especificidad y uso de preprocesadores. En el siguiente esquema podremos observar cómo declarar un módulo con las características mencionadas:
/* Comments.less */
.comments {
.comment {
width:100%;
}
.comment .comment{
padding:5%;
}
}
.comment{
border-color:red;
.content{
color:gray;
}
.avatar {
max-width:20%;
}
.author{
font-size:1.5rem;
}
.date {
font-style:italic;
}
}
Generalmente tendremos dos grupos, uno en plural y el otro en sigular. Si observamos el código veremos que la clase .comments
se repite, la primera vez está includa dentro de .comments
y la segunda abre el segundo grupo, la razón es porque en la primera sólo se definirán aspectos externos y en la segunda aspectos internos, de esta manera evitamos añadir mayor especificidad de la necesaria.
Como podemos ver también evitamos el uso de etiquetas HTML como selectores, lo que nos permite modificar nuestra estructura semántica sin modificar los estilos, es decir, si después se inserta una etiqueta que se llame comment
en lugar de article
, o decidimos que no es la etiqueta adecuada, con el uso de clases en los estilos, podemos modificar las etiquetas sin afectar el diseño. Sobre este tema, pueden encontrar una mejor explicación en un artículos de Nicolas Gallagher.
Con la estructura anterior, podremos crear los archivos para artículos, productos, footer y demás módulos que tenga la página.