css中的网格布局之容器篇

242 阅读7分钟

什么是网络布局

在css中,网络布局指的是允许我们在行和列两个维度去指定元素的大小,对齐方式等的布局方式,它可以将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系。

如何创建网格布局

指定元素的display为grid或inline-grid就可以设置网格布局,如

  <style>
    .grid-container {
      display: grid;
    }
    .grid-item{
      border: 1px solid #000;
    }
  </style>
</head>
<body>
  <div class="grid-container">
    <div class="grid-item">1</div>
    <div class="grid-item">2</div>
    <div class="grid-item">3</div>
    <div class="grid-item">4</div>
    <div class="grid-item">5</div>
    <div class="grid-item">6</div>
    <div class="grid-item">7</div>
    <div class="grid-item">8</div>
    <div class="grid-item">9</div>
    <div class="grid-item">10</div>
  </div>
</body>

其中gird-container类所在的div称为网格布局的容器,其直接子元素为称为网格布局的项目

网格布局默认的定位规则

所有子项目都会把自己摆放到网格中,每个单元格中放一个。默认的流向是按行排列项目,网格会首先尝试在第 1 行的每个单元格中摆放项目。如果已经通过 grid-template-rows 属性创建了其他行,网格就会继续把项目摆放到这些行中。如果在显式的网格中没有足够的行用来摆放所有的项目,隐式的新行就会被创建出来。

image.png

网格布局 容器 所支持的属性

grid-auto-flow

网格布局默认是按行排列项目,通过grid-auto-flow可改变网格布局的排列方式

取值

row

默认值,该关键字指定自动布局算法按照通过逐行填充来排列元素,在必要时增加新行

column

该关键字指定自动布局算法通过逐列填充来排列元素,在必要时增加新列。

dense

该关键字指定自动布局算法使用一种“稠密”堆积算法,如果后面出现了稍小的元素,则会试图去填充网格中前面留下的空白。这样做会填上稍大元素留下的空白,但同时也可能导致原来出现的次序被打乱。如

.grid-container {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  grid-auto-rows: 100px;
  gap: 5px;
}
.grid-container div{
  background-color: #173950;
}

我们建了一个等宽的4列网格布局,行与行之间的轨道大小为100px。考虑以下html

 <div class="grid-container">
    <div>One</div>
    <div>Two</div>
    <div>Three</div>
    <div>Four</div>
    <div>Five</div>
    <div>Six</div>
    <div>Seven</div>
    <div>Eight</div>
 </div>

默认的排列如图

1681455051108.png

现在,改变第1和第5个项目占据的轨道大小,使他们占据两行两列的位置,可以发现此时项目4后面会出现空白区域

1681455337171.png

添加完grid-auto-flow: dense之后布局

image.png

改变网格布局排列方式同时指定“稠密”算法

grid-auto-flow:column dense

grid-template-columns

该属性可以设置网格布局中任意两条竖线之间的间距,如

.grid-container{
    display: grid;
    grid-template-columns:50% 30%;
 }

其中grid-template-columns:50% 30%;表示该网页布局第一条竖线和第二条竖线之间的间距为容器宽度的50%,第二条竖线和第三条竖线之间的距离为容器宽度的30%,线与线之间的距离称为轨道(a grid track)。上面代码创建了一个2列的网格布局。

grid-auto-rows

上面例子中,我们只指定了grid-template-columns,网格布局会根据我们的内容自动创建行,假如我们想指定自动创建的行高时,即创建隐式的行高,可以使用grid-auto-rows,如

.grid-container{
    display: grid;
    grid-template-columns:50% 30%;
    grid-auto-rows: 50px
}

上面代码指定了网格布局中行与行之间的大小为50px。

gird-auto-columns

该属性与grid-auto-rows用法相似,用设置隐式创建的列的宽度。如

.grid-container{
 display: grid;
 grid-template-rows: repeat(3,100px);
 grid-auto-flow: column;
 grid-auto-columns: 50px
}

上面代码设置了一个三行的网络布局,且默认的列宽为50px。

grid-template-rows

该属性用法与grid-template-columns类似,但设置的是网络布局中任意两条横线之间的距离。

column-gap,row-gap

网格布局中默认没有间距,可以通过column-gap设置网格的列间距,row-gap设置网格的行间距。 如

.grid-container{
    display: grid;
    grid-template-columns:50% 30%;
    grid-auto-rows: 50px;
    row-gap: 5px;
    column-gap: 10px;
}

