[TOC]

Node 生成模块化文件的小工具

**talk is cheap, show me the code

目的及用途

  1. 可以方便地自定义生成各种文件模板,可定制化,configs文件夹放入 .gitignore文件里
  2. 与脚手架不同,本地可以随便改,不会影响到团队成员开发
  3. 与vscode的代码片段不同,这种方法更快,而且,不用那么麻烦的格式

正常的vue快捷代码片段

  1. "Print to vueTemplate": {
  2. "prefix": "vueTemplate",
  3. "body": [
  4. "<template>",
  5. " <div>",
  6. " $3",
  7. " </div>",
  8. "</template>",
  9. "<script>",
  10. "export default {",
  11. " name:'$1',",
  12. " props: {",
  13. " },",
  14. " data() {",
  15. " return {",
  16. " $2",
  17. " }",
  18. " },",
  19. " created() {",
  20. " },",
  21. " mounted() {",
  22. " },",
  23. " methods: {",
  24. " }",
  25. "}",
  26. "</script>",
  27. "<style scoped lang='less'>",
  28. "</style>"
  29. ],
  30. "description": "vue 模板"
  31. },

源码

add-module.js

  1. /**
  2. * description: 根据模板文件,自动生成模块文件以及目录
  3. * @author: taoxiaolin
  4. * @create-date: 2019-12-08 23:19:27
  5. * @version: V 1.0.0
  6. */
  7. // ---------------------- 变量定义 ----------------------
  8. const fs = require('fs');
  9. const path = require('path');
  10. const tplRender = require('json-templater/string');
  11. /*
  12. var render = require('json-templater/string');
  13. render('{{xfoo}} {{say.what}}', { xfoo: 'yep', say: { what: 'yep' } });
  14. // yep yep
  15. 注:{{xfoo}} 两侧不能出现空格 :(
  16. */
  17. // 接收输入的模块名
  18. const moduleName = process.argv[2];
  19. const OUTPUT_PATH = path.join(__dirname, `../game/${moduleName}`);
  20. // console.log('out', OUTPUT_PATH, '__dir', __dirname);
  21. // 目录
  22. const dirMap = {
  23. 'html': `../game/${moduleName}/`,
  24. 'js': `../game/${moduleName}/js/`,
  25. 'less': `../game/${moduleName}/css/`,
  26. 'img': `../game/${moduleName}/img/`
  27. };
  28. // 文件最终落地结构以及文件名
  29. const fileTargetMap = {
  30. 'html': `../game/${moduleName}/index.html`,
  31. 'js': `../game/${moduleName}/js/index.js`,
  32. 'less': `../game/${moduleName}/css/index.less`
  33. };
  34. // 引用的文件模板
  35. const tplMap = {
  36. 'html': require('./template/html-tpl.js'),
  37. 'js': require('./template/js-tpl.js'),
  38. 'less': require('./template/less-tpl.js')
  39. };
  40. // 需要渲染变量的模块
  41. const needRenderTpl = {
  42. 'html': {
  43. moduleName
  44. },
  45. 'store': {
  46. moduleName
  47. }
  48. };
  49. // render示例,如果模板内不需要解析变量的话,就不需要这一步
  50. // const htmlStr = tplRender(htmlTpl, { moduleName });
  51. // 检测是否存在同名的 module
  52. if (fs.existsSync(OUTPUT_PATH)) {
  53. console.error(`${moduleName}已存在!`);
  54. return;
  55. }
  56. // ---------------------- 函数定义 ----------------------
  57. // 开始创建文件以及文件夹
  58. /**
  59. * @function: 异步方式
  60. * @description: 递归创建文件夹
  61. * @author: taoixaolin
  62. */
  63. // function mkdirs(dirname, callback) {
  64. // fs.exists(dirname, (exists) => {
  65. // if (exists) {
  66. // callback();
  67. // } else {
  68. // mkdirs(path.dirname(dirname), () => {
  69. // fs.mkdir(dirname, callback);
  70. // });
  71. // }
  72. // });
  73. // }
  74. // 开始创建文件以及文件夹
  75. /**
  76. * @function: 同步
  77. * @description: 递归创建文件夹
  78. * @author: taoixaolin
  79. */
  80. function mkdirsSync(dirname) {
  81. // console.log('mulu: ', mkdirsSync(path.dirname(dirname)));
  82. if (fs.existsSync(dirname)) {
  83. return true;
  84. } else {
  85. if (mkdirsSync(path.dirname(dirname))) {
  86. fs.mkdirSync(dirname);
  87. return true;
  88. }
  89. }
  90. }
  91. function createModule() {
  92. // 先建总目录,再建分目录
  93. mkdirsSync(OUTPUT_PATH);
  94. // 创建目录
  95. Object.keys(dirMap).forEach((key) => {
  96. const folder = path.join(__dirname, dirMap[key]);
  97. mkdirsSync(folder);
  98. });
  99. // 创建文件
  100. Object.keys(fileTargetMap).forEach((key) => {
  101. const outPath = path.join(__dirname, fileTargetMap[key]);
  102. let fileTarget = '';
  103. // 如果需要传参数,遍历一下,然后渲染
  104. if (needRenderTpl[key]) {
  105. const tempObj = {};
  106. Object.keys(needRenderTpl[key]).forEach((key2) => {
  107. tempObj[key2] = needRenderTpl[key][key2];
  108. });
  109. fileTarget = tplRender(tplMap[key], tempObj); // 带参数渲染
  110. } else {
  111. fileTarget = tplRender(tplMap[key], {}); // 不带参数
  112. }
  113. fs.writeFileSync(outPath, fileTarget); // 文件写入
  114. });
  115. }
  116. // ---------------------- 执行 ----------------------
  117. createModule();

