使用getBoundingClientRect()数据重新定位元素

9

我正在尝试编写一个瀑布流布局(请不要建议使用库,我知道新的Firefox CSS瀑布流功能,但我需要更好的支持),从CSS网格布局开始。

HTML看起来像这样,一个带有各种长宽比图像的区域:

<section class='grid--masonry'>
    <img src='black_cat.jpg' alt='black cat'/>
    <!-- and so on, more images following the first -->
</section>

样式设计相当基础,只需要设置网格:

$w: Min(8em, 100%);
$s: .5rem;

.grid--masonry {
  display: grid;
  grid-template-columns: repeat(auto-fit, $w);
  grid-gap: $s;
  padding: $s;
    
  > * { width: $w }
}

在JS中,第一步是获取网格、它的元素节点(过滤出文本节点)、网格间距并初始化列数:

然后,在页面加载之后,我调用 layout() 函数:

addEventListener('load', e => {     
  layout(); /* initial load */
  addEventListener('resize', layout, false) /* on resize */
}, false)

layout()函数执行以下操作:

  • 获取每个网格项的left偏移量
  • 由于同一列上的项具有相同的偏移量,因此创建一个偏移量集合,其大小为当前列数
  • 如果当前列数与我们已有的grid.ncol相同,则不执行任何操作并退出函数
  • 否则,我们更新grid.ncol值,然后...
  • 删除网格项可能存在的顶部边距
  • 检查是否有多列
  • 如果只有一列,则直接退出layout()函数,完成!
  • 否则,对于每列,我们获取该列上的项目(通过偏移过滤)
  • 如果只有一行,则退出layout()函数并不执行更多操作
  • 否则,我们循环遍历当前列上的项目,获取前一个项目的底部边缘和当前项目的顶部边缘,并计算需要向上移动当前项目的量

以下是实现以上功能的代码:

function layout() {
  /* get left offset for every item of the grid */
  grid.items.forEach(c => { c.off = c._el.getBoundingClientRect().left });

  /* make a set out of the array of offsets we've just obtained */
  grid.off = new Set(grid.items.map(c => c.off));
            
  /* if the number of columns has changed */
  if(grid.ncol !== grid.off.size) {
    /* update number of columns */
    grid.ncol = grid.off.size;
                
    /* revert to initial positioning, no margin */
    grid.items.forEach(c => c._el.style.removeProperty('margin-top'));
                
    /* if we have more than one column */
    if(grid.ncol > 1) {         
      grid.off.forEach(o => { /* for each column */
        /* get items on that column */
        let col_items = grid.items.filter(c => c.off === o), 
            col_len = col_items.length;
                        
        /* if we have more than 1 item per column */
        if(col_len > 1) {
          for(let i = 1; i < col_len; i++) {
            let prev_fin = col_items[i - 1]._el.getBoundingClientRect().bottom /* bottom edge of item above */, 
                curr_ini = col_items[i]._el.getBoundingClientRect().top /* top edge of current item */;
                                
           col_items[i]._el.style.marginTop = `${prev_fin + grid.gap - curr_ini}px`
          }
        }
      })
    }
  }
}

我本以为这会起作用,但并没有。它似乎对于两列起作用,但对于更多列却不起作用。我就是搞不清楚为什么。

let grid = { _el: document.querySelector('.grid--masonry'), ncol: 0 };

grid.items = [...grid._el.childNodes].filter(c => c.nodeType === 1).map(c => ({ _el: c }));
grid.gap = parseFloat(getComputedStyle(grid._el).gridRowGap);

function layout() {
  /* get left offset for every item of the current grid */
  grid.items.forEach(c => { c.off = c._el.getBoundingClientRect().left });
  /* make a set out of the array of offsets we've just obtained */
  grid.off = new Set(grid.items.map(c => c.off));

  /* if the number of columns has changed */
  if(grid.ncol !== grid.off.size) {
    /* update number of columns */
    grid.ncol = grid.off.size;

    /* revert to initial positioning, no margin */
    grid.items.forEach(c => c._el.style.removeProperty('margin-top'));

    /* if we have more than one column */
    if(grid.ncol > 1) {         
      grid.off.forEach(o => { /* for each column */
        /* get items on that column */
        let col_items = grid.items.filter(c => c.off === o), 
            col_len = col_items.length;

        /* if we have more than 1 item per column */
        if(col_len > 1) {
          for(let i = 1; i < col_len; i++) {
            let prev_fin = col_items[i - 1]._el.getBoundingClientRect().bottom /* bottom edge of item above */, 
                curr_ini = col_items[i]._el.getBoundingClientRect().top /* top edge of current item */;

            col_items[i]._el.style.marginTop = `${prev_fin + grid.gap - curr_ini}px`
          }
        }
      })
    }
  }
}

