如何为相邻兄弟是input:focus-within的div.pointer-events-none内的SVG设置样式
问题解决:相邻兄弟元素状态关联前序元素内的SVG样式
你遇到的核心问题是CSS没有反向相邻兄弟选择器,没法直接通过后面的input:focus-within状态,去选中它前面的兄弟元素div.pointer-events-none内部的SVG。你写的两个选择器都是在选中input或者input后面的元素,根本碰不到前面div里的SVG。
可行方案
方案1:使用CSS :has() 选择器(推荐,注意兼容性)
:has() 是CSS新增的父选择器,可以实现这种“根据后续元素状态选中前序元素”的需求。写法如下:
/* 当div.pointer-events-none的下一个兄弟是focus-within状态的input时,选中div内的SVG */ div.pointer-events-none:has(+ input:focus-within) svg { stroke: green; } /* 如需更精确的嵌套层级 */ div.text-field div.relative div.pointer-events-none:has(+ input:focus-within) svg { stroke: green; }
注意::has() 目前在Chrome、Edge、Safari已支持,但Firefox需要手动开启layout.css.has-selector.enabled配置项。
方案2:JavaScript 监听焦点事件
如果需要兼容不支持:has()的浏览器,可通过JS监听input的焦点事件,给目标div添加/移除类名:
const inputs = document.querySelectorAll('div.pointer-events-none + input'); inputs.forEach(input => { // 聚焦时给前序div加类 input.addEventListener('focus', () => { input.previousElementSibling.classList.add('svg-stroke-green'); }); // 失焦时移除类 input.addEventListener('blur', () => { input.previousElementSibling.classList.remove('svg-stroke-green'); }); });
对应CSS:
.svg-stroke-green svg { stroke: green; }
方案3:调整DOM结构(如果允许)
若可以修改HTML结构,把SVG所在的div放到input后面,就能用你之前尝试的兄弟选择器:
<!-- 调整后结构示例 --> <div class="relative"> <input type="text"> <div class="pointer-events-none"> <svg>...</svg> </div> </div>
对应CSS:
input:focus-within + .pointer-events-none svg { stroke: green; }
内容的提问来源于stack exchange,提问作者makazoid
相关产品推荐
相关产品推荐

