CSS变量创建网格系统
今天要聊的网格系统不是CSS Grid Layout,而要聊的是类似960gs。到止前为止类似于960gs的网格系统成熟的系统有很多套了。
- Susy
- Gridlex
- Gumby Grid
- Bootstrap Grid
- Foundation Grid
- Flexbox Grid
- FLUIDABLE
- Getskeleton Grid
- Unsemantic
- Materialize Grid
- 其他Grid系统
实现Grid系统的方案
如果忽略CSS Grid Layout特性,所讲的Grid系统都是源自于960gs。而实现这种网格系统所用的方案至今天而言主要实现方式有:
- 固定网格系统
- 流式网格系统
固定网格系统:固定网格系统所说的就是网格的列宽、列数、列间距都是固定的值,比如使用的是px
值。
流式网格系统:流式(也称之为自适应网格系统),也就是网格的列宽,列间距都是使用的百分比,而列数是固定的值,最常见的和固定网格一样,是12
列。但一般情况,流式网格系统都会给网格容器设置一个最大宽度(max-width
)。
而实现网格系统的方法目前为之最为常见的是使用float
或者flexbox
两种。其中先进的一点的是采用CSS处理器来实现。
计算Grid系统的公式
这里所说的网格系统,共实现具有一定的数学公式:
scw = (100 – (m * (mc – 1))) / mc
其对应描述如下:
- scw:指的是单列宽度
- m:指的是列间距
- mc:最大列数(一般是
12
)
根据上面的公式,可以转换出计算其他列的列宽的公式:
cw = (scw * cs) + (m * (cs – 1))
- cw:列宽度
- scw:单列宽度
- cs:列数(
1~12
) - m:列间距
根据上述公式,不难算出网格的各参数值。下面来看两种网格计算方式,以及其得到的相关参数值。
固定网格系统
假设网格系统总共列数为12
列,列间距为20px
(也就是padding-left
和padding-right
各为10px
,当然也可以是单方面的,比如padding-left
或者padding-right
),网格容器的宽度为1180px
。根据上述公式和相关的网格参数,可以计算出各列的宽度:
每列宽度:
scw = (100 – (m * (mc – 1))) / mc
/*
* 网格容器总宽度 1180
* 网格间距m = 20
* 网格列数mc = 12
*/
scw = (1180 - (20 * (12 - 1))) / 12
scw = (1180 - 20 * 11) / 12
scw = (1180 - 220) / 12
scw = 960 / 12
scw = 80
再根据:
cw = (scw * cs) + (m * (cs – 1))
可以计算出每列的宽度
cw = ?
scw = 80
cs = 1 ~ 12
m = 20
如此来可以计算出:
cs = 1 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 1 + 20 * (1 - 1) = 80
cs = 2 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 2 + 20 * (2 - 1) = 180
cs = 3 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 3 + 20 * (3 - 1) = 280
cs = 4 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 4 + 20 * (4 - 1) = 380
cs = 5 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 5 + 20 * (5 - 1) = 480
cs = 6 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 6 + 20 * (6 - 1) = 580
cs = 7 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 7 + 20 * (7 - 1) = 680
cs = 8 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 8 + 20 * (8 - 1) = 780
cs = 9 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 9 + 20 * (9 - 1) = 880
cs = 10 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 10 + 20 * (10 - 1) = 980
cs = 11 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 11 + 20 * (11 - 1) = 1080
cs = 12 => cw = (scw * cs) + (m * (cs – 1)) = 80 * 12 + 20 * (12 - 1) = 1180
根据上述公式,配合Sass可以得到各列的宽度:
[class*="m--"]{
padding-right: $gutter;
padding-left: $gutter;
@for $i from 1 through 12 {
&.m--#{$i} {
width: (80 * $i + 20 * ($i - 1)) * 1px;
}
}
}
流式网格系统
流式网格系统也称之为自适应网格系统,目前众多网格系统采用的都是流式网格系统,根据固定网格系统中所采用的计算公式,很容易计算出各列的列宽。
scw = (100 – (m * (mc – 1))) / mc
- scw = 单列宽度
- m = margin (1.6%)
- mc = 列数 (12)
假设单列列宽为6.86666666667%
,根据对应的计算公式:
cw = (scw * cs) + (m * (cs – 1))
- cw = 列宽
- scw = 单列宽度 (6.86666666667%)
- cs = 列数 (1-12)
- m = margin (1.6%)
上面看到的示例采用的布局方式是Flexbox方式。当然,古老一点的,采用的是浮动布局多。在这篇文章咱位就不做这方面的阐述。
当然,更为强大的一些的网格布局(目前一些主流的网格系统),都使用了媒体查询,对网格系统做了一些响应式的设计。让网格在不同的断点效果都比较完美,如果你对这方面的网格框系统感兴趣的话,可以查阅相关的代码。
CSS变量创建网格系统
如果你耐心的把文章看到这里,可以说你对网格系统的制作有了一定的了解。那么从这里开始,我们回到今天文章的主题部分:CSS变量创建网格系统。
在介绍CSS变量制作网格系统之前,先简单的了解一下CSS的变量相关的内容。CSS变量又称之为CSS自定义属性,在CSS中通过下面这样的方式来声明CSS变量:
:root{
--color: #0C3934;
--bg: #F8EBEE;
--gutter: 10px;
--columns: 12;
}
然后通过下面的方式来调用CSS声明的变量:
.m--1 {
--column-width: 1;
}
这里简单的介绍了如何声明CSS的变量和调用已声明的CSS变量。如果你对这方面感兴趣,可以先阅读《深入学习CSS自定义属性(CSS变量)》一文。
到此,你对CSS自定义变量有了一定的了解,接下来看如何通过CSS变量来制作一个CSS网格系统。根据前面介绍的网格制作原理,可以先定义相关的网格参数,当然用CSS的变量来定义:
:root{
--color: #0C3934;
--bg: #F8EBEE;
/* Grid */
--gutter: 10px; /*列间距*/
--columns: 12; /*列数*/
}
对于网格的基本布局,同样可以通过Flexbox布局来实现:
.container {
max-width: 1140px;
margin: 3em auto;
padding: var(--gutter);
}
*{
box-sizing: border-box;
}
.row{
display: flex;
flex-wrap: wrap;
margin: 0 calc(var(--gutter) - ( var(--gutter) * 2) ) 20px;
}
[class*="m--"]{
padding-right: calc(var(--gutter));
padding-left: calc(var(--gutter));
flex-basis: calc((100% / var(--columns)) * var(--column-width));
}
上面的代码就不做详细的介绍了。有关于这方面的使用可以阅读《深入学习CSS自定义属性(CSS变量)》一文。当然,其中还运用了CSS的calc()
函数。如果你从未接触过calc()
相关的内容,可以点击这里阅读。
所设我们的网格是一个12
列的网格,常规情况之下,都会使用.m--*
(当然很多时候会使用col-*
或者span-*
方式),其中*
表示的是网格1~12
。这也不是千篇一律,如果你的网格列数不到12
或者不止12
列时,那么他最大的值就是表示网格最多的列数。
使用CSS变量制作网格系统,不需要像以前一样,使用那么复杂的计算公式。在CSS变量制作网格系统,可以根据网格的列数来声明网格列宽。比如我们的示例中:
.m--1 {
--column-width: 1;/*列宽是一列*/
}
.m--2 {
--column-width: 2;/*列宽是两列+一个列间距*/
}
以此类推,可以借助Sass的@for
循环,很容易实现网格1
列至12
列的列宽:
[class*="m--"]{
padding-right: calc(var(--gutter));
padding-left: calc(var(--gutter));
flex-basis: calc((100% / var(--columns)) * var(--column-width));
@for $i from 1 through 12 {
&.m--#{$i} {
--column-width: $i;
}
}
}
最后你看到效果如下:
上面示例是通过声明列数来实现一个完美的网格系统。其实还可以通过声明列宽来制作网格系统。比如:
:root {
--grid-width: 20%;
--color-primary: #2980b9;
--color-secondary: #c0392b;
--color-accent: #16a085;
--font-size: 18px;
}
调用的时候:
.four-cols {
--grid-width: 25%;
}
.three-cols {
--grid-width: 33%;
}
更详细的代码可以看下面的示例:
总结
文章从平始制作一个固定网格系统和流式网格系统着手,引入了怎么通过CSS变量制作一个网格系统。从上面的示例对比来讲,通过CSS变量制作一个网格系统,让我们变得更为简单,而且再也不需要通过复杂的数学公式来计算网格系统中每列的列宽。如果你感兴趣的话,可以自己动手尝试一下怎么使用CSS变量来制作一个网格系统。