1. Web Design
  2. HTML/CSS

Una alternativa mixin simple a las cuadrículas CSS estándar

Scroll to top

Spanish (Español) translation by Charles (you can also view the original English article)

En los últimos años, los sistemas de cuadrícula CSS se han convertido en una forma muy popular de producir rápidamente andamios de diseño en el diseño web.

Pueden ser un recurso fantástico que ahorra tiempo, con codificadores talentosos que tienen sistemas inteligentemente diseñados que atienden a una amplia gama de diseños posibles que los diseñadores podrían necesitar crear. Sin embargo, esta no es la única manera de abordar los diseños web basados en cuadrícula, y hoy vamos a examinar una alternativa.


Cómo funcionan los sistemas de cuadrícula CSS

Un sistema de cuadrícula normalmente consta de un número específico de columnas ,(comúnmente doce o dieciséis), y la capacidad de establecer un elemento, (normalmente un div con una clase aplicada), a un ancho de X de esas columnas.

Por ejemplo, un área de contenido se puede establecer en nueve de doce columnas, mientras que una barra lateral junto a ella se establece en tres o doce columnas. Los diseños a menudo también incluyen un contenedor externo de ancho fijo, contenedores de filas dentro de él que ajustan las columnas y establecen canalones de ancho entre las columnas.

Echemos un vistazo rápido a cómo el diseño clásico del sitio web "encabezado, contenido, barra lateral, pie de página" podría construirse utilizando técnicas comunes a las cuadrículas CSS:

examplecssgridexamplecssgridexamplecssgrid

El uso de sistemas de cuadrícula CSS para crear diseños como este puede ser muy rápido y fácil. Sin embargo, si bien hay un montón de valor en oferta, también hay una serie de desventajas de la utilización de un sistema como este. Estas desventajas no significan que los sistemas de cuadrícula CSS sean "malos", solo que, como con cualquier herramienta, debe familiarizarse con los pros y los contras para determinar correctamente si es el adecuado para su proyecto específico.


Las desventajas de las cuadrículas CSS

Si bien todos los sistemas de cuadrícula CSS son diferentes, las desventajas más notables que comúnmente están presentes entre ellos incluyen:

  • Cantidad potencialmente alta de código no utilizado Una biblioteca completa de clases de cuadrícula tiende a estar en cualquier lugar de 200 a 700 líneas de código (sinminificar), sin embargo, en un diseño relativamente simple, gran parte de ese código nunca se puede usar.
  • Restricciones en el diseño Debido a que las cuadrículas están precalculadas, tienden a tener anchos establecidos que son difíciles de cambiar, por ejemplo, para contenedores, anchos de columna, anchos de canalones. El diseño se limita a trabajar con esos anchos.
  • Píxel fijo en lugar de em / rem o diseños basados en porcentajes Los anchos de cuadrícula y/o las consultas de medios a menudo se basan en valores de píxel, lo que impide el uso de valores em / rem o porcentaje más flexibles y escalables para el diseño.Nota: Para obtener información sobre las ventajas del diseño basado en em / rem vs px, por favor lea Tomar el "Erm.." Fuera de Ems
  • Establecer el número de columnas generales Las cuadrículas precalculadas tienden a usar doce o dieciséis columnas, lo que significa que si desea un número diferente de columnas generales, no tiene suerte.
  • Marcado no semántico El uso de clases de cuadrícula precalculadas requiere la colocación de numerosos nombres de clase no semánticos en todo un documento, como "row", "col", etc.
  • Restricciones en el anidamiento A menudo, los sistemas de cuadrícula solo pueden tener columnas anidadas una o dos veces entre sí, lo que restringe la complejidad y la flexibilidad de la generación de diseños.

Cuando se trata de eso, la verdadera razón por la que los diseñadores usan sistemas de cuadrícula CSS es para hacer que la generación de diseños sea más rápida y fácil. Así que la pregunta es:

¿Se puede hacer que la generación de diseños sea igual de rápida y fácil y, al mismo tiempo, superar las limitaciones enumeradas anteriormente?

Gracias a la llegada de los preprocesadores CSS como LESS y SASS / SCSS que pueden trabajar con variables, realizar cálculos y generar CSS según sea necesario a través de mixins, para muchos casos de uso la respuesta es:

Sí, absolutamente puede!


Una solución alternativa preprocesada

La clave de la solución alternativa que cubriremos son los "mixins", disponibles tanto en LESS como en SASS / SCSS. En pocas palabras, los mixins son paquetes reutilizables de reglas que pueden generar diferentes CSS dependiendo de qué información se les pase para su procesamiento.

A partir de aquí asumiremos que tienes una comprensión esencial de lo que son los preprocesadores y cómo funcionan con mixins y variables, por lo que si eres nuevo en estos conceptos te recomiendo comenzar leyendo la información proporcionada en http://lesscss.org/

