likes
comments
collection
share

CSS也能实现瀑布流布局?

作者站长头像
站长
· 阅读数 14

前言

生活中很多软件都会使用到瀑布流,比如说淘宝的商品浏览页面,还有一些图片浏览页面,都会有瀑布流的应用场景。要做出好看的瀑布流,通常是使用js做响应式瀑布流,但是我们也可以通过一些强大的css属性,来完成瀑布流布局。这里我总结几个css属性帮我们制作瀑布流布局。

瀑布流

瀑布流布局,其视觉展示是一种参差不齐的多栏布局,不同数据块会无限附加在一栏中的上一个数据块的尾部,达到可无限加载数据的效果

CSS也能实现瀑布流布局?

多列布局(Multi-column)

Multi-column有下面一些属性:

1.columns:设置列数和每列的宽度
2.column-width:设置每列的宽度。
3.column-count:设置列数
4.column-gap:设置列与列之间的间隙
5.column-rule:设置列与列之间的分割线
6.column-span:设置元素是否跨所有列
7.column-fill:设置所有列的高度统一
...

利用 Multi-column 中几个属性就可以完成瀑布流布局:(这里我们利用vue来实现数据响应)

其中 column-count: 5;将设置为5个列,column-gap: 20px;将设置列与列之间的间距为20px,这样我们就很简单的实现了瀑布流布局。我还在每个数据块放置了文本,那么我在每个数据块设置了break-inside:avoid;属性,用于使每个数据块内容不会中断。因为使用这种方法实现的瀑布流,遵循先从上到下,再从左到右排布,这样如果左边列的最后一个数据块的文本过多,就可能出现在其右一列的头部。

