做网站公司平台,品牌策划公司是做什么的,小程序数据网,安卓app安装CSS Grid网格布局全攻略 所有奇技淫巧都只在方寸之间。 几乎从我们踏入前端开发这个领域开始#xff0c;就不停地接触不同的布局技术。从常见的浮动到表格布局#xff0c;再到如今大行其道的flex布局#xff0c;css布局技术一直在不断地推陈出新。其中网格布局(grid)作为css… CSS Grid网格布局全攻略 所有奇技淫巧都只在方寸之间。 几乎从我们踏入前端开发这个领域开始就不停地接触不同的布局技术。从常见的浮动到表格布局再到如今大行其道的flex布局css布局技术一直在不断地推陈出新。其中网格布局(grid)作为css3的产物它更加贴近网页设计师所使用的布局策略学习并利用好它可以让我们免受很多布局困扰。 虽然网格布局好处有很多但学习起来并不简单原因是用来设置布局的属性实在太多其中光是作用于父容器的属性就有17种再加上子元素属性有10种另外还有这些属性值的不同取值方式。这些对于记忆来说绝对是个不小的负担。那么这么多属性以及用法要如何在短时间内消化掉呢在接下来这篇文章里我将针对这27种属性以及它们各自的用法分享我独家的学习策略希望对大家的学习有所帮助。 布局之道 CSS作为一种网页排版设计语言其核心的设计思想必然要遵守相关的领域知识。网格布局是一种二维布局结构它是由纵横相交的两组网格线形成的框架性布局结构。网页设计者可以利用这些由行(row)和列(column)形成的框架性结构来布局设计元素。 在定义一种网格布局结构的时候我们需要在父容器上描述要布局的主体框架结构。为了描述这一框架结构我们就需要给它的基本构成元素命名。一个网格布局的构成元素可以概括为以下几种概念: row line: 行线column line: 列线track: 网格轨道即行线和行线或列线和列线之间所形成的区域用来摆放子元素gap: 网格间距行线和行线或列线和列线之间所形成的不可利用的区域用来分隔元素cell: 网格单元格由行线和列线所分隔出来的区域用来摆放子元素area: 网格区域由单个或多个网格单元格组成用来摆放子元素牢记上述这些概念是之后熟练掌握和应用网格布局的基础。 构建之法 要熟练掌握一门技术核心是找到最基本的套路然后不断练习从而可以在之后的实践过程中减少决策的时间。所以这一部分主要就是介绍网格布局构建过程中的一些常用套路。 这里我们要解决的问题是如何利用最基本的规则来构建出理想的布局模型。在布局过程中归根结底需要处理的就两种页面元素父容器和子元素。前者主要用来设置基础的布局框架相当于建筑中的设计蓝图而后者就是用来进行个性化的布局调整。因此我个人归纳了在使用网格布局过程中的套路是针对父容器元素进行设置需要三个步骤定框架、设间隔和找对齐对子元素来说有两个步骤摆位置和找对齐。我把它们统称为**32构建之法**。 在这一小节中我将把重心主要放在网格布局中所有用到的27个属性名的讲解上而取值逻辑将在最后一部分进行统一介绍。 父容器 定框架 设置父容器的网格布局的第一步就是将父容器的盒模型设置为grid这样就能触发渲染引擎的网格布局算法。 .parent {display: grid;
}接着我们要开始准备**画线**即设置所需行和列的基础线。这些线条将构成我们接下来进行布局排布的基础模板template。在画线过程中我们需要分别根据行(row)和列(column)两个维度进行设置。你需要画几条线就设置几个值不包括边框其取值是轨道(track)的大小。这里我先画出一个3x3的网格框架代码如下: .parent {display: grid;grid-template-rows: 100px 100px 100px; grid-template-columns: 100px 100px 100px; } 在这里你也可以选择使用缩写形式同时为行和列设置值采用/分隔开: .parent {display: grid;grid-template: 100px 100px 100px / 100px 100px 100px; } 画完线后下一步我们可以选择为这些线条和线条之间形成的网格区域(area)进行命名这样在后续使用的时候就能直接使用这些名字便于子元素的定位。 .parent {display: grid;grid-template-areas: a a bc d e c d . } 上面这两步画线和命名同样可以采用缩写形式进行设置代码如下 .parent {display: grid;grid-template: a a b 101px c d e 102px c d . 103px / 104px 105px 105px } 因为使用grid-template同时设置行列和区域名的写法比较复杂为了讲解方便我把值设置成规律的递增数字。其中(101, 102103)设置的是grid-template-rows的值而(104,105,106)设置的则是grid-template-columns的值。 到这一步我们可以说已经完成所需工作的一大半了。 设间隔 间距(gap)的设置在实际开发中是可选的主要根据网页设计的需求而定。如果你需要给网格线之间设置间距我们可以在行列两个维度上分别进行设置, 下面这段代码将给每个行和列分别设置10px的间隔: .parent {display: grid;grid-template: 100px 100px 100px / 100px 100px 100px; grid-row-gap: 10px; grid-column-gap: 10px; } 如果采用缩写形式上述代码又可以简化成: .parent {display: grid;grid-template: 100px 100px 100px / 100px 100px 100px; grid-gap: 10px 10px; } 设置后的效果如下 找对齐 有了前面两个步骤我们的网格布局框架基本上算是搭建得差不多了。每个子元素都会默认占据一个网格区域。而在父容器这里我们如果有需要就要进行最后一个步骤找对齐。所谓对齐方式可以分为内部和外部两种前者是针对每个网格区域的子元素而言而后者是相对于网格区域本身。另外在行和列更专业的术语是main axis和cross axis)上又各自有两个维度这就构成了4种设置对齐的方式。 先来处理一下每个子元素相对网格区域内部的对齐方式: .parent {display: grid;grid-template: 100px 100px 100px / 100px 100px 100px; grid-gap: 10px 10px; justify-items: center; align-items: center; } 在上面的代码中我分别在行和列方向上都设置了居中对齐这样每个网格区域中的子元素相对于各自的区域行为是一致的都能均匀排布。可以看到效果如下图所示 再来看一下另一种情况: .parent {display: grid;width: 500px;height: 500px; grid-template: 100px 100px 100px / 100px 100px 100px; grid-gap: 10px 10px; justify-content: space-between; align-content: center; } 有时候我们设置的网格不足以覆盖整个父容器的大小时比如在上述的例子中整个父容器有500px*500px的大小而我们只设置了300px*300px的网格区域这时候就需要指定多出来空间的处理规则。justify-content和align-content就是分别在行和列两个方向上用来解决这个问题的属性。它们将针对每个网格区域去设置其在父容器中的对齐方式。 justify和align这两个单词在方向上比较容易搞混所以我在记忆上采取的方式是记住justifyrow和aligncolumn这两个合并词它们长度差不多。如果你有更好的记忆方式请留言告诉我。 子元素 我们通过在父容器上搭建好了基础的框架后对于大部分子元素来说就已经能够很好地满足布局要求了。针对部分子元素可以根据需求进行微调。如果要在子元素上进行布局微调通常需要以下两个步骤摆位置和找对齐。 摆位置 像下棋一样针对子元素的排布我们需要给它们指定要摆放的具体位置。要确定具体位置可以利用之前在父容器中所指定的线名和区域名来定位。一种方式是直接通过设置起始行结束行和起始列结束列来给子元素划定它所要摆放的区域另外一种方式是指定要摆放的区域名。 /* 指定起始行结束行起始列结束列 */
.child:first-child {grid-row-start: 1; grid-row-end: 2; grid-column-start: 1; grid-column-end: 3; background: red; } /* 使用缩写形式 */ .child:nth-child(2) { grid-row: 2/3; grid-column: 2/4; background: yellow; } /* 直接指定区域名 */ .child:nth-child(3) { grid-area: i; background: green; } 这段代码的效果如下 还有一种更加灵活的设置位置方式是指定跨越的行数和列数关键字span用来控制一次跨越的行数或列数, 如上面第三个子元素可以改写成: .child-nth-child(3) {grid-row: 2/3;grid-column: span 2;
}找对齐 和父容器中所设置的对齐方式类似针对个别子元素的对齐处理我们可以按照行列两组属性进行分别处理 /* 列对齐 */
.child:nth-child(1) {align-self: end;
}/* 行对齐 */ .child:nth-child(2) { justify-self: end; } /* 采用缩写形式 */ .child:nth-child(3) { place-self: center center; } *隐式网格 灵活性是网格布局的一大优势除了采用上述那种手动指定框架结构的方式网格布局还有一套自动化布局的机制这套机制称为**“隐式网格布局”**。当我们在网格定义的区域外放置子元素时或因子元素数量过多而需要更多的网格线时布局算法就会自动生成隐式网格。默认情况下这些隐式网格的大小也会随着内容尺寸不同而变化而我们可以利用属性grid-auto-rows和grid-auto-columns来控制隐式网格的大小。 考虑下面这个例子 div classparentdiv classchild stylebackground: red/div div classchild stylebackground: yellow/div div classchild stylebackground: green/div /div .parent {display: grid;grid-auto-rows: 100px;grid-auto-columns: 100px; } 通过手动在父容器中设置隐式网格大小为100x100的大小后效果如下 如果子元素引用了不存在的行号和列号父容器会自动生成隐式网格以容纳所有子元素: .child:first-child {grid-row-start: 1;grid-row-end: 2;grid-column-start: 1;grid-column-end: 3;background: red;
}有了网格大小的控制我们还需要位置的控制。默认情况下子元素都是先将行填充满容器大小不够的时候才会生成新的隐式行。如果要改变这一默认行为我们需要使用grid-auto-flow属性来控制: .parent {display: grid;grid-auto-rows: 100px;grid-auto-columns: 100px; grid-template-areas: a b c d e f g h i; grid-auto-flow: column; } 取值之术 介绍完所有的网格布局属性后我们再来说一下各种属性的取值策略。 大小 在CSS中我们通常使用px,em等取值单位进行属性大小的设置对于灵活的布局需求来说百分比也是常用的取值单位。这些单位在平常工作中似乎已经足够用了。不过为了让布局能够更加灵活网格布局中引入了一种新单位fr它是fraction这个单词的缩写意思是容器内剩余空间的分数比。考虑下面这个例子 .parent {height: 100px;display: grid;grid-template-columns: 100px 1fr 100px;
}我们通过设置100px 1fr 100px的布局框架从而很轻松地就实现了两边宽度固定中间自适应的效果。 如果要实现有比例关系的布局结构还可以使用多个fr的取值: .parent {width: 400px;height: 100px; display: grid; grid-template-rows: 100px 1fr 100px; grid-template-columns: 1fr 1fr 2fr; grid-template-areas: a b c } 可以看到区域a,b,c之间的比例关系就是1:1:2的关系。 除了上述这个支持自适应的单位外网格布局中还能够使用max-content和min-content这组关键字来达到自适应的目的。要理解这两个关键字首先需要理解内在尺寸(intrinsic size)和外部尺寸(extrinsic size)这两个概念。先说一下extrinsic size它的相对值计算是相对于父容器对应的属性值。我们知道width如果使用百分比单位其计算值是相对于该元素所在的容器宽度的比如父容器宽度100px, 子元素设置width: 20%那么它的宽度就是100px * 20% 20px。在css3中引入了intrinsic size则是相对于元素自身尺寸进行计算。max-content和min-content就是相对于元素自身内容块进行计算的属性值。 min-content顾名思义是根据元素内容来设置的最小宽度大小在英文句子中通常是最长单词的那个长度而中文中则是一个字的长度。比如下面这个例子 .parent {display: grid;grid-template-columns: auto min-content auto;
}可以看到中间那个网格的那个宽度就等于scq000这个单词的长度。 与min-content相对应max-content会将尺寸设置成内容尺寸能达到的最大宽度。我们把代码改成下面这样: .parent {display: grid;grid-template-columns: auto max-content auto;
}有了这两个属性值我们可以很容易地让布局区域根据内容进行自适应。 函数 函数是用来避免重复性工作的一种有效工具在网格布局中提供了一些常用CSS函数来方便我们的工作。 第一个要介绍的是minmax这个函数。在设置网格框架的过程中对于自适应的网格区域我们都会设置一个最小值和最大值这个函数就是用来实现这个目的的。 .parent {display: grid;grid-template-columns: 100px minmax(100px, 200px) 100px; } /* 最常用的情况是只设置最小不设置最大值 */ .parent { display: grid; grid-template-columns: 100px minmax(100px, auto) 100px; } 利用这个函数设置的网格布局可以做到很好的自适应在页面伸缩过程中也能保证布局的稳定性。 另一个很有用的函数是fit-content它实际上是min(maximum size, max(minimum size, argument))的简写表示将元素宽度收缩到内容宽度。说得通俗点就是使用这个函数后会尽量不占用多余的空间。如果内容的宽度小于fit-content中设置的长度那么实际子元素宽度是内容宽度。如果内容宽度超出了fit-content中设置的长度那么实际子元素宽度就是设置的那个长度。下面看两个例子: .parent {display: grid;grid-template-rows: auto fit-content(200px) auto;
}第一个句子中的长度超出了200px那么此时中间网格的宽度是200px。而第二个例子中内容宽度不足200px此时中间网格的宽度是句子实际占用的宽度。 最后要介绍的是repeat函数它主要用来批量设置框架的间距这个函数接受两个参数第一个参数控制循环次数第二个参数控制间距大小。让我们用这个函数改写一下上述例子: .parent {display: grid;grid-template-rows: 100px 100px 100px; grid-template-columns: 100px 100px 100px; } /* 利用repeat函数改写 */ .parent { display: grid; grid-template-rows: repeat(3, 100px); grid-template-columns: repeat(3, 100px); } 另外第一个参数除了可以使用数字显示设置网格数量外还能使用auto-fit和auto-fill两个关键字自动分配空间。通常情况下这两个关键字的使用效果都差不多唯一的差别是空余空间的分配规则。搭配minmax函数可以看出区别如下面这两个例子 .parent {display: grid;width: 500px;height: 100px; grid-gap: 10px; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); } .parent { display: grid; width: 500px; height: 100px; grid-gap: 10px; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); } 在单行布局的时候如果有空余空间auto-fit会将它们平均分配到所有子元素中而auto-fill会自动创建空白的列。 命名 我们在创建网格布局框架的时候通过画线来指定基本布局结构。默认情况下网格布局会给每一条网格线进行命名命名顺序同书写顺序一致:从左到右由上至下按数字命名。假设我们指定的是3x3的网格布局结构那么包含边框线就会生成448条线。 除了采用默认命名方式我们还能够自定义网格线的名称以便于后续在子元素定位中使用。 .parent {display: grid;grid-template-rows: [row-a] 100px [row-b] 100px [row-c] 100px [row-d]; } 对齐 对齐是布局过程中一个不可缺少的步骤它的取值是通过已有的关键字来指定的。其中用于网格布局中对齐的关键字有start,center, end和stretch四个。 我们先从默认值stretch看起这个关键字是伸展的意思所以在默认情况下网格中的子元素会尽可能地填充满网格区域由于是默认值所以平常写代码的时候就不太会可以去用这个关键字进行声明。 接着再来看一下常用的对齐取值策略只需要记住一点就可以了用属性justify-*,align-*来分别控制横轴和纵轴两个方向属性值控制其对齐位置。 startcenter和end三个属性值就分别对应了前中后三个位置。 .parent {display: grid;
}
.child:first-child {justify-self: start; } .child:first-child { justify-self: center; } .child:first-child { justify-self: end; } *排列 让我们重新回到隐式网格那部分,隐式的排列规则是通过指定grid-auto-flow这个属性来设置的。它的取值只有三个rowcolumn和dense。上面属性部分已经介绍过row和column两个属性值前者是按行优先来摆放子元素后者是按列优先来摆放子元素。这里主要介绍一下dense这个属性值。通常情况下排列子元素会按照顺序填充行或列如果空间不足的时候会换行或换列。而使用了dense属性后会尽量使用空余空间考虑下面这段代码 .parent {display: grid;grid-template-columns: repeat(3, 100px);
}div classparentdiv classchild1/div div classchild2/div div classchild3/div div classchild4/div div classchild5/div /div 默认情况下显示效果是这样的: 当我们使用dense值进行排列的时候就相当于开启“紧凑”模式会尽可能利用空余空间。 .parent {display: grid;grid-auto-flow: row dense;/* 由于默认为按行排列可省略为dense */grid-auto-flow: dense; } 所以显示效果如下 总结 在这篇文章里我通过拆解分类所有网格布局相关的知识点希望能够为大家提供一个比较系统的运用网格布局的指导方法。在实际应用过程中沿着32构建之法”的这个套路来走可以节约很多思考和决策时间。另外由于这篇文章信息密度可能比较大希望大家能够多多复习并跟着例子实际操练几遍这样在实际工作运用中才能如鱼得水。最后送上一张思维导图帮助大家能够一览本文所有的重点。 推荐阅读 grid.malven.co/ www.w3.org/TR/css-alig… medium.com/patrickbro… www.zhangxinxu.com/wordpress/2… css-tricks.com/difference-… 画图调试工具: www.mozilla.org/en-US/firef… ——本文首发于个人公众号转载请注明出处——— 最后欢迎大家关注我的公众号一起学习交流。 转载于:https://www.cnblogs.com/scq000/p/11206692.html