Antes de comenzar, también señalaré que ya hay algunas bibliotecas existentes de mixins LESS y SASS que están trabajando para abordar las limitaciones de las cuadrículas CSS precalculadas, como:

Sin embargo, tomaremos un enfoque que difiere de estas bibliotecas de varias maneras. Una vez más, no hay una forma estrictamente correcta o incorrecta de abordar las cosas, es una cuestión de entender los pros y los contras al decidir qué enfoque usar para su proyecto.

Nota: Escribiré estos mixins en LESS, porque puede ser un poco más difícil obtener LESS para realizar operaciones sofisticadas que SASS, por lo que será más fácil para los usuarios de SASS adaptar LESS mixins que al revés.

Puede usar su propio método preferido para compilar sus archivos de preprocesador, sin embargo, incluiré un paquete básico de "LESScompiler" que se ejecuta en Node.js / NPM y Grunt que puede usar. Las instrucciones se incluyen en el archivo de readme.md.


Abordar el diseño clásico

Observamos anteriormente cómo el ubicuo diseño de "encabezado, contenido, barra lateral, pie de página" podría crearse utilizando un conjunto típico de clases de cuadrícula CSS, aprovechando alrededor de 200 a 700 líneas de código. Ahora veamos cómo podemos crear este mismo diseño a través de LESS mixins, manteniendo la cantidad de CSS requerida en un mínimo absoluto, sin usar valores de píxel y manteniendo el marcado semántico.

Primero, echemos un vistazo a nuestro HTML:

1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
	<meta charset="UTF-8">
5
	<title>Classic Layout</title>
6
	<script type='text/javascript' src='js/modernizr.js'></script>
7
	<link rel="stylesheet" href="css/normalize.css">
8
	<link rel="stylesheet" href="css/classiclayout.css">
9
</head>
10
<body>
11
<header>
12
	
13
</header>
14
<main>
15
	<article>
16
17
	</article>
18
	<aside>
19
20
	</aside>
21
</main>
22
<footer>
23
24
</footer>
25
</body>
26
</html>

Observe que no hay una sola clase utilizada en esta etapa, solo etiquetas HTML5 semánticas puras. A este HTML aplicaremos el siguiente código LESS, utilizando mixins y variables que se explicarán en breve:

1
header, main, footer {
2
	.Row;
3
	background-color: #ccc;
4
	min-height: 200 * @toRems;
5
}
6
7
article {
8
	.Cols( 3 );
9
	min-height: 500 * @toRems;
10
	background-color: #ddd;
11
}
12
13
aside {
14
	.Cols( 1 );
15
	min-height: 500 * @toRems;
16
	background-color: #eee;
17
}

... que generará las siguientes 35 líneas de CSS:

1
header,
2
main,
3
footer {
4
  max-width: 75rem;
5
  width: 100%;
6
  margin: 0 auto;
7
  background-color: #ccc;
8
  min-height: 12.5rem;
9
}
10
header:before,
11
main:before,
12
footer:before,
13
header:after,
14
main:after,
15
footer:after {
16
  content: "";
17
  display: table;
18
}
19
header:after,
20
main:after,
21
footer:after {
22
  clear: both;
23
}
24
article {
25
  width: 75%;
26
  float: left;
27
  min-height: 31.25rem;
28
  background-color: #ddd;
29
}
30
aside {
31
  width: 25%;
32
  float: left;
33
  min-height: 31.25rem;
34
  background-color: #eee;
35
}

... y el resultado que veremos en el navegador, con una resolución de pantalla de 1920 x 1080, es:

classiclayoutclassiclayoutclassiclayout

Tenga en cuenta que debido a que no estamos trabajando con configuraciones de ancho de píxeles fijos, este diseño ya tiene una capacidad de respuesta básica presente desde word go. El mismo diseño se ve así a 1024px de ancho:

classiclayout1024classiclayout1024classiclayout1024

Y así a 768px de ancho:

classiclayout768classiclayout768classiclayout768

Cubriremos la capacidad de respuesta en tamaños más pequeños más adelante, pero primero echemos un vistazo a los mixins y variables LESS utilizados para crear el diseño anterior.

1
//
2
// Variables for em / rem use
3
//
4
5
@base_px: 16; //set to the most common base px size used in browsers, should generally be left at default
6
7
@toRems: (1 / @base_px) + 0rem; //allows you to set values as the default px size to target, which is then converted into scalable rem values.
8
9
@toEms: (1 / @base_px) + 0em; //same as above, but with em values
10
11
//
12
// Grid mixins
13
//
14
15
@default-width: 1200 * @toRems;
16
17
@default-colspan: 1;
18
19
@default-total_cols: 4;
20
21
.Row ( @width : @default-width ) {
22
	max-width: @width;
23
	width: 100%;
24
	margin: 0 auto;
25
	// clear at the end of container
26
	&:before,
27
	&:after {
28
		content:"";
29
		display:table;
30
	}
31
	&:after {
32
		clear:both;
33
	}
34
}
35
36
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols ) {
37
	width: ( @colspan * (100 / @total_cols) ) + 0%;
38
	float: left;
39
}

