CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。

CSS 网格和自定义形状,第 1 部分

在之前的文章中,我研究了 CSS Grid 的能力 使用其自动放置功能创建复杂的布局. 我在另一篇文章中更进一步 为网格布局中的图像添加了缩放悬停效果. 这一次,我想深入研究另一种类型的网格,一种适用于形状的网格。

比如,如果图像不是完全正方形,而是形状像六边形或菱形怎么办? 剧透警报:我们可以做到。 事实上,我们将结合我们已经研究过的 CSS Grid 技术并加入一些 CSS clip-pathmask 为您可以想象的任何形状创建精美的图像网格的魔法!

让我们从一些标记开始

我们将要看到的大多数布局乍一看似乎很容易实现,但具有挑战性的部分是用 相同的 HTML 标记. 我们可以使用很多包装器, divs,等等,但这篇文章的目标是使用相同且最少的 HTML 代码,并且仍然获得我们想要的所有不同的网格。 毕竟,除了一种分离样式和标记的方法之外,CSS 是什么? 我们的样式不应该依赖于标记,反之亦然。

这就是说,让我们从这个开始:

<div class="gallery">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <!-- as many times as we want -->
</div>

一个带有图像的容器就是我们在这里所需要的。 而已!

六边形的 CSS 网格

这有时也被称为“蜂窝”网格。

已经有很多其他的博客文章展示了如何做到这一点。 咳咳,我 写了一篇 这里是 CSS 技巧! 那篇文章仍然很好,并且深入研究了响应式布局。 但是对于这种特殊情况,我们将依赖一种更简单的 CSS 方法。

首先,让我们使用 clip-path 在图像上创建六边形形状,我们将它们全部放在同一个网格区域中,以便它们重叠。

.gallery {
  --s: 150px; /* controls the size */
  display: grid;
}

.gallery > img {
  grid-area: 1/1;
  width: var(--s);
  aspect-ratio: 1.15;
  object-fit: cover;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0 50%)

还没有什么花哨的。 所有的图像都是六边形并且在彼此之上。 所以看起来我们只有一个六边形的图像元素,但实际上有七个。

下一步是对图像应用平移以将它们正确放置在网格上。

CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
CSS 网格和自定义形状,第 1 部分

请注意,我们仍然希望其中一张图像保持在中心。 其余部分使用 CSS 放置在它周围 translate 和良好的老式几何形状。 这是我为网格中的每个图像提出的模拟公式:

translate((height + gap)*sin(0deg), (height + gap)*cos(0))
translate((height + gap)*sin(60deg), (height + gap)*cos(60deg))
translate((height + gap)*sin(120deg), (height + gap)*cos(120deg))
translate((height + gap)*sin(180deg), (height + gap)*cos(180deg))
translate((height + gap)*sin(240deg), (height + gap)*cos(240deg))
translate((height + gap)*sin(300deg), (height + gap)*cos(300deg))

稍后进行一些计算和优化(让我们跳过那个无聊的部分,对吧?)我们得到以下 CSS:

.gallery {
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  display: grid;
}
.gallery > img {
  grid-area: 1/1;
  width: var(--s);
  aspect-ratio: 1.15;
  object-fit: cover;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50% ,75% 100%, 25% 100%, 0 50%);
  transform: translate(var(--_x,0), var(--_y,0));
}
.gallery > img:nth-child(1) { --_y: calc(-100% - var(--g)); }
.gallery > img:nth-child(7) { --_y: calc( 100% + var(--g)); }
.gallery > img:nth-child(3),
.gallery > img:nth-child(5) { --_x: calc(-75% - .87*var(--g)); }
.gallery > img:nth-child(4),
.gallery > img:nth-child(6) { --_x: calc( 75% + .87*var(--g)); }
.gallery > img:nth-child(3),
.gallery > img:nth-child(4) { --_y: calc(-50% - .5*var(--g)); }
.gallery > img:nth-child(5), 
.gallery > img:nth-child(6) { --_y: calc( 50% + .5*var(--g)); }

也许当我们得到 CSS中的实三角函数!

每张图片都由 --_x--_y 基于这些公式的变量。 只有第二张图片(nth-child(2)) 在任何选择器中都是未定义的,因为它位于中心。 如果您决定使用不同的顺序,它可以是任何图像。 这是我使用的顺序:

CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
CSS 网格和自定义形状,第 1 部分

