zoukankan      html  css  js  c++  java
  • CSS页面布局与网格(下)

    3.二维布局:CSS Grid Layout

    CSS Grid Layout模块为了能在二维空间里控制元素的顺序、位置和大小而定义了一组CSS属性。

    • 被设值为display: grid的元素叫网格容器(grid container)。
    • 容器进一步被网格线划分为不同的区域,叫网格单元(grid cell)。
    • 网格线之间的水平或垂直路径叫网格轨道(grid track)。
    • 由相邻网格单元组合起来的矩形区块叫网格区
    • 网格容器的直接子元素叫网格项,网格项可以放在网格区内。

    3.1 定义行和列

    定义一个2行4列的网格,行高300像素,4列等宽:

    .grid {
    	display: grid;
    	grid-template-rows: 300px 300px;
    	grid-template-columns: 1fr 1fr 1fr 1fr;
    }
    

    表示列宽的单位是fr,意思是可用空间中的部分(fraction of available space)。
    指定行和列的数量及大小时,可以混用不同的长度单位。
    生成页面子区块的网格:

    <section class="subcategory">
      <div class="grid-a">
    	<header class="subcategory-header">
    		<h2>Lorem ipsum</h2>
    	</header>
    	<article class="story story-featured">
    	  <!-- ... -->
    	</article>
    	<article class="story"></article>
    	<article class="story"></article>
    	<!-- ... -->
      </div>
    </section>
    
    .grid-a {
        display: grid;
        grid-template-rows: auto auto auto;
        grid-template-columns: repeat(5, 1fr); /* repeat()函数为网格轨道指定重复的行或列声明 */
    }
    

    使用minmax()函数:

    .grid-a {
        display: grid;
        /* 声明最后两行至少4em高,且占据相等的可用空间。 */
        grid-template-rows: auto minmax(4em, 1fr) minmax(4em, 1fr);
        grid-template-columns: repeat(5, 1fr);
    }
    

    3.2 添加网格项

    添加网格项要以其起止处的网格线作为参考。

    .subsection-header {
        grid-row-start:1;
        grid-column-start:1;
        grid-row-end:4;
        grid-column-end:2;
    }
    

    简写方法:

    .subsection-header {
        /* 起止网格线的编号以斜杠(/)分隔。 */
        grid-row:1/4;
        grid-column:1/2;
    }
    
    .subsection-header {
        grid-row:1/-1; /* -1表示最后一个网格轨道的终止网格线的编号 */
        grid-column:1; /* 等价于grid-column:1/2,即默认跨度为一个网格单元 */
    }
    

    可以使用grid-area属性进一步简化网格项的声明。
    对齐网格项:
    网格项与块级元素类似,会自动填充自己所在网格区的宽度,除非明确设置它的宽度。百分比值相对于网格项所在网格区的宽度来计算。
    如果网格项没有在水平方向填满网格区,可以通过justify-itemsjustify-self属性指定它的左、中、右分布。
    align-selfjustify-self用于个别网格项。align-itemsjustify-items则用于网格容器上设置所有网格项的默认对齐。

    .grid-a {
        display: grid;
        grid-template-rows: auto auto auto;
        grid-template-columns: repeat(5, 1fr);
        align-items: start;
    }
    

    对齐网格轨道:
    只要网格轨道的总和没有覆盖整个网格容器,就可以使用align-content(垂直方向)和justify-content(水平方向)来移动轨道。

    <div class="grid">
        <div></div>
        <!-- 省略7个空div -->
    </div>
    
    .grid {
        display: grid;
        height: 100px;
        outline: 2px dashed #666;
         500px;
        grid-template-rows: 100px; /* 行高100px */
        grid-template-columns: repeat(8, 50px); /* 列宽50px */
        justify-content: start; /* 默认值 */
    }
    .grid > * {
        outline: 1px solid #fff;
        background-color: #ccc;
    }
    

    定义了1行8列的网格,行高100像素,每列宽度为50像素。

    <div class="grid grid-end">
        <div></div>
        <!-- 省略7个空div -->
    </div>
    
    .grid-end {
        justify-content: end;
    }
    

    网格布局中的空距:
    通过grid-column-gapgrid-row-gap属性创建固定宽度的空距,这其实就相当于多栏布局中的column-gap或者表格中的border-spacing

    .grid {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        grid-column-gap: 1.5em;
        grid-row-gap: 1.5em;
    }
    

    3.3 自动网格定位

    Grid Layout规范提供了一种自动定位的机制:所有网格项自动从第一行第一个可用的网格单元开始,逐列填充。一行填满后,网格会自动开启一行并继续填充。

    <ul class="grid-auto-rows">
      <li class="story">
    	<h3><a href="#">Story 1</a></h3>
      </li>
      <!-- 省略8个li -->
    </ul>
    
    .grid-auto-rows {
        display: grid;
        grid-template-rows: auto;
        grid-template-columns: repeat(5, 1fr);
        grid-auto-flow: row; /* 默认值为稀疏模式 */
    }
    /* :nth-child(n)匹配其父元素的第n个子元素 */
    .story:nth-child(1),
    .story:nth-child(2) {
        grid-column: span 3; /* 跨三列 */
    }
    .story:nth-child(4) {
        grid-column: span 2; /* 跨两列 */
    }
    

    切换自动定位算法:

    .grid-auto-rows {
        /* 省略 */
        grid-auto-flow: row dense; /* 稠密模式 */
    }
    

    自动定位的次序:
    网格项的次序与源代码次序一致,每个网格项的默认次序是0。整数值,包括负值在内,都是有效的。

    <!-- 省略 -->
    <div class="grid-a">
      <header class="subcategory-header">
        <h2>Lorem ipsum</h2>
      </header>
      <article class="story story-featured">
        <img src="http://placehold.it/600x300" alt="Dummy image">
        <h3><a href="#">Cras suscipit nec leo id.</a></h3>
        <p>Autem repudiandae aliquid tempora quos reprehenderit architecto, sequi repellat.</p>
      </article>
      <article class="story">
        <img src="http://placehold.it/600x300" alt="Dummy image">
        <h3><a href="#">Perferendis, ipsam!</a></h3>
        <p>Neque magnam vero obcaecati facere nobis sint dolore accusamus vitae consequuntur ad necessitatibus, laborum molestiae.</p>
      </article>
      <article class="story">
        <img src="http://placehold.it/600x300" alt="Dummy image">
        <h3><a href="#">Curabitur mattis purus nec velit.</a></h3>
        <p>Neque magnam vero obcaecati facere nobis sint dolore accusamus vitae consequuntur ad necessitatibus, laborum molestiae.</p>
      </article>
    </div>
    <!-- 省略 -->
    
    .grid-a {
        display: grid;
    }
    /* :nth-of-type(n) 匹配同类型中的第n个同级兄弟元素。 */
    .story:nth-of-type(2),
    .story:nth-of-type(3) {
        order: -2;
    }
    .story-featured {
        order: -1;
    }
    

    3.4 网格模板区

    使用grid-template-areas属性来声明网格布局。
    grid-template-areas属性的值是以空格分隔的字符串列表。
    每个字符串本身是空格分隔的自定义标识符,表示网格中的一行,其中每个标识符表示一列。
    跨行或跨列相邻的同名网格单元构成所谓的命名网格区

    <section class="subcategory">
        <div class="grid-b">
            <header class="subcategory-header">
                <h2>Dolor sit amet</h2>
            </header>
            <article class="story">
                <img src="http://placehold.it/600x300" alt="Dummy image">
                <h3><a href="#">Ut sit amet mi massa</a></h3>
                <p>...</p>
            </article>
            <article class="story"></article>
            <div class="ad">
                <h3><a href="#">Buy more stuff!</a></h3>
            </div>
            <div class="ad"></div>
        </div>
    </section>
    
    .grid-b {
        display: grid;
        grid-template-columns: 20% 1fr 1fr 1fr;
        /* 点号表示匿名单元。 */
        grid-template-areas: "hd st1 . st2"
    				     "hd st1 . st2";
    }
    .grid-b .subcategory-header {
        /* 使用grid-area属性自定义网格区名 */
        grid-area: hd;
    }
    /* :nth-child(n)匹配其父元素的第n个子元素 */
    .grid-b .story:nth-child(2) {
        grid-area: st1;
    }
    .grid-b .story:nth-child(3) {
        grid-area: st2;
    }
    

    默认的自动定位算法会把广告(<div class="ad"></div>)放到剩余的空单元中。

    CSS Grid Layout规范允许用连续多个点表示一个匿名单元,因为这样更方便对齐多行模板字符串。

    grid-template-areas: "hd ... ... ..."
    					 "hd st1 ... st2"
    					 "hd ... ... ...";
    

    参考资料:

    • 菜鸟教程
    • w3school
    • 《精通CSS》— [英] 安迪·巴德、[瑞典] 埃米尔·比约克隆德
  • 相关阅读:
    AOJ 2200 Mr. Rito Post Office
    poj 3259 Wormholes
    01背包求解组合最值问题
    01背包求解面值组成问题
    金明的预算方案
    追赶法
    有关动态规划的一些定理。。。。。
    4980
    并查集
    快速幂
  • 原文地址:https://www.cnblogs.com/gzhjj/p/10949895.html
Copyright © 2011-2022 走看看