del-module.js

  1. const fs = require('fs');
  2. const path = require('path');
  3. // const rm = require('rimraf');
  4. const moduleName = process.argv[2];
  5. const DELETE_PATH = path.join(__dirname, `../game/${moduleName}`);
  6. function deleteAll(path) {
  7. let files = [];
  8. if (fs.existsSync(path)) {
  9. files = fs.readdirSync(path);
  10. files.forEach((file, index) => {
  11. const currentPath = path + '/' + file;
  12. if (fs.statSync(currentPath).isDirectory()) {
  13. deleteAll(currentPath); // 是目录则递归进入下一层
  14. } else {
  15. fs.unlinkSync(currentPath); // 是文件则删除文件
  16. }
  17. });
  18. fs.rmdirSync(path); // 文件完成之后,删除文件夹
  19. } else {
  20. throw new Error('目录不存在!');
  21. }
  22. }
  23. deleteAll(DELETE_PATH);

Template 文件

  1. const htmlTpl =
  2. `<!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  7. <meta name="robots" content="index,follow">
  8. <meta content="telephone=no" name="format-detection">
  9. <meta name="viewport"
  10. content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
  11. <title>Document</title>
  12. </head>
  13. <body>
  14. <div id="app" v-cloak>
  15. {{moduleName}}
  16. </div>
  17. </body>
  18. </html>
  19. `;
  20. module.exports = htmlTpl;
  1. const indexJsTpl =
  2. `import '../css/index.less';
  3. import Vue from 'vue/dist/vue.min';
  4. // ...还可以加很多很多
  5. new Vue({
  6. el: '#app',
  7. data: {},
  8. mounted() {
  9. console.log('args', wb.args);
  10. },
  11. methods: {
  12. }
  13. });
  14. `;
  15. module.exports = indexJsTpl;

package.json 配置

  1. "scripts": {
  2. "add": "node src/config/add-module.js",
  3. "del": "node src/config/del-module.js",
  4. }
  5. "devDependencies": {
  6. "json-templater": "^1.2.0"
  7. },

CSS Grid 布局推荐

本次分享 grid 将围绕三个问题来展开,即什么是CSS Grid? 它能做什么?为什么要推荐它?;-)

什么是CSS Grid?

gird 即格子的意思,它可以将一个容器划分成 行和列,组成一个个的格子,因此,可以看做是一个二维的布局,而我们经常用的 flex 布局,则是利用“轴线”进行布局,需要对容器指定 flex-direction(默认 row), 所以,flex 是一种一维布局

采用网格布局的区域,称为”容器”(container)。容器内部采用网格定位的子元素,称为”项目”(item)。

  1. <div>
  2. <div>
  3. <p>1</p>
  4. </div>
  5. <div>
  6. <p>2</p>
  7. </div>
  8. <div>
  9. <p>3</p>
  10. </div>
  11. </div>

上面代码中,最外层的 <div> 就是容器,里面第一层的 <div> 是项目

注意:项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码的 <p> 元素就不是项目。Grid 布局只对项目生效。

两个重要的概念

单元格

行和列的交叉区域,称为”单元格”(cell)。

Xnip2019-12-12_08-19-06.jpg

网格线