addEventListener('load', e => {     
  layout(); /* initial load */
  addEventListener('resize', layout, false) /* on resize */
}, false);
.grid--masonry {
  display: grid;
  grid-template-columns: repeat(auto-fit, Min(8em, 100%));
  justify-content: center;
  grid-gap: .5rem;
  padding: .5rem;
  background: violet;
}
.grid--masonry > * {
  width: Min(8em, 100%);
}
<section class='grid--masonry'>
    <img src='https://images.unsplash.com/photo-1510137600163-2729bc6959a6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=900&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1587041403375-ddce288f4c49?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1580697895575-883f7c755346?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt=''/>
    <img src='https://images.unsplash.com/photo-1581200459935-685903de7d62?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1578264050450-ccc2f77796a1?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1557153921-10129d0f5b6c?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1584049086295-9f2af90efbb4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1572196663741-b91b8f045330?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1558288215-664da65499af?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1592296109897-9c4d8e490e7a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1525104885119-8806dd94ad58?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1576532116216-84f6a0aedaf6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1533629947587-7b04aaa0e837?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1568386895623-74df8a7406f0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1573777058681-73b866833d90?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1552566852-06d10a5050f4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1576759470820-77a440a4d45b?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1586891622678-999a4419da34?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1584797318381-5958ca2e6b39?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1529093589387-b486dcc37c15?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1587421803669-b403d010dd80?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1570458436416-b8fcccfe883f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1518206245806-5c1f4d0c5a2a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
</section>

2个回答

5

看起来,由于网格中不同列的项之间存在依赖关系,更改较早行中单元格的高度可能会影响下一行较早列中单元格的位置。 将更新项的顺序从“逐列”更改为“逐个”似乎可以解决此问题:

let grid = { _el: document.querySelector('.grid--masonry'), ncol: 0 };

grid.items = [...grid._el.childNodes].filter(c => c.nodeType === 1).map(c => ({ _el: c }));
grid.gap = parseFloat(getComputedStyle(grid._el).gridRowGap);

function layout() {
  /* get left offset for every item of the current grid */
  grid.items.forEach(c => { c.off = c._el.getBoundingClientRect().left });
  /* make a set out of the array of offsets we've just obtained */
  grid.off = new Set(grid.items.map(c => c.off));

  /* if the number of columns has changed */
  if(grid.ncol !== grid.off.size) {
    /* update number of columns */
    grid.ncol = grid.off.size;

    /* revert to initial positioning, no margin */
    grid.items.forEach(c => c._el.style.removeProperty('margin-top'));

    /* if we have more than one column */
    if(grid.ncol > 1) {         
      grid.items.forEach((item, n) => { /* for each item*/
        /* if we have more than 1 item per column */
        if(n >= grid.ncol) {
            let prev_fin = grid.items[n - grid.ncol]._el.getBoundingClientRect().bottom /* bottom edge of item above */, 
                curr_ini = item._el.getBoundingClientRect().top /* top edge of current item */;

            item._el.style.marginTop = `${prev_fin + grid.gap - curr_ini}px`;
        }
      })
    }
  }
}

