制作六边形网格
首先,创建我们的六边形。这个任务使用 clip-path 实现起来相当容易。另外推荐一个很棒的剪辑路径的在线生成器Clippy。裁剪示意图一:
<div class="main"><div class="container"><div></div><div></div><div></div><!--更多的元素. --> </div></div>
css
设置为:
.main {display: flex;--s: 100px;/* size*/--m: 4px; /* margin */}.container {font-size: 0; /* 禁用内联块元素之间的空白 */}.container div {width: var(--s);margin: var(--m);height: calc(var(--s) * 1.1547);display: inline-block;font-size: initial;clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);}
到目前为止并没有什么复杂的处理逻辑,我们设置了一个容器container
来存放inline-block
的六边形元素,另外我们需要处理因为inline-block
而导致的空白间隙问题(我们使用font-size: 0;
进行修复):
<img src=“https://p6-juejin.byteimg.com/tos–cn-i-k3u1fbpfcp/1ab71f73de2d4087afde739f7c4de970~tplv-k3u1fbpfcp–zoom–in–crop–mark:4536:0:0:0.image?) 每隔一行我们都需要设置一些偏移量,以便使六边形元素重叠而不是直接堆叠在彼此之上。该偏移量将等于25%
的元素高度(参考图 1)。我们将该偏移量应用于margin-bottom
” style=“margin: auto” />
.container div {width: var(--s);margin: var(--m);height: calc(var(--s) * 1.1547);display: inline-block;font-size: initial;clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);margin-bottom: calc(var(--m) - var(--s) * 0.2886); /* 设置底部边距 */}
…结果变成: <img src=“https://p9-juejin.byteimg.com/tos–cn-i-k3u1fbpfcp/a05659e35f23495ebbdedf2dc51ced73~tplv-k3u1fbpfcp-zoom–in–crop-mark:4536:0:0:0.image?) 现在我们面临的问题是如何移动第二行元素以获得完美的六边形网格。我们已经将元素压缩到行彼此垂直重叠的程度,我们还需要的是将元素每隔一行向右推,以便六边形交错而不是重叠。这时候就是float
发挥shape-outside作用的时刻了” style=“margin: auto” />
你有没有想过为什么我们要设置一个display: flex
的.main
元素来包裹我们的容器.container
?该操作也是 div
布局技巧的一部分:
<div style="display:flex"> <!-- flex item: block child --> <div id="item1">block</div> <!-- flex item: floated element; 浮动被忽略 --> <div id="item2" style="float: left;">float</div> <!-- flex item: 行内文本会生成一个匿名的块 --> anonymous item 3 <!-- flex item: inline child --> <span> item 4 <!-- flex items 内为普通流布局 --> <q style="display: block" id=not-an-item>item 4</q> item 4 </span> </div>
请注意,元素间的空白消失了:它不会成为自己的弹性项目,即使元素间文本_确实_被包裹在匿名弹性项目中。
还要注意匿名项的框是不可设置样式的,因为没有要为其分配样式规则的元素。然而,它的内容将从 flex 容器继承样式(例如字体设置)。
这里我们使用.container::before
伪类元素创建一个浮动元素,它占据了网格左侧的所有高度,并且宽度等于半个六边形(加上边距):
.container::before { content: ""; width: calc(var(--s)/2 + var(--m)); float: left; height: 100%; }
我们得到以下结果:
<img src=“https://p9-juejin.byteimg.com/tos–cn-i-k3u1fbpfcp/d50f61af4a704c318cf82bbfc6a22c6e~tplv-k3u1fbpfcp-zoom–in-crop-mark:4536:0:0:0.image?) 现在我们快速回顾一下shape-outside
在MDN
的描述” style=“margin: auto” />
shape-outside
的 CSS 属性定义了一个可以是非矩形的形状,相邻的内联内容应围绕该形状进行包装。默认情况下,内联内容包围其边距框;shape-outside
提供了一种自定义此包装的方法,可以将文本包装在复杂对象周围而不是简单的框中。
注意定义中的“内联内容”。这恰恰解释了为什么六边形需要的是inline-block
元素。但要了解我们需要什么样的形状,让我们放大图案:
shape-outside: repeating-linear-gradient(#0000 0 A, #000 0 B); /* #0000 是 transparent 的一种写法 */
现在我们需要定义A、B的值。因为六边形网格布局,我们需要重复每两行,因此B的值两行的高度,两行的高度等于两个六边形的高度(包括它们的边距)减去重叠的两倍(2*Height + 4*M - 2*Height*25% = 1.5*Height + 4*M
),使用csscalc()
并将该数值存在css变量f
中:
.main {display:flex;--s: 100px;/* size*/--m: 4px;/* margin */--f: calc(1.732 * var(--s) + 4 * var(--m)- 1px);}
A(上图中蓝色箭头定义的)的值需要至少等于一个六边形的大小,或更大一点。为了将第二行推到右边,我们需要一些不透明颜色的像素,所以A
可以简单地等于B - Xpx
,其中X
是一个小值,我们最终得到shape-outside
的值如下:
shape-outside: repeating-linear-gradient(#0000 0 calc(var(--f) - 3px),#000 0 var(--f));
我们将得到:
我们重复的线性渐变的形状是将每隔一行向右推一个六边形宽度的一半,以抵消图案,最终代码如下:
.main {display:flex;--s: 100px;/* size*/--m: 4px;/* margin */--f: calc(var(--s) * 1.732 + 4 * var(--m) - 1px); }.container {font-size: 0; /* 清除行内块级元素的边距 */}.container div {width: var(--s);margin: var(--m);height: calc(var(--s) * 1.1547);display: inline-block;font-size:initial;clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);margin-bottom: calc(var(--m) - var(--s) * 0.2885);}.container::before {content: "";width: calc(var(--s) / 2 + var(--m));float: left;height: 120%; shape-outside: repeating-linear-gradient(#0000 0 calc(var(--f) - 3px), #000 0 var(--f));}
至此,六边形网格布局基本完成。您可能已经注意到我在变量f
中添加了-1px
。由于我们正在处理涉及小数的计算,四舍五入可能会给我们带来不好的结果。为了避免这种情况,我们添加或删除了几个像素。出于类似的原因,我们也使用120%
而不是100%
浮动元素的高度。这些值没有特定的逻辑;我们只是简单地调整它们以确保覆盖大多数情况而不会错位我们的形状。
最后
整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。
原文地址:https://blog.csdn.net/Android062005/article/details/128535052
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_20408.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!