精通 CSS 第 7 章学习笔记(下)

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了精通 CSS 第 7 章学习笔记(下)相关的知识,希望对你有一定的参考价值。

精通 CSS 第 7 章学习笔记(下)

「精通 CSS 高级 Web 标准解决方案(第三版)」中 7.3,Grid Layout 的内容。除了书上的内容之外,我也另外找到了一个长期更新的,关于 Grid Layout 信息的网站,不过是英文的。

另外,我会尝试将 精通 CSS 第 7 章学习笔记(上) 中实现的部分用 Grid Layout 实现。

上一篇中最终完成的效果图如下:

result

基础定义

  • 网格容器 (Grid Container)

    display: grid; 作用的元素

  • 网格项 (Grid Item)

    网格容器的直接子元素,不包括隔代的子孙元素

  • 网格线 (Grid Line)

    标记网格的分割线,同时存在水平分割线与垂直分割线

  • 网格单元格 (Grid Cell)

    被网格单元格分割的子项

  • 网格轨道 (Grid Track)

    网格线之间垂直或是水平的路径

    简单地说就是行或是列,不过这里的明明叫做 网格行(Grid Row),或是 网格列(Grid Row)

  • 网格区域 (Grid Area)

    有相邻网络单元格组合起来的矩形空间

栗子的试验田

定义网格行列

先不涉及 精通 CSS 第 7 章学习笔记(上) 中的案例,只是简单的了解一下应该怎么使用网格布局,首先先尝试着实现一个两行四列的页面布局:

tryout1

代码实现:

<div class="grid-two-by-four"></div>
.grid-two-by-four {
  display: grid;
  grid-template-rows: 300px 300px;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  outline: 1px solid #000;
}

由此也可以看出,为什么说网格布局是一个二维的布局方法。

与传统的先拉一行布局,再往行布局里面填充的做法不同的一维一维填充法不同,网格布局直接就将 行 和 列实现了。

其中,fr 代表着 空间中的可用部分 (fraction of abailable space),与之前的讲过的 扩展系数(flex-grow) 有些相似,一个 fr 代表一个可用空间,所以这里的列是 4 等分的。

如果数据完全一致的情况下,也可以使用 repeat(quantity, width) 的方式。 grid-template-columns: 1fr 1fr 1fr 1fr;grid-template-columns: repeat(4, 1fr); 实现的效果是完全一样的。

每一行的高度则是定死了 300px。

随意的填充

<div class="grid-two-by-four"></div> 加一些混乱的内容,就形成了下面这样的情况:

tryout2

添加的内容为:

<div class="grid-two-by-four">
  <!-- 若干个div -->
  <div class="tryout-head">
    <h2>Header Here</h2>
  </div>
</div>
.grid-two-by-four div {
  outline: 1px solid #000;
}

由此可见,在网格系统中,如果不指定网各项占的行列数,那么默认就是一个直接子元素成为网格元素的网格项。当子元素超出定义的部分后,宽度依旧是由父元素定义,高度则是由内容撑开。

撑开网格项

除了默认值外,网格模式也支持分配网格单元格,如制作一个一行两列和两列一行的的网格项:

tryout3

修改和新增的代码为:

<div class="grid-two-by-four">
  <div class="tryout-head grid-item1">
    <h2>两行一列</h2>
  </div>
  <div class="tryout-head grid-item2">
    <h2>一行两列</h2>
  </div>
  <!-- 省略 div r若干 -->
</div>
.grid-item1 {
  grid-row: 1/3;
}
.grid-item2 {
  grid-column-start: 2;
  grid-column-end: 4;
}

网格项与网格轨道的对其

  • 可以使用和 flexbox 相似的 justifyalign 系列的属性。二者的实现我记得没错的话共用了一些特性和计算方式,所以二者的属性名是由重叠的。这也是为什么 grid layout 的扩展系数要用 fr,防止属性名撞车。

  • 使用 grid-column-gapgrid-row-rap 区设置一个固定的值。

可重叠性&自动定位

网格项是可重叠的,以下效果的实现是将代码修改过后的结果:

