CSS——网格布局(display: grid)之上篇

CSS——网格布局(display: grid)

前面介绍了弹性布局,今天我们介绍一下网格布局。

什么是网格布局

CSS网格布局(CSS Grid Layout)是一种用于创建复杂网页布局的系统,它允许开发者以二维系统行和列)来控制元素的布局。跟 Flexbox 类似,网格布局也是作用于两级的 DOM 结构。设置为 display: grid 的元素成为一个网格容器(grid container)。它的子元素则变成网格元素(grid items)。除此之外,另外四个重要的概念如下图所示。

  • 网格线(grid line)——网格线构成了网格的框架。一条网格线可以水平或垂直,并且位于一行或一列的任意一侧。如果指定了 grid-gap 的话,它就位于网格线上。
  • 网格轨道(grid track)——一个网格轨道是两条相邻网格线之间的空间。网格有水平轨道(行)和垂直轨道(列)。
  • 网格单元(grid cell)——网格上的单个空间,水平和垂直的网格轨道交叉重叠的部分。
  • 网格区域(grid area)——网格上的矩形区域,由一个到多个网格单元组成。该区域位于两条垂直网格线和两条水平网格线之间。
    在这里插入图片描述

如何进行网格布局

设置 display: grid 只是网格布局的第一步,下面我们从 grid-template-columnsgrid-template-rows 属性来逐步深入。

grid-template-columns 与 grid-template-rows 属性

  • grid-template-columns: 1fr 1fr 1fr:“fr”代表分数单位(fraction unit),我们这里可以简单的理解为“在被划分的空间中所占据的份数”,所以,这个效果就是:创建三个等宽的列。当然,我们可以采取其他单位,如:%、px等。这些单位可以混搭使用,如:gird-template-columns: 300px 1fr 2fr,那么就会先创建300px宽的列,剩下的空间再分别分配1/3、2/3的空间给剩余的两列。不同单位的优先级如下:
    • 百分比(%):首先,浏览器会计算出可用空间的百分比部分。在这个例子中,第二列的宽度是容器宽度的90%。
    • 固定单位(px等):然后,浏览器会为以像素为单位的列分配固定的空间。在这个例子中,第四列的宽度是100px。
    • 分数(fr):最后,浏览器会将剩余的空间按照分数单位的比例分配给使用 fr 的列。在这个例子中,第一列和第三列分别占据1份和2份。
      示例:
    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>/*  创建了四个格子,父元素的背景色为黄色,其余的为了设置从#111 --> #eee的渐变,并设置了半透明*/.main-container {width: 1000px;background-color: yellow;}.grid-item:nth-child(1) {width: 100px;padding: 10px;border: 1px solid;margin-right: 10px;}.grid-container {display: grid;grid-template-columns: 1fr 95% 100px 2fr;grid-template-rows: 1fr;}.grid-item {background-color: #999;}div {color: red;font-size: 1.5rem;font-weight: bold;}</style>
    </head><body><main class="main-container"><div class="grid-container"><div class="grid-item" style="background-color: rgba(17, 17, 17,.5);">项目1</div><div class="grid-item" style="background-color: rgb(85, 85, 85,.5);">项目2</div><div class="grid-item" style="background-color: rgb(153, 153, 153,.5);">项目3</div><div class="grid-item" style="background-color: rgb(238, 238, 238,.5);">项目4</div></div></main>
    </body></html>
    

在这里插入图片描述

可以自己复制代码进行尝试,我们在开发者工具中看到:项目1的宽度为100px,项目2的宽度为950px,项目3的宽度为100px,项目4的宽度为16px。

首先看到确实复合前面的规则,但是在明明在分配 fr单位的盒子的宽度之前,父元素的空间就已经占满了,那它们的宽度是如何来的呢?

这里就要解释了:在父元素宽度超出之后,浏览器也知道没有宽度了,所有就不按照 fr 比例进行分配了,而是按照元素的宽度包括内容、内边距,甚至是外边距)进行分配,比如项目1 指定宽度为 100px,所有分配给他100px,至于项目4 没有指定宽度,其内容只有几个文字,而这些文字的字号是用户代理样式表(浏览器默认加载的css文件,确保了在用户未设置样式时网页的可读性,其优先级低于作者样式表,即我们自己添加的css样式)中的字号——16px,与以往不同的是,这里浏览器会尽量压缩宽度,使文字换行显示min-width,中文为一个汉字的宽度,英文为一个单词的宽度)。如果不做处理的话,这些内容会正常的超出显示(如上图所示)。