只需几行代码,我们就得到了一个很酷的图像网格。 为此,我在图像上添加了一点悬停效果,让事情变得更漂亮。

你猜怎么着? 我们可以通过简单地更新一些值来获得另一个六边形网格。

如果您检查代码并将其与前一个代码进行比较,您会注意到我只是交换了里面的值 clip-path 我在 --x--y. 就这样!

CSS 菱形网格

菱形是一个旋转 45 度的正方形的奇特词。

相同的 HTML,还记得吗? 我们首先在 CSS 中定义一个 2×2 的图像网格:

.gallery {
  --s: 150px; /* controls the size */

  display: grid;
  gap: 10px;
  grid: auto-flow var(--s) / repeat(2, var(--s));
  place-items: center;
}
.gallery > img {
  width: 100%; 
  aspect-ratio: 1;
  object-fit: cover;
}

可能引起你注意的第一件事是 grid 财产。 它非常不常用,但非常有用,因为它是一种速记,可让您在一个声明中定义完整的网格。 它不是最直观的——更不用说可读的——属性,但我们在这里 学习通过各种方式找到 新事物,所以让我们使用它而不是写出所有单独的网格属性。

grid: auto-flow var(--s) / repeat(2,var(--s));

/* is equivalent to this: */
grid-template-columns: repeat(2, var(--s));
grid-auto-rows: var(--s);

这定义了两列等于 --s 变量并将所有行的高度设置为 --s 也是。 由于我们有四张图像,我们将自动获得一个 2×2 的网格。

这是我们可以编写的另一种方式:

grid-template-columns: repeat(2, var(--s));
grid-template-rows: repeat(2, var(--s));

…可以通过 grid 速记:

grid: repeat(2,var(--s)) / repeat(2,var(--s));

设置网格后,我们用 CSS 旋转它和图像 transforms 我们得到这个:

请注意我如何旋转它们 45deg,但方向相反。

.gallery {
  /* etc. */
  transform: rotate(45deg);
}
.gallery > img {
  /* etc. */
  transform: rotate(-45deg);
}

向负方向旋转图像可防止它们与网格一起旋转,因此它们保持笔直。 现在,我们应用一个 clip-path 从它们中剪出菱形。

CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)

我们快完成了! 我们需要纠正图像的大小以使它们适合在一起。 否则,它们的间距会很远,以至于看起来不像图像网格。

CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
CSS 网格和自定义形状,第 1 部分

图像在绿色圆圈的边界内,绿色圆圈是放置图像的网格区域的内切圆。 我们想要的是将图像变大以适合红色圆圈,即网格区域的外接圆。

别担心,我不会再介绍任何无聊的几何。 您只需要知道每个圆的半径之间的关系是2的平方根(sqrt(2))。 这是我们需要增加图像大小以填充该区域的值。 我们将使用 100%*sqrt(2) = 141% 完成!

.gallery {
  --s: 150px; /* control the size */

  display: grid;
  grid: auto-flow var(--s) / repeat(2,var(--s));
  gap: 10px;
  place-items: center;
  transform: rotate(45deg);
}
.gallery > img {
  width: 141%; /* 100%*sqrt(2) = 141% */
  aspect-ratio: 1;
  object-fit: cover;
  transform: rotate(-45deg);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}

就像六边形网格一样,我们可以通过漂亮的缩放悬停效果让事情变得更漂亮:

三角形的 CSS 网格

您现在可能已经知道,最大的诀窍是弄清楚 clip-path 得到我们想要的形状。 对于这个网格,每个元素都有自己的 clip-path 值,而最后两个网格以一致的形状工作。 所以,这一次,就像我们正在处理几个不同的三角形形状,它们组合在一起形成一个矩形的图像网格。

CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
顶部的三个图像
CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
底部的三张图

我们使用以下 CSS 将它们放置在 3×2 网格中:

.gallery {
  display: grid;
  gap: 10px; 
  grid-template-columns: auto auto auto; /* 3 columns */
  place-items: center;
}
.gallery > img {
  width: 200px; /* controls the size */
  aspect-ratio: 1;
  object-fit: cover;
}
/* the clip-path values */
.gallery > img:nth-child(1) { clip-path: polygon(0 0, 50% 0, 100% 100% ,0 100%); }
.gallery > img:nth-child(2) { clip-path: polygon(0 0, 100% 0, 50% 100%); }
.gallery > img:nth-child(3) { clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%); }
.gallery > img:nth-child(4) { clip-path: polygon(0 0, 100% 0, 50% 100%, 0 100%); }
.gallery > img:nth-child(5) { clip-path: polygon(50% 0, 100% 100%, 0% 100%); }
.gallery > img:nth-child(6) { clip-path: polygon(0 0, 100% 0 ,100% 100%, 50% 100%); } }

