flex布局优化(两端对齐,从左至右)
后台-插件-广告管理-内容页头部广告(手机) |
文章目录
- 前言
- 方式一 nth-child
- 方式二 gap属性
- 方式三 设置margin左右两边为负值
- 方式四 在最后面添加超过一行数量的空标签
- 总结
前言
flex布局是前端常用的布局方式之一,但在使用过程中,我们总是感觉不太方便,因为日常开发中,大多数时候,我们想要的效果是这样的
即左右两端对齐并顶满,小盒子左右间距一致,并且从左至右排布。
今天主要就来讨论,通过css,有几种方式来实现,以及它们的优缺点。
方式一 nth-child
<template> <div class="main"> <div class="flex-box"> <div class="item-box">...div> ... div> div> template>- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
优点:实现了我们想要的布局方案,代码量也并不复杂,基本没有兼容性的问题。
缺点1:当遇到下面这种情况时,该设置将会失效。
<template> <div class="main"> <div class="flex-box"> <div class="item-box">...div> <div class="item-box" style="display:none;">div> div> div> template>- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这是因为nth-child是按照子盒子的个数来设置的,虽然其中一部分子盒子消失了,但它的元素依然存在,个数并没有变。
缺点2: 不够灵活,如果在不同屏幕分辨率下,每行个数不一样(做响应式的时候经常会遇见这种情况),需要在不同分辨率下,多写一套样式代码。
@media screen and (max-width: 991px) { .flex-box { display: flex; // 设置成为flex模式 flex-wrap: wrap; // 允许换行 } .item-box { width: 48%; // 以2个一行为例,有2个子盒子,1个间距 margin-right: 4%; // 1 * 4 + 2 * 48 = 100 margin-bottom: 20px; // 行与行之间也要设置边距。 } // 如果一行是2个就是 2 + 2n .item-box:nth-child(2 + 2n) { // 当n为0时,即表示第一行最后一个元素,不需要右外边距,否则就超出 100%了。 margin-right: 0 !important; } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
方式二 gap属性
.flex-box { display: flex; // 设置成为flex模式 flex-wrap: wrap; // 允许换行 gap: 4%; // 设置间距为4% } .item-box { width: 22%; // 以4个一行为例,有4个子盒子,3个间距 margin-bottom: 20px; // 行与行之间也要设置边距。 }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
优点: 显而易见,这种方式的代码量更少,更方便,并且不存在方式一的缺点1,即display:none;不会造成影响。
缺点1:gap目前还是一个很新的属性,对浏览器的兼容性并不高,尤其是不兼容ie11,如果项目对浏览器没有兼容性要求,可以使用gap,当然也可以换一种布局方式,display:grid;
缺点2:当然这种方式也需要对不同分辨率的设配,额外多写一套代码,但相对来说,也轻松许多。
方式三 设置margin左右两边为负值
.flex-box { display: flex; // 设置成为flex模式 flex-wrap: wrap; // 允许换行 margin: 0 -2% 0 -2% // 间距为4% } .item-box { width: 21%; // 以4个一行为例,有4个子盒子,4个间距 4 * 21 + 4 * 4 = 100 margin: 0 2% 20px 2%; // 左右两边各2%,所以间距为4% }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
优点:兼容性很好,能够兼容ie11,并且不存在display:none;时的问题。
缺点1:代码略微有些复杂,需要合理安排盒子宽度和间距的宽度,与前面的两种方式不同间距数量和盒子数量一致。需要分别设置左边距和右边距。
缺点2:需要对不同分辨率的设配,额外多写一套代码。
方式四 在最后面添加超过一行数量的空标签
<template> <div class="main"> <div class="flex-box"> <div class="item-box">...div> ... <div class="item-empty">div> <div class="item-empty">div> <div class="item-empty">div> <div class="item-empty">div> div> div> template>- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
如上代码所示,我打算弄一行四列,所以我在最后面加了四个空标签
.flex-box { display: flex; // 设置成为flex模式 flex-wrap: wrap; // 允许换行 justify-content: space-between; // 为了让两边对齐 } .item-box { width: 22%; // 以4个一行为例,有4个子盒子,只要五个盒子加起来超过100%,能换行就行 margin-bottom: 20px; // 行与行之间也要设置边距。 } .item-empty { width: 22%; // empty保持跟真实的item一样的宽度 height: 1px; // 高度可以给一点,如果0px也行,那就0px }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
这种方式也有缺点,就是必须得渲染empty dom,但这点缺点跟实际使用的感觉比较起来,也可以忽略不计。
总结
四种方式中,第四种最简单,第二种方式比较简单简单,但兼容性有限;第一种方式代码量不少,兼容性适中,而且display:none;的问题严重,最后一种方式,最推荐,虽然有一些计算,并且也要合理分配宽度,但其兼容性最好,基本没啥场景不能适用,正所谓一招鲜,吃遍天。
至于缺点2,面对不同分辨率,每行数量会变化的问题,目前没有特别好的解决方案,都需要额外一套样式代码才能解决。
当然,你可以通过使用scss或者less,弄一个for循环,从一行2个到 10个 进行样式的封装,这样使用的时候,直接使用类名即可,比如 flex-row-6,flex-row-4等。
@for $i from 2 through 10 { .flex-row-#{$i} { display: flex; flex-wrap: wrap; .item { width: calc(96% / #{$i}) !important; margin-right: calc(4% / #{$i - 1}) !important; margin-bottom: 20px; } .item:nth-child(#{$i}n + #{$i}) { margin-right: 0 !important; } } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
好了,以上就是这个问题的全部内容了,你可以根据实际情况选择一种解决方案。都看到这儿了,点赞,关注,收藏来一波吧。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |