使用flex实现瀑布流式布局

  • Post author:
  • Post category:其他


为了演示效果,使用了《国家地理》两位作者的图片,在此表示感谢。如侵权,请联系我删除,再次感谢。



展示效果


codepen



代码



HTML

注意其中一行代码

style="width: calc(100vw / 3);

,如果你使用的vue或者react或者小程序,请使用动态绑定列数,是可以修改的。

<div class="masonry">
    <div class="column">
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M00/46/FC/wKgBy1iv0WmAaXa1AE7LkZQs2kI077.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M02/46/FD/wKgBy1iv1m6AJjScAERga2XvgKI984.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M01/46/FC/wKgBy1iv1eiAVGZCAAXavDgRVDw422.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
    </div>
    <div class="column">
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M00/48/F7/wKgBy1llvmCAAQOVADC36j6n9bw622.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M01/46/FC/wKgBy1iv1eiAVGZCAAXavDgRVDw422.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M02/46/FD/wKgBy1iv1m6AJjScAERga2XvgKI984.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
    </div>
    <div class="column">
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M01/46/FC/wKgBy1iv1eiAVGZCAAXavDgRVDw422.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M02/46/FD/wKgBy1iv1m6AJjScAERga2XvgKI984.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
        <div class="photo-wrapper">
            <img
                src="http://img0.dili360.com/ga/M00/46/FC/wKgBy1iv0WmAaXa1AE7LkZQs2kI077.tub.jpg@!rw9"
                class="photo"
                style="width: calc(100vw / 3);"
            />
        </div>
    </div>
</div>



CSS

/** 瀑布流布局 */
.masonry {
    display: flex;
    flex-direction: row;
    font-size: 0;  /* HACK: 避免图片之间出现1px间隙 */
}
    /** 行布局 */
    .column {
        display: flex;
        flex-flow: column wrap;
    }
        .photo-wrapper {
            padding: 20px;
            box-sizing: border-box;
        }
            .photo {
                width: 100%;
                height: 100%;
            }



小程序端代码展示

这种方式如果直接传入列表循环,会导致展示顺序不再是列表顺序,如果需要请使用下面的函数修改为对应每列列表的方式:

/** 获取瀑布流列表 */
_getMasonryList(list) {
	let columnCount = 3;  // 列数
   	let masonryList = [];
   	// 每列
	for (let i = 0; i < this.data.columnCount; i++) {
	    masonryList.push([]);
	    // 每行
	    for (let j = i; j < list.length - 1; j += this.data.columnCount) {
	        console.log('[masonry] column ', i, ' row ', j);
	        masonryList[i].push(list[j]);
	    }
	}
	console.log('[masonry] list', masonryList);
	return mssonryList;
}

这样之后,展示的HTML就如下列代码,我以小程序代码为例:

<view
    wx:if="{{ masonryList.length > 0 }}"
    class="masonry"
>
    <block
        wx:for="{{ masonryList }}"
        wx:for-item="column"
        wx:key="index"
    >
        <view class="column">
            <block wx:for="{{ column }}" wx:key="_id">
                <navigator 
                	url="/pages/photos/photo/photo?id={{ item._id }}"
                	class="photo-wrapper"
                    style="width: calc(100vw / {{ columnCount }})"
                >
                    <image
                        mode="widthFix"
                        lazy-load
                        src="{{ item.photo }}"
                        class="photo"
                        style="width: calc(100vw / {{ columnCount }});"
                    />
                </navigator>
            </block>
        </view>
    </block>
</view>
/** 瀑布流布局 */
.masonry {
    display: flex;
    flex-direction: row;
    font-size: 0;
}
    /** 行布局 */
    .column {
        display: flex;
        flex-flow: column wrap;
    }
        .photo-wrapper {
            padding: 20rpx;
            box-sizing: border-box;
        }
            .photo {
                width: 100%;
                height: 100%;
            }



版权声明:本文为Simoral原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。