让我们构建一个真正的正方形网格,并在每个正方形内居中放置一些杂志的徽标。我想你们中的许多人以前都必须构建过徽标网格。您可能已经可以想象它:网站的一个区域列出了捐助者、赞助商,或者展示了使用某些产品的那些大型知名公司。将徽标放入正方形是一种不错的处理方式,因为它迫使所有不同大小、纵横比和视觉权重的徽标之间保持干净的结构,这可能会变得很麻烦,看起来很凌乱。
我所说的“网格”是指 CSS 网格。建立一个(灵活的)正方形网格本身就是一个技巧。然后,我们将以一种保持其大小和居中的方式将这些徽标放置在那里。最后,我们将看看一个小小的奇点。
1) 网格标记
您是否曾在支持 Emmet 的编辑器中尝试过此操作?
.grid>div*5>img
然后按tab键。它将扩展为
<div class="grid">
<div><img src="" alt=""></div>
<div><img src="" alt=""></div>
<div><img src="" alt=""></div>
<div><img src="" alt=""></div>
<div><img src="" alt=""></div>
</div>
只是一个快速工作的小技巧。
2) CSS 网格基础
我们将使用臭名昭著的灵活列技术
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 1rem;
}
这将不仅为我们提供灵活的列,还提供灵活的列数。请记住,我们并不真正关心有多少列——我们只是在构建一个徽标网格来显示。
如果我们给每个网格项目 div 设置一个背景和一个强制高度,我们会看到类似以下内容

2) 制作真正的正方形
与其强制网格项目具有特定高度,不如使用纵横比技巧。我们将用padding-bottom: 100%;
放置一个空的伪元素,这意味着它将强制高度至少与宽度一样高。
.grid > div {
background: black;
padding: 1rem;
}
.grid > div::before {
content: "";
padding-bottom: 100%;
display: block;
}
如果我们暂时隐藏图像,您将看到矩形网格已变为完美的正方形网格

3) 使图像重叠
但是在图像位于其中时,它们会变得有点长方形,因为图像位于伪元素中。

我们需要一种将它们彼此叠加的方法。通常,使用纵横比技术,我们会使用绝对定位来放置内部子容器,以覆盖现在具有纵横比的形状。但是,由于我们已经使用了网格,所以让我们再次使用网格将项目放置在同一空间中
.grid > div {
/* ... */
display: grid;
}
.grid > div::before,
.grid > div > img {
grid-area: 1 / 1 / 2 / 2;
}
这意味着将主网格的网格项目也变成网格容器,没有明确的行和列,然后将伪元素和图像都放置在该网格的第一行和第一列中。这将迫使它们重叠,再次形成一个漂亮的正方形网格。

4) 放置图像
让我们在那里为每个图像放置一个合适的src
。如果我们确保图像使用width: 100%
填充空间(并限制自身),我们将看到它们沿着网格项目的顶部

还不错,但我们更希望看到它们居中。这是一个技巧。首先,我们还将使它们的height: 100%
,这会扭曲它们

然后使用object-fit
修复它!
.grid > div > img {
width: 100%;
height: 100%;
object-fit: contain;
}
就是这样