grid-template-rows的同理。

网格轨道的创建——repeat()函数

该函数可以用于 CSS Grid 属性 grid-template-columnsgrid-template-rows中。repeat() 函数表示轨道列表的重复片段,允许以更紧凑的形式写入大量显示重复模式的列或行。如:grid-template-rows: repeat(3, 2fr 1fr):重复“2fr 1fr”这两个模式三次,总共创建6行。
repeat()函数有两个参数:
第一个参数可以是以下三种之一:

  • 数字(比如1,2,3)
  • auto-fit关键字
  • auto-fill关键字

第二个参数可选值包括:

  • 长度值,可使用单位包括fr、px、em、%和ch等等
  • min-content关键字
  • max-content关键字
  • auto关键字
  • minmax()函数,其可以嵌套min()或者max()函数
  • fit-content()函数
  • 命名线
参数取值
  1. <length>
    正整数数值

  2. <percentage>
    百分比长度。

    • 如果是行(rows),则相对于网格容器的宽度,如果是列(columns),则相对于网格容器的高度。
    • 如果网格容器的大小取决于网格元素,那么必须为关键字 auto
    • 如果网格元素的大小超过了网格容器的大小,那么浏览器会对网格元素的大小进行调整
  3. <flex>
    带有 fr 单位的非负尺寸指定轨道的弹性系数。任何被 <flex> 指定大小的轨道会根据其弹性系数按比例分配剩余空间。

  4. 关键字max-content
    首先介绍一下,min-content和max-content尺寸是根据内容来的,min-content是最小内容尺寸,中文的最小内容单位是一个汉字,英文的最小内容单位是单词,因此min-content最终宽度是所有这些最小内容单元最长的那个单元宽度;max-content是最大内容宽度,可以理解为文本内容不换行时候的宽度。不过,min-content和max-content在实际开发的时候是不会相对于字符进行尺寸设定的,而是相对于图片或者内联性质的容器元素,比方说容器宽度不确定同时一行最多显示一个容器(min-content),或者所有元素在一行显示(max-content)。

    container{grid-template-columns: repeat(3, min-content);
    }
    

    min-content 关键字可将轨道设置为与其最小内容一样宽或一样高。通常是单词间没有额外空间时的尺寸。如下图:
    在这里插入图片描述

  5. 关键字min-content
    max-content 关键字的作用基本上与 min-content 相反:它根据网格单元格中最大的内容来确定轨道大小。如下图:
    在这里插入图片描述

  6. 关键字auto
    auto 关键字的最大值为 max-content,最小值为 min-content(auto 只有在与其他值混合时才会出现上述行为。如果单独使用 repeat(3, auto),其行为就像我们设置 repeat(3, 1fr) 一样)。

    .container{grid-template-columns: repeat(3, auto 1fr);
    }
    

    在这里,我们将有六列,每一奇数列的宽度设置为 auto。在下面的演示中,我们可以看到,在有足够空间的情况下,带有"auto"文本的 div 将在max-content时达到最大宽度,而 1fr div 则共享剩余空间。当浏览器变窄时,"auto"列继续变窄,直到达到min-content阈值。
    在这里插入图片描述

  7. 关键字auto-fill

    .container {grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
    }
    

    效果如下,默认宽度很宽的情况下,最后会有匿名的格子:
    在这里插入图片描述
    随着尺寸变小,列数会跟着动态变化,同时宽度自动填充Grid容器(因为设置了1fr)。弹性变化效果如图:
    在这里插入图片描述
    当我们使用auto-fill自动填充的时候,repeat()函数是不能和auto一起使用的,例如下面这种写法是无效的:

    .container {/* 无效 */grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)) auto;
    }
    

    但是可以和长度只和百分比值一起使用,例如:

    .container {/* 有效,最后一列的宽度始终为 20% */grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)) 20%;
    }
    
  8. 关键字auto-fit
    auto-fit 与 auto-fill 的行为是相似的,区别在于auto-fit 会把空的匿名格子进行折叠合并,而这个合并的 0px 大小格子可以认为具有单个格子轨道大小调整的功能,对了,其两侧的格子过道也会合并。在 auto-fill 自动填充的时候,如果 Grid容器的尺寸特别的宽,则最后会有一些空的格子占位:
    在这里插入图片描述但是auto-fit自动适应的时候,如果Grid容器的尺寸特别的宽,则最后会有一些空的格子会合并成 1个,且宽度是 0。auto-fit 区别示意:
    在这里插入图片描述

  9. maxmin()函数
    minmax() 函数本身需要两个参数–最小值和最大值,中间用逗号隔开。因此,通过 minmax(),我们可以在灵活的环境中为轨道设置一系列可能的尺寸。
    例如,我们可以将一列设置为 minmax(40px, 100px),这意味着其最小宽度为 40px,最大宽度为 100px。minmax() 的两个参数都可以使用长度值,如 fr、px、em、% 和 ch,以及 min-content、max-content 和 auto。不过,最好至少为一个参数使用长度值,因为关键字不应该同时作为两个参数工作 。
    下面代码设置了五列,每一列的最小宽度为60px,最大宽度为1fr:

    article {grid-template-columns: repeat(5, minmax(60px, 1fr));
    }
    

    minmax() 函数的参数也可以是 min() 或 max() 函数。这两个函数都接收两个参数。min()函数应用两个值中较小的值,而 max() 函数应用较大的值。这在响应式环境中非常有用。

    比如说:

    article {grid-template-columns: repeat(5, minmax(min(60px, 8vw), 1fr));
    }
    

    在这里插入图片描述
    上面的代码设置了五列。在宽屏幕浏览器上,五列的间距均为 1fr。在较窄的设备上,列会越来越窄。一旦达到 60px 和 8vw 之间的较低值,就会停止缩小。

  10. fit-content()函数
    只有一个参数,只能为长度或者百分值<length> | <percentage>。
    其底层原理不过多解释,效果可以描述为:“尺寸由内容决定,内容越多尺寸越大,最小为 min-content,最大不超过限定的尺寸”。

    .container {grid-template-columns: repeat(2, fit-content(100px) 40px) auto;
    }
    

    在这里插入图片描述