以下是完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <title>Document</title>
  <style>
    .box{
      padding: 10px;
      column-count: 5;
      column-gap: 20px;
    }
    .item{
      border: 1px solid #999;
      margin-bottom: 10px;
      break-inside:avoid;
    }
    .item img{
      width: 100%;
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="box">
      <div class="item" v-for="item in list" :key="item.id">
        <img :src="item.img" alt="">
        <span class="title">{{item.content}}</span>
      </div>
    </div>
  </div>

  <script>
    const {createApp} = Vue
    createApp({
      data(){
        return {
          list:[
            {
              id: 0,
              content: '出或属及然立物区际团干林品号界织声政自青',
              img: 'https://picsum.photos/200/335?random=58'
            },
            {
              id: 1,
              content: '规社需别至打她南气提现身记指今化油百积体',
              img: 'https://picsum.photos/200/349?random=761'
            },
            {
              id: 2,
              content: '许题状世声程管么物社社同圆了而备公所料青',
              img: 'https://picsum.photos/200/442?random=71'
            },
            {
              id: 3,
              content: '然立物区际团干林品号界织声政自青参从运统',
              img: 'https://picsum.photos/200/322?random=312'
            },
            {
              id: 4,
              content: '团干林品号界织声政自青参从运统类半口识高',
              img: 'https://picsum.photos/200/399?random=460'
            },
            {
              id: 5,
              content: '例导向王活中叫社就江工外以气图专律北多建',
              img: 'https://picsum.photos/200/446?random=898'
            },
            {
              id: 6,
              content: '六思断名过增思复许石查再生斯法派带改叫向',
              img: 'https://picsum.photos/200/495?random=460'
            },
            {
              id: 7,
              content: '可定开京出或属及然立物区际团干林品号界织',
              img: 'https://picsum.photos/200/451?random=389'
            },
            {
              id: 8,
              content: '定开京出或属及然立物区际团干林品号界织声',
              img: 'https://picsum.photos/200/374?random=216'
            },
            {
              id: 9,
              content: '提现身记指今化油百积体量但国参根书为影从',
              img: 'https://picsum.photos/200/339?random=426'
            },
            {
              id: 10,
              content: '问任写主速情及极需和始亲点酸七建红放周养',
              img: 'https://picsum.photos/200/400?random=22'
            },
            {
              id: 11,
              content: '参从运统类半口识高多选石空改流通工来万北',
              img: 'https://picsum.photos/200/468?random=373'
            },
            {
              id: 12,
              content: '习七准导离每见里可求产着影却响百产际片院',
              img: 'https://picsu m.photos/200/442?random=903'
            },
            {
              id: 13,
              content: '划子要步百图引美须成展党复任场走许就素受',
              img: 'https://picsum.photos/200/416?random=874'
            },
            {
              id: 14,
              content: '上是题快而被己老制米制往例导向王活中叫社',
              img: 'https://picsum.photos/200/421?random=219'
            },
            {
              id: 15,
              content: '开京出或属及然立物区际团干林品号界织声政',
              img: 'https://picsum.photos/200/427?random=909'
            }
          ]
        }
      }
    }).mount('#app')
  </script>
</body>
</html>

网格布局-grid

网格布局实现瀑布流也只需要使用其中几个属性:

1. grid-auto-rows:设置行高(auto; 即自适应行数)
2. grid-template-rows:设置每行的高度或比例(1fr 1fr 1fr;即三行且高度1:1:1
3. grid-template-columns:设置列数
5. grid-row-start:设置开始的行数(auto;自适应开始的行数)
6. grid-row-end:结束行数(span 2; 即跨两行)

网格布局实现瀑布流需要先设置列数grid-template-columns: 1fr 1fr 1fr 1fr;即四列均分,再设置网格布局的行高为一个较小的高度grid-auto-rows: 1px;,但是不能高于图片最小高度,还需要设置每个容器的开始行grid-row-start: auto;即自适应,最后用js来配合计算每张图片占有的网格行数,再设置每个图片容器的尾部(结束)行数,即跨多少行。(由于这里的图片数据都是用ChatGPT生成,所以是随机的,获取宽高也是从生成的图片链接截取)

注:这种方法不便于自适应的瀑布流,加载完成后,拖动改变窗口宽高但图片容器宽高未变,导致重叠或留白

CSS也能实现瀑布流布局?

源代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <title>Document</title>
  <style>
    .box{
      display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr;
      grid-auto-rows: 1px;
      column-gap: 5px;
    }
    .item{
      grid-row-start: auto;
    }
    .item img{
      width: 100%;
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="box">
      <div class="item" v-for="item in list" :key="item.id">
        <img :src="item.img" alt="">
      </div>
    </div>
  </div>

  <script>
    const {createApp} = Vue
    createApp({
      data(){
        return {
          list:[
        {
          id: 0,
          content: '出或属及然立物区际团干林品号界织声政自青',
          img: 'https://picsum.photos/200/335?random=58'
        },
        {
          id: 1,
          content: '规社需别至打她南气提现身记指今化油百积体',
          img: 'https://picsum.photos/200/349?random=761'
        },
        {
          id: 2,
          content: '许题状世声程管么物社社同圆了而备公所料青',
          img: 'https://picsum.photos/200/442?random=71'
        },
        {
          id: 3,
          content: '然立物区际团干林品号界织声政自青参从运统',
          img: 'https://picsum.photos/200/322?random=312'
        },
        {
          id: 4,
          content: '团干林品号界织声政自青参从运统类半口识高',
          img: 'https://picsum.photos/200/399?random=460'
        },
        {
          id: 5,
          content: '例导向王活中叫社就江工外以气图专律北多建',
          img: 'https://picsum.photos/200/446?random=898'
        },
        {
          id: 6,
          content: '六思断名过增思复许石查再生斯法派带改叫向',
          img: 'https://picsum.photos/200/495?random=460'
        },
        {
          id: 7,
          content: '可定开京出或属及然立物区际团干林品号界织',
          img: 'https://picsum.photos/200/451?random=389'
        },
        {
          id: 8,
          content: '定开京出或属及然立物区际团干林品号界织声',
          img: 'https://picsum.photos/200/374?random=216'
        },
        {
          id: 9,
          content: '提现身记指今化油百积体量但国参根书为影从',
          img: 'https://picsum.photos/200/339?random=426'
        },
        {
          id: 10,
          content: '问任写主速情及极需和始亲点酸七建红放周养',
          img: 'https://picsum.photos/200/400?random=22'
        },
        {
          id: 11,
          content: '参从运统类半口识高多选石空改流通工来万北',
          img: 'https://picsum.photos/200/468?random=373'
        },
        {
          id: 12,
          content: '习七准导离每见里可求产着影却响百产际片院',
          img: 'https://picsum.photos/200/442?random=903'
        },
        {
          id: 13,
          content: '划子要步百图引美须成展党复任场走许就素受',
          img: 'https://picsum.photos/200/416?random=874'
        },
        {
          id: 14,
          content: '上是题快而被己老制米制往例导向王活中叫社',
          img: 'https://picsum.photos/200/421?random=219'
        },
        {
          id: 15,
          content: '开京出或属及然立物区际团干林品号界织声政',
          img: 'https://picsum.photos/200/427?random=909'
        }
      ]
        }
      },
      mounted(){//生命周期函数
        let items = document.getElementsByClassName('item')
        Array.from(items).forEach(item => {//遍历每个图片容器
          let img = item.getElementsByTagName('img')[0]
          let newImg = new Image()//img是特例,只要被js创建就会被浏览器加载
          newImg.src = img.src
          //获取生成的图片的宽高
          height = img.src.slice(img.src.lastIndexOf('/') + 1, img.src.lastIndexOf('?'))
          width = img.src.slice(img.src.lastIndexOf('/') - 3 ,img.src.lastIndexOf('/'))
          //根据窗口宽度计算缩放之后的图片高度,以便计算跨多少行
          newImg.height = height * (item.clientWidth / width)
          // console.log(newImg.height);
          newImg.onload = function(){
            //设置item占据网格的几行
            item.style.gridRowEnd = `span ${newImg.height}`
          }
        })
      }
    }).mount('#app')
  </script>
</body>
</html>

弹性布局

弹性布局实现瀑布流就是利用纵向弹性,使每列的每个容器接在上一个图片容器之后,瀑布流需要几栏就要设置几个div包裹,还要将数据分成相应的组数,方法比较low,一般不使用,优点就是可以设置flex: 1 ;让每列宽度自适应,达到响应式效果。

CSS也能实现瀑布流布局?

源代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <title>Document</title>
  <style>
    .box{
      display: flex;
      flex-wrap: wrap;
    }
    .clomun{
      flex: 1 ;
      display: flex;
      flex-direction: column;
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="box">
      <div class="clomun">
        <img :src="item.img" v-for="item in list1" alt="">
      </div>
      <div class="clomun">
        <img :src="item.img" v-for="item in list2" alt="">
      </div>
      <div class="clomun">
        <img :src="item.img" v-for="item in list3" alt="">
      </div>
    </div>
  </div>

  <script>
    const {createApp} = Vue
    createApp({
      data(){
        return {
          list1:[],
          list2:[],
          list3:[],
          list:[
        {
          id: 0,
          content: '出或属及然立物区际团干林品号界织声政自青',
          img: 'https://picsum.photos/200/335?random=58'
        },
        {
          id: 1,
          content: '规社需别至打她南气提现身记指今化油百积体',
          img: 'https://picsum.photos/200/349?random=761'
        },
        {
          id: 2,
          content: '许题状世声程管么物社社同圆了而备公所料青',
          img: 'https://picsum.photos/200/442?random=71'
        },
        {
          id: 3,
          content: '然立物区际团干林品号界织声政自青参从运统',
          img: 'https://picsum.photos/200/322?random=312'
        },
        {
          id: 4,
          content: '团干林品号界织声政自青参从运统类半口识高',
          img: 'https://picsum.photos/200/399?random=460'
        },
        {
          id: 5,
          content: '例导向王活中叫社就江工外以气图专律北多建',
          img: 'https://picsum.photos/200/446?random=898'
        },
        {
          id: 6,
          content: '六思断名过增思复许石查再生斯法派带改叫向',
          img: 'https://picsum.photos/200/495?random=460'
        },
        {
          id: 7,
          content: '可定开京出或属及然立物区际团干林品号界织',
          img: 'https://picsum.photos/200/451?random=389'
        },
        {
          id: 8,
          content: '定开京出或属及然立物区际团干林品号界织声',
          img: 'https://picsum.photos/200/374?random=216'
        },
        {
          id: 9,
          content: '提现身记指今化油百积体量但国参根书为影从',
          img: 'https://picsum.photos/200/339?random=426'
        },
        {
          id: 10,
          content: '问任写主速情及极需和始亲点酸七建红放周养',
          img: 'https://picsum.photos/200/400?random=22'
        },
        {
          id: 11,
          content: '参从运统类半口识高多选石空改流通工来万北',
          img: 'https://picsum.photos/200/468?random=373'
        },
        {
          id: 12,
          content: '习七准导离每见里可求产着影却响百产际片院',
          img: 'https://picsum.photos/200/442?random=903'
        },
        {
          id: 13,
          content: '划子要步百图引美须成展党复任场走许就素受',
          img: 'https://picsum.photos/200/416?random=874'
        },
        {
          id: 14,
          content: '上是题快而被己老制米制往例导向王活中叫社',
          img: 'https://picsum.photos/200/421?random=219'
        },
        {
          id: 15,
          content: '开京出或属及然立物区际团干林品号界织声政',
          img: 'https://picsum.photos/200/427?random=909'
        },
        {
          id: 16,
          content: '题快而被己老制米制往例导向王活中叫社就江',
          img: 'https://picsum.photos/200/490?random=87'
        },
        {
          id: 17,
          content: '复许石查再生斯法派带改叫向派更织证果克长',
          img: 'https://picsum.photos/200/481?random=643'
        },
        {
          id: 18,
          content: '产张声很那响备育然际看离面市用大平张律般',
          img: 'https://picsum.photos/200/375?random=612'
        },
        {
          id: 19,
          content: '石空改流通工来万北林向小府万就八往得白证',
          img: 'https://picsum.photos/200/431?random=16'
        },
        {
          id: 20,
          content: '备公所料青反要看万采如指组更产张声很那响',
          img: 'https://picsum.photos/200/449?random=444'
        },
        {
          id: 21,
          content: '图专律北多建战器解然才料只根维光者率把律',
          img: 'https://picsum.photos/200/311?random=625'
        },
        {
          id: 22,
          content: '石南至构严九题可定开京出或属及然立物区际',
          img: 'https://picsum.photos/200/324?random=523'
        },
        {
          id: 23,
          content: '很那响备育然际看离面市用大平张律般那意县',
          img: 'https://picsum.photos/200/341?random=443'
        },
        {
          id: 24,
          content: '图引美须成展党复任场走许就素受事多观界立',
          img: 'https://picsum.photos/200/477?random=799'
        },
        {
          id: 25,
          content: '际看离面市用大平张律般那意县对门并议省取',
          img: 'https://picsum.photos/200/459?random=62'
        },
        {
          id: 26,
          content: '社同圆了而备公所料青反要看万采如指组更产',
          img: 'https://picsum.photos/200/361?random=105'
        },
        {
          id: 27,
          content: '知片具加其许题状世声程管么物社社同圆了而',
          img: 'https://picsum.photos/200/321?random=569'
        },
        {
          id: 28,
          content: '南至构严九题可定开京出或属及然立物区际团',
          img: 'https://picsum.photos/200/431?random=788'
        },
        {
          id: 29,
          content: '往得白证易习七准导离每见里可求产着影却响',
          img: 'https://picsum.photos/200/328?random=462'
        },
        {
          id: 30,
          content: '京出或属及然立物区际团干林品号界织声政自',
          img: 'https://picsum.photos/200/391?random=918'
        },
        {
          id: 31,
          content: '照酸但明片种设音规地白声那火半省上是题快',
          img: 'https://picsum.photos/200/426?random=989'
        },
        {
          id: 32,
          content: '件型各离性格术五织做圆界位为经员间阶知片',
          img: 'https://picsum.photos/200/430?random=505'
        },
        {
          id: 33,
          content: '件型各离性格术五织做圆界位为经员间阶知片',
          img: 'https://picsum.photos/200/317?random=542'
        },
        {
          id: 34,
          content: '界位为经员间阶知片具加其许题状世声程管么',
          img: 'https://picsum.photos/200/471?random=355'
        },
        {
          id: 35,
          content: '属及然立物区际团干林品号界织声政自青参从',
          img: 'https://picsum.photos/200/432?random=552'
        },
        {
          id: 36,
          content: '感近度产数直华名车书细先值山不口问任写主',
          img: 'https://picsum.photos/200/395?random=497'
        },
        {
          id: 37,
          content: '际团干林品号界织声政自青参从运统类半口识',
          img: 'https://picsum.photos/200/327?random=773'
        },
        {
          id: 38,
          content: '界真离气建各划音感近度产数直华名车书细先',
          img: 'https://picsum.photos/200/331?random=640'
        },
        {
          id: 39,
          content: '改流通工来万北林向小府万就八往得白证易习',
          img: 'https://picsum.photos/200/348?random=187'
        },
        {
          id: 40,
          content: '叫向派更织证果克长商统八规社需别至打她南',
          img: 'https://picsum.photos/200/484?random=777'
        },
        {
          id: 41,
          content: '八规社需别至打她南气提现身记指今化油百积',
          img: 'https://picsum.photos/200/355?random=535'
        },
        {
          id: 42,
          content: '通工来万北林向小府万就八往得白证易习七准',
          img: 'https://picsum.photos/200/400?random=173'
        },
        {
          id: 43,
          content: '离性格术五织做圆界位为经员间阶知片具加其',
          img: 'https://picsum.photos/200/306?random=741'
        },
        {
          id: 44,
          content: '圆界位为经员间阶知片具加其许题状世声程管',
          img: 'https://picsum.photos/200/302?random=605'
        },
        {
          id: 45,
          content: '种设音规地白声那火半省上是题快而被己老制',
          img: 'https://picsum.photos/200/312?random=120'
        },
        {
          id: 46,
          content: '题状世声程管么物社社同圆了而备公所料青反',
          img: 'https://picsum.photos/200/484?random=768'
        },
        {
          id: 47,
          content: '八规社需别至打她南气提现身记指今化油百积',
          img: 'https://picsum.photos/200/459?random=661'
        },
        {
          id: 48,
          content: '用大平张律般那意县对门并议省取空万酸至名',
          img: 'https://picsum.photos/200/303?random=329'
        },
        {
          id: 49,
          content: '高多选石空改流通工来万北林向小府万就八往',
          img: 'https://picsum.photos/200/463?random=885'
        }
      ]
        }
      },
      mounted(){
        let num = ~~(this.list.length / 3)//计算列的数据数量,便于下面分配
        this.list1 = this.list.slice(0,num)
        this.list2 = this.list.slice(num,num*2)
        this.list3 = this.list.slice(num*2,this.list.length)
      }
    }).mount('#app')
  </script>
</body>
</html>

实现瀑布流布局的主要手段是使用JS,因为用CSS一般难以实现我们想要的瀑布流效果(数据块分布,响应式等等),这里只是应该知道CSS也能完成瀑布流布局,一般使用第一种方法来实现,但是网格布局很强大,基本能实现我们想要的各种布局效果。