欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

grid布局笔记

程序员文章站 2024-01-20 19:33:16
最近挺忙的,准备考试,还有其他的事,没时间研究东西,快周末了,难得学点东西,grid是之前看到的,很好奇,讲的二维的布局,看起来很方便,应该很适合移动端布局,所以今天抽时间学一学,这个当是笔记了。参考的是阮老师的博客和HTML中文网的文章。 阮一峰:CSS Grid 网格布局教程 CSS Grid ......

最近挺忙的,准备考试,还有其他的事,没时间研究东西,快周末了,难得学点东西,grid是之前看到的,很好奇,讲的二维的布局,看起来很方便,应该很适合移动端布局,所以今天抽时间学一学,这个当是笔记了。参考的是阮老师的博客和html中文网的文章。

阮一峰:css grid 网格布局教程

css grid 布局示例大全

不系统的解释了,系统的看阮老师的博客,我再复述一遍没屁用,然后再看布局示例大全,然后就能懂个八九不离十了。但是我途中遇到一些问题,我这篇是总结一下我遇到的问题,顺便和flex做一下对比,方便以后回顾。

fr关键字:

grid-template-columns:150px 1fr 2fr

这个1fr 和 2fr和父容器宽度有关系,1fr 和2fr是会主动填补父容器宽度(类似flex里的basis属性),保证他们俩的宽度关系为1:2,但是他们和150px没有关系,150px始终为150px。

布局实例:

1.父容器中设置两个项目分别占七三比例
.wrapper {
  display: grid;
  grid-template-columns: 70% 30%;
}

这个是一维的,只有一行,所以flex也能够布局出来。(简写啥的看不懂的话可以去看我有一篇flex布局笔记)

.wrapper{
  display: flex;
}
.item1{
  flex:70%
}
.item2{
  flex:30%
}

好像grid方便一点哈,那就接着往下看哈。

2.传统十二网格布局

可以直接在容器上定义一个

display: grid;
grid-template-columns: repeat(12, 1fr);

就完事了。

flex布局虽然也是一维的,但是要分别定义容器还有项目

.warpper{
  display:flex
}
//前提12个项目的class都为item
.item{
  flex:1
}

各有千秋吧,但是flex强项就是一维的,grid强项在于二维布局。我接着看看二维的布局

控制边距

flex没有控制边距的特殊属性,都是自动的,如果想要就是加margin.但是grid加了gap属性,可以column-gap也可以row-gap

指定区域,合并多块

.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
  grid-template-areas: 'a b c'
                       'd e f'
                       'g h i';
}

上面这个是默认的情况,九个单元格各司其职。谁都不理谁。

但是可以可以将他们更换变成

grid-template-areas: 'a a a'
                     'b b b'
                     'c c c';

类似,如果将其中一块变成.的话,那.所属的区域傻东西都没有

表示没有用到该单元格,或者该单元格不属于任何区域

注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end

比如,区域名为header,则起始位置的水平网格线和垂直网格线叫做header-start,终止位置的水平网格线和垂直网格线叫做header-end

grid-auto-flow

跟flex的flow不一样,flow是wrap和nowrap还有wrap-reverse。而这个gird-auto-flow可以调整密度。

column denserow dense可以自动填补竖向和横向的空白

剩下没啥东西了,记得东西偏多,感觉和flex差不多,都是比较方便的布局方式,多了二维操作和指定特殊的块儿的功能。

项目中应用

在项目中的布局主要是应用到下面这样的类似的效果。

.warpper{
    display: grid;
    grid-gap: 5px;    
    grid-template-columns: repeat(12, 1fr);
    grid-template-rows: 50px 350px 50px;
    grid-template-areas:
        "h h h h h h h h h h h h"
        "m m c c c c c c c c c c"
        "f f f f f f f f f f f f";
}

然后再在项目中指定相应的iteam为h,m,c,f

.header {
    grid-area: h;
}
.menu {
    grid-area: m;
}
.content {
    grid-area: c;
}
.footer {
   grid-area: f;
}

圣杯布局:

<!doctype html>
<html>
<head>
    <title></title>
</head>
<body>
    <div class="grid">
        <header>header</header>
        <aside class="siderbar-left">lefr sidebar</aside>
        <article>article</article>
        <aside class="sidebar-right">right sidebar</aside>
        <footer>footer</footer>
    </div>
</body>
<style type="text/css">
    .grid{
        display:grid;
        grid-template-rows: repeat(3,100px);
        grid-template-columns: 150px auto 150px;
        grid-gap:1em;
    }
    header,
    aside,
    article,
    footer {
      background: #eaeaea;
      padding: 1em;
    }
    header,footer{
        grid-column: 1/4;
    }
</style>
</html>

关于span

sapn表示跨越,有些时候可以gird-column:1/span2这样会让人感到困惑,我到底是跨越到哪去了,span2就是加两个,相当于gird-column:1/3,其实占得部分就是1块儿和2块儿。

auto-fill的补充

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
}

我自己瞎看,于是乎走进了误区,因为总觉得这个gird-template-columns明明说设置列,但是为什么设计出来却是控制的行,我现在想明白了,就像上面这个例子,因为他要控制的是一个列的宽度,然后配合上auto-fill,我一列设置成100px,然后将这100px宽度的列自动填满整个行的宽度。直到写到这里我的困惑才被揭开,我服了。

关于fr的补充

fr是自动计算剩余地方的,比如说让

grid-template-columns:100px repeat(10,1fr)这个解释一下就是,第一个列的宽度为100px,然后这十个把剩下的父容器宽度(一般grid布局的父容器都是body元素,所以会根据浏览器的宽度进行变化,方便进行响应式布局,以下父容器如果没有特殊标注的话一般都指的body元素)平均分了。

这个fr有几种情况:

  • 1fr单独出现,会把父容器都占满
  • n个1fr出现,这几个1fr会平均分父容器
  • n个1fr,和一个2fr出现,会n+2的平均分,然后给1fr的一份,给2fr的两份。其他比例同理

自认为的难点

grid-template-columns: repeat(auto-fill, minmax(200px, 1fr) )

这个破玩意困扰我很久,repeat的意思是前面是个数,后面是宽度,表示一种快速方便的写法。auto-fill是用列给这一行自动添加满元素,minmax是控制这个列的宽度最小为200px,最大为1fr。fr是上面讲过的。

可是最大为1fr ,1fr不是占满整个父容器宽度吗?,既然占满也就没有auto-fill的事儿了,一行一个不就完事了吗?

我开始陷入了这个误区好久,后来写了写demo才发现我的误区在于盲目的认为1fr会占整个宽度,但却忽略了几个1fr同时存在会平分的关系。也就是说,在父容器变化宽度的同时,我们的列会自动添加进来,比如说由399px变到了400px(现实情况一般会比400px大,因为默认会有边距)那么我们就会出现第二个列加入到同一行。但是在400px到600px这之间,我们列的最小宽度是200px,所以不会有新的列加入。那么剩下的宽度就会空着吗?

答案显然是不是的,因为我们设置了列的宽度,宽度为minmax这个范围,200px到1fr,1fr这时候的作用便显示出来了,因为比如说现在父容器宽度为500px,现在两个列存在这一行,都是1fr,所以这两个会把500px平均分,变成250px。