阅读 277

神奇的Grid布局

神奇的Grid布局


本来以为,漂泊,就是家乡只有冬夏,再无春秋。现在才发现,漂泊,是连冬夏都没有了。

什么是flex

​ 遥想当年,一手flex布局走天下,每每面试官问到关于关于布局方面的问题,大多离不开flex,当下看来flex布局确实是日常开发中最为常见的布局了,

2009年,W3C提出了一种新的方案--Flex布局,可以简便、完整、响应式地实现各种页面布局。目前已得到所有现在浏览器的支持。

​ 距今来看已经十多年了,确确实实占据了前端布局中很大的地位,相比大家对flex都很熟悉,所以今天我们的主角就是-------> Grid

什么是Grid布局

​ Grid布局又称网格布局,Grid 布局是网站设计的基础,CSS Grid 是创建网格布局最强大和最简单的工具。轻松使用 Grid 布局提高开发效率,对复杂的网页结构布局更加灵活。Grid 将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。网格是一组相交的水平线和垂直线,它定义了网格的列和行。我们可以将网格元素放置在与这些行和列相关的位置上。我们比较熟悉的比如说坐标轴,坐标点;如果你看到下面这样一个网格首先想到是这不就是被淘汰的表格吗,表格之所以被淘汰最主要在性能方面,然而我们不得不承认表格对于整个网页的布局来说有一定的便利性。那么现在的网格布局就可以把表格里面的一些较好的方便的东西抽出来,然后把性能方面较差的地方去掉,所以说网格布局会成为将来互联网企业的一个热潮是有原因的。我们可以把一个网页理解成一个网格,然后往里面填充东西即可.

当我们吧网页划分成这样的一个一个格子的时候,是否就觉得很清晰了呢,当然这样还不够,我们在有的时候也需要像tabel那样对单元格进行合并或者删除,例如下面这样:

​ 总之你可以对这些格子随意操作,不再再仅限于一条轴线,这里有很多条了。让我们上代码看看这些在浏览器中如何实现吧

demo<基础运用>
<body>
    <div class="wrapper">
        <div class="box box1">box 1</div>
        <div class="box box2">box 2</div>
        <div class="box box3">box 3</div>
        <div class="box box4">box 4</div>
        <div class="box box5">box 5</div>
    </div>
</body>

<style>
    .wrapper{
        padding: 1rem;
    }
    .wrapper>div{
        background: #ccc;
        padding: 1rem;
    }
    .wrapper>div:nth-child(odd){
        background: #ddd;
    }
 </style>
复制代码

先上五个盒子,看看本来的样子吧:

对于不使用任何布局的时候就是这样子啦:五个div独占一行,这个时候让我们改造一下让他变成像上面一样的格子吧,我们来做一个一行有三个格子的网格出来吧

<style>
    .wrapper{
        display: grid;
        padding: 1rem;
        grid-template-columns: repeat(3,1fr);
        grid-gap: 1rem;
        grid-auto-rows:minmax(100px,auto);
        }
    .wrapper>div{
        background: #ccc;
        padding: 1rem;
    }
    .wrapper>div:nth-child(odd){
        background: #ddd;
    }
 </style>
复制代码