Vamos a recorrer cada elemento de lo que está sucediendo en lo anterior.

Fácil conversión de px a em / rem

1
//
2
// Variables for em / rem use
3
//
4
5
@base_px: 16; //set to the most common base px size used in browsers, should generally be left at default
6
7
@toRems: (1 / @base_px) + 0rem; //allows you to set values as the default px size to target, which is then converted into scalable rem values.
8
9
@toEms: (1 / @base_px) + 0em; //same as above, but with em values

Las variables en la sección superior del código nos ponen a configurar para generar fácilmente valores em o rem escalables en toda la hoja de estilos en lugar de valores px. Sin embargo, el uso de estas variables también nos permitirá conceptualizar nuestro diseño en píxeles para empezar, porque es un ejercicio mental más fácil imaginar cómo se ven 500px de espacio que 31.25rem.

Por ejemplo, en nuestro diseño base no queremos que los elementos de encabezado, principal o pie de página sean más anchos que 1200 píxeles en ningún momento. Pero en lugar de especificar 1200px como el ancho máximo, convertimos ese valor 1200 en rems multiplicándolo por la variable @toRems así:

1
1200 * @toRems;

Esto generará un valor de 75rem, lo que significa que si un navegador o usuario ha establecido el tamaño de fuente predeterminado en algo distinto del valor predeterminado más común de 16px, todo el diseño del sitio se escalará proporcionalmente.

Lo mismo se puede hacer para generar valores em, utilizando en su lugar la variable @toEms.

. Row() mixin

1
@default-width: 1200 * @toRems;
2
3
.Row ( @width : @default-width ) {
4
	max-width: @width;
5
	width: 100%;
6
	margin: 0 auto;
7
	// clear at the end of container
8
	&:before,
9
	&:after {
10
		content:"";
11
		display:table;
12
	}
13
	&:after {
14
		clear:both;
15
	}
16
}

El primer mixin que se utiliza es el . Row() mixin.

En lugar de usar clases ".container", llamamos a este mixin donde queramos que un elemento se centre con un ancho máximo. En el caso de nuestro diseño clásico llamamos a esto mixin en los elementos de encabezado, principal y pie de página.

El mixin establece un ancho máximo junto con un ancho del 100%. Esto nos da una capacidad de respuesta básica al hacer que el elemento se ajuste automáticamente para llenar el espacio disponible siempre que la ventanilla sea menor que el valor de ancho máximo.

También establece el margen en 0 auto para que el elemento se centre automáticamente.

Finalmente, agrega los pseudoelementos :before y :after y los usa para borrarlos automáticamente al final del elemento. Esto es necesario para que cuando empecemos a agregar columnas dentro del elemento, se borre su configuración float.

El mixin acepta un parámetro, un valor @width:

1
.Row (@width : @default-width ) {

A continuación, este valor se pasa a la propiedad max-width:

1
	max-width: @width;

Cuando el mixin tiene un parámetro de ancho pasado, por ejemplo. Row( 40rem ), ese valor se aplicará a la propiedad max-width.

Sin embargo, si se llama al mixin sin pasar un parámetro, es decir. Fila, se utilizará un valor predeterminado en su lugar. Ese valor predeterminado se almacena en la variable @default ancho de @default, que se establece donde ve:

1
@default-width: 1200 * @toRems;

Como ahora comprenderá por lo que cubrimos anteriormente con respecto a la variable @toRems, esto significa que el ancho máximo predeterminado de cualquier elemento en el que se use este mixin será de 1200 píxeles, convertidos en valores rem.

Mediante el uso de este mixin ahora puede establecer cualquier elemento para que se centre en su ancho máximo predeterminado, o en cualquier otro ancho máximo que desee aplicar. Esto significa que puede cambiar el ancho de todo el sitio simplemente cambiando el valor de la variable de ancho @default. por ejemplo:

1
@default-width: 800 * @toRems;

... cambia el diseño base a:

classiclayout800classiclayout800classiclayout800

O bien, puede cambiar el ancho de un solo elemento a la vez, pasando un parámetro de ancho a través del mixin.

Por ejemplo, aplicando el mixin así:

1
header, footer {
2
	.Row;
3
	background-color: #ccc;
4
	min-height: 200 * @toRems;
5
}
6
7
main {
8
	.Row( 800 * @toRems );
9
	background-color: #ccc;
10
}

... le daría:

classiclayout_differentwidthsclassiclayout_differentwidthsclassiclayout_differentwidths

. Cols() mixin

1
@default-colspan: 1;
2
3
@default-total_cols: 4;
4
5
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols ) {
6
	width: ( @colspan * (100 / @total_cols) ) + 0%;
7
	float: left;
8
}

