Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8707

React.js で SVGファイルのサイズや色をCSSで変える方法

$
0
0

前提

  • React.js, webpack
  • ReactでSVGファイルをimgとして読むとスタイルをCSSで変更できない(サイズはできるが色はできない)のでinlineで読む必要がある
  • 複数のサイズや色のために複数のSVGファイルを用意したくない
  • SVGファイルを変換したReact Componentのファイルも作りたくない

概要

  • inline SVGとして埋め込む方法3つ
  • CSSでスタイルを上書きする方法

を紹介
利点としてはSVGをReact Component化せずそのまま使うことで、(デザイナーの用意した)素材を極力そのままにし、ファイル数も増やさずに色を変えることができる

SVGの埋め込み方

1. raw-loader + dangerouslySetInnerHTML の場合

webpack.config.js
test:/\.svg$/i,loader:'raw-loader',
jsx
importHogefrom'... .svg'...<divdangerouslySetInnerHTML={{__html:Hoge}}/>

typescriptならパスを通したglobal型置き場に次のように書く

global.d.ts
declaremodule'*.svg'{constcontent:string;exportdefaultcontent;}

利点

  • 変換も何もされないので詰まったり失敗しない

欠点

  • dangerously

2. react-svg-loader の場合

https://github.com/boopathi/react-svg-loader/tree/master/packages/react-svg-loaderを使う

webpack.config.js
{test:/\.svg$/,use:["babel-loader",{loader:'react-svg-loader',options:{svgo:{plugins:[{removeViewBox:false},// to enable overwriteing width/height by CSS{moveElemsAttrsToGroup:false},// to prevent attribute destruction for overwriting color by CSS],floatPrecision:2,},},},],},

ここでsvgoのオプションをdisableしているのは自分の扱うsvgが壊れないように設定した項目だが、扱うsvgによって別のdisableが必要かもしれない

jsx
importHogefrom'... .svg'...<Hoge/>

typescriptならパスを通したglobal型置き場に次のように書く

global.d.ts
declaremodule'*.svg'{constcontent:React.ComponentType;exportdefaultcontent;}

利点

  • 巨大ツールでない
  • 噛ませるbabel-loaderを自由に指定できる
    • next.config.js の defaultLoaders.babelとか

欠点

  • 最近メンテされてないっぽくてリリースがない
  • svgoを無効化できない
    • SVGの中身によっては更にsvgoのオプションをdisableしないとスタイルを上手く上書きできないかもしれない

3. svgr の場合

https://github.com/gregberge/svgrを使う以外のコードの部分はreact-svg-loaderと同じなので差分だけ書く

  1. https://react-svgr.com/docs/webpack/に従う
  2. svgr.config.jsを設定する
svgr.config.js
module.exports={svgoConfig:{plugins:{removeViewBox:false,// to enable overwriteing width/height by CSSmoveElemsAttrsToGroup:false,// to prevent attribute destruction for overwriting color},},};

最適化不要、またはファイルに直接かけておく方針なら、svgoを無効化してしまう

svgr.config.js
module.exports={svgo:false,};

利点

  • メンテ・リリースが続いている
  • svgoを無効化できる
    • 破壊的変更のせいでうまくいかなかったら無効化で逃げれる
  • star多し
  • webpack以外にも対応

欠点

  • 依存ライブラリがちょっと多そう

スタイルの当て方

埋め込んだSVGやそのラッパーdivに対しCSSで以下のように書けばサイズや色を変えれる

svg{width:70px;height:70px;}svg*:not([stroke='none'i]){stroke:red;}svg*:not([fill='none'i]){fill:red;}

ポイントは、SVGの色指定はstrokeとfillがあるので、それらがnoneでない箇所を上書きする点

所感

  • サクッと実現するならraw-loader + dangerouslySetInnerHTML
  • キレイにimportして埋め込みたいなら svgr
  • 2つのツールがデフォルトで使うsvgoのデフォルト設定がSVGを破壊的に変更するので曲者
  • @svgr/cliなどを使ってSVG用のReact Componentを作ってPropsで柔軟に中身を変えるのもアリだけど、SVG素材とReact Componentでほぼ重複するのも悲しいし、用意された素材との同期などが少し面倒

参考


Viewing all articles
Browse latest Browse all 8707

Latest Images

Trending Articles

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>