这是我们得到的:

最后一点是使中间列的宽度相等 0 摆脱图像之间的空间。 我们在菱形网格中遇到了同样的间距问题,但对我们使用的形状采用了不同的方法:

grid-template-columns: auto 0 auto;

我不得不摆弄 clip-path 值,以确保它们看起来像拼图一样很好地组合在一起。 中间一列宽度为零时原始图像重叠,但切片图像后,错觉完美:

CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
CSS 网格和自定义形状,第 1 部分

CSS 比萨饼网格

你猜怎么着? 我们可以通过简单地添加另一个很酷的网格 border-radiusoverflow 到我们的网格或三角形。 🎉

拼图的 CSS 网格

这次我们要玩 CSS mask 属性使图像看起来像拼图的碎片。

如果你还没有用过 mask CSS 渐变,我强烈建议 这另一篇文章 我写了这个话题,因为它会帮助接下来发生的事情。 为什么是渐变? 因为这就是我们用来在拼图形状中获得圆形凹口的方法。

设置网格现在应该是小菜一碟,所以让我们专注于 mask 部分。

如上面的演示所示,我们需要两个渐变来创建最终形状。 一个渐变创建一个圆形(绿色部分),另一个在填充顶部时创建正确的曲线。

--g: 6px; /* controls the gap */
--r: 42px;  /* control the circular shapes */

background: 
  radial-gradient(var(--r) at left 50% bottom var(--r), green 95%, #0000),
  radial-gradient(calc(var(--r) + var(--g)) at calc(100% + var(--g)) 50%, #0000 95%, red)
  top/100% calc(100% - var(--r)) no-repeat;

两个变量控制形状。 这 --g 变量不过是网格间隙。 我们需要考虑间隙以正确放置我们的圆圈,以便在组装整个拼图时它们完美重叠。 这 --r 变量控制拼图形状的圆形部分的大小。

CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
CSS 网格和自定义形状,第 1 部分

现在我们采用相同的 CSS 并更新其中的一些值来创建其他三个形状:

我们有形状,但没有我们需要使它们组合在一起的重叠边缘。 每个图像都被限制在它所在的网格单元中,所以现在形状有点混乱是有道理的:

CSS 网格和自定义形状,第 1 部分 PlatoBlockchain 数据智能。 垂直搜索。 哎。
CSS 网格和自定义形状,第 1 部分

我们需要通过增加图像的高度/宽度来创建溢出。 从上图中,我们必须增加第一个和第四个图像的高度,同时增加第二个和第三个图像的宽度。 您可能已经猜到我们需要使用 --r 变量。

.gallery > img:is(:nth-child(1),:nth-child(4)) {
  width: 100%;
  height: calc(100% + var(--r));
}
.gallery > img:is(:nth-child(2),:nth-child(3)) {
  height: 100%;
  width: calc(100% + var(--r));
}

我们越来越近了!

我们创建了重叠,但默认情况下,我们的图像要么在右侧(如果我们增加宽度)重叠,要么在底部(如果我们增加高度)重叠。 但这不是我们想要的第二张和第四张图片。 解决方法是使用 place-self: end 在这两张图片上,我们的完整代码变成了这样:

这是另一个示例,我使用圆锥渐变而不是径向渐变。 这为我们提供了三角形拼图,同时保持相同的底层 HTML 和 CSS。

最后一个! 这次我使用 clip-path 并且由于它是我们可以动画的属性,我们只需更新控制形状的自定义属性即可获得很酷的悬停。

结束了

这就是第一部分的全部内容! 通过将我们已经了解的有关 CSS Grid 的内容与添加的一些内容相结合 clip-pathmask 神奇的是,我们能够制作具有不同形状的网格布局。 而且我们每次都使用相同的 HTML 标记! 标记本身只不过是一个包含少量图像元素的容器!

在第二部分中,我们将探索外观更复杂的网格,它们具有更多花哨的形状和悬停效果。

我打算演示我们一起制作的扩展图像面板 这另一篇文章:

…并将其转换为之字形图像面板! 这只是我们将在下一篇文章中发现的众多示例中的一个。

时间戳记:

更多来自 CSS技巧