Grid 与 Flexbox
Flexbox 用于一维布局,即纵向或横向的布局,将若干元素排列成一行或是一列。
Grid 用于二维布局,即纵向加横向的布局。
Grid 基本属性
基本设置
CSS 需要先设置基本的3项:以网格显示 display: grid,以及网格有多少行,多少列,高和宽分别是多少:
display: grid;
grid-template-columns: the columns with width;
grid-template-rows: the rows with height;
如下的例子先在HTML中定义A
~F
6个div
,
<body>
<div class="grid-container">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
</div>
</body>
对应的css 设置如下:
body {
margin: 0;
height: 100vh;
}
.grid-container {
display: grid;
/* 定义网格有3列,每列的宽度 */
/* 长度单位可以使用px:
grid-template-columns: repeat(3, 100px);
相当于:
grid-template-columns: 100px, 100px, 100px;
grid-template-rows: rrrrrrrrrs;
grid-template-columns: cccccccccs;
二者可以合并简写为 grid-template: rrrrrrrrs/ccccccs;
*/
grid-template-columns: 1fr 2fr 1fr;
/* 定义网格有两行,每行的高度 */
grid-template-rows: 1fr 1fr;
height: 60vh;
width: 60vw;
/* 网格每一个item 在单个 cell 内部的对齐
可以有left, right, center 等属性。
默认stretch,即拉伸。
*/
justify-items: center;
align-items: center;
/* 将整个网格看作一个整体,在其容器元素内的对齐。
*/
justify-content: center;
align-content: center;
/* 定义网格之间的缝隙gap宽度: */
row-gap: 30px;
column-gap: 10px;
background: lightgreen;
}
.box {
width: 6rem;
height: 6rem;
background: lightseagreen;
font-size: xx-large;
}
使用Firefox 查看:
网格的对齐
justify-content
和 align-content
,是整个网格在容器 grid-container
内部的对齐,如果设 grid 每一栏每一列高度宽度设为固定的px,容器内部有剩余空间,就容易看出来是怎么对齐的。实际不设这两项没看出有什么影响。
justify-items
和 align-items
在网格内部对齐每一个item, 默认属性是 stretch
,所以如果不设这两项,并且取消下面的设定:
.box {
width: 6rem;
height: 6rem;
}
可以看出每一项自动填充网格:
设定位置
每一项 item 在网格中的位置可以任意改变。如果要将上图的 A 和 E 交换位置,那么在CSS 中增加下面的行,其中的数字对应上图中的线条的数字,使用这些纵向和横向的线的数字就可以设置 item 所在的具体位置:
/* 将 A 放到 E 所在的位置 */
.box.a {
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 3;
}
/* 将 E 放到 A 所在的位置 */
.box.e {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
其中类似下面的代码:
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 3;
可以简写为:
grid-column: 2/3; /* start/end */
grid-row: 2/3;
可以进一步简化为:
/* row start / column start / row end / column end */
grid-area:2/2/3/3;
横向的线和纵向的线形成坐标轴,4 个数字可以看作位置左上角的坐标加右下角的坐标。数字可以反过来数,-1 是倒数第一条线,也就是最后一条线,依此类推。
A和E交换位置后的图形:
除了使用数字,更简单的做法是定义各个网格的名称。
Grid 网页布局例 1
下面是一个基本的网页布局,由 header,sidebar,main, footer 4 个部分组成:
<body>
<div class="grid-container">
<header>Navigation bar</header>
<sidebar>Content List</sidebar>
<main>Main Content</main>
<footer>About Us</footer>
</div>
</body>
对应的CSS:
body {
margin: 0;
height: 100vh;
background: lightsteelblue;
}
.grid-container {
display: grid;
/* 根据实际情况,此网格分为3行两列,即 3 X 2 网格 */
grid-template-columns: 1fr 5fr;
grid-template-rows: 1fr 6fr 1fr;
/* 每一行每一列的cell都定义一个名称,名称任意指定 */
grid-template-areas:
"header header"
"sidebar main"
"sidebar footer";
height: 100vh;
margin: 0 100px;
}
/* 根据需要,将 item 放在不同的位置 */
/* grid-area 后的属性不能加引号 */
header {
grid-area: header;
background: lightseagreen;
}
sidebar {
grid-area: sidebar;
background: mediumaquamarine;
}
main {
grid-area: main;
background:light;
}
footer {
grid-area: footer;
background: grey;
}
使用 firefox 查看各个cell的名称以及最终布局。
Grid 网页布局例 2
(参考了某些网站)
HTML:
<!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>Document</title>
<link rel="stylesheet" href="css/Normalize.css" />
<link rel="stylesheet" href="css/grid2.css" />
</head>
<body>
<div class="grid-container">
<main>
<h3>We have the best candy in the world</h3>
<h1>Awesome Candy</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ipsum
accusamus non, natus quod veritatis pariatur voluptatum quasi sunt
eaque vitae ducimus? Deleniti nobis rem qui dignissimos alias
consequatur veritatis labore expedita commodi officiis itaque unde hic
autem quia voluptatem incidunt voluptas, accusamus quod ipsum minus
magni. Ea ad aliquam est facere quos amet eaque autem dolor natus,
vitae, veniam sapiente ipsam reiciendis minima nostrum molestias
possimus distinctio incidunt blanditiis! A aut modi molestiae sit,
officia debitis cupiditate ullam totam excepturi molestias harum
labore, repudiandae architecto commodi assumenda omnis natus veniam.
Repellat fugiat commodi eos magnam. Animi modi totam nobis at.
</p>
</main>
<section class="candy1"></section>
<section class="candy2"></section>
<section class="footer">
<p>Contact us</p>
</section>
<header>
<a>Home</a>
<a>About</a>
<a>Our Candies</a>
</header>
<div class="candy"></div>
</div>
</body>
</html>
CSS:
body {
height: 100vh;
}
.grid-container {
display: grid; /* do nothing */
/* 4 X 3 */
grid-template-columns: 1fr 1.5fr 1fr;
grid-template-rows: 1fr 6fr 4fr 1fr;
height: 100vh;
margin: 0 10vw;
grid-template-areas:
"main main header"
"main main candy"
"candy1 candy2 candy"
"footer footer candy";
}
main {
grid-area: main;
background: #fffadf;
}
.candy1 {
grid-area: candy1;
background: url("../candy1.webp") no-repeat;
background-size: cover;
}
.candy2 {
grid-area: candy2;
background: url("../candy2.jpg") no-repeat;
background-size: cover;
}
.footer {
grid-area: footer;
background: lightseagreen;
}
header {
grid-area: header;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
}
.candy {
grid-area: candy;
background: url("../candy.jpg") no-repeat;
background-size: cover;
}
a {
margin: auto;
}
h1,
h3,
p {
margin: 20px;
}
布局如下: