Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

SVGをcss/jsで操作するときに知っておきたいこと

More than 3 years have passed since last update.

はじめに

※SVG初心者向きの記事です

SVGはスケーラブルでベクターなグラフィックスです。レスポンシブや高解像度ディスプレイに対応する時にはとても頼もしい存在です。htmlと同じようにcssやjsでの制御も可能なため、インタラクティブなコンテンツもお手の物です。

そんなSVGは表示だけであれば簡単ですが、cssやjsを利用する際には知っておきたい基本知識があります。
これ以上、私のように時間を浪費してしまう哀れな子鳥たちを増やさぬようメモしたいと思います。アーメン

目次

  • 表示のさせかたに気をつけろ!
  • cssに気をつけろ!
  • fill: none;に気をつけろ!
  • viewBoxに気をつけろ!
  • jQueryに気をつけろ!
  • サーバーの設定に気をつけろ!

表示のさせかたに気をつけろ!

SVGの表示方法は複数あります。

  1. <img>のsrcでファイルを読み込む
  2. background-imageプロパティでファイルを読み込む
  3. htmlにインラインで直接SVGタグを記述する
  4. object要素のdata属性でファイルを読み込む
  • 1, 2は画像要素となり、SVGタグ内のpathに対してcss, jsが効きません
  • 4はiframeのように別documentになりcss, jsはそのdocumentに対して適用させる必要があります
1.html
<img src="hoge.svg">
2.css
div {
  background-image:url("hoge.svg");
}
3.html
<div>
  <svg width="" height="" viewBox="">
    <!-- 略 -->
  </svg>
</div>
4.html
<object id="mySvg" data="hoge.svg" type="image/svg+xml"></object>
4を操作する.js
var svg_doc = document.getElementById('mySvg').contentDocument;
var $svg = $(svg_doc).find('svg');

追記: ajax()で追加する

後で気づきましたが、ajax()でhtml内にSVGタグを動的に追加しても問題なく動きました。
同じdocument内に追加しているためcssもそのまま適用されました。

環境によって動作が異なるかもしれません

ajaxでsvgタグを追加する.js
$.ajax({
    type: 'get',
    url: './xxx.svg',
  })
  .done(function(returnData) {
    var svg = $(returnData).find('svg');
    $('#addArea').append(svg);
});

cssに気をつけろ!

SVGのcssはいわゆるあのcssとは異なります
共有して使用できるプロパティも多くありますが、独自のものや逆に使えないものもあります。

スタイル付け – SVG 1.1 (第2版)
https://triple-underscore.github.io/SVG11/styling.html

(原文) http://www.w3.org/TR/SVG/styling.html#SVGStylingProperties

fill: none;に気をつけろ!

fill: none;はそのpathの塗りつぶし色を透明にします。
ただしイベント自体も無効にしてしまいます。
そのためfill: none;が効いている場合はpath:hover {fill: <color>;}と指定しても動作しません。
特にIllustratorなどツールで書きだした時には、意図しないでnone属性がタグに付いているかもしれません。

回避策としてはpointer-eventsを設定してやるか、noneではなくrgbaのalpha0で色を透明にしてやります。

イベント無効対策.css
path {
  pointer-events: all;
}
/* もしくは */
path {
  fill: rgba(0,0,0,0);  /* fill: none; の代わり */
}

viewBoxに気をつけろ!

SVGのviewPortとviewBoxがズレていると見た目上のサイズ(比率)や位置が異なることがあります。意図が無ければviewPortとviewBoxのwidth, heightは揃えておいた方が良いかと思います。

※viewBoxに関しては以前記事を書きました
SVGのViewBoxがよく分からないアナタとワタシへ

jQueryに気をつけろ!

jQueryの手にかかれば、SVGもDOM操作のように簡単に制御ができます。
ですが一部メソッドについては、同じようには使えません
上手く動作しないものがあれば、そもそも同じように使用できるのか調べると良いかと思います。

jQueryのバージョンによっては解決されているかもしれません
動作はjQuery-2.1.4で確認しました

attr('viewBox', '')

jQuery側で属性がlower caseに変換されてしまい動作しません。
setAttribute()を使いましょう。

$(obj)[0].setAttribute('viewBox', '')

addClass() / removeClass()

.attr('class', )などを使いましょう。

※他にもあるかもしれません。

サーバーの設定に気をつけろ!

本番サイトでSVGが表示されない!
そんな時は焦らずサーバー側でsvgが許可されているか確認しましょう。
特にsvgをgzipしていた場合は見落としがちかもしれません。

AddType image/svg+xml .svg .svgz
AddEncoding gzip .svgz

反映されない場合は、キャッシュのクリアを試しましょう

※これはSVGに限ったことではなくcss/jsにも関係ありませんが、痛い目見たので......

おわりに

まだまだ経験が少ないので、もっと色々と出てきそうです。気づいたら更新していければと思います。

nekoneko-wanwan
Webデザイン、フロントエンド開発を主にやっています。真面目なものから、変なものまで。色々な記事を投稿していければと思います。
hotstartupinc
「ペライチ」を開発する会社です。
https://peraichi.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away