前端入坑第九弹——Flex和Grid

                今天主要来介绍CSS中Flex和Grid的相关应用,这两个对于网页排版来说是非常好用的工具。

Flex——有弹性的盒子

Flex是一种一维空间的设置,可以设置子级元素在同一行或者同一列的样式。

使用时要用display:flex来设置一下。

Flex Box

  • 控制盒子的流向   

                对于盒子的流向,我们可以利用flex-direction来设置,常用的参数值如下:

                row 按行从左向右排列;row-reverse按行从右向左排列;

                column按列从上向下排列;column-reverse按列从下到上排列。

                如果设置为row是这样:

                那么设置为row-reverse就是如下所示:

                 同理,如果column是如下所示:

                那么column-reverse就是如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flex——有弹性的盒子</title>
    <style>
        .box {
            
            display: flex;
            /* 这里的参数值还可以写为row/row-reverse/column-reverse */
            flex-direction: column;
            
            justify-content:space-evenly; 
           
            align-items:flex-end;
            
        }
        .A {
            background-color: blue;width: 100px;height: 100px;
        }
        .B {
            background-color: green;width: 100px;height: 100px;
        }
        .C {
            background-color: pink;width: 100px;height: 100px;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
    </div>
</body>
</html>

  • 同一行中主轴方向的设置

        主轴就是水平方向的中线,围绕主轴可以对于对齐方式和空隙结构,利用justify-content进行设置。

       如果使用flex-start/flex-end/center,子级元素之间就没有空隙,并且分别为左对齐、右对齐和居中的效果,如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flex——有弹性的盒子</title>
    <style>
        .box {
            
            display: flex;
            /
            flex-direction: row;
            /* 这里还可以设置为flex-start/center */
            justify-content:flex-end; 
            
            align-items:flex-end;
            
        }
        .A {
            background-color: blue;width: 100px;height: 100px;
        }
        .B {
            background-color: green;width: 100px;height: 100px;
        }
        .C {
            background-color: pink;width: 100px;height: 100px;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
    </div>
</body>
</html>

                如果想要得到有空隙的效果,可以使用如下的值:space-between/space-around/space-evenly,它们的效果分别如下所示:

                 如上,space-between是指空隙仅仅存在于子级元素之间。

 

                space-around和space-evenly看起来没有太大的差别,这里找到了一张图片介绍了它们的不同之处。

                就是这样的区别,图源:(如有侵权,请联系删除)Day 14: space-around vs space-evenly | SamanthaMing.comhttps://www.samanthaming.com/flexbox30/14-space-around-vs-space-evenly/ 

  • 同一行中副轴方向的设置

                所谓副轴,就是中轴线,即垂直方向的中线。想要设置在纵向的位置,就可以使用align-items进行设置,常用的值有以下几个:flex-start/flex-end/center/stretch,它们的效果分别如下:

                flex-start:上边缘对齐

                flex-end:下边缘对齐

                center:中心对齐

                stretch:占据能够占据的所有空间

                flex-start/flex-end/center时的代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flex——有弹性的盒子</title>
    <style>
        .box {
            
            display: flex;
            
            flex-direction: row;
            
            justify-content:space-evenly; 
            /* 上/下/中间对齐,还可以写flex-start/flex-end */
            align-items:center;
            
        }
        .A {
            background-color: blue;width: 100px;height: 200px;
        }
        .B {
            background-color: green;width: 100px;height: 100px;
            
        }
        .C {
            background-color: pink;width: 100px;height: 300px;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
    </div>
</body>
</html>

                 当align-items的值设置为stretch时,我将box类的高度设置为600px,并取消了对于ABC类高度的设定,意在让大家看看stretch时能够占据所有可以占据的空间,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flex——有弹性的盒子</title>
    <style>
        .box {
            
            display: flex;
            
            flex-direction: row;
            
            justify-content:space-evenly; 
            
            align-items:stretch;
            height: 600px;
            
        }
        .A {
            background-color: blue;width: 100px;
        }
        .B {
            background-color: green;width: 100px;
            
        }
        .C {
            background-color: pink;width: 100px;
        }
    </style>
</head>
<body>
    <div class="box">
        
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
    </div>
</body>
</html>
  • 特殊元素的设置

                上述的设置都是对于所有子级元素的设置,如果想要将其中的某一些设置为其它值该怎么办呢?这里我们可以使用align-self进行设置。例如,我想达到如下的效果:

                就像这里,蓝色的盒子和粉色的盒子都是下边缘对齐,但是绿色盒子是上边缘对齐,这种效果我们应当如何设置?

                我们先将三个盒子的align-items设置为flex-end,再写一个绿色盒子专属的选择器,将align-self设置为flex-start,根据选择器的优先级, 绿色盒子会上边缘对齐,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flex——有弹性的盒子</title>
    <style>
        .box {
            
            display: flex;
            
            flex-direction: row;
            
            justify-content:space-evenly; 
           
            align-items:flex-end;
            height: 400px;
            
        }
        .A {
            background-color: blue;width: 100px;height: 200px;
        }
        .B {
            background-color: green;width: 100px;height: 100px;
            /* 特殊元素设置,根据选择器的优先级应当执行flex-start */
            align-self: flex-start;
        }
        .C {
            background-color: pink;width: 100px;height: 300px;
        }
    </style>
</head>
<body>
    <div class="box">
        
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
    </div>
</body>
</html>

Flexibility

        接下来介绍一些Flex的性质:

        flex-basis:弹性盒的原始长度

        flex-grow:反映存在空间时的伸展能力

        flex-shrink:反映空间不足时的收缩能力

        例如,我将三个盒子的初始长度设置为1000px,将收缩能力设置为2,1,1,即意味着第一个盒子收缩的长度时第二个和第三个盒子的2倍。

         通过点击F12进入调试工具,我们发现三个盒子的宽度依次为260px、630px、630px,也就是说分别收缩了740px、370px、370px。

        现在我再将盒子的宽度设置为100px,将伸展能力设置为2,1,1,即意味着第一个盒子的伸展量时第二个和第三个盒子的2倍。

         通过点击F12进入调试工具,我们发现三个盒子的宽度依次为710px、405px、405px,也就是说分别收缩了610px、305px、305px。

Grid——将网页划分为网格

        如果说Flex的适用范围仅仅是一维空间,那么Grid就是二维平面的网页布局工具。

        要使用grid,我们需要先进行display:grid设置。

栅格划分

        例如下面的效果:

        

        想要达到这种效果,可以利用如下对行和列分别进行划分:

        grid-template-rows/grid-template-columns

         设置的时候,需要几行/几列就在对应行/列属性后面写几个值。这里的值,既可以写具体的xxpx,又可以写xxfr(可以理解为xx份),还可以将二者混用。混用的时候,先给绝对长度的分配地方,剩下的就按照分数比例进行空间分配。上面的效果完整的代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid</title>
    <style>
        .grid-container {
            display: grid;
            /* 列的划分 */
            grid-template-rows: repeat(2,200px);
            /* 行的划分 */
            grid-template-columns: 200px 200px 200px; 
            
            
        }
        
        .A {
            
            background-color: blue;
        }
        .B {
            
            background-color: red;
        }
        .C {
            background-color: green;
        }
        .D {
            
            background-color: gold;
        }
        .E {
            background-color: salmon;
        }
        .F {
            
            background-color: black;
        }
    </style>
</head>
<body>
    <div class="grid-container">
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
        <div class="D"></div>
        <div class="E"></div>
        <div class="F"></div>
    </div>
</body>
</html>

         对了,相同的值可以用repeat来写,即repeat(个数,长度)。

        当然这个时候盒子也可以有自身的宽度和高度,就像下面这样:

        只需要写一个对于所有子级元素的选择器,在其中设置宽度和高度就可以了。

        那么这些子级元素是不是就只能在左上角呢,能不能改变它们的位置呢?我们可以通过和Flex中相同的属性来进行设置,即justify-items和align-items,设置参数值同Flex不再赘述,这里仅仅举例说明居中时的代码。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid</title>
    <style>
        .grid-container {
            display: grid;
            
            grid-template-rows: repeat(2,200px);
            
            grid-template-columns: 200px 200px 200px; 
            
            /* 在水平方向居中  */
            justify-items:center; 
            /* 在垂直方向居中 */
            align-items: center;  
            
            
        }
        .item {
            height: 100px;width: 100px;
            
        }  
        .A {
            
            background-color: blue;
        }
        .B {
            
            background-color: red;
        }
        .C {
            background-color: green;
        }
        .D {
            
            background-color: gold;
        }
        .E {
            background-color: salmon;
        }
        .F {
            
            background-color: black;
        }
    </style>
</head>
<body>
    <div class="grid-container">
        <div class="A item"></div>
        <div class="B item"></div>
        <div class="C item"></div>
        <div class="D item"></div>
        <div class="E item"></div>
        <div class="F item"></div>
    </div>
</body>
</html>

 间隔设置

        这样的间隔设置可以利用column-gaprow-gap分别进行实现,当然如果二者相等可以直接使用gap进行实现。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid</title>
    <style>
        .grid-container {
            display: grid;
            
            grid-template-rows: repeat(2,200px);
            
            grid-template-columns: 200px 200px 200px; 
            
            /* 间隔 */
            gap:24px     
            
        }
        
        .A {
            
            background-color: blue;
        }
        .B {
            
            background-color: red;
        }
        .C {
            background-color: green;
        }
        .D {
            
            background-color: gold;
        }
        .E {
            background-color: salmon;
        }
        .F {
            
            background-color: black;
        }
    </style>
</head>
<body>
    <div class="grid-container">
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
        <div class="D"></div>
        <div class="E"></div>
        <div class="F"></div>
    </div>
</body>
</html>

跨行/跨列选择栅格

        例如这里的蓝色盒子横跨了两列,我们如何进行设置呢?

        我们可以利用grid-column-start和grid-column-end进行设置,前者是开始的位置,后者是结束的位置。将这两个参数值合起来,也可以简写为grid-column,这样写就需要两个参数值,第一个是起始位置,第二个是结束位置。

        

         通过调试工具,我们能够看到,这里的起始位置或者结束位置是对于栅格边缘来说的。

        如图,我们要让蓝色盒子横跨两列,也就是说从第一条纵边开始,到第三条纵边结束,所以始末位置分别应该设置为1和3。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid</title>
    <style>
        .grid-container {
            display: grid;
            
            grid-template-rows: repeat(3,200px);
            
            grid-template-columns: 200px 200px 200px; 
            
            gap:24px     
            
        }
        
        .A {
            /* 跨列 */
            grid-column-start: 1;
            grid-column-end: 3; 
            
            background-color: blue;
        }
        .B {
            
            background-color: red;
        }
        .C {
            background-color: green;
        }
        .D {
            
            background-color: gold;
        }
        .E {
            background-color: salmon;
        }
        .F {
            
            background-color: black;
        }
    </style>
</head>
<body>
    <div class="grid-container">
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
        <div class="D"></div>
        <div class="E"></div>
        <div class="F"></div>
    </div>
</body>
</html>

        当然也有其它写法,比如横跨两列就可以用grid-column:1/span 2来解决,效果是一样的。

        如果想要横跨一整行,有没有什么好办法呢?细心的小伙伴发现了纵向的边缘从左向右是整数依次递增,从右向左是负数依次递减。所以,最简单的办法就是grid-column:1/-1

        

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid</title>
    <style>
        .grid-container {
            display: grid;
            
            grid-template-rows: repeat(3,200px);
            
            grid-template-columns: 200px 200px 200px; 
            
            gap:24px     
            
            
        }
        
        .A {
            
            grid-column: 1/-1; 
            
            background-color: blue;
        }
        .B {
            
            background-color: red;
        }
        .C {
            background-color: green;
        }
        .D {
            
            background-color: gold;
        }
        .E {
            background-color: salmon;
        }
        .F {
            
            background-color: black;
        }
    </style>
</head>
<body>
    <div class="grid-container">
        <div class="A"></div>
        <div class="B"></div>
        <div class="C"></div>
        <div class="D"></div>
        <div class="E"></div>
        <div class="F"></div>
    </div>
</body>
</html>

页面设计

        如果一个页面,上面需要设计为header,左边要设计为sidebar,中右部要设计为content,下边要设计为footer,有没有什么直观一点的好方法呢?使用grid-template-areasgrid-area结合的方法就可以解决。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid页面设计</title>
    <style>
        .item {
            display:grid;
            grid-template-rows: repeat(4,200px);
            grid-template-columns: 200px 200px 200px 200px; 
            grid-template-areas: 
                "header header header header"
                "sidebar content content content"
                "sidebar content content content"
                "footer footer footer footer";
        }
        .item1 {
            background-color: rgb(167,224,8);
            grid-area: header;
        }
        .item2 {
            background-color: rgb(197,35,109);
            grid-area: sidebar;
        }
        .item3 {
            background-color: rgb(0,0,227);
            grid-area: content;
        }
        .item4 {
            background-color: rgb(226,227,9);
            grid-area: footer;
        }
    </style>
</head>
<body>
    <div class="item">
        <div class="item1"></div>
        <div class="item1"></div>
        <div class="item1"></div>
        <div class="item1"></div>
        <div class="item2"></div>
        <div class="item3"></div>
        <div class="item3"></div>
        <div class="item3"></div>
        <div class="item2"></div>
        <div class="item3"></div>
        <div class="item3"></div>
        <div class="item3"></div>
        <div class="item4"></div>
        <div class="item4"></div>
        <div class="item4"></div>
        <div class="item4"></div>
        
    </div>
</body>
</html>

        在上面这段代码之中,grid-template-areas的属性值就非常直观的反映了页面的样式。

        今天的分享就到这里了,感谢大家收看,欢迎大家提出宝贵的意见和建议。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值