可以看到只需添加两行代码,轻松实现,display: grid;和flex布局同理申明一个容器,表示外层的这个div为网格容器了,那么这一行呢grid-template-columns: repeat(3,1fr);这一行表示一行放三个盒子并且宽度一样,这里用到了一个repeat函数正常写法是这样,grid-template-columns: 1fr 1fr 1fr; 这样就代表一行三个格子,当然你可以写四个五个六七个,这里的fr就是一个单位(弹性尺寸使用fr尺寸单位,其来自 “fraction” 或 “fractional unit” 单词的前两个字母,表示整体空间的一部分。)fr是一个相对尺寸单位,表示剩余空间做等分,此项分配到的百分比(如果只有一个项使用此单位,那就占剩余空间的100%,所以多个项联合使用更有意义,在flex布局中也有用到,这里你可以自由搭配,当然这里也可以使用百分比例如:

`grid-template-columns: 30% 30% 40%;`
复制代码

当然了多种多样都可以,任你自由搭配,那么剩下两行呢:

grid-gap: 1rem;横纵轴的间距可以写两个参数,就是格子间的间距,可以自我尝试

grid-auto-rows:minmax(100px,auto);这里用到了minmax函数表示最小高度为100px,如果文字撑起高度大于100px了,那么则自适应,这里只是为了大家看得更清晰添加的,可以自我尝试

以上就是基础的grid布局两行代码上手,soeasy!!!

接下来我们试试合并单元格吧,像图二一样合并各种格子自由搭配

demo<合并格子>
<style>
    .wrapper{
        display: grid;
        padding: 1rem;
        grid-template-columns: repeat(3,1fr);
        grid-gap: 1rem;
        grid-auto-rows:minmax(100px,auto);
        }
    .wrapper>div{
        background: #ccc;
        padding: 1rem;
    		}
    .wrapper>div:nth-child(odd){
        background: #ddd;
    		}
    .box1{
        grid-column:1/3;
        grid-row:1/3;
        }
    .box2{
        grid-column: 3;
        grid-row:1/3;
    }
    .box4{
        grid-column: 2/4;
    }
    .box5{
        grid-column: 1/4;
    }
 </style>
复制代码

​ 好了,我们来看看效果吧!!!

我们发现所有的盒子都发生了变化:我们来分析下

我们对五个盒子进行了操作,但是实际上只用到了两个属性 ----->

grid-column: 1/3; 这个属性代表合并单元格的横轴,后面的1/3(box1)代表合并了从一条线到第三条线的范围(这里的线就是网格线了,这个很好理解,图一中红色黑色的都是网格线,网格线会比盒子多1,例如横向红色线五条是四个盒子,纵向四条线三个盒子),那么这里横向的1-3就很好理解了,就是当前行第一第二个盒子合并,在下面可以轻松看出,我们没有对box3做任何操作,把box3当做一个盒子,显然box1有两个box3那么宽。

grid-row:1/3; 那么很显然这个就是纵向合并了同理以box1为例,box3对比,box1是2倍的box3高度,它在纵向依然合并了两个盒子,第一条线到第三条,想要对谁操作,这个属性加给谁就ok,后面我会把所以属性写出来,以便大家更方便查看,

看起来文字很多实际上代码不多,接下来我们进行实战看看吧>>>

demo<实战--->模板加媒体查询轻松实现移动pc端>

这里我准备了一个demo先来看看吧

<div class="wrapper">
        <div class="header">
            <h1>九儿的小书屋</h1>
        </div>
        <div class="content">
            <h3>hello word</h3>
            <p>Lorem</p>
        </div>
        <div class="silebar">
            <h3>联系我们</h3>
            <ul>
                <li>九儿的小书屋</li>
                <li>shangHai</li>
                <li>xiaojiu@163.com</li>
                <li>927898639</li>
            </ul>
        </div>
        <div class="box1">
            <h3>titleOne</h3>
            <p>Lorem</p>
        </div>
        <div class="box2">
            <h3>titleTwo</h3>
            <p>Lorem </p>
        </div>
        <div class="box3">
            <h3>titleThree</h3>
            <p>Lorem </p>
        </div>
        <div class="footer">
            Copyright @ 2020
        </div>
    </div>
复制代码

看看效果吧(删除掉了各个dom的内容量方便直观观看)

可以看到,一个没有css的文件就是这样,下面我们采用模板的方式对他就行布局,我们先来设置一个模板看看吧

<style>
        body{
            margin: 0;
            padding: 1rem;
        }
        .wrapper{
            display: grid;
            grid-template-areas: 
                'header header header'
                'content content silebar'
                'box1 box2 box3'
                'footer footer footer';
            grid-gap: 1rem;
        }
        .header{
            grid-area: header;
        }
        .content{
            grid-area: content;
        }
        .silebar{
            grid-area: silebar;
        }
        .box1{
            grid-area: box1;
        }
        .box2{
            grid-area: box2;
        }
        .box3{
            grid-area: box3;
        }
        .footer{
            grid-area: footer;
            text-align: center;
        }
        .header,
        .content,
        .silebar,
        .box1,
        .box2,
        .box3,
        .footer{
            border: 1px solid #ccc;
            padding: .5rem;
        }
    </style>
复制代码

来看看效果吧

来分析下吧,看起来很多代码对不,实际上我们只需要关注这个模板即可

.wrapper{
        display: grid;
        grid-template-areas: 
            'header header header'
            'content content silebar'
            'box1 box2 box3'
            'footer footer footer';
        grid-gap: 1rem;
    }
复制代码

可以看到一共有四行,第一行三个都是header表示第一行header独占一行占了所有位置,那么为什么是三个header呢,这个其实是不固定的,因为我们在第三行放了三个格子三个div即box123,所以我们应当在设计模板的时候考虑一行最多的那一行会放多少个div即多少个格子,我们的这个模板给他加上一个border就可以发现它就是一行三个格子一共四行十二个格子,当然这个随意你修改都可以,在下面给各个class单独设置属性的时候只需要使用grid-area: xxx;进行关联就好,上面模板用的这些词汇不固定,即使使用abc都可以,当然我们需要语义化以便更直观看出来,这里你可以多做尝试,其实就是一个拼图游戏,自己随意尝试,然后在下面关联上模板即可,我们来看看这个模板占比:

header header header
content content silebar
box1 box2 Box3
footer footer footer

这是pc端的模块,假设我们在移动端呢,我们的手机和电脑屏幕相差甚远如何做到呢,在以前我们对pc移动的自适应可能需要写到两套css代码而用Grid的模板我们可以轻松解决,我们只需要修改他的模板即可,下面是代码:

@media(max-width: 500px){
            .wrapper{
                grid-template-areas: 
                    'header'
                    'content'
                    'silebar'
                    'box1'
                    'box2'
                    'box3'
                    'footer';
            }
        }
复制代码

只需要简单的一个媒体查询:当宽度小于500px(据实际情况而定)的时候,我们把模板改为各个div都是独占一行的,pc端就是上图,让我们看看移动端

通过一个模板轻松改变移动pc的适应,是不是很神奇呢。

Flex和Grid的不同之处

我们常常把Flex布局称之为一维布局(一次只能处理一个维度(一行或者一列)上的元素布局),so,Grid便是所谓的二维布局了(可以同时处理行和列上的布局。)

网格容器 VS Flex容器

网格属性 VS Flex属性

Flex:

flex是flexible box(弹性布局)的简介,是一个一维系统,用来为盒状模型提供最大的灵活性。

**使用:**任何容器(行内元素可设置为display:inline-block);

**特点:**空间分布在行中进行,而非整体

Grid

Gird Layout(css网格布局)是css中最强大的布局系统,是一个二维系统,可以同时处理行和列,可以通过将css规则用于父元素(网格容器)和该元素的子元素(网格元素)来使用网格布局。

使用:对父元素设置dispay:grid;grid-template-colums和grid-template-rows来设置几行几列,然后对子元素设置占据几行几列

特点:二维网格结构,十分便于操作

这两者的核心是:一个盒子里有很多小盒子,如何排列?

flex就是沿着一条线铺下去,这个线可能水平,也可能垂直,这个平铺的方向用flex-direction来控制。

所以flex才有换行命令。而且当同级小盒子很多的时候,往往动一发而动全身,很不方便。

grid是把盒子用线分成很多份,把小盒子一个个填进去。

所以我们在使用grid布局的时候考虑的往往是如何 排列我们的盒子呢,或者说,这个拼图游戏怎么拼才好呢?

Grid的常用属性集合
常用属性 介绍
display: grid; 表示为网格布局,和flex布局中的display:flex意义相同
grid-template-columns 创建网格的列数,除了百分比的形式之外,还支持各种单位的组合形式
grid-template-rows 属性值和grid-template-columns的属性值完全一样。
grid-gap 可以取一或两个值,表示行列之间的间隙。
grid-template-areas 通过引用 grid-area 属性指定的 网格区域(Grid Area) 名称来定义网格模板。
grid-auto-flow: dense|row(default)|column 告诉自动布局算法依次填充每行,根据需要添加新行/列
justify-items: start|end|center|stretch(default) 沿着 行轴线(row axis) 对齐 网格项(grid items) 内的内容
align-items:start|end|start|center|stretch 沿着 列轴线(row axis) 对齐 网格项(grid items) 内的内容
grid-auto-columns: 隐式网格的宽度
兼容性

作为前端,我们逃不掉的一个问题就是兼容性问题了,看似强大的grid布局为什么在日常中使用的却不多呢,那就是因为目前的grid布局还不够普及导致兼容性还较差,在低版本的浏览器是无法使用的,但是前段技术进步很快,更新很快,相信在移动端目前grid布局已经支持性很高了,在目前互联网飞速发展的时代,我认为,作为目前最强大的css布局方案,grid终究会是前端布局的一个主流方向,初次使用,感到新鲜神奇,也许目前的兼容性还没有flex好,但是慢慢的应该grid布局就会兼容更多了,大家可以先学习了,多做尝试,你是否也会觉得他很神奇呢?

结语

​ 作者 : 小九

​ 时间 : 2020/03/31

​ 如有错漏之处,请纠正,看官们点个赞吧。


欲望以提升热忱,毅力以磨平高山。