《uni-app》移动端纯CSS实现不等高的瀑布流效果

在这里插入图片描述


前言

前两天无意中看到朋友在玩小红书,第一眼就被其瀑布流的布局给吸引住了,感觉非常有意思,之前知道有这种布局,但大多数都是在web端,移动端上还是首次见到,因此特别想试试~
这一章节,玩一点好玩的,移动端或者直接说uni-app能否使用 纯CSS 实现瀑布流的布局效果~ 我们知道,不等高的瀑布流布局可以给用户造成视觉上的错位,非常具有美感,实际上绝大多数项目中的的瀑布流都是借助于JavaScript实现的,通过JavaScript动态计算每一个DOM的尺寸与坐标,最终实现布局,毫无疑问,这种就是目前的最优解;
但是,布局这东西不应该是CSS的领域么,那么 纯CSS 能不能实现呢,我觉得是可以的,虽然有不少问题无法解决…

示例

可能会有小伙伴问,什么是瀑布流布局,简单看两种示例吧,一看就明白了的

WEB端示例

在这里插入图片描述

移动端示例

在这里插入图片描述


这种就是不等高的瀑布流布局,还是比较一目了然的;

瀑布流实现

先看一下原始状态吧,原始状态的图片效果如下

在这里插入图片描述

第一种: flex

flex布局作为现代前端开发最常用的布局方式,那么flex能不能实现瀑布流呢,答案是可以的,虽然不完美,但确实是实现了

核心代码

核心利用的就是 flex的纵向布局,以及当超出高度时自动换行,也就是这两行代码

flex-direction: column;
flex-wrap: wrap;

以及当纵向排序而非横向排序时必须借助 order属性进行重新排序;

order:1

实现

我们知道,flex 默认时沿着X轴进行排布的,并且超出后也不会换行,即是设置了flex-wrap: wrap; 也是这种,如下图展示

在这里插入图片描述


并且,还会有一个致命的问题,即同一行的高度是保持一致的,它并 不会因为其中一张高度低下方的图片就自动补上空缺的位置,具体细节可以参考下图

在这里插入图片描述


既然不会自动补上空缺,那是不是就没办法了,那肯定不是,我们不妨换个思路,flex在同一行内会不断的往前顶补空位,那是不是代表如果纵向排列,一列之间会不断的往上补位,因为一列等同于横着时候的一行,那么结果就会变成 不同列之间的起始的位置是同一个水平的,但同一列之内它不会有空隙,对代码尝试了修改,加添方向后的代码如下:

<template>
	<view class="content">
		  <view class="img-container" v-for="(item,index) in list" :key="index">
		    <img class="img-style" :src="item.src" :style="{height:item.height}" />
			<div>
				标题{{index}}
			</div>
		  </view>
	</view>
</template>
<style>
	.content {
		display: flex;
		flex-direction: column;
		flex-wrap: wrap; 
	}
	.img-container{
		position: relative;
		
		width: 375rpx;
		padding-bottom: 0;
		box-sizing: border-box;
	}
</style>

编写代码后发现,这么写的 图片超出屏幕后并没有自动新开启一列,而是有多少张图片,这一列就有多高

在这里插入图片描述


我们不能让他无限变高,必须限定一个高度,只有限定了高度,超出时才会自动新起一列,我们给父级容器加上个高度 height

<style>
	.content {
		display: flex;
		flex-direction: column;
		flex-wrap: wrap; 
		height: 1100px;
	}
	.img-container{
		position: relative;
		
		width: 375rpx;
		padding-bottom: 0;
		box-sizing: border-box;
	}
</style>

得到结果如下:

在这里插入图片描述


看起来有点相像了,但是我们知道,这个图片它是纵向排列的,就如上图中的线条图那种,不信我们可以标签看一下,加上如下CSS代码

.img-container{
  position: relative;
  
  width: 375rpx;
  padding-bottom: 0;
  box-sizing: border-box;
  
  counter-increment: item-counter;
}
.img-container::after{
  position: absolute;
  top: 10rpx;
  right: 10rpx;
  
  display: block;
  width: 30px;
  height: 30px;
  
  text-align: center;
  line-height: 30px;
  background-color: #000;
  color: #fff;
  content:counter(item-counter);
}

加上后,我们可以得到一个标签,如下图所示(因为标题的文字还需要排版,所以先去掉了)

在这里插入图片描述


确实是纵向排列的,但 理论上我们需要的是横向排列,我们得找一个办法将这个 布局方式改为横向排列,那必须要借助一个叫 order 的值了

order 属性 设置或检索弹性盒模型对象的子元素出现的順序。

因此,借助 order属性 我们可以给所有的 img-container 按照比例进行排序(注意,这个属性只对flex布局生效),也就是如下

.img-container:nth-child(2n+1){
  order: 1;
}
.img-container:nth-child(2n){
  order: 2;
}

得到效果图如下:

在这里插入图片描述

缺点

至于缺陷,自然是有的,其实我们一开始就说了,一切的一切都 必须借助于flex容器高度固定这个基础上,如果这个值没有,下面这些实现都是不可能的,如果实际项目中想要用flex实现瀑布流布局,那么 一定要对高度进行精确的计算,否则很容易出现图片叉了的情况,比如出现了第三列这种,完全超出了预期…

完整代码

