显示填充网格的照片 – 无论宽高比如何。

huangapple go评论73阅读模式
英文:

Displaying photos that fill the grid - regardless of aspect ratio

问题

以下是翻译的内容:

我正在尝试在React中创建一个家庭学习项目的照片库。我能够在网格中显示照片:

显示填充网格的照片 – 无论宽高比如何。

使用以下代码:

const Container = styled.div`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
justify-items: center;
align-items: center;
margin: 0;
padding: 0;
`

const PhotoWrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 200px; /* 为每个网格项设置固定高度 */
`

const Photo = styled.img`
max-width: 100%;
max-height: 100%;
object-fit: contain;
height: 100%; /* 使图像填充网格项的高度 */
`

const Home = () => {

       return (
        
            <Container>
                {imagesData.map((image) => <PhotoWrapper><Photo src={image.imageUrl} /></PhotoWrapper> )}
            </Container>
           
    )
}

export default Home

这差不多是我想要的,但是...我想让它更像Flickr。他们在填充网格时做得非常出色,而且不会拉伸照片(据我所知)。

示例:
https://www.flickr.com/prints/discover

显示填充网格的照片 – 无论宽高比如何。

他们是如何保持行的长度和高度一致的?是否有一些出色的CSS技巧?或者可能有很多后端工作来计算大小并看看什么适合?我怎样才能像那样显示我的网格?

编辑:已接受的解决方案非常适合我所需的。这是现在的样子:

显示填充网格的照片 – 无论宽高比如何。

唯一的问题是当少数照片放在最后一行时。它们被大大裁剪,很难看清它们是什么。是否有一种类似 :last 的类可以帮助解决这个问题?

显示填充网格的照片 – 无论宽高比如何。

英文:

I am trying to create a photo gallery as a home learning project in react. I am able to display the photos in a grid:

显示填充网格的照片 – 无论宽高比如何。

Using this code:

const Container = styled.div`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
justify-items: center;
align-items: center;
margin: 0;
padding: 0;
`

const PhotoWrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 200px; /* set a fixed height for each grid item */
`

const Photo = styled.img`
max-width: 100%;
max-height: 100%;
object-fit: contain;
height: 100%; /* make the image fill the height of the grid item */
`

const Home = () =&gt; {

       return (
        
            &lt;Container&gt;
                {imagesData.map((image) =&gt; &lt;PhotoWrapper&gt;&lt;Photo src={image.imageUrl} /&gt;&lt;/PhotoWrapper&gt; )}
            &lt;/Container&gt;
           
    )
}

export default Home

That's NEARLY how I want it, but... I want it to be more like Flickr. Who do an AMAZING job at filling the grid without stretching photos (That I can tell).

Example:
https://www.flickr.com/prints/discover

显示填充网格的照片 – 无论宽高比如何。

How do they manage to keep the rows the same length, and height? Is there some awesome CSS trick? Or is there maybe a load of backend work to calculate sizes and see what fits? How can I display my grid like that?

Edit: The solution accepted is amazing for what I need. Here's what it looks like for me now:

显示填充网格的照片 – 无论宽高比如何。

The only issue is when a small number of photos go onto the last row. The get cropped a lot, ad hard to see what they are. Is there a :last type class that could help this?

显示填充网格的照片 – 无论宽高比如何。

答案1

得分: 2

一个简单的解决方案是使用 object-fitflex-wrap。请注意,如果图片无法适应,则只会显示一部分。

首先,我们需要一个具有多个 .item#gallery

<div id="gallery">
  <div class="item">
    <img src="https://www.example.com/img.png">
  </div>
  <!-- ... -->
</div>

由于无法预测图像的数量和宽度,我们将 #gallery 设置为 flex-wrap: wrap 容器。

#gallery {
  display: flex;
  flex-wrap: wrap;
}

然后,允许 .item 在其行上自由扩展,行的高度固定为 100px 或您选择的其他值:

.item {
  flex: 1 1 auto;
  height: 100px;
}

最后,为图像设置 object-fit: cover。这个设置,再加上 height: 100%width: 100%,确保它们始终触碰两侧并溢出另外两侧:

.item img {
  object-fit: cover;
  height: 100%;
  width: 100%;
}

尝试一下:

(最后的图像可能有点太宽,因为我们显示的图像数量有限,但通常使用infiniscroll来解决这个问题。)

【代码部分未翻译】

英文:

A simple solution is to use object-fit and flex-wrap. Note that only a portion of an image will be displayed if it doesn't fit.

First, we need a #gallery with multiple .items:

&lt;div id=&quot;gallery&quot;&gt;
  &lt;div class=&quot;item&quot;&gt;
    &lt;img src=&quot;https://www.example.com/img.png&quot;&gt;
  &lt;/div&gt;
  &lt;!-- ... --&gt;
&lt;/div&gt;

As the number of images and their width cannot be predicted, we make #gallery a flex-wrap: wrap container.

#gallery {
  display: flex;
  flex-wrap: wrap;
}

We then allow .items to expand as much as they'd like on their row, which has a fixed height of 100px or another value of your choice:

.item {
  flex: 1 1 auto;
  height: 100px;
}

Finally, set object-fit: cover for the images. This, along with height: 100% and width: 100%, ensure that they will always touch two sides and overflow the other two:

.item img {
  object-fit: cover;
  height: 100%;
  width: 100%;
}

Try it:

(The last images might be a bit too wide, since we are displaying a limited number of images, but infiniscroll is normally used to overcome this.)

<!-- begin snippet: js hide: true console: false babel: false -->

<!-- language: lang-js -->

/**
 * Randomly add 15 - 44 images, of which sizes are in range 100 - 499.
**/

const gallery = document.querySelector(&#39;#gallery&#39;);

const l = 15 + Math.random() * 30 | 0;

for (let i = 0; i &lt; l; i++) {
  const wrapper = document.createElement(&#39;div&#39;);
  const img = document.createElement(&#39;img&#39;);
  
  const [width, height] = [0, 0].map(
    _ =&gt; 100 + Math.random() * 400 | 0
  );
  
  wrapper.classList.add(&#39;item&#39;);
  img.src = `https://picsum.photos/${width}/${height}`;
  
  wrapper.appendChild(img);
  gallery.appendChild(wrapper);
}

<!-- language: lang-css -->

#gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 1em;
}

.item {
  flex: 1 1 auto;
  display: flex;
  height: 100px;
}

.item img {
  object-fit: cover;
  object-position: center center;
  height: 100%;
  width: 100%;
}

body {
  background: #000;
}

<!-- language: lang-html -->

&lt;div id=&quot;gallery&quot;&gt;&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月11日 09:05:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75981738.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定