划分网格的线,称为”网格线”(grid line)。水平网格线划分出行,垂直网格线划分出列。

Xnip2019-12-12_07-56-28.jpg

CSS Grid 能做什么?有哪些用处?

先介绍一些 grid 比较重要的属性吧

容器属性

display

display: grid 网格项目按行排列,网格项目占用整个容器的宽度。
display: inline-grid 网格项目按行排列, 网格项目宽度由自身宽度决定。

  1. displaygrid inline-grid

grid-template-columns 和 grid-template-rows属性 (重要)

grid-template-columns: 属性定义每一列的列宽
grid-template-rows: 属性定义每一行的行高。

  1. #container{
  2. display: grid;
  3. grid-template-columns: 100px 100px 100px;
  4. grid-template-rows: 100px 100px 100px;
  5. // grid-template-columns: 33.33% 33.33% 33.33%;
  6. // grid-template-rows: 33.33% 33.33% 33.33%;
  7. .item {
  8. font-size: 4em;
  9. text-align: center;
  10. border: 1px solid #e5e4e9;
  11. }
  12. }

repeat() 函数

这个函数用的非常多, repeat() 接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。

  1. // grid-template-rows: 100px 100px 100px;
  2. grid-template-rows: repeat(3, 100px);
  3. // repeat() 也可以重复某种模式,如下
  4. #container{
  5. display: grid;
  6. grid-template-columns: repeat(2, 100px 20px 80px);
  7. grid-template-rows: repeat(3, 100px);
  8. }

fr 关键字

为了方便表示比例关系,网格布局提供了fr关键字(fraction 的缩写,意为”片段”)

  1. .container {
  2. display: grid;
  3. grid-template-columns: 150px 1fr 2fr;
  4. }

计算规则:

  1. grid-template-columns: 100px 25% 1fr 2fr;

单位fr和其它长度单位混合使用时,fr的计算基于其它单位分配后的剩余空间。
本例中,1fr = (容器宽度 - 100px - 容器宽度的25%) / 3

minmax() 函数

minmax() 函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。

  1. grid-template-columns: 1fr 1fr minmax(100px, 1fr);
  2. // minmax(100px, 1fr)表示列宽不小于100px,不大于1fr

auto-fill 和 auto-fit

单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充。

  1. grid-template-columns: repeat(12, minmax(250px, 1fr)); // 如果容器宽度不够,不会换行
  2. // 这样的话,如果行内剩下的空间不足以容纳另外一列时,已有的列能自动扩张占满一整行,不造成空间浪费。
  3. grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

auto-fill 倾向于容纳更多的列,所以如果在满足宽度限制的前提下还有空间能容纳新列,那么它会暗中创建一些列来填充当前行。即使创建出来的列没有任何内容,但实际上还是占据了行的空间。

auto-fit 倾向于使用最少列数占满当前行空间,浏览器先是和 auto-fill 一样,暗中创建一些列来填充多出来的行空间,然后坍缩(collapse)这些列以便腾出空间让其余列扩张。

column-gap, row-gap,grid-gap 属性

用来设置间距,row-gap: 行间距 column-gap: 列间距

  1. grid-gap: <grid-row-gap> <grid-column-gap>; // 如果 grid-gap省略了第二个值,浏览器认为第二个值等于第一个值。

grid-template-areas 属性