Debido a que no estamos usando anchos de píxeles fijos y queremos que nuestro diseño permanezca completamente flexible, todos nuestros anchos de columna se basarán en porcentajes. Utilizamos el archivo . Cols() mixin para calcular estos porcentajes.

En función de los valores que se pasan al mixin, se utiliza una fórmula simple para determinar el valor de ancho de porcentaje que se debe aplicar al elemento. El valor float del elemento también se establece en left para que las columnas se sitjen una al lado de la otra (recordará que borramos automáticamente los floats aplicados a las columnas a través de . Row() mixin).

Con el . Cols() mixin puedes especificar cuántas columnas de ancho quieres que sea tu elemento, tal como lo harías con un sistema de cuadrícula CSS regular. Esto se hace pasando un parámetro @colspan a través del mixin, o estableciendo el valor predeterminado para el mixin a través de la variable @default-colspan.

Sin embargo, a diferencia de la mayoría de los sistemas de cuadrícula CSS, también tiene un control completo sobre cuántas columnas totales tiene ese valor en relación con, en lugar de quedarse atascado con columnas totales de 12 o 16. Las columnas totales se pueden establecer pasando un parámetro @total_cols a través del mixin, o estableciendo el valor predeterminado del mixin a través de la variable @default-total_cols.

En nuestro ejemplo anterior de cómo nuestro diseño "clásico" se crearía utilizando una cuadrícula CSS típica, el área de contenido se estableció en 9 de 12 columnas (es decir, tres cuartos), mientras que la barra lateral era 3 de 12 columnas (es decir, un cuarto). Sin embargo, para los propósitos simples de este diseño realmente no necesitamos las doce columnas.

Todo lo que estamos tratando de hacer es establecer nuestra área de contenido en 3/4 de ancho, y la barra lateral en 1/4 del ancho. Así que dividir el diseño en doceavas partes sería exagerado, cuando todo lo que necesitamos son cuartos.

Debido a que sabemos que solo necesitamos dividir este diseño en trimestres, podemos establecer el valor de nuestra variable @default-total_cols en 4:

1
@default-total_cols: 4;

Luego, cuando usamos el mixin como lo hemos hecho en nuestro ejemplo de diseño "clásico", el mixin asume que desea que sus columnas estén fuera de un posible total de cuatro columnas. Así que para establecer nuestro elemento de artículo a tres cuartos de ancho todo lo que tenemos que hacer es:

1
article {
2
	.Cols( 3 );
3
}

Luego, para dejar de lado / barra lateral a un cuarto de ancho, simplemente usamos:

1
aside {
2
	.Cols( 1 );
3
}

Sin embargo, si decidimos que queremos usar un número totalmente diferente de columnas totales, podemos hacerlo fácilmente pasando diferentes valores a través del archivo . Cols() mixin.

Esto nos permite cambiar los anchos del artículo y dejar de lado los elementos a cualquier cosa que nos plazca con extrema facilidad, por ejemplo:

1
article {
2
	.Cols( 7, 11 ); // sets this element to span 7 of a total 11 columns
3
	min-height: 500 * @toRems;
4
	background-color: #ddd;
5
}
6
7
aside {
8
	.Cols( 4, 11 ); // sets this element to span 4 of a total 11 columns
9
	min-height: 500 * @toRems;
10
	background-color: #eee;
11
}

Lo que nos da:

classiclayout_colschangedclassiclayout_colschangedclassiclayout_colschanged

Esto a su vez hace que sea muy fácil agregar columnas adicionales, por ejemplo, si agregamos un segundo elemento aside antes del elemento article en nuestro HTML, y luego cambiamos nuestro LESS a lo siguiente:

1
article {
2
	.Cols( 5, 9 );
3
	min-height: 500 * @toRems;
4
	background-color: #ddd;
5
}
6
7
aside {
8
	.Cols( 2, 9 );
9
	min-height: 500 * @toRems;
10
	background-color: #eee;
11
}

... obtendremos:

classiclayout_extracolclassiclayout_extracolclassiclayout_extracol

Agregar relleno y márgenes

Una vez que comience a agregar contenido dentro de sus contenedores, por supuesto, querrá poder controlar el espaciado a su alrededor. En este momento, cuando agregamos contenido, se sentará al ras contra los bordes:

classiclayout_contentflushclassiclayout_contentflushclassiclayout_contentflush

Hay un par de maneras en las que puede controlar su espaciado, y cuál es la mejor para usar dependerá de lo que esté tratando de lograr con el diseño específico que está creando.

Agregar relleno

La forma más fácil de controlar el espaciado es con la simple adición de parámetros de relleno a ambos el archivo . Row() y . Cols() mixins.

