使用 CSS flexbox 或网格布局的响应式图片库

Responsive image gallery using CSS flexbox or grid-layout

我正在开发一个 Image-Gallery-Widget,用户可以在其中设置缩略图宽度、缩略图高度和边距(缩略图之间),该小部件将在一个漂亮的网格中显示所有图像缩略图,其中每个图像都有相同的宽度和高度。

我想知道 css-flexbox 或 css-grid 是否使这成为可能而不需要在代码中定义行和列并且不需要 breakpoints/media-queries.

缩略图图像被包裹在一个锚点中,因此画廊项目(或网格项目)看起来像这样:

<a href="#" class="gallery-item">
    <img src="myimage" width="300" height="200" />
</a>

图库项目应完全填满容器 div,这意味着一行中的最后一个缩略图与容器 div 的右边缘之间不应有间隙(除非我们没有足够的项目来填充该行,即当连续 3 个项目时,但我们只有 8 个项目,那么第 3 行将只有 2 个项目,右边的间隙与一个项目一样宽) .

图库项目的宽度永远不能超过用户设置的缩略图宽度,因为我们不想降低缩略图的质量。假设此示例的宽度为 300 像素。图库项目之间的边距是固定的,由用户设置。如果没有足够的项目来填充一行,只需将它们左对齐即可,例如:

我不想在 CSS 中定义任何断点,也不想为 row/column 构造添加任何 html。我希望浏览器简单地并排放置尽可能多的画廊项目以适应容器。如果右侧有空隙(即 3 个缩略图 * 300px 宽度 = 900px,但容器宽度为 1000px),浏览器应缩小网格项目,以便多一个画廊项目适合并消除空隙。我需要能够在每个画廊项目周围定义边距。

您可以在此 gif 中看到所需的响应行为(在更改浏览器宽度时):

您在 gif 中看到的内容是在没有 flexbox 的情况下完成的,但需要大量 CSS,我希望通过 flexbox 避免这种情况。我对 flexbox 进行了相当多的研究,但还不能完全理解它。

感谢任何提示!

使用 flex 功能应该足以完成您的任务。请注意 IE11 中的部分支持:http://caniuse.com/#feat=flexbox.

将这些样式放在您的容器中:

.gallery {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  justify-content: space-between;
}

包装样式:

.gallery a {
  flex-grow: 1;
  flex-basis: 125px;
  max-width: 300px;
  margin: 5px;
}

图片样式:

.gallery img {
  height: 100%;
  width: 100%;
}
图像之间的

Space 可以简单地使用 margin 定义。 为了保持图像比例,您可以使用例如链接 (<a>) 作为图像 (<img>) 的包装器。

此外,为了防止放大图像,您可以在锚点上应用 flex-growflex-basismax-width 属性。 最后一行中的拉伸图像也存在问题 - 破解方法是将 n - 1(其中 n 是图像数量)空项目放入容器中。

将图像的 widthheight 设置为 100% 会强制它们自动增长到 max-width 属性定义的宽度,同时保持纵横比。

请检查工作示例: FIDDLE

如果您不介意使用媒体断点,请使用新的 CSS Grid Layout。 不要忘记为 IE10+ 支持添加前缀。

网格:

.gallery {
    display: grid;
    grid-gap: 5px;
}

响应式图片:

.gallery img {
    width: 100%;
}

媒体断点(取自 Bootstrap 4 的值)

@media (max-width: 575.98px) {
    .gallery {
        grid-template-columns: repeat(1, 1fr);
    }
}
@media (max-width: 768.98px) and (min-width: 576px) {
    .gallery {
        grid-template-columns: repeat(2, 1fr);
    }
}
@media (max-width: 991.98px) and (min-width: 768px) {
    .gallery {
        grid-template-columns: repeat(3, 1fr); 
    }
}
@media (max-width: 1199.98px) and (min-width: 992px) {
    .gallery {
        grid-template-columns: repeat(4, 1fr); 
    }
}
@media (min-width: 1200px) {
    .gallery {
        grid-template-columns: repeat(5, 1fr); 
    }
}

jsFiddle