zoukankan      html  css  js  c++  java
  • CSS躬行记(9)——网格布局

      网格布局(Grid Layout)也叫栅格布局,与表格布局类似,也依赖行和列。但与之不同的是,网格布局能直接控制HTML文档中元素的顺序、位置和大小等,而不用再借助辅助元素。

    一、术语

      下图展示了CSS规范中定义的网格。

      (1)网格容器(grid container)由display属性的两个特殊值(grid和inline-grid)所创建,由于它不是块级容器,因此其布局不受浮动和外边距塌陷的影响。

      (2)网格项(grid item)也叫网格元素,是网格容器的子元素,注意,它的后代元素不是网格项,但它自身也能变为网格容器。

      (3)网格线(grid line)为网格容器划分不同的区域,注意,网格线的数量没有限制。

      (4)网格单元(grid cell)是由四条网格线限定的区域,其内部不会有其它的网格线。

      (5)网格区域(grid area)由一个或多个相邻的网格单元组成的矩形区域,最大的网格区域会包含所有的网格单元。

      (6)网格轨道(grid track)是由两条网格线夹住的区域,从容器的一边延伸到另一边,水平方向的叫网格行(grid row),垂直方向的叫网格列(grid column),它们的尺寸由网格线的位置决定。

    二、行和列

      grid-template-rows和grid-template-columns两个属性可以定义网格线的名称和网格轨道的尺寸,前者可声明行的数量,后者可声明列的数量。

      在下面的示例中,将网格容器分成两行三列,其中第一条网格线距离容器左边界200px的位置,第二条网格线距离第一条网格线的偏移是容器宽度的一半,第三条网格线距离第二条30px的位置。

    <style>
      div {
        display: grid;
        width: 200px;
        height: 100px;
        grid-template-rows: 50px 50px;
        grid-template-columns: 50px 50% 30px;
      }
    </style>
    <div>
      <section>1</section>
      <section>2</section>
      <section>3</section>
      <section>4</section>
      <section>5</section>
      <section>6</section>
    </div>

      下图的左侧是上述代码的效果,右侧中的虚线是生成的网格线,后文会反复使用这种格式的标注图。注意,网格线可以不与容器的边界接触,两个属性中的百分数参照的是网格容器的宽度或高度。

      如果要占满网格容器的横向空间,那么可以使用minmax()函数,如下所示。minmax(30px, 100%)表示该列所占的空间在30px和容器宽度之间,即不能小于30px并且不能大于容器宽度,效果如下图所示。

    div {
      grid-template-columns: 50px 50% minmax(30px, 100%);
    }

      如果要为网格线命名,那么可以将名称放在值的恰当位置(例如名称在值之前,样式如下),并用方括号包裹。

    div {
      grid-template-columns: [col-a] 50px [col-b] 50% [col-c] minmax(30px, 100%);
    }

    1)fr

      在网格布局中,包含一个全新的fr单位,能将空间分成一定份数,弹性的分配给行或列,这个单位的作用类似于弹性盒中的flex-grow属性。在下面的示例中,将容器均分为3列,效果如下图所示。

    div {
      grid-template-columns: 1fr 1fr 1fr;
    }

      注意,fr可与其它长度单位混合使用,其作用的是可用空间,即剩余空间。在下面的示例中,将第一列宽度固定,剩余的空间由两列均分,效果如下图所示。

    div {
      grid-template-columns: 30px 1fr 1fr;
    }

    2)min-content和max-content

      当网格轨道的尺寸与其内容有关时,可使用这两个关键字。min-content会占据内容所需的最小空间,例如将min-content应用于网格容器的第二列,样式如下,效果如下图所示,网格项中有大量的断行。

    <style>
      div {
        grid-template-columns: 30px min-content 1fr;
      }
    </style>
    <div>
      <section>1</section>
      <section>2 2 2</section>
      <section>3</section>
      <section>4</section>
      <section>5</section>
      <section>6</section>
    </div>

      max-content的作用正好与min-content相反,它会占据内容所需的最大空间。将max-content也应用到上面的第二列,样式如下,效果如下图所示,网格项为了防止文本换行,会不断地扩大其宽度。

    div {
      grid-template-columns: 30px max-content 1fr;
    }

    3)fit-content()

      该函数的参数是一个长度值或百分数,能将占用空间指定成特定的值,它相当于下面等号右边的公式。

    fit-content(argument) = min(max-content, max(min-content, argument))

      先将接收的参数与min-content比较,得出较大值,再将该值与max-content比较,得到较小值。理解起来比较拗口,如果换成minmax()函数,含义就比较清晰了,与fit-content(argument)等价的公式如下。

    minmax(min-content, max-content)

    4)repeat()

      该函数能为网格轨道声明重复的行或列,它的第一个参数是重复次数,第二个参数是轨道尺寸,例如将网格容器均分成三列,样式如下。

    div {
      grid-template-columns: repeat(3, 1fr);
      /* 等价于 */
      grid-template-columns: repeat(1fr, 1fr, 1fr);
    }

      注意,轨道尺寸不局限于一个,可以指定多个,样式如下,效果如下图所示。

    div {
      grid-template-columns: repeat(2, 20px 1fr);
    }

    三、网格项

      通过起始和终止处的网格线的名称或编号可指定网格项的位置,其中列的编号从左到右依次递增,行的编号从上到下依次递增,如下图所示。

      在下面的示例中,将网格容器均分成三行四列,并且把第一个section元素指定到第二行第二列的位置,效果如下图所示。

    <style>
      div {
        grid-template-rows: repeat(3, 1fr);
        grid-template-columns: repeat(4, 1fr);
      }
      .one {
        grid-row-start: 2;
        grid-row-end: 3;
        grid-column-start: 2;
        grid-column-end: 3;
      }
    </style>
    <div>
      <section class="one">1</section>
      <section>2</section>
      <section>3</section>
      <section>4</section>
      <section>5</section>
      <section>6</section>
      <section>7</section>
      <section>8</section>
      <section>9</section>
      <section>10</section>
    </div>

       将下面的样式添加给第一个section元素,可以得到跨列的效果,如下图所示。

    .two {
      grid-row-start: 2;
      grid-row-end: 3;
      grid-column-start: 2;
      grid-column-end: 4;
    }

      网格线的编号支持负数,也就是以相反的方式计数,从后往前或从下往上,例如将第一个section元素放置在容器的右下角,样式如下,效果如下图所示。

    .three {
      grid-row-start: -2;
      grid-row-end: -1;
      grid-column-start: -2;
      grid-column-end: -1;
    }

    1)span

      还有另一种方式可用来指定网格项的位置,即用span和正整数组合,表示要跨的网格轨道数目。在下面的样式中,“span 2”用于跨过两列。

    .four {
      grid-row-start: 2;
      grid-row-end: 3;
      grid-column-start: 2;
      grid-column-end: span 2;
    }

      当把span应用于grid-row-start或grid-column-start属性时,将会沿着网格开始的方向计数,样式如下,效果如下图所示。

    .five {
      grid-row-start: 2;
      grid-row-end: 3;
      grid-column-start: span 2;
      grid-column-end: 3;
    }

      注意,span后面可以省略数字,默认是1,但不能跟零或负数。

    2)简写属性

      grid-row是grid-row-start和grid-row-end的简写属性,grid-column是grid-column-start和grid-column-end的简写属性。

      grid-row和grid-column可分别将行和列的起止网格线声明在一行,并用斜杠(/)分隔,如下所示。

    .six {
      grid-row: 2 / 3;
      grid-column: 2 / span 2;
    }

      注意,由于默认跨度是1,因此可以省略grid-row和grid-column斜杠后的数字,如下所示。

    .seven {
      grid-row: 2;
      grid-column: 2;
    }

      grid-area是grid-row-start、grid-row-end、grid-column-start和grid-column-end的简写属性,也可用斜杠(/)将值分隔,如下所示。

    .eight {
      grid-area: 2 / 2 / 3 / span 2;
    }

      注意,网格线值的顺序是:起始行、起始列、终止行、终止列,围绕网格项逆时针排列。

    3)重叠

      当两个网格项发生重叠时,可通过z-index属性来决定谁在上,谁在下。例如为两个section元素分别添加下面的样式,效果如下图所示,第二个section元素覆盖了第一个section元素。

    <style>
      .overlap1 {
        grid-row: 1;
        grid-column: 1 / span 2;
      }
      .overlap2 {
        grid-row: 1;
        grid-column: 2 / span 2;
      }
    </style>
    <div>
      <section class="overlap1">1</section>
      <section class="overlap2">2</section>
      <section>3</section>
      <section>4</section>
      <section>5</section>
      <section>6</section>
      <section>7</section>
      <section>8</section>
      <section>9</section>
      <section>10</section>
    </div>

      当为第一个section元素添加z-index属性后(样式如下),就会覆盖第二个section元素,效果如下图所示。

    .overlap1 {
      z-index: 1;
    }

    4)自动增加网格线

      当网格项超出容器边界时,可通过grid-auto-rows和grid-auto-columns分别控制行和列的尺寸。

      在下面的示例中,将网格容器分成两行三列,它的第七个超出边界的网格项的高度默认是内容的高度,即“height:auto”,效果如下图所示。

    <style>
      div {
        grid-template-rows: 50px 50px;
        grid-template-columns: repeat(3, 1fr);
      }
    </style>
    <div>
      <section>1</section>
      <section>2</section>
      <section>3</section>
      <section>4</section>
      <section>5</section>
      <section>6</section>
      <section>7</section>
    </div>

      当为网格容器添加grid-auto-rows属性后,就能改变网格项的高度,如下所示,效果如下图所示。

    div {
      grid-auto-rows: 50px;
    }

      grid-auto-columns的用法与之类似,但修改的是超出边界的网格项的宽度。在下图中,左侧是默认超出时的宽度,即内容的宽度(auto);右侧是为容器添加下面样式后的宽度。

    div {
      grid-auto-flow: column;
      grid-auto-columns: 50px;
    }

      注意,grid-auto-flow是一个网格流属性,可让网格项按列排序,后文第五节会重点讲解。

    四、网格区域

       通过grid-template-areas属性能够以可视化的方式声明网格布局,其值是用空格或换行符分隔的字符串列表,每段字符串又是以空格分隔的自定义标识符,如下所示。

    div {
      grid-template-areas: "a b b" 
                  "a . c";
    }

      每个标识符表示一个网格单元,注意,组合在一起的形状必须得是矩形。当只需要占位时,可以使用点号(.)创建匿名单元。

      为了将网格项与网格区域关联,需要使用grid-area属性。通过它来引用命名好的网格区域,如下所示,grid-area的属性值就是grid-template-areas属性中的标识符,效果如下图所示。

    <style>
      .a {
        grid-area: a;
      }
      .b {
        grid-area: b;
      }
      .c {
        grid-area: c;
      }
    </style>
    <div>
      <section class="a">a</section>
      <section class="b">b</section>
      <section class="c">c</section>
    </div>

    五、网格流

      网格流可由grid-auto-flow属性控制,它分为两种填充方式:逐行和逐列,并且两者都可通过稠密模式更高效地占用网格单元。

      在下面的示例中,第一个div元素中的网格项会先填满一行再换到下一行,效果如图5-57的左侧;第二个div元素中的网格项会先填满一列再换到下一列,效果如下图的右侧。

    <style>
      .row {
        grid-auto-flow: row;
      }
      .column {
        grid-auto-flow: column;
      }
    </style>
    <div class="row">
      <section>1</section>
      <section>2</section>
      <section>3</section>
      <section>4</section>
      <section>5</section>
      <section>6</section>
    </div>
    <div class="column">
      <section>1</section>
      <section>2</section>
      <section>3</section>
      <section>4</section>
      <section>5</section>
      <section>6</section>
    </div>

      grid-auto-flow属性默认是稀疏模式,而稠密模式会尽力找出最前面的空位置。假设网格容器包含三个网格项,其中有两个会占用两个网格单元,样式如下,效果如下图所示,第一个网格项之后的网格单元闲置着。

    <style>
      .across {
        grid-column: auto / span 2;
      }
    </style>
    <div class="row">
      <section class="across">1</section>
      <section class="across">2</section>
      <section>3</section>
    </div>

      当为网格容器的grid-auto-flow属性添加dense后,就能触发稠密模式,得到的效果如下图所示,第三个网格项会移动到第一个之后。

    .row {
      grid-auto-flow: row dense;
    }

    六、间距

      间距(gutter)也叫空距或栏距,用于控制两个网格轨道之间的距离,类似于将网格线加粗,使其具有宽度。

      间距可由grid-row-gap和grid-column-gap两个属性设定,但要注意,现在这两个属性已改名成row-gap和column-gap,它们相当于表格样式中的border-spacing属性。在下面的示例中,为网格容器添加了两个方向的间距,效果如下图所示。

    div {
      row-gap: 10px;
      column-gap: 20px;
    }

      grid-gap是一个简写属性,可将行和列的间距组合在一起定义,下面样式的效果与上图一样。注意,该属性现已改名成gap。

    div {
      gap: 10px 20px;
    }

      顺便说一句,CSS规范提供了一个简写属性:grid,可将上述grid-template-rows、grid-auto-rows、row-gap等属性组合在一起声明。

    七、对齐方式

       网格布局中的对齐属性与弹性盒中的类似,也是使用下表中的相关属性。

    属性 作用
    justify-self 控制一个网格项的水平对齐
    align-self 控制一个网格项的垂直对齐
    justify-items 控制网格容器中的所有网格项的水平对齐
    align-items 控制网格容器中的所有网格项的垂直对齐
    justify-content 控制网格轨道的水平对齐
    align-content 控制网格轨道的垂直对齐

    1)对齐网格项

      justify-self和align-self两个属性适用于单个网格项,它们的默认值都是stretch,其它可选的关键字包括start、end和center等。

      假设有一个两行三列的网格容器,为它的四个网格项分别添加四个不同关键字的justify-self属性,效果如下图所示。

    <style>
      div {
        display: grid;
        grid-template-rows: repeat(2, 1fr);
        grid-template-columns: repeat(3, 1fr);
      }
      .justify-self-start {
        justify-self: start;
      }
      .justify-self-end {
        justify-self: end;
      }
      .justify-self-center {
        justify-self: center;
      }
      .justify-self-stretch {
        justify-self: stretch;
      }
    </style>
    <div>
      <section class="justify-self-start">start</section>
      <section class="justify-self-center">center</section>
      <section class="justify-self-end">end</section>
      <section class="justify-self-stretch">stretch</section>
    </div>

      将这四个关键字赋给align-self属性,再应用到另一个两行三列的网格容器中,得到的效果如下图所示。

      justify-items和align-items两个属性适用于网格容器,它们的默认值也是stretch,可选的关键字与之前的两个属性类似,下面的样式在为之前的div元素(网格容器)添加justify-items属性。

    div {
      justify-items: start;
    }

    2)对齐网格轨道

      justify-content和align-content两个属性适用于网格容器,可用的关键字包括start、end、center、space-between和space-around等。

      下图展示了这五个关键字赋给justify-content属性后,再分别应用于网格容器的效果。

      下图展示了这五个关键字赋给align-content属性后,再分别应用于网格容器的效果。

    八、排序

      在网格布局中,也可以像弹性盒那样使用order属性调整网格项的顺序。注意,order属性作用于网格项,其值是一个整数,包括零和负数。在下面的示例中,将第一个和第三个section元素调换了次序,效果如下图所示。

    <style>
      .first {
        order: 1;
      }
      .second {
        order: 2;
      }
      .third {
        order: 3;
      }
    </style>
    <div>
      <section class="third">1</section>
      <section class="second">2</section>
      <section class="first">3</section>
    </div>

  • 相关阅读:
    js中的原生Ajax和JQuery中的Ajax
    this的用法
    static的特性
    时政20180807
    java compiler没有1.8怎么办
    Description Resource Path Location Type Java compiler level does not match the version of the installed Java project facet Unknown Faceted Project Problem (Java Version Mismatch)
    分词器
    [数算]有一个工程甲、乙、丙单独做,分别要48天、72天、96天完成
    一点感想
    解析Excel文件 Apache POI框架使用
  • 原文地址:https://www.cnblogs.com/strick/p/12607383.html
Copyright © 2011-2022 走看看