Nuestro código mixin se ajustará a lo siguiente:

1
@default-padding: 0;
2
3
.Row ( @width : @default-width; @padding: @default-padding; ) {
4
	max-width: @width;
5
	width: 100%;
6
	margin: 0 auto;
7
	padding: @padding;
8
	// clear at the end of container
9
	&:before,
10
	&:after {
11
		content:"";
12
		display:table;
13
	}
14
	&:after {
15
		clear:both;
16
	}
17
}
18
19
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols; @padding: @default-padding; ) {
20
	width: ( @colspan * (100 / @total_cols) ) + 0%;
21
	float: left;
22
	padding: @padding;
23
}

Ahora podemos agregar relleno a nuestros elementos de encabezado, artículo, aparte y pie de página.

Tenga en cuenta que también estableceremos la propiedad de tamaño de cuadro predeterminada en todo el diseño en border-box para que el relleno no se incluya en ningún cálculo del explorador del ancho de los elementos:

1
* {
2
	box-sizing:border-box;
3
	-moz-box-sizing:border-box;
4
}
5
6
header, footer {
7
	.Row ( 
8
		@padding: 20 * @toRems;
9
	);
10
	background-color: #ccc;
11
	min-height: 200 * @toRems;
12
}
13
14
main {
15
	.Row;
16
	background-color: #ccc;
17
}
18
19
article {
20
	.Cols (
21
		@colspan: 3;
22
		@padding: 10 * @toRems 20 * @toRems;
23
	);
24
	min-height: 500 * @toRems;
25
	background-color: #ddd;
26
}
27
28
aside {
29
	.Cols (
30
		@colspan: 1;
31
		@padding: 10 * @toRems 20 * @toRems;
32
	);
33
	min-height: 500 * @toRems;
34
	background-color: #eee;
35
}

Esto ahora nos da relleno alrededor de cada una de nuestras piezas de contenido:

classiclayout_paddedclassiclayout_paddedclassiclayout_padded

Adición de márgenes de contenedor

A veces, el espaciado que desea agregar a su diseño está en el exterior de un elemento, no en el interior, por ejemplo, cuando desea que el fondo de un sitio se muestre entre los elementos. Para permitir esto, haremos algunas adiciones adicionales tanto al . Row() y . Cols() mixins.

Para empezar, permitamos que se agregue espaciado por encima y por debajo de los elementos que tienen nuestro archivo . Row() mixin aplicado a ellos. Esto se hace fácilmente simplemente reemplazando el valor de nuestra propiedad de margen existente con una variable que se puede enviar como parámetro a través del mixin.

1
@default-row_margin: 0 auto;
2
3
.Row ( @width : @default-width; @padding: @default-padding; @margin: @default-row_margin; ) {
4
	max-width: @width;
5
	width: 100%;
6
	margin: @margin;
7
	padding: @padding;
8
	// clear at the end of container
9
	&:before,
10
	&:after {
11
		content:"";
12
		display:table;
13
	}
14
	&:after {
15
		clear:both;
16
	}
17
}

Tenga en cuenta que el valor predeterminado para el margen de fila todavía se establece en 0 auto, por lo que si no se pasa ningún parámetro, el mixin seguirá centrando automáticamente el elemento.

Sin embargo si pasamos un valor @margin a través del mixin:

1
header, footer {
2
	.Row ( 
3
		@padding: 20 * @toRems;
4
		@margin: 10 * @toRems auto;
5
	);
6
	background-color: #ccc;
7
	min-height: 200 * @toRems;
8
}

... podemos agregar espaciado vertical así:

classiclayout_vertspacerowclassiclayout_vertspacerowclassiclayout_vertspacerow

Además, si decide que ya no desea que su elemento se centre, también puede hacer cosas como pasar un valor de @margin de 0 auto 0 0 para alinear a la izquierda un elemento o 0 0 0 auto para alinear a la derecha.

Adición de canalones de columna

Otra característica común de los sistemas de cuadrícula CSS es la capacidad de agregar canalones entre columnas, es decir, márgenes que se aplican entre cada columna, pero no al exterior de las columnas más externas.

Una vez más, podemos agregar esta funcionalidad con algunas adiciones al mixin Cols():

1
@default-gutter: 0;
2
3
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols; @padding: @default-padding; @gutter: @default-gutter; @edge: false; ){
4
	@total_gutter: (@total_cols - 1) * @gutter;
5
	@spanned_gutters: (@colspan - 1) * @gutter;
6
	width: ( @colspan * ( (100 - @total_gutter) / @total_cols) ) + @spanned_gutters + 0%;
7
	float: left;
8
	padding: @padding;
9
	.IfEdge (@edge; @gutter);
10
}
11
12
.IfEdge ( @edge; @gutter; ) when (@edge = false) {
13
	margin-right: @gutter + 0%;
14
}
15
16
.IfEdge ( @edge; @gutter; ) when (@edge = true) {
17
	margin-right: 0;
18
}