tryout4

.grid-item1 {
  grid-area: 1/1/3/1;
  background-color: rgba(0, 0, 255, 0.3);
}
.grid-item2 {
  grid-row-start: 1;
  grid-row-end: 2;
  grid-column-start: 1;
  grid-column-end: 3;
  background-color: rgba(0, 255, 0, 0.3);
}

这种情况下必须要强制执行 grid-rowgrid-column 的各项属性,不然的话网格布局会自动找下一个空余的位置,而不是抢占已经使用过的位置。

强大的网格模板

CSS 写得好,html 代码少,效果如下:

tryout5

代码如下:

<div class="grid-two-by-four">
  <div class="grid-8">第一个插入,想放到最后一个去</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div class="hd">
    header <br />
    是最后div中最后一个创建的元素 <br />
    而且会占据两行一列的空间 <br />
    而且会占据两行一列的空间 <br />
  </div>
</div>
.grid-two-by-four {
  display: grid;
  grid-template-rows: 50px 50px;
  /* grid-template-columns: 1fr 1fr 1fr 1fr; */
  grid-template-columns: repeat(4, 1fr);
  grid-template-areas:
    "hd 2 3 4"
    "hd 6 7 last";
  outline: 1px solid #000;
}
.grid-8 {
  grid-area: last;
}
.hd {
  grid-area: hd;
}

这里巧用了 grid-template-areas 网格模板区 这个属性去动态的调整了网格的区域,这样就不用每次一修改布局,先从所有地方的 grid-area 开始,然后痛苦的做计算题。

使用网格布局完成之前的案例

header 这里就不重写了,就以主内容为准开始重写吧。

布局

完成图:

result

实现其实真的是出乎意料的简单……

代码如下:

<div class="wrapper">
  <div class="content-area1">
    <div class="hd"><h2>Lorem ipsum</h2></div>
    <article class="story st1">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story">
      <!-- 中间内容省略,上文有 -->
    </article>
  </div>
  <div class="content-area2">
    <div class="hd"><h2>Dolor sit amet</h2></div>
    <article class="story st1">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story">
      <!-- 中间内容省略,上文有 -->
    </article>
    <article class="story st2">
      <!-- 中间内容省略,上文有 -->
    </article>
  </div>
</div>
/* content implemented in grid layout */
.content-area1,
.content-area2 {
  margin-right: -10px;
}

.content-area1 {
  display: grid;
  grid-template-columns: 20% repeat(4, 1fr);
  grid-template-areas:
    "hd1 st1 st1 . ."
    "hd1 . . . .";
}
.st1 {
  grid-area: st1;
}
.st2 {
  grid-area: st2;
}
.content-area2 {
  display: grid;
  grid-template-columns: 20% repeat(3, 1fr);
  grid-template-areas:
    "hd1 st1 . st2"
    "hd1 st1 . st2";
}
.hd {
  grid-area: hd1;
}
.story {
  padding: 5px;
  margin: 0 10px 20px;
  background-color: #eee;
}
.story img {
  width: 100%;
}

本来还以为需要换不同的名字,不过想着 CSS 中的自动定位是查找空的区域,而一旦 .content-area1 加载完毕了之后就不属于空的区域了,就决定莽一下用重名——发现自己的猜测是正确的。

突然发现布局从来没有这么轻松过 OTL ……

参考

  • A Complete Guide to Grid

    这个网站我在第一个项目学习时,找 Flexbox 的时候就有看到的。当时还以为是配合着 Bootstrap 理解的,还不知道 CSS 原生就已经这么强大了。

以上是关于精通 CSS 第 7 章学习笔记(下)的主要内容,如果未能解决你的问题,请参考以下文章

精通 CSS 第 8 章 响应式布局 学习案例

精通 CSS 第 10 章 变换过渡与动画 学习笔记

精通 CSS 第 8 章 响应式布局 学习笔记

精通 CSS 第 9 章 表单与数据表 学习笔记

HTML5 权威指南第 12 章 表单 学习笔记

《精通CSS:高级Web标准解决方案》学习笔记(下)