这将响应式工作
5) 奇特的拖动大小
这(可能)不是什么大问题,但请注意,当您将徽标拖离(例如,用户在尝试保存一个徽标时可能会这样做)时,徽标是什么样的
这些图像看起来就像width: 100%; height: 100%;
没有object-fit: contain;
。
以下是到目前为止的工作演示,其中包含该怪癖
6) 改用绝对定位
如果拖动怪癖是一个大问题,我们可以始终将图像绝对定位在网格子元素内。
以下是一种方法,假设网格子元素 div 为position: relative;
.grid > div > img {
position: absolute;
max-width: 100%;
top: 0;
bottom: 0;
right: 0;
left: 0;
margin: auto;
}
还有一种方法
.grid > div > img {
position: absolute;
max-width: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
这两种方法都可以解决拖动怪癖。以下是一个演示
视频
如果您想观看此过程的视频演练,请前往这里!
很棒……喜欢它的一切。
实际上,我在 Firefox 中没有出现拉伸时拖动错误。可能是 Chrome 的问题
我在新的 Edge 中也没有遇到它。奇怪
关于:.grid>div*5>img
好技巧!
我给它加了一点晃动,并在悬停时进行了背光。
这是一个非常有趣的方法,也是一个非常实用的解决方案。
不过我认为您提到的拖动怪癖是 Mac 特有的?我在 Windows 10 上使用最新版本的 Firefox 和 Chrome 并没有看到任何失真。
感谢分享!
我真的很感谢这一点,它真的很酷
深入研究实际问题的技术文章非常有趣。我永远不会想到检查拖动功能,更不用说为它重构我的代码了。但正是这种对细节的关注对于拥有大量用户的重大项目来说是必不可少的。
为什么在图像上使用绝对定位,而您可以用两行 flexbox 解决这个问题?
您只需在子 div 上使用“display: flex; align-items: center;”,图像就会完美居中。我认为这种解决方案更简洁。
我在几个不同的方法中都介绍了这一点,尤其是在视频中。绝对定位是其中之一。网格是另一种。由于整个内容都是网格,所以我更喜欢网格解决方案,但你说得对,flexbox 也能够很好地居中内容。
这行不通。图像需要位于伪元素的顶部
非常棒,非常有用!
相关的是,我在 2 月份(基于 Piper Haywood 的代码)做了一些实验,至少部分地规范化了不同纵横比的徽标的视觉权重。它将图像的大小调整为具有大致相当的像素平方英寸的表面积。你可以在这里看到一个更详细的解释的演示
https://nicksherman.com/size-by-area/
只是好奇这里使用 `
` 和 `- ` 作为网格项是否会更明智/语义化?
此外,对我来说,在 Chrome(Windows 上)中,图像以网格中相同的宽度/高度拖动,因此没有奇怪的爆炸尺寸。看起来像一个浏览器怪癖。
你当然可以使用无序列表!我想这会向屏幕阅读器用户宣布有多少个徽标,如果你认为这对他们很重要的话。可能最好问问你的屏幕阅读器用户他们是否认为这很重要。对我来说似乎并不重要,但我不是屏幕阅读器用户。如果它们的顺序很重要,你也有有序列表。
绝对应该使用 `
` 和 `- `。我们这里有一系列的徽标。它们可能以网格形式显示,但显然是一个列表。看得见的用户会立即知道有多少个,因为这是视觉上显而易见的,视觉信息通常比人们处理音频信息快得多。依赖屏幕阅读器的用户则不会,直到他们的阅读器到达结尾,并且如果他们一直在计数。
此外,因为它不会影响视觉表示,所以这是一个零和游戏。
这对于 SVG 有效吗?——想知道为什么你没有使用 SVG 作为链接图像(即不是内联的),而是使用 PNG ;)
很酷的文章,我只错过了一件事(我过去不得不处理的事情)。
你使用的这些徽标都是宽而短的。但是,如果你必须将不同纵横比的徽标放到网格中呢?想象一下,那里有一些方形的徽标,也许有一些高的?
提醒一下:图像拖动时看起来很奇怪的方式似乎在 Firefox 中不会发生,所以它在将来可能会在 Chrome 中修复!
这对我来说不起作用!
我的图像变大,覆盖了方格,而不是填充它们。
嘿,这很棒!
感谢你花时间整理这些。
我正在阅读有关 CSS 网格的信息,对这个功能还很陌生。
是否有可能让网格和网格项扩展以填充给定的屏幕,而不是在网格底部留下空白?
这将类似于 Zoom 应用屏幕。
例如,如果有四个徽标,它们会对称地拉伸以填充整个屏幕,或者如果有 1000 个,它们也会这样做?
上述情况是否可行?
再次感谢!
Marc
嘿,Marc!是的,如果你从 `.grid` 元素中删除 `grid-gap` 属性,那么所有徽标都会紧贴在一起。秘密酱汁就在这里
这告诉元素将自己分成尽可能多的列来填充空间,只要每列不小于 200 像素。超过 200 像素,列将平等地共享空间 (1fr)。
嗨,我想做这个,但我希望图像可以点击以链接到一个链接。当我将 a href 链接标签添加到 img 标签之前,它似乎破坏了布局,拉伸了图标。