El mixin ahora hace dos cosas adicionales. En primer lugar, comprueba si hay un valor a través del nuevo parámetro @gutter y lo tiene en cuenta en el cálculo de ancho de la columna.

Nota: El valor de @gutter debe ser un número destinado a ser utilizado como un valor de porcentaje, por ejemplo, 2 para una canaleta del 2%.

En segundo lugar, comprueba la nueva variable @edge para ver si está establecida en true o false. Si @edge se establece en false, el valor del parámetro @gutter se agrega al margen derecho como un porcentaje. Si @edge se establece en true, el margen derecho se establece en 0. Esto le permite especificar dónde está una columna en el borde de su diseño y, por lo tanto, no debe tener un canal aplicado.

Para mostrar el efecto de este cambio en el mixin más claramente he añadido dos elementos de artículo adicionales a nuestro HTML. El MENOS para el artículo y los elementos de lado se ha ajustado a lo siguiente:

1
article {
2
	.Cols (
3
		@colspan: 1;
4
		@padding: 10 * @toRems 20 * @toRems;
5
		@gutter: 1; //include a gutter of 1%
6
	);
7
	min-height: 500 * @toRems;
8
	background-color: #ddd;
9
}
10
11
aside {
12
	.Cols (
13
		@colspan: 1;
14
		@padding: 10 * @toRems 20 * @toRems;
15
		@gutter: 1; //include a gutter of 1%
16
		@edge: true; //this is the column on the edge so don't set a right margin
17
	);
18
	min-height: 500 * @toRems;
19
	background-color: #eee;
20
}

Lo que ahora nos da:

classiclayout_guttersclassiclayout_guttersclassiclayout_gutters

Permitir el control sobre los márgenes verticales en las columnas es de nuevo sólo una cuestión de incluir algunos parámetros adicionales en el mixin, ajustándolo a:

1
@default-margin_top: 0;
2
3
@default-margin_bottom: 0;
4
5
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols; @padding: @default-padding; @gutter: @default-gutter; @edge: false; @margin_top : @default-margin_top; @margin_bottom : @default-margin_bottom; ){
6
	@total_gutter: (@total_cols - 1) * @gutter;
7
	@spanned_gutters: (@colspan - 1) * @gutter;
8
	width: ( @colspan * ( (100 - @total_gutter) / @total_cols) ) + @spanned_gutters + 0%;
9
	float: left;
10
	padding: @padding;
11
	.IfEdge (@edge; @gutter; @margin_top; @margin_bottom; );
12
}
13
14
.IfEdge ( @edge; @gutter; @margin_top; @margin_bottom;  ) when (@edge = false) {
15
	margin: @margin_top @gutter + 0% @margin_bottom 0;
16
}
17
18
.IfEdge ( @edge; @gutter; @margin_top; @margin_bottom;  ) when (@edge = true) {
19
	margin: @margin_top 0 @margin_bottom 0;
20
}

La configuración de los márgenes superior e inferior ahora también se puede incluir cuando se utiliza el archivo . Cols() mixin, por ejemplo:

1
article {
2
	.Cols (
3
		@colspan: 1;
4
		@padding: 10 * @toRems 20 * @toRems;
5
		@gutter: 1;
6
		@margin_top: 20 * @toRems;
7
		@margin_bottom: 30 * @toRems;
8
	);
9
	min-height: 500 * @toRems;
10
	background-color: #ddd;
11
}
12
13
aside {
14
	.Cols (
15
		@colspan: 1;
16
		@padding: 10 * @toRems 20 * @toRems;
17
		@gutter: 1;
18
		@edge: true;
19
		@margin_top: 20 * @toRems;
20
		@margin_bottom: 30 * @toRems;
21
	);
22
	min-height: 500 * @toRems;
23
	background-color: #eee;
24
}

Lo que agregaría márgenes verticales a las columnas de la siguiente manera:

classiclayout_vertmargincolsclassiclayout_vertmargincolsclassiclayout_vertmargincols

Anidamiento y aumento de la complejidad del diseño

Ahora agregaremos otro nivel de complejidad a nuestro diseño de ejemplo aumentando el número de elementos del artículo a seis y colocándolos dentro de un contenedor de elementos de sección, luego aplicando nuestros mixins para crear el siguiente diseño:

classiclayout_nestedclassiclayout_nestedclassiclayout_nested

Para lograr este diseño, el código HTML ahora se cambia a:

1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
	<meta charset="UTF-8">
5
	<title>Classic Layout</title>
6
	<script type='text/javascript' src='js/modernizr.js'></script>
7
	<link rel="stylesheet" href="css/normalize.css">
8
	<link rel="stylesheet" href="css/classiclayout.css">
