美文网首页CSS权威指南
Css权威指南(4th,第四版中文翻译)-13.Grid布局

Css权威指南(4th,第四版中文翻译)-13.Grid布局

作者: 秋名山车神12138 | 来源:发表于2018-10-30 18:28 被阅读0次

    其实在CSS早期,布局这块一直是个空白,只能通过类似于Float,clear等hack技术来完成布局。到后面flexble box的出现极大扩展了布局的功能,但是flex更适合于细节的布局,例如导航栏,而全局的布局知道Grid出现才有了较大的进步。


    创建一个Grid容器

    创建grid的第一步就是定义一个grid的容器(container),类似于定位中的容器盒子。grid分为两类:普通的regular grid和inline grid。跟flex一样,都需要在容器元素的display属性值进行申明:


    image.png

    虽然grid在很多时候和block很类似,不过他们也有以下的区别:

    1. 浮动元素在grid容器中无效:


      image.png
    2. grid容器的margin并不会与子代的margin合并


      image.png

    同时也有一些CSS属性是对grid元素无效的:

    • 所有的column属性
    • ::first-line ::first-letter
    • float, clear
    • vertical-align

    基本的Grid术语

    基本的元素名称汇总如下:


    image
    • grid track: 其实是横向和纵向的长度;
    • grid cell:是由4条网格线(grid line)所包围的最小区域;
    • grid area:网格区域就是有网格线包围的区域,可能有一个或多个cell组成。

    放置Grid Lines

    放置grid line还是比较复杂的,来看下下面这两个属性:


    image.png

    首先我们来试试创建固定宽度的格点:

    #grid {display: grid; grid-template-columns: 200px 50% 100px;}
    
    image.png

    而且有意思的是,你开可以为你的grid line设置名称,放到[]里面就可以:

    #grid {display: grid; grid-template-columns:
                [start col-a] 200px [col-b] 50% [col-c] 100px [stop end last];
            }
    
    image.png

    row方向的配置和column是一致的:

    #grid {display: grid; grid-template-columns:
    [start col-a] 200px [col-b] 50% [col-c] 100px [stop end last]; grid-template-rows:
                [start masthead] 3em [content] 80% [footer] 2em [stop end];
            }
    
    image.png

    有时候我们想要区间的范围设定一个范围而不是个具体的值,那么就可以借助minmax来实现:

    #grid {display: grid; grid-template-columns:
    [start col-a] 200px [col-b] 50% [col-c] 100px [stop end last]; grid-template-rows:
                [start masthead] 3em [content] minmax(3em,100%) [footer] 2em [stop end];
            }
    
    
    image.png

    另外还可以借助calc来做计算,如果要计算剩余范围的话:

    grid-template-rows:
    [start masthead] 3em [content] calc(100%-5em) [footer] 2em [stop end];
    

    flexible grid 轨迹

    之前我们看到的都是定死的grid配置,那么现在来看看grid的弹性配置。我们用的单位比较特别,称为分数单位(Fractional units),简称为fr。

    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-columns: 25% 25% 25% 25%;
    

    上面两个操作其实效果是一样的:


    image.png

    grid 适配内容大小

    除了上面的弹性布局,其实CSS还提供了针对内容的适配,有min-conten, max-content还有fit-content。

    #g1 {display: grid;
    grid-template-columns: max-content max-content max-content max-content; }
    #g2 {display: grid;
    grid-template-columns: minmax(0,max-content) minmax(0,max-content)
                  minmax(0,max-content) minmax(0,max-content);
            }
    
    
    image.png
    #grid {display: grid; grid-template-columns: 1fr fit-content(150px) 2fr;}
    #grid2 {display: grid; grid-template-columns: 2fr fit-content(50%) 1fr;}
    

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

    #thefollowing { display: grid;
    grid-template-columns:
    fit-content(50ch) fit-content(50ch) fit-content(50ch);
    font-family: monospace;}
    
    
    image.png

    重复格线

    想要实现重复的格线,利用repeat函数会更加方便,比如要产生10个5em宽度的区域就可以写成:

    #grid {display: grid; grid-template-columns: repeat(10, 5em);}
    

    而且repeat的后面参数是可以持续添加的,比如:

    #grid {display: grid;
    grid-template-columns: repeat(3, 2em 1fr 1fr);}
    
    image.png

    Grid 区域

    image.png

    网格区域是用来标志区域的,来看下:

    #grid {display: grid; grid-template-areas:
                "h h h h"
                "l c c r"
                "l f f f";}
    
    image.png

    可以是更形象的:

    #grid {display: grid; grid-template-areas:
                "header     header    header    header"
                "leftside   content   content   rightside"
                "leftside   footer    footer    footer";}
    

    将元素添加到Grid

    之前我们都是在讲怎么定义grid,现在讲讲怎么把元素放到grid里面。

    使用column和row线

    image.png
    .grid {display: grid; width: 50em; grid-template-rows: repeat(5, 5em); grid-template-columns: repeat(10, 5em);}
    .one {
    grid-row-start: 2; grid-row-end: 4; grid-column-start: 2; grid-column-end: 4;}
    .two {
    grid-row-start: 1; grid-row-end: 3; grid-column-start: 5; grid-column-end: 10;}
    .three {
    grid-row-start: 4; grid-column-start: 6;}
    
    

    这个通过设置row和column两个方向的起点和终点来规定元素在grid所占用的位置。


    也可以用span来标识要跨几个格点:

    #grid {display: grid;
    grid-template-rows: repeat(5, 5em); grid-template-columns: repeat(10, 5em);}
    .one {
    grid-row-start: 2; grid-row-end: span 2; grid-column-start: 2; grid-column-end: span 2;}
    .two {
    grid-row-start: 1; grid-row-end: span 2; grid-column-start: 5; grid-column-end: span 5;}
    .three {
    grid-row-start: 4; grid-row-end: span 1; grid-column-start: 6; grid-column-end: span;}
    

    row和column的简写

    image.png

    这两个属性极大简化了选择的操作,来看例子:

    #grid {display: grid;
    grid-template-rows: repeat(10, [R] 1.5em);
    grid-template-columns: 2em repeat(5, [col-A] 5em [col-B] 5em) 2em;}
    .one {
    grid-row: R 3 / 7; grid-column: col-B / span 2;}
    .two {
    grid-row: R / span R 2;
    grid-column: col-A 3 / span 2 col-A;}
    .three { grid-row: 9;
    grid-column: col-A -2;}
    
    #grid {display: grid; grid-template-areas:
                "header header"
                "sidebar content"
                "footer footer";
    grid-template-rows: auto 1fr auto;
    grid-template-columns: 25% 75%;}
    #header {grid-row: header / header; grid-column: header;}
    #footer {grid-row: footer; grid-column: footer-start / footer-end;}
    
    image.png

    同时也可以通过area的名称来做范围的选择:

    
    #grid {display: grid; grid-template-areas:
                "header header"
                "sidebar content"
                "footer footer";
    grid-template-rows: auto 1fr auto;
    grid-template-columns: 25% 75%;}
    #header {grid-row: header / header; grid-column: header;}
    #footer {grid-row: footer; grid-column: footer-start / footer-end;}
    
    image.png

    使用区域

    image.png

    借助grid-area可以直接让元素绑定之前定义好的区域:

    
    #grid {display: grid; grid-template-areas:
                "header     header    header    header"
                "leftside   content   content   rightside"
                "leftside   footer    footer    footer";}
    #masthead {grid-area: header;} #sidebar {grid-area: leftside;} #main {grid-area: content;} #navbar {grid-area: rightside;} #footer {grid-area: footer;}
    
    <div id="grid">
    <div id="masthead">...</div> <div id="main">...</div> <div id="navbar">...</div> <div id="sidebar">...</div> <div id="footer">...</div>
    </div>
    
    image.png

    Grid Flow

    之前我们讲到的是用户自己定义grid元素位置的情况,那么如果不指定的话有没有自动填充的方式么?答案是有的,就是使用grid-auto-flow


    image.png
    <ol id="grid"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ol>
    
    #grid {display: grid; width: 45em; height: 8em; grid-auto-flow: row;}
    #grid li {grid-row: auto; grid-column: auto;}
    
    image.png

    grid 简写

    image.png
    grid:
    "header header header header" 3em ". content sidebar ." 1fr
    "footer footer footer footer" 5em / 2em 3fr minmax(10em,1fr) 2em;
    grid-template-areas:
    "header header header header" ". content sidebar ."
    "footer footer footer footer";
    grid-template-rows: 3em 1fr 5em; grid-template-columns: 2em 3fr minmax(10em,1fr) 2em;
    

    打开Grid间的空隙

    之前我们所有的grid都是紧挨着的,接下来我们来看下如何在其中添加空白。


    image.png
    #grid {display: grid; 
    grid-template-rows: 5em 5em;
    grid-template-columns: 15% 1fr 1fr; 
    grid-column-gap: 1em;}
    
    image.png

    另外一个添加gap的属性是:


    image.png
    #grid {display: grid; grid-template-rows: 5em 5em; grid-template-columns: 15% 1fr 1fr; grid-gap: 12px 2em;}
    
    
    image.png

    Grid对齐

    grid 元素的对齐和flexbox其实是很像的,来看下对照表:


    image.png
    #grid {display: grid;
    align-items: center; justify-items: center;}
    
    image.png

    图层及其排序

    grid元素支持重叠,例如:

    #grid {display: grid; width: 80%; height: 20em;
    grid-rows: repeat(10, 1fr); grid-columns: repeat(10, 1fr);}
    .box01 {grid-row: 1 / span 4; grid-column: 1 / span 4;} .box02 {grid-row: 4 / span 4; grid-column: 4 / span 4;} .box03 {grid-row: 7 / span 4; grid-column: 7 / span 4;} .box04 {grid-row: 4 / span 7; grid-column: 3 / span 2;} .box05 {grid-row: 2 / span 3; grid-column: 4 / span 5;}
    
    image.png

    所以可以通过设置z-index来调整图层的前后顺序:


    image.png

    另一种方式的排序就是使用order属性:

    .box02 {order: 10;}
    
    image.png

    小结

    grid布局还是比较复杂的,不过功能也非常强大。作者自己有时候也被搞晕了,但还是希望能够克服这些,因为你付出的耐心和坚持的回报会是巨大的。

    相关文章

      网友评论

        本文标题:Css权威指南(4th,第四版中文翻译)-13.Grid布局

        本文链接:https://www.haomeiwen.com/subject/fuqntqtx.html