如何在孙级输入框展开时用CSS修改父容器背景色?
解决思路
核心是利用CSS的:has()选择器(现代浏览器支持),结合输入框的类名变化和焦点状态,通过styled-components覆盖原样式,同时规避:focus-within的缺陷。
1. 针对场景a:输入框展开时修改背景色
输入框展开时会添加name-expanded类,我们可以通过:has()选择器检测容器内是否存在该类的输入框,从而修改外层容器背景色:
import styled from 'styled-components'; // 重写Search组件的样式 const StyledSearch = styled(Search)` .outer-container { /* 保留原样式 */ display: flex; position: relative; width: max-content; background-color: yellow; padding: 5px; /* 当内部输入框处于展开状态时,切换背景色 */ &:has(.name-expanded) { background-color: orange; } } `;
2. 针对场景b:输入框获得焦点时修改背景色
原:focus-within的问题在于点击X按钮时,按钮会获得焦点,导致容器的focus-within状态持续生效。我们可以直接检测输入框本身的焦点状态,而非容器内任意元素:
const StyledSearch = styled(Search)` .outer-container { /* 保留原样式 */ display: flex; position: relative; width: max-content; background-color: yellow; padding: 5px; /* 仅当输入框获得焦点时,切换背景色 */ &:has(.name:focus, .name-expanded:focus) { background-color: orange; } } `;
3. 组合两种场景的最终样式
将两个条件合并,只要满足输入框展开或输入框获得焦点,就切换背景色:
const StyledSearch = styled(Search)` .outer-container { display: flex; position: relative; width: max-content; background-color: yellow; padding: 5px; /* 场景a:输入框展开 */ &:has(.name-expanded) { background-color: orange; } /* 场景b:输入框获得焦点 */ &:has(.name:focus, .name-expanded:focus) { background-color: orange; } } /* 按需保留或覆盖原组件其他样式 */ .container { display: flex; position: relative; width: max-content; height: 30px; align-items: center; background: gray; border-radius: 16px; padding-left: 16px; padding-right: 16px; } .name { min-width: 70px; width: 70px; outline: none; } .name-expanded { min-width: 70px; width: 150px; outline: none; } .close { position: absolute; left: calc(100% - 30px); } `;
关键说明
:has()选择器可以直接检测容器内的元素状态,是解决父元素依赖子元素状态的核心,现代浏览器(Chrome 105+、Firefox 121+、Safari 15.4+)均支持。- 相比
:focus-within,:has(.name:focus)只关注输入框的焦点状态,点击X按钮时输入框失去焦点,容器会自动恢复黄色背景。
内容的提问来源于stack exchange,提问作者1192805
相关产品推荐
相关产品推荐