9
</head>
10
<body>
11
<header>
12
	<h1>Site Title</h1>
13
</header>
14
<main>
15
	<section>
16
		<h1>Latest Articles</h1>
17
		<article>
18
			<h1>Article Title</h1>
19
			<p>...</p>
20
		</article>
21
		<article>
22
			<h1>Article Title</h1>
23
			<p>...</p>
24
		</article>
25
		<article>
26
			<h1>Article Title</h1>
27
			<p>...</p>
28
		</article>
29
		<article>
30
			<h1>Article Title</h1>
31
			<p>...</p>
32
		</article>
33
		<article>
34
			<h1>Article Title</h1>
35
			<p>...</p>
36
		</article>
37
		<article>
38
			<h1>Article Title</h1>
39
			<p>...</p>
40
		</article>
41
	</section>
42
	<aside>
43
		<p>...</p>
44
	</aside>
45
</main>
46
<footer>
47
	<p>Example Footer</p>
48
</footer>
49
</body>
50
</html>

El código LESS que estamos usando para controlar el diseño ahora se ha cambiado a:

1
header, footer {
2
	.Row ( @padding: 20 * @toRems; @margin: 10 * @toRems auto; );
3
	background-color: #ccc;
4
	min-height: 100 * @toRems;
5
}
6
7
main {
8
	.Row;
9
}
10
11
section {
12
	.Cols ( @colspan: 3; @padding: 10 * @toRems 20 * @toRems; @gutter: 1; );
13
	background-color: #ddd;
14
}
15
16
aside {
17
	.Cols ( @colspan: 1; @padding: 10 * @toRems 20 * @toRems; @gutter: 1; @edge: true; );
18
	min-height: 500 * @toRems;
19
	background-color: #eee;
20
}
21
22
article {
23
	.Cols ( @colspan: 1; @total_cols: 3; @padding: 0 20 * @toRems 20 * @toRems 20 * @toRems; @margin_bottom: 20 * @toRems;  @gutter: 2; );
24
	background-color: #eee;
25
	&:nth-of-type(3n) {
26
		margin-right: 0;
27
	}
28
}

Para resumir lo que contiene el código LESS anterior:

El elemento section está configurado para ocupar tres columnas de las cuatro columnas totales predeterminadas. Junto a él está el elemento aparte, todavía establecido en una columna de cuatro.

El elemento section actúa como contenedor para los elementos article. Dado que los elementos de artículo ahora están anidados, pueden tener todos los nuevos anchos de columna aplicados a ellos, y cada uno de ellos tomará un porcentaje del interior de su elemento primario. Como tal, cada uno se establece en una columna de cada tres, con una canaleta del 2%.

Cada tercer elemento de artículo se identifica mediante el selector :nth-of-type(3n) y se establece para que no tenga margen derecho / canalón.


Ajuste a pantallas más pequeñas

Anteriormente en el artículo mostramos cómo se agrega la capacidad de respuesta básica desde el primer momento mediante el uso de este enfoque. Otra cosa que haremos de manera diferente a muchas otras es nuestro enfoque para agregar puntos de interrupción y determinar el comportamiento en estos puntos.

En lugar de tratar de identificar y apuntar a los tamaños de pantalla exactos de varios dispositivos, queremos hacer que nuestro diseño funcione en cada resolución. De esta manera nos volvemos independientes del dispositivo.

Para lograr esto, simplemente introduciremos puntos de interrupción en anchos arbitrarios cuando el diseño se vuelva demasiado aplastado para ser cómodamente legible, y modificaremos las columnas para que el contenido se pueda presentar de nuevo.

En el caso de este diseño, agregaremos las siguientes consultas de medios:

1
article {
2
	.Cols ( @colspan: 1; @total_cols: 3; @padding: 0 20 * @toRems 20 * @toRems 20 * @toRems; @margin_bottom: 20 * @toRems;  @gutter: 2; );
3
	background-color: #eee;
4
	@media (min-width: 68rem) {
5
		&:nth-of-type(3n) {
6
			margin-right: 0;
7
		}
8
	}
9
}
10
11
@media (max-width: 68rem) {
12
	article {
13
		.Cols ( @colspan: 1; @total_cols: 2; @padding: 0 20 * @toRems 20 * @toRems 20 * @toRems; @margin_bottom: 20 * @toRems;  @gutter: 2; );
14
		@media (min-width: 53rem) {
15
			&:nth-of-type(2n) {
16
				margin-right: 0;
17
			}
18
		}
19
	}
20
}
21
22
@media (max-width: 53rem) {
23
	article {
24
		.Cols ( @colspan: 1; @total_cols: 1; @padding: 0 20 * @toRems 20 * @toRems 20 * @toRems; @margin_bottom: 20 * @toRems;  @gutter: 0; );
25
	}
26
	section {
27
		.Cols ( @colspan: 2; @total_cols: 3; @padding: 10 * @toRems 20 * @toRems; @gutter: 1; );
28
	}
29
	aside {
30
		.Cols ( @colspan: 1; @total_cols: 3; @padding: 10 * @toRems 20 * @toRems; @gutter: 1; @edge: true; );
31
	}
32
}
33
34
@media (max-width: 36rem) {
35
	section {
36
		.Cols ( @colspan: 1; @total_cols: 1; @padding: 10 * @toRems 20 * @toRems; @edge: true; );
37
	}
38
	aside {
39
		.Cols ( @colspan: 1; @total_cols: 1; @padding: 10 * @toRems 20 * @toRems; @edge: true; );
40
	}
41
}

