5分钟入门CSS GRID layout

曾经在视频网站看过国外的关于css grid layout演讲,一看视频时长就关了。。。后来在一个项目里用了一下,发现其实要简单使用起来没有那么多名堂。

试想一下这个场景:当页面左侧有一个只有window高度一样高的菜单,而右侧的主要内容却高过这个菜单,我们无法得知右侧内容的高度来写给菜单,却要保证左侧菜单和右侧内容一样高(通常是为了background-color),如果强行用float解决了之后,有另一个同样的页面右侧内容比菜单要矮,是不是可能又要重写样式了?

以这个为目标写一个简单的html框架

head
side
content
foot

开始第一行CSS代码

.grid{
    display:grid;
}

或者

.grid{
    display:inline-grid;
}

这样.grid容器内的直属子容器,将会以网格的形式存在。写了inline会自动宽高,不写则宽度撑满父容器。

.grid{
    display:grid;
    grid-template-columns:1fr 1fr;
    grid-template-rows:1fr 2fr 1fr;
}

rows的参数决定了有几行,columns的参数决定了有几列,一个fragment会占用一份空间。由于我的目标一行最多就只有两列,columns我只写两个就足够了,最终menu和content会平均分配父容器的宽度,而一列最多会有三个容器,head,foot都要占一整行,只给一个fr,而content的menu会比较高,给它2fr,这样高度就被分成了4份,每一份的高度从总高度里平均分配,注意这里的参数可以支持px,%, em,等等。

接下来给每一个grid定义一个名称

.head{
    grid-area:head;
}
.side{
    grid-area:side;
}
.content{
    grid-area:content;
}
.foot{
    grid-area:foot;
}

给每个grid定义了一个标签之后,就可以在父容器中规划排序了。

.grid{
    display:grid;
    grid-template-columns:1fr 1fr;
    grid-template-rows:1fr 2fr 1fr;
    grid-template-areas: //新增
        "head head" //第一行全部是head,撑满整个宽度
        "side content" //第二行左侧是side,右侧content
        "foot foot" //第三行全是foot,撑满整个宽度
}

grid-basic.jpg

好了,基本搞定了。接下来就是优化尺寸。因为side的宽度通常会固定,content自由变化,所以我们只要给side定义一个宽,让side所在的grid的宽度自动就可以了。

.side{
    width:200px;
}
.grid{
    display:grid;
    grid-template-columns:auto 1fr;
    grid-template-rows:1fr 2fr 1fr;
    grid-template-areas: 
        "head head"
        "side content"
        "foot foot"
}

grid-autowidth.jpg

好了,获得基础任务成就。

以下是延伸阅读:

Gap:

有时候grid之间需要一个相等的空白空间。一句话解决。

.grid{
    display:grid;
    grid-gap: 10px; //同样支持em,%等
    grid-template-columns:1fr 1fr;
    grid-template-rows:1fr 2fr 1fr;
    grid-template-areas: //新增
        "head head"
        "side content"
        "foot foot"
}

gird-gap.jpg

我开始很疑惑,这种需求,flexbox似乎也可以实现,但是如下图,一旦有一些较为复杂的需求,可能flex会比较麻烦,而grid就显得方便许多。。。

grid-multiple.jpg

.grid{
    display:grid;
    grid-gap: 10px; //同样支持em,%等
    grid-template-columns:1fr 1fr;
    grid-template-rows:1fr 1fr 1fr 1fr;
    grid-template-areas:
        "head content"
        "head content"
        "side content"
        "foot foot"
}

浏览器兼容:

IE下由于不支持grid-template-areas, 所以考虑兼容的时候以上用法就失效了,每个div都要单独声明自己占用了几块。
虽然caniuse上说IE10,11,只需要加前缀-ms-,但是实际上我试了下,这样是完全行不通的。

.grid{
    display:-ms-grid;
    display:grid;
   -ms-grid-rows: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    -ms-grid-columns: 1fr 2fr 1fr;
    grid-template-columns: 1fr 2fr 1fr;
    grid-template-areas:
        "head head"
        "side content"
        "foot foot"
}
.head{
    -ms-grid-column: 1;
    -ms-grid-row: 1;
    -ms-grid-row-span: 1;
    grid-area:head;
}
.side{
    -ms-grid-column: 2;
    -ms-grid-row: 1;
    grid-area:side;
}
.content{
    -ms-grid-column: 2;
    -ms-grid-row: 2;
    grid-area:content;
}
.foot{
    -ms-grid-column: 3;
    -ms-grid-row: 1;
    -ms-grid-row-span: 1;
    grid-area:foot;
}

好像没有办法测试,但是应该是这样没错。

Leave a Reply

Your email address will not be published. Required fields are marked *