<template>
	<view class="content">
		  <view class="img-container" v-for="(item,index) in list" :key="index" >
		    <img class="img-style" :src="item.src" :style="{height:item.height}" />
		  </view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello',
				list:[
					{
						src:"https://picsum.photos/300/400?random=1",
						height:"180px"
					},{
						src:"https://picsum.photos/300/420?random=2",
						height:"220px"
					},{
						src:"https://picsum.photos/300/460?random=3",
						height:"240px"
					},{
						src:"https://picsum.photos/300/380?random=4",
						height:"160px"
					},{
						src:"https://picsum.photos/300/420?random=5",
						height:"220px"
					},{
						src:"https://picsum.photos/300/440?random=6",
						height:"260px"
					},{
						src:"https://picsum.photos/300/500?random=7",
						height:"220px"
					},{
						src:"https://picsum.photos/300/490?random=8",
						height:"200px"
					}
				]
			}
		},
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		flex-wrap: wrap; 
		height: 1100px;
	}
	.img-container{
		position: relative;
		
		width: 375rpx;
		padding-bottom: 0;
		box-sizing: border-box;
		
		counter-increment: item-counter;
	}
	.img-container:nth-child(2n+1){
		padding-left: 10rpx;
		padding-right: 5rpx;
	}
	.img-container:nth-child(2n){
		padding-left: 5rpx;
		padding-right: 10rpx;
	}
	.img-container .img-style{
		width: 100%;
	}
	.img-container::after{
		position: absolute;
		top: 10rpx;
		right: 10rpx;
		
		display: block;
		width: 30px;
		height: 30px;
		
		text-align: center;
		line-height: 30px;
		background-color: #000000;
		color: #ffffff;
		content:counter(item-counter);
	}
	.img-container:nth-child(2n+1){
		order: 1;
	}
	.img-container:nth-child(2n){
		order: 2;
	}
</style>

第二种:column-count及column-gap

这两个属性…我相信可能好多人都没有见过…简单的介绍一下吧,column-count,这是一个CSS3的属性,官方说明如下:

column-count CSS 属性,描述元素的列数。

简单的说,它的作用只有一个,指定某个元素内部应当分为几列,就这么简单粗暴,而 column-gap 的官方说明如下:

CSS column-gap 属性用来设置元素列之间的间隔(gutter)大小。

这个属性得和 column-count 配合使用,作用就是 指定列于列之间的间隔宽度,这两个属性对兼容性还是由一些要求的,但好在移动端的容器版本都不会老,因此 如果仅在移动端使用,还是有些可行性的~

核心代码

column-count: 2;
column-gap: 0;

核心代码就这两行,一行申明几列,一行声明间隔;

实现

依旧是上一节中的原始代码,我们只需要在父容器加上这两行代码

.content {
  column-count: 2;
  column-gap: 0;
}

就会得到如下结果

在这里插入图片描述


是不是已经非常像了,而且比 flex布局还要简单,毕竟只有2行代码,那么排列方向呢?很遗憾,还是纵向排列的,我们加上上一节中的伪类,对每张图片进行一个标记,得到如下结果

在这里插入图片描述


有没有办法改为横向排列呢,好像是没有,至少博主没有找到,order 这个属性是针对 flex 的,普通的盒模型并不会生效

缺点

缺点很明显了,就是排列顺序 仅仅支持纵向排列,它不支持横向,和 flex布局 相对,优点就是实现简单,也不需要计算高度

完整代码

<template>
	<view class="content">
		  <view class="img-container" v-for="(item,index) in list" :key="index" >
		    <img class="img-style" :src="item.src" :style="{height:item.height}" />
		  </view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello',
				list:[
					{
						src:"https://picsum.photos/300/400?random=1",
						height:"180px"
					},{
						src:"https://picsum.photos/300/420?random=2",
						height:"220px"
					},{
						src:"https://picsum.photos/300/460?random=3",
						height:"240px"
					},{
						src:"https://picsum.photos/300/380?random=4",
						height:"160px"
					},{
						src:"https://picsum.photos/300/420?random=5",
						height:"220px"
					},{
						src:"https://picsum.photos/300/440?random=6",
						height:"260px"
					},{
						src:"https://picsum.photos/300/500?random=7",
						height:"220px"
					},{
						src:"https://picsum.photos/300/490?random=8",
						height:"200px"
					}
				]
			}
		},
	}
</script>

<style>
	.content {
		column-count: 2;
		column-gap: 0;
	}
	.img-container{
		position: relative;
		
		width: 375rpx;
		padding: 4px;
		padding-bottom: 0;
		box-sizing: border-box;
		
		counter-increment: item-counter;
	}
	.img-container .img-style{
		width: 100%;
	}
	.img-container::after{
		position: absolute;
		top: 10rpx;
		right: 10rpx;
		
		display: block;
		width: 30px;
		height: 30px;
		
		text-align: center;
		line-height: 30px;
		background-color: #000000;
		color: #ffffff;
		content:counter(item-counter);
	}
</style>

小结

本文分享了 两种实现瀑布流布局的纯CSS办法,他们各有优缺点,大致如下:

  • flex:支持横向排序,但父容器必须计算高度,而且是精准的高度,没有高度,那么布局将实现不了
  • column不支持横向排序,实现有效并且非常简单;

(PS:都已经看到这里了,点个赞,求个关注吧,万分感谢~)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340