使用 Styled Components 更改 SVG 笔触的颜色

Posted

技术标签:

【中文标题】使用 Styled Components 更改 SVG 笔触的颜色【英文标题】:Using Styled Components to change the color of an SVG's stroke 【发布时间】:2019-11-03 16:13:26 【问题描述】:

我有一个 SVG 用作<img> 标签。使用样式化组件我试图达到在悬停时更改笔触颜色的地步。

我导入了 SVG:

import BurgerOpenSvg from '../../images/burger_open.svg';

我为它创建了一个样式化组件:

   const BurgerImageStyle = styled.img`
    &:hover      
        .st0 
          stroke: red;
        
    
`;

我使用它:

<BurgerImageStyle  src=BurgerOpenSvg/>     

结果是,我的 SVG 显示正确,但在悬停时没有颜色变化

我使用的 SVG 的来源:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
     viewBox="0 0 38 28.4" style="enable-background:new 0 0 38 28.4;" xml:space="preserve">
<style type="text/css">
    .st0fill:none;stroke:#221f1f;stroke-width:2;stroke-miterlimit:10;
</style>
<g>
    <g id="XMLID_7_">
        <line class="st0" x1="0" y1="1" x2="38" y2="1"/>
    </g>
    <g id="XMLID_6_">
        <line class="st0" x1="0" y1="14.2" x2="38" y2="14.2"/>
    </g>
    <g id="XMLID_5_">
        <line class="st0" x1="0" y1="27.4" x2="38" y2="27.4"/>
    </g>
</g>
</svg>

SVG 渲染如下:

是否可以更新加载到&lt;img&gt; 标签中的 SVG 上的类?还是必须是内联的&lt;svg&gt; 标签?

【问题讨论】:

你在浏览器中看到悬停样式了吗? .NYIBr:hover .st0stroke:red; 。 -- 但没有效果。 那么问题不在于 React。它与您的 CSS 一起使用。元素上有那个类吗? 是的。 st0 是用于在 SVG 中渲染 3 行的类。 我的意思是.NYIBr。那是手术班。 【参考方案1】:

如果您想在多个 SVG 之间共享一些样式,并且不想额外依赖 react-inlinesvg,您可以改用这个东西:

src prop 中,它接受 SVG React 组件

import styled from 'styled-components';
import React,  FC, memo  from 'react';

type StyledIconProps = 
  checked?: boolean;
;

const StyledIconWrapper = styled.div<StyledIconProps>`
  & svg 
    color: $(p) => p.checked ? '#8761DB' : '#A1AAB9';
    transition: 0.1s color ease-out;
  
`;

export const StyledIcon = memo((props: StyledIconProps &  src: FC ) => 
  const  src, ...rest  = props;

  const Icon = src;

  return (
    <StyledIconWrapper ...rest>
      <Icon/>
    </StyledIconWrapper>
  );
);

然后你可以像这样使用它:

import  StyledIcon  from 'src/StyledIcon';
import  ReactComponent as Icon  from 'assets/icon.svg';

const A = () => (<StyledIcon src=Icon checked=false />)

【讨论】:

【参考方案2】:

如果您希望避免编写单独的组件或复制原始 SVG 文件,请考虑 react-inlinesvg

https://github.com/gilbarbara/react-inlinesvg

import React from "react";
import styled from "styled-components";
import SVG from "react-inlinesvg";
import radio from "./radio.svg";

interface SVGProps 
  color: string;


const StyledSVG = styled(SVG)<SVGProps>`
  width: 24px;
  height: 24px;
  & path 
    fill: $( color ) => color;
  
`;

export default function App() 
  const color = "#007bff";
  return <StyledSVG color=color src=radio />;


代码沙盒:https://codesandbox.io/s/stack-56692784-styling-svgs-iz3dc?file=/src/App.tsx:0-414

【讨论】:

【参考方案3】:

所以我调查了这个。事实证明,您无法使用 &lt;img&gt; 标签对正在加载的 SVG 图像进行 CSS 样式化。

我所做的是这样的:

我这样内联了我的 SVG:

 <BurgerImageStyle x="0px" y="0px" viewBox="0 0 38 28.4">
      <line x1="0" y1="1" x2="38" y2="1"/>
      <line x1="0" y1="14.2" x2="38" y2="14.2"/>
      <line x1="0" y1="27.4" x2="38" y2="27.4"/>
 </BurgerImageStyle>

然后我使用 Styled Components 给BurgerImageStyle 设置样式:

const BurgerImageStyle = styled.svg`
    line 
      stroke: black;
        
    &:hover 
      line 
        stroke: purple;
      
         
`;

这行得通。

【讨论】:

以上是关于使用 Styled Components 更改 SVG 笔触的颜色的主要内容,如果未能解决你的问题,请参考以下文章

NextJS 使用 s-s-r 和 Styled-Components 构建错误

styled-components:扩展样式并更改元素类型

使用 Styled Components 更改 SVG 笔触的颜色

Styled Components - 内联样式与媒体查询样式重叠

标题组件根据 React / Gatsby / Styled-components 中的背景更改文本颜色

使用 Styled-components 修改 SVG (react / next)