网格布局允许指定”区域”(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域。

  1. grid-template-areas: "header header header"
  2. "main main sidebar"
  3. "footer footer footer";
  4. .header {
  5. grid-area: header;
  6. }
  7. ...

gird-auto-flow 属性

划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是”先行后列”,即先填满第一行,再开始放入第二行,即下图数字的顺序。

  1. gird-auto-flow: row(默认) column; // 子元素排列方式
  2. grid-auto-flow: row dense; // 表示"先行后列",并且尽可能紧密填满,尽量不出现空格。

justify-items 属性,align-items 属性,place-items 属性

justify-items 属性设置 单元格内容 的水平位置(左中右)
align-items 属性设置 单元格内容 的垂直位置(上中下)。

  1. .container {
  2. justify-items: start | end | center | stretch;
  3. align-items: start | end | center | stretch;
  4. }
  5. /*
  6. start:对齐单元格的起始边缘。
  7. end:对齐单元格的结束边缘。
  8. center:单元格内部居中。
  9. stretch:拉伸,占满单元格的整个宽度(默认值)。
  10. */

Xnip2019-12-12_16-42-31.jpg

justify-content 属性,align-content 属性,place-content 属性

justify-content属性是 整个内容区域 在容器里面的水平位置(左中右),
align-content属性是 整个内容区域 的垂直位置(上中下)。

  1. .container {
  2. justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  3. align-content: start | end | center | stretch | space-around | space-between | space-evenly;
  4. }

Xnip2019-12-12_16-42-19.jpg

容器所有属性总览

  1. display
  2. grid-template-columns
  3. grid-template-rows
  4. grid-template-areas
  5. grid-template
  6. grid-column-gap
  7. grid-row-gap
  8. grid-gap
  9. justify-items
  10. align-items
  11. justify-content
  12. align-content
  13. grid-auto-columns
  14. grid-auto-rows
  15. grid-auto-flow
  16. grid

项目属性

grid-row-start, grid-row-end, grid-column-start, grid-column-end 属性

用网格线编号定位项目
Xnip2019-12-12_07-56-28.jpg

  1. grid-row-start: 2;
  2. grid-row-end: 3;
  3. grid-column-start: 2;
  4. grid-column-end: 3;

grid-row和grid-column属性

合并写法,减少代码量

  1. .item-1 {
  2. grid-column-start: 1;
  3. grid-column-end: 3;
  4. grid-row-start: 1;
  5. grid-row-end: 2;
  6. }
  7. /* 等同于 */
  8. .item-1 {
  9. grid-column: 1 / 3;
  10. grid-row: 1 / 2;
  11. }
  12. /* 等同于 */
  13. .item-1 {
  14. background: #b03532;
  15. grid-column: 1 / span 2;
  16. grid-row: 1 / span 2;
  17. }
  18. // grid-area 总体简写
  19. .item {
  20. grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
  21. }

justify-self 属性,align-self 属性,place-self 属性

justify-self属性设置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目。
align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目。

  1. .item {
  2. justify-self: start | end | center | stretch;
  3. align-self: start | end | center | stretch;
  4. }
  5. /*
  6. start:对齐单元格的起始边缘。
  7. end:对齐单元格的结束边缘。
  8. center:单元格内部居中。
  9. stretch:拉伸,占满单元格的整个宽度(默认值)。
  10. */

Xnip2019-12-12_16-59-10.jpg

项目所有属性总览

  1. grid-column-start
  2. grid-column-end
  3. grid-row-start
  4. grid-row-end
  5. grid-column
  6. grid-row
  7. grid-area
  8. justify-self
  9. align-self

常见布局

两栏布局

  1. // 两栏式布局只需要一行代码
  2. // 左列定宽,右列自适应
  3. .wrapper {
  4. display: grid;
  5. grid-template-columns: 100px auto;
  6. // grid-template-columns: 100px 1fr;
  7. }
  8. // 右列定宽,左列自适应
  9. .wrapper {
  10. display: grid;
  11. grid-template-columns: auto 100px;
  12. // grid-template-columns: 1fr 100px;
  13. }
  14. // 左/右不定宽,另一侧自适应
  15. .wrapper {
  16. display: grid;
  17. grid-template-columns: 1fr auto;
  18. // grid-template-columns: auto 1fr;
  19. }

三栏布局

  1. 左列中列定宽,右列自适应

    1. grid-template-columns: 100px 200px auto;
  2. 左列右列定宽,中间自适应

    圣杯布局

    ```less

    parent {

    height: 600px; display: grid; grid-template-columns: 200px auto 200px; grid-template-rows: 60px auto 60px; grid-template-areas:

    1. "header header header"
    2. "leftside main rightside"
    3. "footer footer footer";

    }

  1. <a name="XNcmx"></a>
  2. #### 多列布局
  3. <a name="WXQzG"></a>
  4. ##### 九宫格
  5. ```less
  6. #parent {
  7. width: 600px;
  8. height: 600px;
  9. display: grid;
  10. grid-template-columns: repeat(3, 1fr);
  11. grid-template-rows: repeat(3, 1fr);
  12. }

栅格系统
  1. // 12栏布局
  2. grid-template-columns: repeat(12, 1fr);
  3. // 24栏布局
  4. grid-template-columns: repeat(24, 1fr);

为什么推荐使用 CSS Grid?

与flex的对比

演示代码