网格元素的安放

三种语法:带编号的网格线命名的网格线以及命名的网格区域

带编号的网格线

网格线编号从左上角为 1 开始递增,负数则指向从右下角开始的位置,如下图:
网格线编号从左上角为 1 开始递增,负数则指向从右下角开始的位置

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>网格布局</title><style>.grid-container {display: grid;grid-template-columns: repeat(2, 1fr);grid-template-rows: repeat(4, 1fr);grid-gap: 10px;}.header {grid-column: 1 / 3;grid-row: 1 / 2;}.nav {grid-column: 1 / 3;grid-row: 2 / 3;}.main {grid-column: 1 / 2;grid-row: 3 / 5;}.sidebar-top {grid-column: 2 / 3;grid-row: 3 / 4;}.sidebar-bottom {grid-column: 2 / 3;grid-row: 4 / 5;}.grid-container>div {background-color: #999;}</style>
</head><body><div class="grid-container"><div class="header">Header</div><div class="nav">Nav</div><div class="main">Main</div><div class="sidebar-top">Sidebar Top</div><div class="sidebar-bottom">Sidebar Bottom</div></div>
</body></html>

其中,grid-column 属性是 grid-column-startgrid-column-end 的简写,中间使用 “/” 分隔开。
效果如下:
在这里插入图片描述

span关键字

作为 grid-columngrid-row属性的值,后面跟正整数,表示在前面属性的方向上占据多少个轨道。由于没有指定是具体的哪几行和哪几列,会根据浏览器的布局算法进行布局(这里先不解释)。
以下表示占据两列一行:

.item {grid-column: span 2;grid-row: span 1;
}
命名的网格线

与前面的带编号的命名方式相似,只不过是为那些编号起了名字(就好像学号和姓名一样,虽然有点“倒反天罡”了,但是大致是这样的意思),不过不必要给所有的网格线都起名字,就相当于并不是所有的人都是学生。结合下面的例子:

 .container {display: grid;grid-template-columns: [left-start] 2fr[left-end right-start] 1fr[right-end];grid-template-rows: repeat(4, [row] auto);grid-gap: 1.5em;max-width: 1080px;margin: 0 auto;
} 
header,
nav {grid-column: left-start / right-end;grid-row: span 1;
} 
.main {grid-column: left;grid-row: row 3 / span 2;
} 
.sidebar-top {grid-column: right;grid-row: 3 / 4;
} 
.sidebar-bottom {grid-column: right;grid-row: 4 / 5;
}

在这里插入图片描述

我们把纵向的1、2、3号网格线分别命名为 left-start、left-end(right-start)、right-end,这样我们就可以使用 left-start、left-end(right-start)、right-end代替前面的数字,其语义化更好。
这里有个彩蛋:-start-end 后缀作为关键字,定义了两者之间的区域。如果给元素设置 grid-column: left,它就会跨越从 left-start 到 left-end 的区域
此外,我们还在 repeat()函数中使用了这种写法,由于repeat()函数是用来创建轨道的,我们这里 grid-template-rows: repeat(4, [row] auto)auto 的前面添加 [row]就是在为轨道的前面的网格线起名字,所以导致了最后一根网格线是没有名字的,只有编号 “5”。还注意到 grid-row: row 3 / span 2的操作,虽然我们设置了四条名字一样的网格线,但是我们可以通过“名字 第几条同名线”的组合来定位具体是哪根线。

命名网格区域

不用计算或者命名网格线,直接用命名的网格区域将元素定位到网格中。实现这一方法需要借助网格容器的 grid-template-areas 属性和网格元素的 grid-area 属性。

.container { display: grid; grid-template-areas: "title title""nav nav" "main aside1" "main aside2"; grid-template-columns: 2fr 1fr;grid-template-rows: repeat(4, auto);grid-gap: 1.5em; max-width: 1080px; margin: 0 auto; 
} 
header { grid-area: title;
} 
nav { grid-area: nav; 
} 
.main { grid-area: main; 
} 
.sidebar-top { grid-area: aside1; 
} 
.sidebar-bottom { grid-area: aside2;
}

grid-template-areas 属性使用了一种 ASCII art 的语法,可以直接在 CSS 中画一个可视化的网格形象。该声明给出了一系列加引号字符串,每一个字符串代表网格的一行,字符串内用空格区分每一列。在这个例子中,第一行完全分配给了网格区域 title,第二行则分配给了 nav。接下来两行的左列分配给了 main,侧边栏的板块分别分配给了 aside1 和 aside2。用 grid-area 属性将每个网格元素放在这些命名区域中。
注意:每个命名的网格区域必须组成一个矩形。不能创造更复杂的形状,比如 L或者 U型。
还可以用句点(.)作为名称,这样便能空出一个网格单元。比如,以下代码定义了四个网
格区域,中间围绕着一个空的网格单元。

grid-template-areas: "top top right""left . right""left bottom bottom";

结语

这篇文章已经介绍完网格布局的最基础的部分,也请关注下一篇(实战篇)。感谢大家的支持,如有错误,恳请指出,希望与大家共同进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/425637.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

双三次插值及MATLAB实现

一、双三次插值的概念 双三次插值&#xff08;Bicubic interpolation&#xff09;&#xff0c;又叫双立方插值。在数值分析这个数学分支中&#xff0c;双三次插值是二维空间中最常用的插值方法。在这种方法中&#xff0c;函数f在点 (x0 ,y0) 的值不仅考虑其直接邻接点对其的影响…

Leetcode—1137. 第 N 个泰波那契数【简单】

2024每日刷题&#xff08;160&#xff09; Leetcode—1137. 第 N 个泰波那契数 记忆化搜索实现代码 class Solution { public:int tribonacci(int n) {int zero 0;int one 1;int two 1;if(n 0) {return zero;}if(n 1) {return one;}if(n 2) {return two;}int ans 0;fo…

MATLAB、FPGA、STM32中调用FFT计算频率、幅值及相位差

系列文章目录 文章目录 系列文章目录前言MATLABSTM32调用DSPSTM32中实现FFT关于初相位 FPGA 前言 最近在学习如何在STM32中调用FFT MATLAB 首先对FFT进行一下说明&#xff0c;我们输入N个点的数据到FFT中&#xff0c;FFT会返回N个点的数据&#xff0c;这些数据都是复数&#…

【ACM出版】第三届人工智能与智能信息处理国际学术会议(AIIIP 2024,10月25-27)

第三届人工智能与智能信息处理国际学术会议&#xff08;AIIIP 2024&#xff09; 2024 3rd International Conference on Artificial Intelligence and Intelligent Information Processing 中国-天津 | 2024年10月25-27日 | 会议官网&#xff1a;www.aiiip.net 官方信息 会议…

智能客服自动化新体验:Function Calling让问题处理更高效

Function Calling作为一项创新功能&#xff0c;正深刻改变着大模型与实际产业之间的融合方式。它不仅**为大模型增添了与外部工具和API无缝连接的能力&#xff0c;助力大模型向实际产业落地迈进&#xff1b;还极大地简化了开发者与模型间的交互流程&#xff0c;使得开发者从模型…

Leetcode—1184. 公交站间的距离【简单】

2024每日刷题&#xff08;161&#xff09; Leetcode—1184. 公交站间的距离 实现代码 class Solution { public:int distanceBetweenBusStops(vector<int>& distance, int start, int destination) {int clockwise 0;int counterclockwise 0;if(start > desti…

RabbitMQ(高阶使用)死信队列

文章内容是学习过程中的知识总结&#xff0c;如有纰漏&#xff0c;欢迎指正 文章目录 一、什么是死信队列&#xff1f; 二、死信队列使用场景 三、死信队列如何使用 四、打车超时处理 1.打车超时实现 以下是本篇文章正文内容 一、什么是死信队列&#xff1f; 先从概念解释上搞…

linux入门到实操-4 linux系统网络配置、连接测试、网络连接模式、修改静态IP、配置主机名

教程来源&#xff1a;B站视频BV1WY4y1H7d3 3天搞定Linux&#xff0c;1天搞定Shell&#xff0c;清华学神带你通关_哔哩哔哩_bilibili 整理汇总的课程内容笔记和课程资料&#xff08;包含课程同版本linux系统文件等内容&#xff09;&#xff0c;供大家学习交流下载&#xff1a;…

【C++算法】前缀和

前缀和 题目链接 前缀和https://www.nowcoder.com/practice/acead2f4c28c401889915da98ecdc6bf?tpId230&tqId2021480&ru/exam/oj&qru/ta/dynamic-programming/question-ranking&sourceUrl%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%2…

CefSharp_Vue交互(Element UI)_WinFormWeb应用---设置应用透明度(含示例代码)

一、界面预览 1.1 设置透明(整个页面透明80%示例) 限制输入值:10-100(数字太小会不好看见) 1.2 vue标题栏 //注册类与js调用 (async function(

【Linux基础】冯诺依曼体系结构操作系统的理解

目录 前言一&#xff0c;冯诺依曼体系1. 为什么有内存结构?2. 对硬件中数据流动的再理解 二&#xff0c;操作系统(Operator System)1. 概念2. 操作系统结构的层状划分3. 操作系统对硬件管理的理解4. 用户与操作系统的关系的理解5. 系统调用和库函数的关系6. 为什么要有操作系统…

eclipse使用 笔记02

创建一个项目&#xff1a; 【File-->New-->Dynamic Web Project】 进入页面&#xff1a; Project name为项目命名 Target runtime&#xff1a;选择自己所对应的版本 finish创建成功&#xff1a; 创建成功后的删除操作&#xff1a; 创建前端界面&#xff1a; 【注意&a…

RT-DETR改进策略:BackBone改进|Swin Transformer,最强主干改进RT-DETR

摘要 在深度学习与计算机视觉领域,Swin Transformer作为一种强大的视觉Transformer架构,以其卓越的特征提取能力和自注意力机制,正逐步引领着图像识别与检测技术的革新。近期,我们成功地将Swin Transformer引入并深度整合至RT-DERT(一种高效的实时目标检测与识别框架)中…

数据结构(7.3_2)——平衡二叉树

平衡二叉树&#xff0c;简称平衡树(AVL树)----树上任一结点的左子树和右子树的高度之差不超过1. 结点的平衡因子左子树高-右子树高 //平衡二叉树结点 typedef struct AVLNode {int key;//数据域int blalance;//平衡因子struct AVLNode* lchild, * rchild; }AVLNode,*AVLTree; …

【开放词汇检测】基于MMDetection的MM-Grounding-DINO实战

文章目录 摘要安装基础环境新建虚拟环境安装pytorch安装openmim、mmengine、mmcv安装 MMDetection验证安装配置OV-DINO环境 MMDetection的MM-Grounding-DINO详细介绍测试结果Zero-Shot COCO 结果与模型Zero-Shot LVIS ResultsZero-Shot ODinW&#xff08;野生环境下的目标检测&…

【网络安全】Node.js初探+同步异步进程

未经许可,不得转载。 文章目录 Node.js 基础介绍NPM 包管理安装同步与异步fs 模块示例child_process 模块Node.js 基础介绍 Node.js 是运行在服务器端的 JavaScript 环境。它基于 Chrome 的 V8 引擎,拥有高效的执行性能。Node.js 采用事件驱动的 I/O 模型,使得它在处理高并…

Java笔记 2 java概述和基础知识

第2章 Java概述与基础知识 Java 历史 Java技术体系平台 Java 重要特点 Java 虚拟机[JVM] JDK&#xff0c;JRE JDK 基本介绍 JRE 基本介绍 JDK、JRE 和JVM 的包含关系 Java 快速入门 注意细节 Java 转义字符 Java 常用的转义字符 注释(comment) Java 中的注释类型 关于文档注释 …

java多线程编程示例

程序功能 程序展示了 Java 中如何使用多线程来并行执行任务。具体功能如下&#xff1a; 程序创建了三个线程&#xff0c;每个线程执行相同的任务类 Task。 每个线程在运行时输出自身名称&#xff0c;并模拟执行五次任务&#xff0c;每次任务间隔 1 秒。 主线程在启动这三个线程…

「Next.js中文文档」网站发布

大家好&#xff0c;我是程普&#xff08;weijunext&#xff09;&#xff0c;我联合“阿伟dev”搭建了一个「Next.js 中文文档」网站&#x1f447; 这个网站我们设计得很特别&#xff1a; 样式很特别 我们模仿 Next.js 官方网站样式&#xff0c;努力做到除了语言不同&#xff…

基于PHP的丽江旅游管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的丽江旅游管理系统 一 介绍 此丽江旅游系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈&#xff1a;phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销…