尝试将 :focus 样式应用于样式化组件内的嵌套 SVG

Posted

技术标签:

【中文标题】尝试将 :focus 样式应用于样式化组件内的嵌套 SVG【英文标题】:Trying to apply :focus styling to a nested SVG inside of styled component 【发布时间】:2020-08-20 19:11:29 【问题描述】:

我有一个简单的搜索栏 React 组件。

该组件是一个 <div> 包装一个 <input> 元素和一个 <svg> 并通过样式组件应用样式。我已经阅读了有关 Styled Components 的文档,但在这种情况下,我似乎找不到将 :focus 样式应用于嵌套子元素的方法 <svg>

Expected behavior: The SVG should turn blue when the input is in :focus

Current behavior: The SVG color stays black no matter if the input is in :focus or not

我这里有一个 CodePen,显示 :focus 样式适用于输入,但不适用于 <svg>

还有我当前的组件:

import React,  useState  from "react";
import styled from "styled-components";

export const FilterTextbox = () => 
  const [text, setText] = useState("");
  const handleChange = (event: any) => 
    setText(event.target.value);
  ;
  return (
    <StyledInput className="inputWithIcon">
      <Input
        type="text"
        value=text
        onChange=handleChange
        placeholder="Search"
      />
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        
        
      >
        <path d="M 13.261719 14.867188 L 15.742188 17.347656 C 15.363281 18.070313 15.324219 18.789063 15.722656 19.1875 L 20.25 23.714844 C 20.820313 24.285156 22.0625 23.972656 23.015625 23.015625 C 23.972656 22.058594 24.285156 20.820313 23.714844 20.25 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 L 14.867188 13.261719 Z M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z" />
      </svg>
    </StyledInput>
  );
;

const Input = styled.input`
  height: 50px;
  width: 100%;
  border: 2px solid #aaa;
  border-radius: 4px;
  margin: 8px 0;
  outline: none;
  padding: 8px;
  box-sizing: border-box;
  transition: 0.3s;
  padding-left: 50px;
  font-size: 25px;
  :focus 
    border-color: dodgerBlue;
    box-shadow: 0 0 8px 0 dodgerBlue;
  
`;

const StyledInput = styled.div`
  svg 
    position: absolute;
    left: 0;
    top: 8px;
    padding: 9px 8px;
    color: black;
    transition: 0.3s;
    :focus 
      color: dodgerBlue;
    
  

  /* &svg:focus 
    color: dodgerBlue;
   */

  &.inputWithIcon 
    position: relative;
  
`;

【问题讨论】:

【参考方案1】:

input 引起了关注,所以样式规则应该包含input:focus

当输入具有焦点时,此 CSS 规则将针对 svg:

input:focus + svg 
  /* styling goes here */

这是一个使用直接 html 和 CSS 的示例。

div 
  margin: 8px;
  position: relative;


input 
  height: 50px;
  width: 100%;
  border: 2px solid #aaa;
  border-radius: 4px;
  margin: 8px 0;
  outline: none;
  padding: 8px;
  box-sizing: border-box;
  transition: 0.3s;
  padding-left: 50px;
  font-size: 25px;


svg 
  position: absolute;
  left: 0;
  top: 8px;
  padding: 9px 8px;
  color: black;
  transition: 0.3s;


input:focus 
  border-color: dodgerBlue;
  box-shadow: 0 0 8px 0 dodgerBlue;


input:focus+svg 
  fill: dodgerBlue;
<div>
  <input>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"  >
        <path d="M 13.261719 14.867188 L 15.742188 17.347656 C 15.363281 18.070313 15.324219 18.789063 15.722656 19.1875 L 20.25 23.714844 C 20.820313 24.285156 22.0625 23.972656 23.015625 23.015625 C 23.972656 22.058594 24.285156 20.820313 23.714844 20.25 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 L 14.867188 13.261719 Z M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z" />
  </svg>
</div>

【讨论】:

开个玩笑,我将 Styled Components 从 5.0.1 更新到版本 5.1.0,现在这个语法就像一个魅力!谢谢!

以上是关于尝试将 :focus 样式应用于样式化组件内的嵌套 SVG的主要内容,如果未能解决你的问题,请参考以下文章

为 React 搜索栏使用带有嵌套样式的样式化组件,尝试将两个不同的 SVG 放置在搜索栏的相对两侧

在使用样式化组件时将动画应用于 React 组件

如何聚焦样式化的组件?

将布局样式应用于站点上不同位置的样式组件和 React 组件的最佳方法是啥?

与样式组件一起使用的 Before 和 After 伪类

材质 UI 已选择选项卡样式