Flex

  1. <div class="container-flex">
  2. <div class="box box1">
  3. <div class="item">1</div>
  4. </div>
  5. <div class="box box2">
  6. <div class="item">1</div>
  7. <div class="item">2</div>
  8. </div>
  9. <div class="box box3">
  10. <div class="item">1</div>
  11. <div class="item">2</div>
  12. <div class="item">3</div>
  13. </div>
  14. <div class="box box4">
  15. <div class="column">
  16. <div class="item">1</div>
  17. <div class="item">2</div>
  18. </div>
  19. <div class="column">
  20. <div class="item">3</div>
  21. <div class="item">4</div>
  22. </div>
  23. </div>
  24. <div class="box box5">
  25. <div class="column">
  26. <div class="item">1</div>
  27. <div class="item">2</div>
  28. </div>
  29. <div class="column">
  30. <div class="item">3</div>
  31. </div>
  32. <div class="column">
  33. <div class="item">4</div>
  34. <div class="item">5</div>
  35. </div>
  36. </div>
  37. <div class="box box6">
  38. <div class="column">
  39. <div class="item">1</div>
  40. <div class="item">2</div>
  41. <div class="item">3</div>
  42. </div>
  43. <div class="column">
  44. <div class="item">4</div>
  45. <div class="item">5</div>
  46. <div class="item">6</div>
  47. </div>
  48. </div>
  49. <div class="box box7">
  50. <div class="item">1</div>
  51. <div class="item">2</div>
  52. <div class="item">3</div>
  53. <div class="item">4</div>
  54. <div class="item">5</div>
  55. <div class="item">6</div>
  56. <div class="item">7</div>
  57. </div>
  58. <div class="box box8">
  59. <div class="item">1</div>
  60. <div class="item">2</div>
  61. <div class="item">3</div>
  62. <div class="item">4</div>
  63. <div class="item">5</div>
  64. <div class="item">6</div>
  65. <div class="item">7</div>
  66. <div class="item">8</div>
  67. </div>
  68. <div class="box box9">
  69. <div class="item">1</div>
  70. <div class="item">2</div>
  71. <div class="item">3</div>
  72. <div class="item">4</div>
  73. <div class="item">5</div>
  74. <div class="item">6</div>
  75. <div class="item">7</div>
  76. <div class="item">8</div>
  77. <div class="item">9</div>
  78. </div>
  79. </div>
  1. [v-cloak] {
  2. display: none;
  3. }
  4. .container-common {
  5. width: 640px;
  6. height: 640px;
  7. box-sizing: border-box;
  8. padding: 5px;
  9. background-color: #292929;
  10. }
  11. .container-flex {
  12. .container-common;
  13. display: flex;
  14. flex-wrap: wrap;
  15. .box {
  16. width: 180px;
  17. height: 180px;
  18. margin: 15px;
  19. background-color: #E7E7E7;
  20. box-sizing: border-box;
  21. display: flex;
  22. .item {
  23. width: 40px;
  24. height: 40px;
  25. border-radius: 50%;
  26. background-color: #292929;
  27. margin: 10px;
  28. color: white;
  29. display: flex;
  30. justify-content: center;
  31. align-items: center;
  32. }
  33. }
  34. .box1 {
  35. justify-content: center;
  36. align-items: center;
  37. }
  38. .box2 {
  39. justify-content: space-between;
  40. .item:nth-child(2) {
  41. align-self: flex-end;
  42. }
  43. }
  44. .box3 {
  45. .item:nth-child(2) {
  46. align-self: center;
  47. }
  48. .item:nth-child(3) {
  49. align-self: flex-end;
  50. }
  51. }
  52. .box4 {
  53. flex-wrap: wrap;
  54. justify-content: space-between;
  55. .column {
  56. display: flex;
  57. flex-direction: column;
  58. justify-content: space-between;
  59. }
  60. }
  61. .box5 {
  62. flex-wrap: wrap;
  63. justify-content: space-between;
  64. .column {
  65. display: flex;
  66. flex-direction: column;
  67. justify-content: space-between;
  68. }
  69. .column:nth-child(2) {
  70. justify-content: center;
  71. }
  72. }
  73. .box6 {
  74. flex-wrap: wrap;
  75. align-content: space-between;
  76. justify-content: space-between;
  77. .column {
  78. display: flex;
  79. flex-direction: column;
  80. }
  81. }
  82. .box7 {
  83. flex-wrap: wrap;
  84. }
  85. .box8 {
  86. flex-wrap: wrap;
  87. }
  88. .box9 {
  89. flex-wrap: wrap;
  90. }
  91. }

