TNBLOG
首页
博客
视频
资源
问答
猿趣
手机
关于
搜索
收藏
便签
笔记
消息
创作
登录
剑轩
故如虹,知恩;故如月,知明
博主信息
排名
6
文章
6
粉丝
16
评论
8
文章类别
CSS
15篇
微服务
41篇
Git
14篇
.NET
102篇
移动开发
33篇
软件架构
23篇
.NET Core
119篇
.NET MVC
11篇
英语
3篇
随笔
86篇
Bootstrap
3篇
Redis
21篇
编辑器
10篇
Js相关
15篇
虚拟化
8篇
更多
Oracle
7篇
Python
14篇
数据库
26篇
EF
17篇
微信
3篇
前端
151篇
消息队列
6篇
docker
41篇
多线程
1篇
Java
4篇
软件基础
2篇
C++
2篇
WCF
7篇
Linux
7篇
nginx
5篇
K8S
9篇
ABP
2篇
最新文章
最新评价
{{item.articleTitle}}
{{item.blogName}}
:
{{item.content}}
关于我们
ICP备案 :
渝ICP备18016597号-1
网站信息:
2018-2024
TNBLOG.NET
技术交流:
群号656732739
联系我们:
contact@tnblog.net
欢迎加群
欢迎加群交流技术
原
flex实现一行显示n个数量的布局,不同屏幕宽度下显示不同的数量,自适应一行显示的个数
1682
人阅读
2021/8/15 18:02
总访问:
3966720
评论:
0
收藏:
0
手机
分类:
前端
[TOC] ## 要实现的效果如下: ![](https://img.tnblog.net/arcimg/aojiancc2/c5a7ff9962a44d0e93b3da1b3245c531.png) #### 其实原理也非常简单,父元素主要是 主要就是设置一个flex布局,然后flex-wrap设置为需要换行 ``` .app-container { display: flex; flex-wrap: wrap; } ``` #### 子元素主要就是设置一个宽度 子元素主要就是设置一个宽度,比如要一行显示5个就是20%,一行显示8个就是100/8=12.5%,以此类推就行了。至于其他margin-top,高度这些就是辅助样式而已。 ``` .shcoolItem { width: 20%; margin-top: 10px; margin-bottom: 20px; height: 100px; background: #ffabcd; } ``` html结构这种: ``` <div class="app-container"> <div class="shcoolItem"></div> <div class="shcoolItem"></div> <div class="shcoolItem"></div> </div> ``` #### 但是目前这种方式虽然每个子元素可以均分宽度了,一行显示完就换行,但是每块之间就没有一点间距 如果颜色设置成一样我们都看不出来,看到的就是一块,所以我们可以把每块设置一个不一样的颜色来测试 ``` <div class="app-container"> <div class="shcoolItem "></div> <div class="shcoolItem shcoolItemColor2"></div> <div class="shcoolItem shcoolItemColor3"></div> <div class="shcoolItem "></div> <div class="shcoolItem shcoolItemColor2"></div> <div class="shcoolItem shcoolItemColor3"></div> </div> <style > .app-container { display: flex; flex-wrap: wrap; } .shcoolItem { width: 20%; height: 100px; background: #ffabcd; } .shcoolItemColor2{ background: #abcdff; } .shcoolItemColor3{ background: #00cc66; } </style> ``` 效果如下,可以看到是没有间距的: ![](https://img.tnblog.net/arcimg/aojiancc2/3897a6794b36472aaa262061f9a9d585.png) ## 如何设置间距宽度呢 如果直接设置margin这种间距就会影响每行的显示了,因为我们使用了固定的宽度了,比如固定了宽度20%,设置了margin的话,每个子元素在占20%每行就显示不了5个了,我们就不好去控制它了,那么我们就不改子元素,我们直接去给子元素里边在加子元素,我们把样式设置到子元素里边的元素就行了撒。 **html结构变成了这样:** 子级里边在加了子级 ``` <div class="container"> <div class="app-container"> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> </div> </div> ``` **我们在子元素里边的子级去设置一个margin-left,就会有间距了** ``` .shcoolItemWaper { /* 要设置这种间距要设置到flex子元素的里边的元素,不能直接设置到flex子元素里边, 因为如果子元素算上了间距,就不能控制均分了 */ margin-left: 20px; background: #ffabcd; height: 100px; } ``` 效果如下: <img src="https://img.tnblog.net/arcimg/aojiancc2/ee4e5100eee04abba9339e2d048f3ef4.png" style="width:666px;height:auto;"> 可以看到我们左边好想并没有对齐,因为我们给每个子元素都设置了margin-left,所以就没有对齐,要对齐也非常简单在容器那边设置一个-20px就行了 ``` .app-container { display: flex; flex-wrap: wrap; margin-left: -20px; } ``` tn2>这里我们利用flex子元素里边的子元素来控制了间距,其实每个flex的子元素的宽度还是20%,每个flex子元素还是紧紧的挨到一起的,我们只是利用了flex的子元素里边元素的margin值来实现的,这样就不会影响每个flex元素的宽度,这样就比较好控制每行显示的个数了 ## 如果一行不是显示固定的个数,宽度不写死,针对不同的屏幕下在去写宽度就行了 利用`@media`去在不同分辨率下设置宽度就行了 #### 整体的代码如下(这里可以直接复制出来看效果) ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="container"> <div class="app-container"> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> <div class="shcoolItem"> <div class="shcoolItemWaper"></div> </div> </div> </div> </body> </html> <style> body { padding: 0; margin: 0; } .container { width: 700px; margin: 20px auto; border: 2px solid #acbdff; } .app-container { display: flex; flex-wrap: wrap; margin-left: -20px; } .shcoolItem { /* 如果一行不是显示固定的个数,这里宽度不写死,针对不同的屏幕下在去写宽度就行了 */ /* width: 20%; */ margin-top: 10px; margin-bottom: 20px; height: 100px; } .shcoolItemWaper { /* 要设置这种间距要设置到flex子元素的里边的元素,不能直接设置到flex子元素里边, 因为如果子元素算上了间距,就不能控制均分了 */ margin-left: 20px; background: #ffabcd; height: 100px; } /* 小屏下一行显示5个 */ @media screen and (min-width:100px) { .shcoolItem { width: 20%; } } /* 中屏一行显示6个 写到下面会覆盖掉上面的样式 */ @media screen and (min-width:1430px) { .shcoolItem { width: 16.66%; } } /* 大屏一行显示7个。写到下面会覆盖掉上面的样式 */ @media screen and (min-width:1799px) { .shcoolItem { width: 14.2857%; } } /* 超大屏一行显示8个。写到下面会覆盖掉上面的样式 */ @media screen and (min-width:1899px) { .shcoolItem { width: 12.5%; } } </style> ``` 小屏下一行显示5个: ![](https://img.tnblog.net/arcimg/aojiancc2/960264243d4d418f9e1b91a8b0315c1f.png) 随便改一下宽度,默认一下大一点的分辨率一行显示6个的效果: ![](https://img.tnblog.net/arcimg/aojiancc2/57af3b3ba0534085b1b298411a37cf62.png) ## 最开始贴的效果图,vue中的写法 最开始贴的效果图是在vue中的实现的,其实样式写法也是一样的,只是里边flex子元素里边的元素信息多一点,包含图片,描述等,贴一下大致代码 ``` <template> <lab-nav class="course-resources"> <div class="course-box"> <div v-for="(item, index) in courseData" :key="index" class="course-box-item" @click="goCourseDetails(item)"> <div class="course-box-item-waper"> <div class="img-waper"> <img :src="'/oss/api/ImageViewer/' + item.pic + '.jpg?percent=0.6&quality=80&od=true'"> </div> <div class="title courseName">{{ item.courseName }}</div> <div class="process-bar"> <el-progress :stroke-width="10" :percentage="Number((item.process * 100).toFixed(2))" /> </div> </div> </div> </div> </lab-nav> </template> <script> import LabNav from './components/Nav/nav.vue' import subsys_lab from '../../services/subsys_lab.js' export default { components: { LabNav }, data() { return { loadCourseParam: { PageIndex: 1, PageSize: 10000, KeyWord: '', mjdid: this.$route.params.type }, courseData: [] } }, watch: { '$route': 'loadCourseData' }, mounted() { this.loadCourseData() }, methods: { } } </script> <style scoped="scoped" lang="scss"> .course-resources { .course-box { display: flex; flex-wrap: wrap; margin-left: -20px; .course-box-item { // 宽度不写死,针对不同的屏幕下在去写宽度 //width: 20%; min-width: 160px; .course-box-item-waper:hover { box-shadow: 0px 0px 8px 0px #d3d3d3; cursor: pointer; // 图片手指上去放大 img { object-fit: cover; -webkit-transition: all .2s; transition: all .2s; -webkit-transform: scale(1.4); transform: scale(1.4); } } .course-box-item-waper { background-color: #fff; padding-bottom: 10px; margin-left: 20px; margin-bottom: 20px; .img-waper { overflow: hidden; } img { width: 100%; height: 160px; height: auto; } .title { font-size: 13px; font-family: Microsoft YaHei; font-weight: 400; color: #393939; padding: 5px; } .process-bar { padding: 5px; } } } // 小屏下一行显示5个 @media screen and (min-width:100px) { .course-box-item { width: 20%; } } // 中屏一行显示6个 写到下面会覆盖掉上面的样式 @media screen and (min-width:1430px) { .course-box-item { width: 16.66%; } } // 大屏一行显示7个。写到下面会覆盖掉上面的样式 @media screen and (min-width:1799px) { .course-box-item { width: 14.2857%; } } // 超大屏一行显示8个。写到下面会覆盖掉上面的样式 @media screen and (min-width:1899px) { .course-box-item { width: 12.5%; } } } // 下面的文字宽度超过了出现省略号 .courseName { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } </style> ``` ## 备注,一行固定显示几个等更简单的写法 上面的实现方法只是一种实现方法而已,在很多情况下其实可以有更简单的实现,比如如果一行固定显示4个这种,布局就直接写两级就行了,不用子元素里边在去增加元素来控制。贴一下其他flex布局的应用技巧。 #### 如果只有一行的显示的话参考这个,写法比较简洁 flex 实现等宽布局且间隔相等的小技巧 https://www.tnblog.net/aojiancc/article/details/7975 #### 如果一行固定显示4个这种,布局就直接写两级就行了 参考这个里边的:flex 实现每行4个,自适应排列 https://tnblog.net/aojiancc2/article/details/7904 ### flex布局一行显示多个。flex布局固定显示n个,自适应布局 https://www.tnblog.net/aojiancc6/article/details/8094
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
👈{{preArticle.title}}
👉{{nextArticle.title}}
评价
{{titleitem}}
{{titleitem}}
{{item.content}}
{{titleitem}}
{{titleitem}}
{{item.content}}