用offset-path实现N多子元素静态布局
本帖最后由 马黑黑 于 2022-11-12 08:36 编辑此前介绍过offset-path,借助该CSS属性,通过svg路径(无需svg标签)实现各种路线的关键帧动画。本帖,则简单探讨一下使用 offset-path 实现子元素沿svg路径(同样无需svg标签)的静态布局(即摆放成什么样子)。
我们先来复习一下 offset-pass 这个 CSS 属性,它的语句一般是酱紫:
offset-path: path('svg路径');
offset-path 是属性名称,其后用冒号引出值。值的构成用 path 关键字引导,svg 路径放在小角引号内,并整体置于小角小括号内。
关于路径,要求符合 svg 路径表达规则,即,只要是合法的 svg 路径均可使用。路径可以自己制作,也可以通过工具生成。
配套 offset-path 属性使用的另一个重要的CSS属性,offset-distance,则能将子元素布置到路径上的指定位置,例如,我们把子元素放置在路径上的50%处:
offset-distance: 50%;
下面开始实现子元素的静态布局——
子元素的静态布局需要载体,所以,我们先得创建一个父盒子:
#papa {
margin: auto;
width: 1024px;
height: 640px;
background: snow;
box-shadow: 3px 3px 20px #000;
display: grid;
place-items: center;
position: relative;
}
接着设定子元素的样式。本帖示范的,是帖子 《只爱我自己》 里的心形效果(注意观察 offset-path 属性和它的设定值):
.heart {
position: absolute;
left: 0;
top: 0;
width: 40px;
height: 40px;
display: grid;
place-items: center;
font: normal 40px sans-serif;
color: pink;
offset-path: path('m271.44526,175.38086c65.55493,-161.83822 322.4013,0 0,208.07771c-322.4013,-208.07771 -65.55493,-369.91593 0,-208.07771z');
}
这两个CSS盒子,都用到 grid 布局,其作用是快速定位子元素绝对居中(.heart也将拥有文本,文本是其子元素)。
记得写上HTML代码:
<div id="papa"></div>
在HTML代码里,我们没有写上任何一个 .heart 的子元素,它们将由 JS 生成,因为量大:
<script>
let total = 25;
Array.from({length: total}).forEach((item,key) => {
item = document.createElement('span');
item.className = 'heart';
item.innerText = '♥';
item.style.offsetDistance = 100/total *key + '%';
papa.appendChild(item);
});
</script>
JS代码里,total 变量是 ♥ 的总数,可根据实际场景决定赋值。
然后遍历长度为 total 个子项目的数组,每一个数组元素都遍历(forEach)一次,遍历中对每一个数组元素进行处理:
① 将 forEach() 的参数 item 赋值为待添加的子元素 span;
② item 的CSS类名为 heart;
③ item 的文本内容为 ♥(本论坛需要使用Unicode编码表示心形:\u2764);
④ 重要!设置偏移距离(offsetDistance),实现按路径分散摆放效果。offsetDistance可以使用百分比表示偏移量,所以有这个算式 100/total *key ,后面再加上字串 '%';
⑤ 最后将子元素 item 追加到 papa 父框,papa.appendChild(item);
偏移路径起始点、分散摆放子元素的实现,核心是CSS属性 offset-distance,偏移距离,在JS里写为 offsetDistance 。子元素偏移量的计算,以自身的索引(forEach参数中的key)参与计算,从而实现路径上的均衡布局。
效果请查看下楼。
<style>
#papa {
margin: 0 0 0 calc(50% - 593px);
width: 1024px;
height: 640px;
background: snow;
box-shadow: 3px 3px 20px #000;
display: grid;
place-items: center;
position: relative;
}
.heart {
position: absolute;
left: 0;
top: 0;
width: 40px;
height: 40px;
display: grid;
place-items: center;
font: normal 40px sans-serif;
color: pink;
offset-path: path('m271.44526,175.38086c65.55493,-161.83822 322.4013,0 0,208.07771c-322.4013,-208.07771 -65.55493,-369.91593 0,-208.07771z');
}
</style>
<div id="papa">
</div>
<script>
let total = 25;
Array.from({length: total}).forEach((item,key) => {
item = document.createElement('span');
item.className = 'heart';
item.innerText = '\u2764';
item.style.offsetDistance = 100/total *key + '%';
papa.appendChild(item);
});
</script>
二楼效果的代码
<style>
#papa {
margin: auto;
width: 1024px;
height: 640px;
background: snow;
box-shadow: 3px 3px 20px #000;
display: grid;
place-items: center;
position: relative;
}
.heart {
position: absolute;
left: 0;
top: 0;
width: 40px;
height: 40px;
display: grid;
place-items: center;
font: normal 40px sans-serif;
color: pink;
offset-path: path('m271.44526,175.38086c65.55493,-161.83822 322.4013,0 0,208.07771c-322.4013,-208.07771 -65.55493,-369.91593 0,-208.07771z');
}
</style>
<div id="papa">
</div>
<script>
let total = 25;
Array.from({length: total}).forEach((item,key) => {
item = document.createElement('span');
item.className = 'heart';
item.innerText = '\u2764';
item.style.offsetDistance = 100/total *key + '%';
papa.appendChild(item);
});
</script>
如果需要移动心形在papa盒子中的位置,请酌情修改 .heart 选择器的 top 和 left 值 好想学习一个。。 这星星好漂亮,谢谢黑黑分享教程{:4_187:} 水区的彩色星星也是很漂亮的{:4_178:} 白开水 发表于 2022-11-12 08:55
好想学习一个。。
这个不是很复杂,慢慢看都能懂 小辣椒 发表于 2022-11-12 11:40
水区的彩色星星也是很漂亮的
彩色的可能更丰富 小辣椒 发表于 2022-11-12 11:39
这星星好漂亮,谢谢黑黑分享教程
喝水{:4_190:} 马黑黑 发表于 2022-11-12 12:03
喝水
都学老头{:4_180:} 马黑黑 发表于 2022-11-12 12:02
彩色的可能更丰富
是的,和淡色图图衬托会更加漂亮 小辣椒 发表于 2022-11-12 13:40
是的,和淡色图图衬托会更加漂亮
一切看着办就好,你的帖子就应用的不错 小辣椒 发表于 2022-11-12 13:40
都学老头
适当喝水挺好的
这个 100/total *key公式没看懂,为什么是这样的取值? 红影 发表于 2022-11-12 16:52
这个 100/total *key公式没看懂,为什么是这样的取值?
offset-distance 偏移初始点的设置,这里使用百分比,total 是子元素总数量,子元素在100个单位里平均偏移量当然要用 100 除以 总数,然后,每个子元素都有自己的所以,从 0 开始,key 就是子元素的索引。
以第一个子元素为例,它的偏移量 100/total *0 = 0,它在原位置,也就是路径的初始位置,其它的子元素的偏移量计算依此类推。 马黑黑 发表于 2022-11-12 12:02
这个不是很复杂,慢慢看都能懂
目前还是一脑蒙。。但是很想学会。 白开水 发表于 2022-11-12 20:03
目前还是一脑蒙。。但是很想学会。
需要点基础,CSS,HTML,JS
马黑黑 发表于 2022-11-12 20:04
需要点基础,CSS,HTML,JS
那完了。我都不会耶。 白开水 发表于 2022-11-12 20:21
那完了。我都不会耶。
那很难理解和掌握