Grid

  1. <div class="container-grid">
  2. <div class="box box1">
  3. <div class="item">1</div>
  4. </div>
  5. <div class="box box2">
  6. <div class="item">1</div>
  7. <div class="item">2</div>
  8. </div>
  9. <div class="box box3">
  10. <div class="item">1</div>
  11. <div class="item">2</div>
  12. <div class="item">3</div>
  13. </div>
  14. <div class="box box4">
  15. <div class="item">1</div>
  16. <div class="item">2</div>
  17. <div class="item">3</div>
  18. <div class="item">4</div>
  19. </div>
  20. <div class="box box5">
  21. <div class="item">1</div>
  22. <div class="item">2</div>
  23. <div class="item">3</div>
  24. <div class="item">4</div>
  25. <div class="item">5</div>
  26. </div>
  27. <div class="box box6">
  28. <div class="item">1</div>
  29. <div class="item">2</div>
  30. <div class="item">3</div>
  31. <div class="item">4</div>
  32. <div class="item">5</div>
  33. <div class="item">6</div>
  34. </div>
  35. <div class="box box7">
  36. <div class="item">1</div>
  37. <div class="item">2</div>
  38. <div class="item">3</div>
  39. <div class="item">4</div>
  40. <div class="item">5</div>
  41. <div class="item">6</div>
  42. <div class="item">7</div>
  43. </div>
  44. <div class="box box8">
  45. <div class="item">1</div>
  46. <div class="item">2</div>
  47. <div class="item">3</div>
  48. <div class="item">4</div>
  49. <div class="item">5</div>
  50. <div class="item">6</div>
  51. <div class="item">7</div>
  52. <div class="item">8</div>
  53. </div>
  54. <div class="box box9">
  55. <div class="item">1</div>
  56. <div class="item">2</div>
  57. <div class="item">3</div>
  58. <div class="item">4</div>
  59. <div class="item">5</div>
  60. <div class="item">6</div>
  61. <div class="item">7</div>
  62. <div class="item">8</div>
  63. <div class="item">9</div>
  64. </div>
  65. </div>
  1. [v-cloak] {
  2. display: none;
  3. }
  4. .container-common {
  5. width: 640px;
  6. height: 640px;
  7. box-sizing: border-box;
  8. padding: 5px;
  9. background-color: #292929;
  10. }
  11. .container-grid {
  12. .container-common;
  13. display: grid;
  14. grid-template-rows: repeat(3, 1fr);
  15. grid-template-columns: repeat(3, 1fr);
  16. .box {
  17. width: 180px;
  18. height: 180px;
  19. margin: 15px;
  20. background-color: #E7E7E7;
  21. box-sizing: border-box;
  22. display: grid;
  23. grid-template-rows: repeat(3, 1fr);
  24. grid-template-columns: repeat(3, 1fr);
  25. grid-template-areas: 'a b c'
  26. 'd e f'
  27. 'g h i';
  28. .item {
  29. width: 40px;
  30. height: 40px;
  31. border-radius: 50%;
  32. background-color: #292929;
  33. margin: 10px;
  34. color: white;
  35. display: flex;
  36. justify-content: center;
  37. align-items: center;
  38. }
  39. }
  40. .box1 {
  41. .item {
  42. grid-area: e;
  43. }
  44. }
  45. .box2 {
  46. .item:nth-child(2) {
  47. grid-area: c;
  48. }
  49. }
  50. .box3 {
  51. .item:nth-child(2) {
  52. grid-area: e;
  53. }
  54. .item:nth-child(3) {
  55. grid-area: i;
  56. }
  57. }
  58. .box4 {
  59. }
  60. .box5 {
  61. }
  62. .box6 {
  63. .item:nth-child(1) {
  64. grid-area: a;
  65. }
  66. .item:nth-child(2) {
  67. grid-area: c;
  68. }
  69. .item:nth-child(3) {
  70. grid-area: g;
  71. }
  72. .item:nth-child(4) {
  73. grid-area: d;
  74. }
  75. .item:nth-child(5) {
  76. grid-area: f;
  77. }
  78. .item:nth-child(6) {
  79. grid-area: i;
  80. }
  81. }
  82. .box7 {
  83. }
  84. .box8 {
  85. }
  86. .box9 {
  87. }
  88. }

需要注意的地方

浏览器对 css grid的适配情况

Xnip2019-12-11_01-32-08.jpg
(grid)

Xnip2019-12-11_20-05-20.jpg(flex)

学习链接

  1. http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html
  2. http://topic.42du.cn/grid#grid-container
  3. https://www.caniuse.com/#search=display%3A%20grid
  4. https://cssgridgarden.com/#zh-cn
  5. http://flexboxfroggy.com/#zh-cn