gap

gap:行间距 列间距 来指定,如

.grid-container{
    display: grid;
    grid-template-columns:50% 30%;
    grid-auto-rows: 50px;
    gap:5px 10px;
}

设置了该网格布局的行间距为5px,列间距为10px。

grid-template-area

使用该属性可以直接为网格布局划分区域,而不用在各个项目中单独指定属性(grid-row,grid-column,grid-area等)

取值

  1. none 表示该网格容器没有定义任何网格区域
  2. 代表网格区域的字符串,如
.grid-container{
    display: grid;
    grid-template-areas: "header header"
                        "nav main"
                        "nav footer";
}                       

表示将网格容器划分为三行两列,并将其分为四个网格区域,分别为header,nav,main,footer。 当我们将网格容器划分好区域后,我们可以指定每个区域的大小,假如我们想

  1. header高度为50px,footer高度为30px,nav和main区域为容器的剩余高度
  2. nav的宽度为150px 可以按如下代码指定
.grid-container{
    height: 100%;
    display: grid;
    grid-template-areas: "header header"
                        "nav main"
                        "nav footer";
   grid-template-rows: 50px 1fr 30px;
   grid-template-columns: 150px 1fr;
}  

划分好区域和区域对应的大小之后,指定项目具体属于哪个区域即可,如下html结构

<div class="grid-container">
    <header>header content</header>
    <nav>nav content</nav>
    <main>main content</main>
    <footer>footer content</footer>
</div>

通过css指定所属区域

header {
 grid-area: header;
 background-color: #8ca0ff;
}
nav {
 grid-area: nav;
 background-color: #ffa08c;
}
main {
 grid-area: main;
 background-color: #ffff64;
}
footer {
 grid-area: footer;
 background-color: #8cffa0;
}

结果图

image.png

指定grid-template-areas的空白区域

上述例子中整个容器的都划分了区域,假如我们想要某部分内容不属于任何区域,可以使用.来实现,如下代码

.grid-container{
    height: 100%;
    display: grid;
    grid-template-areas: "header header"
                        "nav main"
                        ". footer";
   grid-template-rows: 50px 1fr 30px;
   grid-template-columns: 150px 1fr;
} 

direction属性

为容器添加direction属性可以改变网格线的方向,如添加direction:rtl,么 第 1 条线就变到了网格的右侧。而第 -1 条线则变到左侧。如

image.png

控制对齐

网格布局共有两条轴线用于控制对齐,分块轴和行轴,在默认的排列方式下,可将块轴理解为y轴的对齐方向,行轴理解为x轴的对齐方向

align-items

控制项目在块轴方向的对齐方式

常用取值

  • normal 默认值。对于那些网格项目而言,效果和stretch一样,除了有部分比例或者一个固定大小的盒子的效果像start
  • start 元素向侧轴起点对齐。
  • end 元素向侧轴终点对齐。
  • center 元素居中对齐
  • stretch 元素内容被拉升至整个项目

justify-items

设置项目在行轴上的对齐方式

place-items

该属性为align-items和justify-items的简写,如

.grid-container{
    display: grid;
    place-items: center center
 }

对齐整个网格布局进行对齐

当我们的整个网格轨道的大小比网格容器小,我们可以对整个网格轨道进行对齐,如

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  height: 500px;
  width: 500px;
  gap: 10px;
  grid-template-areas:
    "a a b"
    "a a b"
    "c d d";
}

我们容器的宽高为500px,但我们整个轨道的宽高只有300px。

align-content

控制整个网络轨道在块轴的对齐方式

justify-content

控制整个网络轨道在行轴的对齐方式

fr单位

在定义轨道间距时,比如grid-template-columns``grid-template-rows,可以使用fr单位,其表示将网格布局分隔成几等分。如我们可以使用以下代码实现随着浏览器大小自适应的4列图片布局

<div class="container">
    <div>
      <img src="../img/img1.png"/>
    </div>
    <div>
      <img src="../img/img2.png"/>
    </div>
    <div>
      <img src="../img/img3.png"/>
    </div>
    <div>
      <img src="../img/img4.png"/>
    </div>
  </div>
html,
body{
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

*{
  box-sizing: border-box;
}

.container{
  display: grid;
  width: 100%;
  grid-template-columns: repeat(4,1fr); //创建4列布局,每列占容器的4分之一
  div{
    img{
       width: 100%;
       height: 100%;
    }
  }
}