grid 布局:一般用于多行排版、单页排版、......(响应式布局)
速食上手:
<div class="container"> <div class="header">HEADER</div> <div class="menu">MENU</div> <div class="content">CONTENT</div> <div class="footer">FOOTER</div> </div>
.container { display: grid; grid-gap: 5px; // 网格项的间距 grid-template-columns: repeat(12, 1fr); // 将宽度分成 12 等份 (1fr = 1等份) grid-template-rows: 50px 350px 50px; // 分成 3 行,第一行 50px,第二行 350px,第三行 50px grid-template-areas: // 排列方式,可以用点(.)来占位,代表这个网格是空着的 "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"; } .header { grid-area: h; } .menu { grid-area: m; } .content { grid-area: c; } .footer { grid-area: f; }
grid 详细教学:https://www.html.cn/archives/8506
使用等分(fr)单位实现基本的响应式
等分单位值使你可以非常容易地改变列的宽度。
.container { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 50px 50px; }
1fr 的意思是 1份。 fr,份的意思,和 rem、px、等,都是某种单位的意思。
grid-template-columns: 1fr 1fr 1fr; //用等份实现响应式。这句代码的意思是:将网格的宽度分成 3 等份,每一列占 1fr (1等份)。
更加高级的响应式:
但是,上面的例子并没有给我们想要的响应式,因为这个网格总是包含 3 列。我们希望我们的网格根据容器的宽度来改变列的数量。要做到这一点,你必须学习三个新的概念。
1 . repeat()
我们将从 repeat()
函数开始。 这是指定列和行更强大的方法。 让我们把原来的网格改成使用 repeat()
:
.container { display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(2, 50px); }
repeat(3, 100px)
与 100px 100px 100px
相同。 第一个参数指定了你想要的列数或行数,第二个参数指定了它们的宽度,所以上面的代码将为我们创建和第一个一样的布局。
2. auto-fit (自适应)
然后是自适应。让我们跳过固定数量的列,而是用 auto-fit
取代 3 。
.container { display: grid; grid-gap: 5px; grid-template-columns: repeat(auto-fit, 100px); grid-template-rows: repeat(2, 100px); }
现在这个网格已经可以通过容器的宽度来改变列的数量。
它只是试图尽可能多地将 100px
宽的列排列在容器中。
但是,如果我们将所有列硬编码为 100px
,我们永远得不到我们想要的灵活性,因为它们很少会加起来正好等于容器的宽度。网格通常会在右侧留下空白区域。
3. minmax()
为了解决这个问题,我们需要的最后一方法是 minmax()
。我们只需用 minmax(100px, 1fr)
替换 100px
即可。这是最终的CSS。
好处:自适应,由屏幕由宽到窄,从多列布局,逐渐减少列数,以做到自适应的效果。
.container { display: grid; grid-gap: 5px; // 网格项之间添加的间隙 grid-template-columns: repeat(auto-fit, minmax(100px,1fr)); // 列, 每列最小宽度100px,最大宽度为1分,列数不固定按实际情况增减
grid-template-rows: repeat(2, 100px); // 行, 这里的意思是:两行,每行100px }
minmax()
函数定义大于或等于 min
且小于或等于 max
的大小范围。
所以现在列的宽度至少 100px
。但是,如果有更多的可用空间,网格将简单地分配给每个列,因为列的值变成了一个等分单位 1fr
,而不是 100px
。
4. 添加 grid-template-areas
这个属性被称为网格区域,也叫模板区域,能够让我们轻松地进行布局实验。
.container { 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"; }
grid-template-areas
属性背后的逻辑是你在代码中创建的网格可视化表示。正如你所看到的,它有 3 行 12 列,和我们在 grid-template-columns
和 grid-template-rows
中定义的正好呼应。
每行代表一行,用网格术语来说是 网格轨道(Grid Track) ,每个字符( h
,m
,c
,f
)代表一个网格单元格。注:其实是 网格区域(Grid Area) 名称,你可以使用任意名称。
四个字母中的每一个现在都形成一个矩形 grid-area
。
你可能已经猜到,我选择了字符 h
,m
,c
,f
,是因为他们是 header
, menu
, content
和 footer
的首字母。 当然,我可以把它们叫做任何想要的名称,但是使用他们所描述的东西的第一个字符更加容易让人理解。
5. 给网格项设定网格区域名称
现在我们需要将这些字符与网格中的网格项建立对应的连接。 要做到这一点,我们将在网格项使用 grid-area
属性:
<div class="container"> <div class="header">HEADER</div> <div class="menu">MENU</div> <div class="content">CONTENT</div> <div class="footer">FOOTER</div> </div>
.header { grid-area: h; } .menu { grid-area: m; } .content { grid-area: c; } .footer { grid-area: f; }
我们可以使用点 .
来创建空白的网格单元格。(占位用)
grid-template-areas: “. h h h h h h h h h h .” "c c c c c c c c c c m m” “. f f f f f f f f f f .”;
6. 添加响应式布局
将 Grid(网格) 布局与响应式布局结合起来,简直就是一个杀手锏。因为在 Grid(网格) 布局之前,仅使用 HTML 和 CSS 实现的响应式布局不可能的做到简单而又完美。此时就需要使用 @media
@media screen and (max-width: 640px) { .container { grid-template-areas: "m m m m m m h h h h h h" "c c c c c c c c c c c c" "f f f f f f f f f f f f"; } }
请记住,所有这些更改都是使用纯 CSS 完成的,不需要修改 HTML 。 无论 div
标签如何在 HTML 中是怎么样的顺序结构,我们都可以随意转换。(注:这点与 flexbox 类似,网格项(grid items)的源顺序无关紧要。你的 CSS 可以以任何顺序放置它们,这使得使用 媒体查询(media queries)重新排列网格变得非常容易。)
这被称为结构和表现分离, Grid(网格) 布局真正做到了这点,对于 CSS 来说是一个巨大的进步。
它允许 HTML 成为它想要的样子: 作为内容的标记。HTML 结构不再受限于样式表现,比如不要为了实现某种布局而多次嵌套,现在这些都可以让 CSS 来完成。