Cet article partagera avec vous les techniques avancées de mise en page d'arrière-plan graphique irrégulière et vous présentera comment utiliser CSS pour réaliser une image d'arrière-plan de grille hexagonale sympa. J'espère que cela sera utile à tout le monde !
Aujourd'hui, j'ai reçu une question très intéressante, comment réaliser un rendu de fond similaire à celui-ci :
Hmm ? Le corps central est formé par superposition de plusieurs grilles hexagonales.
Alors comment y parvenir ? Est-ce possible en utilisant du CSS pur ?
Bien sûr que vous pouvez, nous allons essayer ci-dessous comment utiliser CSS pour obtenir un tel effet d'arrière-plan. [Apprentissage recommandé : Tutoriel vidéo CSS]
Tout d'abord, lorsque vous voyez un tel graphique, si vous souhaitez utiliser une étiquette pour compléter tout l'arrière-plan, la première chose qui vous vient à l'esprit est certainement d'utiliser l'arrière-plan. Mais malheureusement, bien que l'arrière-plan en CSS soit très. puissant, ce n'est pas un moyen particulièrement efficace qui permet de générer des arrière-plans hexagonaux répétés par lots.
Donc, dans cette exigence, nous devrons peut-être nous contenter de la meilleure solution suivante, une implémentation hexagonale utilisant une étiquette.
Donc, en prenant 1 DIV comme exemple, de combien de façons avons-nous pour implémenter un hexagone ? Voici 2 façons de présenter brièvement :
Tout d'abord, utilisez la bordure pour implémenter la forme des hexagones. L’essentiel ici est que les triangles supérieur et inférieur chevauchent un rectangle au milieu. Ici, deux pseudo-éléments de l'élément sont utilisés pour implémenter les triangles supérieur et inférieur, de sorte que l'élément ressemble à un hexagone.
L'idée est relativement simple, il suffit d'aller au code :
.hexagon { position: relative; width: 200px; height: 100px; background-color: red; } .hexagon:before, .hexagon:after { content: ""; position: absolute; width: 0; height: 0; border-left: 100px solid transparent; border-right: 100px solid transparent; } .hexagon:before { bottom: 100%; border-bottom: 50px solid red; } .hexagon:after { top: 100%; border-top: 50px solid red; }
Le code ci-dessus va créer un hexagone d'une largeur de 200 pixels et d'une hauteur de 100 pixels, composé de deux triangles et d'un rectangle. L’avantage d’utiliser des pseudo-éléments est que vous pouvez facilement contrôler la taille, la couleur et d’autres styles de l’hexagone.
Bien sûr, le code ci-dessus n'est pas un hexagone régulier, car dans un hexagone régulier, la hauteur de l'élément est 1,1547 fois la largeur de l'élément.
De plus, la méthode ci-dessus est un peu plus compliquée. Par conséquent, aujourd'hui, nous vous recommandons d'utiliser la méthode clip-path
pour implémenter un hexagone : clip-path
的方式去实现一个六边形:
.clippath { --w: 100px; width: var(--w); height: calc(var(--w) * 1.1547); clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%); background: deeppink; margin: auto; }
这样,基于 clip-path
,也能快速得到一个六边形图形:
CodePen Demo -- Two ways to achieve a hexagon
好了,有了上一步的铺垫之后,接下来我们要做的,就是绘制多个六边形,组成背景。
但是我们仔细观察一下由多个六边形组成的背景,会发现每双数行的的六边形,需要向右侧有一个明显的缩进,宽度大概为单个六边形的宽度的一半:
这里其实是一个非常棘手的问题。首先,我们会想到这样一种解决方案:
每一行为一组,设置一个父 div 容器,填满六边形元素,设置元素不换行
给偶数行设置一个固定的 margin-left
基于这个策略,我们的代码,大概会是这样:
<div class="container"> <div class="wrap"> // ... 填满六边形 </div> <div class="wrap" style="margin-left: 25px"> // ... 填满六边形 </div> <div class="wrap"> // ... 填满六边形 </div> <div class="wrap" style="margin-left: 25px"> // ... 填满六边形 </div> </div>
可以看到,我们给偶数行,都添加了一个 margin-left
<div class="container"> <div class="shape-outside"> <img src="image.png"> </div> xxxxxxxxxxx,文字描述,xxxxxxxxx </div>
clip. -path
, vous pouvez aussi obtenir rapidement un graphique hexagonal :
Chaque ligne est regroupée, définir un conteneur div parent, le remplir d'éléments hexagonaux et définir les éléments à ne pas envelopper
Définir un marge-gauche🎜🎜🎜🎜Basé sur cette stratégie, notre code ressemblera probablement à ceci :🎜.shape-outside { width: 160px; height: 160px; shape-outside: circle(80px at 80px 80px); float: left; }
marge-gauche à tous lignes paires. 🎜🎜Mais il y a plusieurs problèmes avec ce code : 🎜🎜🎜🎜Notre largeur de page n'est pas nécessairement fixe, alors combien d'éléments sous-hexagonaux doivent être définis dans chaque ligne ? Trop de paramètres entraîneront inévitablement du gaspillage, et trop peu ne répondront pas aux besoins. Une couche supplémentaire d'imbrication rendra la logique du code plus compliquée. C'est-à-dire que l'effet peut échouer lorsque l'écran est très large. 🎜🎜Regardez, dans des circonstances normales, nous définissons 20 hexagones par rangée. L'image ci-dessous est normale🎜🎜🎜🎜🎜Mais si notre écran est particulièrement large, alors nous pouvons obtenir un tel effet :🎜🎜🎜 🎜<p>因此,这种方式存在非常大的弊端,我们希望能有一整布局方式,能够满足我们如下两个诉求:</p>
<ul style="list-style-type: disc;">
<li><p>所有六边形代码写在一个父容器下</p></li>
<li><p>这个弹性布局中,第二行的元素最左边,能够实现固定一个缩进</p></li>
</ul>
<p>仔细思考一下,CSS 中有能够实现类似布局的方法么?</p>
<h2 id="妙用-shape-outside-实现隔行错位布局"><strong>妙用 shape-outside 实现隔行错位布局</strong></h2>
<p>有的!在 CSS 中,有一个神奇的元素能够让元素以非直线形式排布。它就是 <code>shape-outside
!
如果你对
shape-outside
不太了解,也可以先看看我的这篇文章 -- 奇妙的 CSS shapes
shape-outside
是 CSS 中的一个属性,用于控制元素的浮动方式。它允许你定义一个元素浮动时周围元素的形状。例如,你可以使用 shape-outside
属性来定义一个元素浮动时周围元素的形状为圆形、六边形等。
它和 clip-path
的语法非常类似,很容易触类旁通。看看实例,更易理解:
假设我们有下面这样的结构存在:
<div class="container"> <div class="shape-outside"> <img src="image.png"> </div> xxxxxxxxxxx,文字描述,xxxxxxxxx </div>
定义如下 CSS:
.shape-outside { width: 160px; height: 160px; shape-outside: circle(80px at 80px 80px); float: left; }
注意,上面 .shape-outside
使用了浮动,并且定义了 shape-outside: circle(80px at 80px 80px)
,表示在元素的 (80px, 80px) 坐标处,生成一个 80px 半径的圆。
如此,将会产生一种图文混排的效果:
CodePen Demo -- 图文混排 shape-outside
总得来说,shape-outside
有两个核心特点:
shape-outside
属性仅在元素定义了 float
属性且不为 none
时才会生效
它能够实现了文字根据图形的轮廓,在其周围排列
shape-outside
的本质划重点,划重点,划重点。
所以,shape-outside
的本质其实是生成几何图形,并且裁剪掉其几何图形之外周围的区域,让内容能排列在这些被裁剪区域之内。
所以,了解了这个本质之后,我们再将他运用在上面的六边形布局之中。
为了方便理解,我们首先使用文字代替上面的六边形,假设我们有这样一段文本内容:
<p> Lorem ipsum dolor sit amet conse... </p>
p { line-height: 36px; font-size: 24px; }
非常平平无奇的一段代码,效果如下:
现在,我们想利用 shape-outside
,让文本内容的偶数行,向内缩进 24px
,怎么实现呢?非常简单:
p { position: relative; line-height: 36px; font-size: 24px; &::before { content: ""; height: 100%; width: 24px; shape-outside: repeating-linear-gradient( transparent 0, transparent 36px, #000 36px, #000 72px ); float: left; } }
这样,我们就实现了文字隔行缩进 24px
的效果:
一定有小伙伴会很好奇,为什么呢?核心在于我们利用元素的伪元素实现了一个 shape-outside
图形,如果我们把这个图形用 background
绘制出来,其实它长这样:
p { position: relative; line-height: 36px; font-size: 24px; &::before { content: ""; height: 100%; width: 24px; shape-outside: repeating-linear-gradient( transparent 0, transparent 36px, #000 36px, #000 72px ); float: left; background: repeating-linear-gradient( transparent 0, transparent 36px, #f00 36px, #f00 72px ); } }
效果如下:
因为文本的行高是 36px
,这样我们以 72 为一段,每 36px 绘制一段透明,另外 36px 绘制一段宽为 24px 的内容,这样,结合 shape-outside
的特性,我们就实现了隔行将内容向里面挤 24px
的效果!
非常的 Amazing 的技巧!完整的代码你可以戳这里:
CodePen Demo -- Shape-outside achieves even line indentation
基于这个技巧,我们就可以实现上述我们想要的效果了。我们回到正题,重新实现一个充满六边形的背景:
<ul class="wrap"> <li></li> //... 非常多个 li <ul>
:root { --s: 50px; /* size */ --m: 4px; /* margin */ --perHeight: calc(calc(var(--s) * 2 * 1.1547) + calc(var(--m) * 4) - 0.4px) } .wrap { position: relative; height: 100%; font-size: 0; &::before { content: ""; height: 100%; width: 27px; shape-outside: repeating-linear-gradient( transparent 0, transparent 70px, #000 70px, #000 var(--perHeight) ); float: left; } } li { width: var(--s); height: calc(var(--s) * 1.1547); background: #000; clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%); margin: var(--m); display: inline-block; }
借助 shape-outside
,我们就实现了隔行让我们的六边形向内缩进的诉求!效果如下:
当然,有一些优化点:
为了让两边不那么空,我们可以让整个容器更宽一点,譬如宽度为父元素的 120%
,然后水平居中,这样,两侧的留白就解决了
让两行直接贴紧,可以设置一个 margin-bottom
做完这两点优化之后,效果如下:
可以做到任意屏幕宽度下的六边形完美平铺布局:
完整的代码你可以戳这里:CodePen Demo -- Hexagon Layout
有了上述的铺垫后,要实现文章一开头的效果就不难了。
是的,我们要实现这样一个效果:
如何让它们动态的实现颜色变换呢?是给每一个六边形一个单独的颜色,然后进行动画吗?不,借助混合模式,我们可以非常快速的实现不同的颜色值。
首先,我们将上述效果,改成白底黑色六边形色块:
然后,利用父容器剩余的一个伪元素,我们叠加一层渐变层上去:
.wrap { position: relative; // 代码与上述保持一致 &::before { content: ""; // ... 实现 shape-outside 功能,代码与上述保持一致 } &::after { content: ""; position: absolute; inset: 0; background: linear-gradient(45deg, #f44336, #ff9800, #ffe607, #09d7c4, #1cbed3, #1d8ae2, #bc24d6); } }
这样,我们就叠加了一层渐变色彩层在原本的六边形背景之上:
接着,只需要一个混合模式 mix-blend-mode: darken
,就能实现六边形色块与上层渐变颜色的融合效果:
.wrap { position: relative; // 代码与上述保持一致 &::before { content: ""; // ... 实现 shape-outside 功能,代码与上述保持一致 } &::after { content: ""; position: absolute; inset: 0; background: linear-gradient(45deg, #f44336, #ff9800, #ffe607, #09d7c4, #1cbed3, #1d8ae2, #bc24d6); z-index: 1; + mix-blend-mode: darken; } }
效果如下:
好, 我们再给上层的渐变色块,添加一个 filter: hue-rotate()
动画,实现色彩的渐变动画:
.wrap { position: relative; // 代码与上述保持一致 &::before { content: ""; // ... 实现 shape-outside 功能,代码与上述保持一致 } &::after { content: ""; position: absolute; inset: 0; background: linear-gradient(45deg, #f44336, #ff9800, #ffe607, #09d7c4, #1cbed3, #1d8ae2, #bc24d6); z-index: 1; mix-blend-mode: darken; + animation: change 10s infinite linear; } } @keyframes change { 100% { filter: hue-rotate(360deg); } }
这样,我们就完美的实现了我们想要的效果:
完整的代码,你可以戳这里:CodePen Demo -- Hexagon Gradient Layout
当然,有了这个基础图形之后,其实我们可以基于这个图形,去做非常多有意思的效果。
下面我是尝试的一些效果示意,譬如,我们可以将颜色放置在六边形背景的下方,制作这样一种效果:
CodePen Demo -- Hexagon Gradient Layout
配合 mask 的蒙版效果及鼠标定位,我们还能实现这样一种有趣的交互效果:
CodePen Demo -- Hexagon Gradient & MASK Layout
当然,3D 效果也不在话下:
CodePen Demo -- 3D Hexagon Gradient Layout
原文地址:https://www.cnblogs.com/coco1s/p/17005071.html
作者:ChokCoco
(学习视频分享:web前端)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!