【问题标题】:Using Styled Components to change the color of an SVG's stroke使用 Styled Components 更改 SVG 笔触的颜色
【发布时间】: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 alt="my-burger" 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">
    .st0{fill: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 .st0{stroke:red;} 。 -- 但没有效果。
  • 那么问题不在于 React。它与您的 CSS 一起使用。元素上有那个类吗?
  • 是的。 st0 是用于在 SVG 中渲染 3 行的类。
  • 我的意思是.NYIBr。那是手术班。

标签: reactjs svg styled-components


【解决方案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;
            }
          }     
      `;
      

      这行得通。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-22
        • 2021-08-07
        • 1970-01-01
        • 1970-01-01
        • 2019-05-09
        • 2016-08-02
        • 2020-12-16
        相关资源
        最近更新 更多