flex 每行3个。flex一行显示3个。flex 每行显示4个自适应排列。flex每行固定几个布局。css 格子栏效果,css实现框框效果。模板。小屏下一行显示4个,大屏下一行显示5个 电脑版发表于:2019/11/16 21:31 [TOC] ### 效果如下,每行显示3个自适应排列 ![](https://img.tnblog.net/arcimg/aojiancc2/60cc4a06d05c4bfaaea042653ad0bb46.png) 其实也很简单,只需要设置父元素flex布局,然后设置一下换行排列,flex-wrap: wrap。然后子元素设置一下宽度占1/3就可以了。其他什么间距这些微调就行了。这是这种方式主要适用于里边只是文字内容的形式,显示的时候能看到的宽度就是文字的长度,如果要显示固定的那种一块一块的效果就不是太适用了,这个下面有讲其他方法实现。 tn2> 使用grid布局可以更简单更通用,可以参考:https://www.tnblog.net/aojiancc2/article/details/8231 #### 代码如下 html代码: ``` <div class="labroom-level"> <!-- 优良中差分别为excellent,good ,middle,poor --> <div class="labroom-level-item labroom-level-excellent"> <div class="labroom-level-title"> 优 </div> <div class="labroom-level-box"> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计XXXX》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计MMM》</span> <span class="course-completepr">99%</span> </div> </div> </div> <div class="labroom-level-item labroom-level-middle"> <div class="labroom-level-title"> 及格 </div> <div class="labroom-level-box"> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计XXXX》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计MMM》</span> <span class="course-completepr">99%</span> </div> </div> </div> <div class="labroom-level-item labroom-level-poor"> <div class="labroom-level-title"> 差 </div> <div class="labroom-level-box"> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计XXXX》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计》</span> <span class="course-completepr">99%</span> </div> <div class="labroom-level-box-course"> <span class="course-name">《Photoshop应用设计MMM》</span> <span class="course-completepr">99%</span> </div> </div> </div> </div> ``` 样式:样式用了lang="scss",可以写层级 ``` .labroom-level-item { margin-top: 20px; .labroom-level-title { background: #F5F9FF; height: 45px; line-height: 45px; padding: 0 20px; font-size: 16px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; } .labroom-level-box { border: 1px solid #EAEEF0; border-top: none; padding-top: 10px; padding-bottom: 20px; min-height: 20px; display: flex; flex-wrap: wrap; padding-left: 13px; } .labroom-level-box-course { // 直接让宽度为33.33%就可以每行显示3快了 width: 33.33%; margin-top: 10px; .course-name { color: #333339; font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; } } } // 优秀时候的字体颜色与字体颜色 .labroom-level-excellent { color: #3E91F7; .labroom-level-title { background: #F5F9FF; } } // 及格时候的字体颜色与背景颜色 .labroom-level-middle { color: #F19537; .labroom-level-title { background: #FFF9F0; } } // 不及格时候的字体颜色与背景颜色 .labroom-level-poor { color: #E57470; .labroom-level-title { background: #FFF4F4; } } ``` ### 小屏下一行显示4个,中屏下一行显示5个,大屏下一行显示6个 <img src="https://img.tnblog.net/arcimg/aojiancc2/e8b875edb0d8402db3e8dde60779c75d.jpg" style="width:666px;height:auto;"> 其实和上面那种类似,在上面的基础上做一个屏幕适配就行了,在多大的分辨率下单独设置一下就行了 ``` // 小屏下一行显示4个 @media screen and (min-width:100px) { .menuItem { width: 25%; margin-bottom: 20px; } } // 中屏一行显示5个 写到下面会覆盖掉上面的样式 @media screen and (min-width:1366px) { .menuItem { width: 20%; margin-bottom: 20px; } } // 大屏一行显示6个。写到下面会覆盖掉上面的样式 @media screen and (min-width:1799px) { .menuItem { width: 16.66%; margin-bottom: 20px; } } ``` 贴一下完整一点的代码吧 ``` <template> <div class="my-app-container"> <div class="content"> <el-card v-if="schoolList.length > 0" class="box-card mymenucard"> <div slot="header" class="clearfix"> <span>教学看板</span> </div> <div class="menuItemWrap"> <div v-for="(item, index) in schoolList" :key="index" class="menuItem" @click="jumpSchool(item.schoolID)"> <div class="menuItemImg" /> <div class="menuItemDesc">{{ item.schoolName }}</div> </div> </div> </el-card> </div> </div> </template> <script> import { mapGetters } from 'vuex' export default { // 组件名字 name: 'ApplicationCenter', data() { return { schoolList: [], permission_routes_show: [] } }, mounted() { this.getSchoolListByTeacher() this.handlerMenus() }, computed: { ...mapGetters([ 'permission_routes' ]) }, // 组件方法 methods: { } } </script> <style scoped="scoped" lang="scss"> .my-app-container { padding-left: 20px; padding-right: 20px; background: #F8F8F8; .content { // margin-top: 20px; .mymenucard { margin-top: 20px; margin-bottom: 20px; } .menuItemWrap { display: flex; flex-wrap: wrap; // justify-content: space-between; } .menuItem { font-size: 14px; display: flex; cursor: pointer; // background-color: #ffabcd; .menuItemImg { height: 43px; width: 43px; // background-image: url('~@/assets/imgs/applicationCenter/applicationCenter1.png'); background-size: cover; } .menuItemImgBasic { height: 43px; width: 43px; background-size: cover; } .menuItemDesc { height: 43px; line-height: 43px; margin-left: 9px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } // 没有图标的循环换一下图标 .menuItem:nth-child(6n-1) { .menuItemImg { background-image: url('~@/assets/imgs/applicationCenter/applicationCenter5.png'); } } .menuItem:nth-child(6n-2) { .menuItemImg { background-image: url('~@/assets/imgs/applicationCenter/applicationCenter4.png'); } } .menuItem:nth-child(6n-3) { .menuItemImg { background-image: url('~@/assets/imgs/applicationCenter/applicationCenter3.png'); } } .menuItem:nth-child(6n-4) { .menuItemImg { background-image: url('~@/assets/imgs/applicationCenter/applicationCenter2.png'); } } .menuItem:nth-child(6n-5) { .menuItemImg { background-image: url('~@/assets/imgs/applicationCenter/applicationCenter1.png'); } } .menuItem:nth-child(6n) { .menuItemImg { background-image: url('~@/assets/imgs/applicationCenter/applicationCenter6.png'); } } // 小屏下一行显示4个 @media screen and (min-width:100px) { .menuItem { width: 25%; margin-bottom: 20px; } } // 中屏一行显示5个 写到下面会覆盖掉上面的样式 @media screen and (min-width:1500px) { .menuItem { width: 20%; margin-bottom: 20px; } } // 大屏一行显示6个。写到下面会覆盖掉上面的样式 @media screen and (min-width:1799px) { .menuItem { width: 16.66%; margin-bottom: 20px; } } } } </style> ``` ### flex 实现每行4个(带格子方块的),自适应排列 上面的实现方法一般主要适用里边都是文字的情况,但是我要显示类似这种一块一块的效果,就不太适用了,比如下面的效果 ![](https://img.tnblog.net/arcimg/aojiancc2/9ddcfbc541f741dda8d51972a115af01.png) #### 实现如下 ``` <template> <div class="app-container"> <div class="shcoolItem">重庆应用职业技术学院</div> <div class="shcoolItem">重庆应用职业技术学院</div> <div class="shcoolItem">重庆应用职业技术学院</div> <div class="shcoolItem">重庆应用职业技术学院</div> <div class="shcoolItem">重庆应用职业技术学院</div> <div class="shcoolItem">重庆应用职业技术学院</div> <div class="shcoolItem">重庆应用职业技术学院</div> </div> </template> <script> export default { // 组件名字 name: 'SchoolChangeDialog', // 组件参数 props: { percentage: { type: Number, default: 0 }, title: { type: String, default: '' }, }, data() { return { } }, mounted() { }, // 组件方法 methods: { } } </script> <style scoped="scoped" lang="scss"> .app-container { margin-top: 20px; margin-bottom: 100px; padding-left: 10px; padding-right: 10px; display: flex; flex-wrap: wrap; justify-content: space-between; .shcoolItem { // width: 240px; height: 46px; background: rgba(0, 150, 255, 0.15); border: 1px solid #0E66A1; border-radius: 4px; font-size: 16px; font-family: Microsoft YaHei; font-weight: 400; color: #FFFFFF; text-align: center; line-height: 46px; // 这里如果某些情况下有问题,比如百分比不是相对于父级而是整个页面了,可以调整为width:23%试试 flex: 0 0 23%; /* 动态计算间距 */ margin-right: calc(8% / 3); // margin-bottom: calc(5% / 3); margin-bottom: 20px } /* 去除每行尾的多余边距 */ .shcoolItem:nth-child(4n) { margin-right: 0; } /* 使最后一个元素的边距填满剩余空间 */ .shcoolItem:last-child { margin-right: auto; } } </style> ``` #### 父容器主要的样式就是 ``` display: flex; flex-wrap: wrap; justify-content: space-between; ``` 这个没什么好说的 #### 子元素主要的样式就是 ``` .shcoolItem { flex: 0 0 23%; /* 动态计算间距 */ margin-right: calc(8% / 3); // margin-bottom: calc(5% / 3); margin-bottom: 20px } /* 去除每行尾的多余边距 */ .shcoolItem:nth-child(4n) { margin-right: 0; } /* 使最后一个元素的边距填满剩余空间 */ .shcoolItem:last-child { margin-right: auto; } ``` >其中的flex: 0 0 23%,表示每个子元素占宽度的23%。 >其中的margin-right: calc(8% / 3),表示每块右边距离是8%除以3。为什么是8%呢,因为每块是23%,4块就是92%,还剩下8%的宽度,让他们之间均分,就是8%/3了,至于为什么不是除以4因为4个元素中间是3块空白。如果每块占用的宽度是24,flex: 0 0 24%,那么间距的计算就不是8%/3,而是4%/3,因为每块占24%,4块就是96%了,就还剩4%来做他们之间的间距了。 **其实感觉使用上面文字的那种实现方法也可以** 文字的宽度其实不是固定的应该是文字有多宽块块就有多宽,但是为了让一行固定显示几个就固定一下宽度,比如一个块的宽度是25%那么就是一行显示4个,其实宽度固定实现起来还要方便一些,比如下面这种情况一行固定显示4个还要有点间距,我们其实可以这样。 每块的宽度设置成23%,或者是24%都可以,然后在设置一下: ``` justify-content: space-between ``` 它就会自动分配剩下的空间给每块之间的间隔了,感觉实现起来比刚刚上面提到的方法还简单很多,就设置一下宽度和justify-content即可。 ### flex 实现每行3个(带格子方块的),自适应排列 tn2> 和上面那个实现方法一样,用的时候方便直接复制。 设计图(选中的效果请忽略,主要是每行三个的布局): ![](https://img.tnblog.net/arcimg/aojiancc2/95d6698dd1d44a839092c98866942d52.png) **标签:** ``` <view class="completeInfo"> <view class="completeItem" v-for="(item, index) in 17" :key="index">张三三</view> </view> ``` **样式:** ``` .completeInfo { background-color: #fff; display: flex; flex-wrap: wrap; justify-content: space-between; .completeItem { flex: 0 0 31%; /* 动态计算间距,除以2是因为3个元素中间只有2个缝隙 */ margin-right: calc(7% / 2); margin-bottom: 15rpx; height: 65rpx; background: #F6F6F6; font-size: 26rpx; color: #313960; text-align: center; line-height: 65rpx; } /* 去除每行尾的多余边距 */ .completeItem:nth-child(3n) { margin-right: 0; } /* 使最后一个元素的边距填满剩余空间 */ .completeItem:last-child { margin-right: auto; } } ``` ### flex 实现图片一行显示4个,自适应排列 tn2> 和上面那两个实现方法逻辑一样的 **效果图:** ![](https://img.tnblog.net/arcimg/aojiancc2/0e42518f0b9e4f7bb62d381b1d058e02.png) **标签:** ``` <view class="image-content"> <image class="imgitem" @click="previewImg(0)" mode="scaleToFill" src="https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg"> </image> <image class="imgitem" @click="previewImg(1)" src="https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg"> </image> <image class="imgitem" @click="previewImg(2)" src="https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg"> </image> <image class="imgitem" @click="previewImg(3)" src="https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg"> </image> <image class="imgitem" @click="previewImg(4)" src="https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg"> </image> <image class="imgitem" @click="previewImg(5)" src="https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg"> </image> </view> ``` **样式:** ``` .image-content { margin-top: 10px; display: flex; flex-wrap: wrap; justify-content: space-between; .imgitem { flex: 0 0 23%; /* 动态计算间距 */ margin-right: calc(8% / 3); margin-bottom: 15rpx; height: 200rpx; background: #F6F6F6; border-radius: 0px 0px 0px 0px; opacity: 1; } /* 去除每行尾的多余边距 */ .imgitem:nth-child(4n) { margin-right: 0; } /* 使最后一个元素的边距填满剩余空间 */ .imgitem:last-child { margin-right: auto; } } ``` ### 如果一行显示的数量不固定,控制不同分辨率下显示不同的个数 参考:https://www.tnblog.net/aojiancc2/article/details/8176 ### 其实多列多行的情况,使用grid布局会更好实现一点,grid布局是真正的二维布局 tn2>grid布局的使用记录,可参考考:https://www.tnblog.net/aojiancc2/article/details/8231