Como se mencionó anteriormente, los puntos de interrupción se determinan caso por caso para cada diseño.

Para este propósito utilizo el plugin de Firefox Firesizer para darme una muestra de lo ancha que es la ventana de mi navegador en píxeles. Gradualmente encojo el ancho del navegador y cuando identifico un punto que es demasiado estrecho, hago una nota del ancho de la pantalla.

Desafortunadamente, LESS no permitirá que se produzca ninguna operación en los valores que estamos usando para nuestras consultas de medios, por lo que no podemos hacer algo como @media (max-width: 1000 * @toRems).

Debido a que la variable @toRems no se puede usar aquí para convertir el valor de píxel, en su lugar convierto el ancho a ems usando http://pxtoem.com/

Después de convertir el ancho identificado en rems, agregamos un punto de interrupción en ese ancho y aplicamos un nuevo archivo . Cols() mixin al elemento. Esto puede cambiar el valor de colspan y / o el valor de totalcols dependiendo de lo que se ve mejor en ese ancho.

Cuando sea necesario, también estamos envolviendo cada selector n-de-tipo() en una consulta de medios basada en el ancho mínimo. Esto garantiza que cuando el diseño se hace más pequeño y el número de columnas se reduce, la columna de borde se identifica correctamente como cada segundo en lugar de cada tercio.

Por ejemplo, en el primer punto de interrupción de 68rem cambio los artículos de cada uno de los tres columnas, a ser uno de dos columnas.

También agrego una consulta de medios min-width: 68rem alrededor del selector :nth-of-type(3n) por lo que se aplica solo en tamaños mayores que 68rem.

Luego agrego un nuevo selector :nth-of-type(2n) a nuestra consulta de medios para tamaños inferiores a 68rem, que identificará cada segundo post como que no necesita medianil.

Estos cambios crean el siguiente diseño cuando la ventanilla es menor que 68rem de ancho:

classiclayout_2colsclassiclayout_2colsclassiclayout_2cols

En el siguiente punto de interrupción de 53rem, redeje el número de columnas de artículo nuevamente a una sola columna, es decir, @colspan 1 de @total_cols 1, con cada artículo apilado encima del otro.

Nuevamente agrego una consulta de medios min-width: 53rem alrededor del selector nth-of-type(2n) que agregamos anteriormente, por lo que ya no se aplica cuando nuestros artículos se reducen a una de una de las columnas.

También cambio el ancho de la sección de 3 / 4 columnas a 2 / 3, y cambio el ancho del aparte de 1 / 4 ancho a 1 / 3. Esto permite un poco más de espacio para la barra lateral para que no esté demasiado aplastado en este ancho.

Ahora, cuando el diseño se reduce a menos de 53rem de ancho, se ve así:

classiclayout_singlearticlecolclassiclayout_singlearticlecolclassiclayout_singlearticlecol

Finalmente, en 36rem cuando el diseño se vuelve demasiado estrecho para acomodar varias columnas en absoluto, cambio tanto la sección como los elementos secundarios a 1 / 1 columnas, lo que empuja el aparte por debajo del elemento de sección.

El diseño ahora se ve así en cualquier ancho menor que 36rem:

classiclayout_collapsedclassiclayout_collapsedclassiclayout_collapsed

Envolviendo

Hemos pasado por un montón de detalles anteriores sobre cómo el . Row() y . Cols() mixins trabajo, con el fin de darle una comprensión completa para que pueda hacer aún más adiciones o modificaciones a ellos si lo desea. Sin embargo, el resultado final de todo lo que hemos cubierto es en realidad un sistema de diseño súper simple y fácil de usar.

Mediante el uso de solo dos mixins, ahora puede crear diseños altamente complejos, pero flexibles y escalables sin prácticamente restricciones, generando solo el CSS que necesita y usando marcado altamente semántico.

Puede utilizar cualquier número de columnas totales que desee para la cuadrícula, cualquier ancho de columnas individuales y cualquier ancho de canalones. Además, sus cuadrículas son infinitamente anidables.

¡Descargue su propia copia de los mixins escritos para este tutorial y pruébelos para el diseño de su próximo proyecto!