仅用CSS能否实现获焦按钮再次点击后失焦?Styled Components场景
用Styled Components实现点击切换按钮颜色(无需JavaScript)
你当前的代码用:focus伪类实现了获焦时变蓝,但再次点击按钮并不会让它失焦,所以没法切回红色。要实现点击切换状态的效果,CSS本身没有直接对应伪类,我们可以借助表单元素的checked状态来完成,下面是具体实现方案:
方案:借助隐藏的Checkbox实现切换
利用checkbox的选中/未选中状态,配合CSS兄弟选择器来控制按钮样式,完全不需要JavaScript逻辑:
import styled from "styled-components"; const ToggleWrapper = styled.div` position: relative; /* 隐藏原生checkbox */ input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; } /* 把label样式改成按钮的样子 */ label { display: inline-block; width: 200px; height: 100px; background-color: red; border: none; cursor: pointer; color: #fff; font-size: 18px; line-height: 100px; text-align: center; user-select: none; } /* 当checkbox被选中时,改变label的背景色 */ input[type="checkbox"]:checked + label { background-color: blue; } `; export default function ToggleButton() { return ( <ToggleWrapper> <input type="checkbox" id="color-toggle" /> <label htmlFor="color-toggle">Button</label> </ToggleWrapper> ); }
原理说明
- 用
label模拟按钮,label可关联checkbox,点击label会自动切换checkbox的选中状态 - 隐藏原生
checkbox,仅展示样式化后的label - 通过CSS兄弟选择器
input:checked + label,在checkbox选中时修改label的背景色,实现点击切换红色/蓝色的效果
可选方案(不推荐):保留
如果一定要用原生<button>标签,可通过tabindex和:focus-within配合,但此方案无法实现"再次点击恢复红色"的需求(需点击页面其他区域才会失焦),示例如下:
import styled from "styled-components"; const ButtonWrapper = styled.div` button { width: 200px; height: 100px; background-color: red; border: none; cursor: pointer; color: #fff; font-size: 18px; } &:focus-within button { background-color: blue; } `; export default function ToggleButton() { return ( <ButtonWrapper tabIndex="0"> <button>Button</button> </ButtonWrapper> ); }
内容的提问来源于stack exchange,提问作者NewJr
相关产品推荐
相关产品推荐