addEventListener('load', e => {     
  layout(); /* initial load */
  addEventListener('resize', layout, false); /* on resize */
}, false);
.grid--masonry {
  display: grid;
  grid-template-columns: repeat(auto-fit, Min(8em, 100%));
  justify-content: center;
  grid-gap: .5rem;
  padding: .5rem;
  background: violet;
}
.grid--masonry > * {
  width: Min(8em, 100%);
}
<section class='grid--masonry'>
    <img src='https://images.unsplash.com/photo-1510137600163-2729bc6959a6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=900&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1587041403375-ddce288f4c49?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1580697895575-883f7c755346?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt=''/>
    <img src='https://images.unsplash.com/photo-1581200459935-685903de7d62?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1578264050450-ccc2f77796a1?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1557153921-10129d0f5b6c?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1584049086295-9f2af90efbb4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1572196663741-b91b8f045330?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1558288215-664da65499af?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1592296109897-9c4d8e490e7a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1525104885119-8806dd94ad58?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1576532116216-84f6a0aedaf6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1533629947587-7b04aaa0e837?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1568386895623-74df8a7406f0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1573777058681-73b866833d90?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1552566852-06d10a5050f4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1576759470820-77a440a4d45b?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1586891622678-999a4419da34?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1584797318381-5958ca2e6b39?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1529093589387-b486dcc37c15?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1587421803669-b403d010dd80?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1570458436416-b8fcccfe883f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1518206245806-5c1f4d0c5a2a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
</section>


2

我是Masonry js插件的作者。与其通过比较列中前一个和当前的项目来计算margin-top偏移量,我建议跟踪列高度。对于每个项目,将其margin-top设置为该列高度的偏移位置。然后更新列高度以考虑项目的高度。

let grid = { _el: document.querySelector('.grid--masonry'), ncol: 0 };

grid.items = [...grid._el.childNodes].filter(c => c.nodeType === 1).map(c => ({ _el: c }));
grid.gap = parseFloat(getComputedStyle(grid._el).gridRowGap);

function layout() {
  /* keep track of column heights */
  let initial_height = grid.items[0]._el.getBoundingClientRect().top;
  grid.col_heights = new Map();
  grid.items.forEach(c => {
    /* get left offset for every item of the current grid */
    let rect = c._el.getBoundingClientRect();
    c.off = rect.left;
    grid.col_heights.set(c.off, initial_height);
  });

  /* if the number of columns has changed */
  if(grid.ncol === grid.col_heights.size) {
    return
  }
  /* update number of columns */
  grid.ncol = grid.col_heights.size;

  /* revert to initial positioning, no margin */
  grid.items.forEach(c => c._el.style.removeProperty('margin-top'));

  if(grid.ncol === 1) { 
    return
  }
  /* if we have more than one column */

  grid.items.forEach(grid_item => {
    let rect = grid_item._el.getBoundingClientRect();
    /* get height of masonry-ed column */
    let col_height = grid.col_heights.get(grid_item.off);
    /* set marginTop to different between where it is and where it should be */
    grid_item._el.style.marginTop = `${col_height - rect.top}px`;
    /* update col_height with element height */
    col_height += grid_item._el.offsetHeight + grid.gap;
    grid.col_heights.set(grid_item.off, col_height);
  })
}

addEventListener('load', e => {     
  layout(); /* initial load */
  addEventListener('resize', layout, false) /* on resize */
}, false);
.grid--masonry {
  display: grid;
  grid-template-columns: repeat(auto-fit, Min(8em, 100%));
  justify-content: center;
  grid-gap: .5rem;
  padding: .5rem;
  background: violet;
}
.grid--masonry > * {
  width: Min(8em, 100%);
}
<section class='grid--masonry'>
    <img src='https://images.unsplash.com/photo-1510137600163-2729bc6959a6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=900&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1587041403375-ddce288f4c49?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1580697895575-883f7c755346?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt=''/>
    <img src='https://images.unsplash.com/photo-1581200459935-685903de7d62?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1578264050450-ccc2f77796a1?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1557153921-10129d0f5b6c?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1584049086295-9f2af90efbb4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1572196663741-b91b8f045330?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1558288215-664da65499af?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1592296109897-9c4d8e490e7a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1525104885119-8806dd94ad58?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1576532116216-84f6a0aedaf6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1533629947587-7b04aaa0e837?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1568386895623-74df8a7406f0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1573777058681-73b866833d90?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1552566852-06d10a5050f4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1576759470820-77a440a4d45b?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1586891622678-999a4419da34?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1584797318381-5958ca2e6b39?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1529093589387-b486dcc37c15?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1587421803669-b403d010dd80?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1570458436416-b8fcccfe883f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
    <img src='https://images.unsplash.com/photo-1518206245806-5c1f4d0c5a2a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='black cat'/>
</section>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接