如何使用JavaScript为动态创建元素的CSS伪元素设置差异化高度
问题原因
所有琴弦高度都取数组最后一个值,核心问题是你把--string-height这个CSS变量设到了全局:root根节点上。
CSS变量是沿DOM树继承的,根节点上的变量全局唯一,循环里每次给根节点赋值都会覆盖前一次的结果,循环结束后根节点上存的就是数组最后一个值8,所有琴弦的伪元素从根节点继承到的自然都是同一个值,改索引也只是统一改全局值,没法做到单根差异化。
修复方法
伪元素虽然不能直接加行内样式,但它可以继承所属父元素上的CSS变量,你不用把变量挂到根节点,直接给每根单独创建的string元素设置自己的--string-height就行,各元素上的变量互相独立,不会互相覆盖。
JS部分修改
只需要改循环里设置变量的目标对象,其他逻辑不用动:
setupFretboard() { fretboard.innerHTML = ""; for (let i = 0; i < numberOfStrings; i++) { let string = tools.createElement("div"); string.classList.add("string"); // 把变量设到当前创建的琴弦元素上,不要设到root string.style.setProperty("--string-height", stringGauge[i]); fretboard.appendChild(string); } },
CSS部分说明
你原来写的CSS不用大改,:root里定义的--string-height: 8留着当默认兜底值就行。单个string元素上设置的同名变量优先级比根节点继承的高,每根弦的:before伪元素会自动读取自己父元素上的变量值,直接就能实现琴弦厚度从1到8递增的效果。
/* 原有CSS逻辑保持不变即可 */ .string:before { content: ""; width: 100%; height: calc(var(--string-height) * 1px); background: linear-gradient(#eee, #999); box-shadow: 76px 3px 10px #806233; z-index: 1; position: absolute; top: calc(var(--string-top-position) * 1px); }
后续你要给每根弦单独设置
--string-top-position这类差异化属性,也可以用同样的方式,直接给对应string元素赋值,伪元素能直接读取到,不用找其他黑科技绕过伪类不能设行内样式的限制。
内容的提问来源于stack exchange,提问作者RScanlon2021
相关产品推荐
相关产品推荐

