25

タグによって:hover埋め込まれた SVG 要素のスタイルを設定するために CSS 疑似クラスを使用しようとしていますが、うまくいかないようです :-/ これが私のコードです:<defs><use>

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
 <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8"/>
 <style type="text/css" media="screen">
        .active { fill: #0BE; }
        .active:hover { opacity: 0.8; stroke: #F0F; stroke-width: 4px; }
        .active2 #p2 { fill: #0BE; }
        .active2:hover #p2 { opacity: 0.8; stroke: #F0F; stroke-width: 4px; }
        #p2:hover { opacity: 0.8; stroke: #F0F; stroke-width: 4px; }
    </style>
</head>
<body>


<svg version="1.1" width="640" height="480"
 xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink">

 <defs>
  <polygon id="p0" points="100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" class="active"/>
  <g id="gr1">
      <polygon id="p1" points="130,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6"/>
      <polygon id="p2" points="100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" class="active"/>
  </g>
 </defs>

 <g transform="translate(70,100)">
    <use xlink:href="#p0" transform="translate(40,0)"/>
    <use xlink:href="#p0" transform="translate(250,0)"/>
    <use xlink:href="#p0" transform="translate(460,0)" class="active" />
 </g>
 <g transform="translate(100,300)">
    <polygon id="style" points="110,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" class="foo"/>
    <use xlink:href="#gr1" transform="translate( 350,2)" class="active2"/>
 </g>

</svg>

</body>
</html>

ユーザーが埋め込み要素の上にマウスポインターを置くと、クラスが「アクティブ」な内部要素のスタイルが変更されるように機能させたいと考えています。から 1 つのシェイプを<defs>直接埋め込み、<use>それを埋め込む CSS クラスを適用すると機能します。ただし、 を介して埋め込まれたグループ内のクラスまたは ID では機能しません<use>

修正方法は?

または、もっと良い方法がありますか?

グループ全体ではなく、ユーザーがホバーしたときに埋め込みオブジェクト内のこの特定の部分のみを変更する必要があります。これは、このグループのさまざまな部分にさまざまなスタイルが適用され、マウスでホバーしたときにさまざまに変更する必要があるためです。

編集:取得したいもの

私が取得したいのは、1 つの「ライブラリ オブジェクト」を<defs>SVG ドキュメントのさまざまな場所に埋め込む方法です。ライブラリ オブジェクトのコードを変更せずにこれらの色を簡単にカスタマイズする必要があるため、このオブジェクトの一部は CSS のカスタム カラーでスタイル設定する必要があります。

次に、マウス ポインターがそのような「アクティブな」オブジェクトの上にあるときに、そのパーツのスタイルを変えることでユーザーに知らせる必要があります。

残念ながら、<use>要素のサブ要素にスタイルを適用することはできません。DOM のサブ要素ではないためです<use>(他の人が既に述べたように)。<defs>DOM 内にあり、CSS セレクターでアドレス指定できるため、セクション内の要素にいくつかのスタイルを適用できますが、非表示であるためホバーできず:hover、疑似クラスを適用しても機能しません。また、このクラスが に適用された場合も機能しません<use>。適切なサブ要素をサブ選択できないためです (それらは のサブ要素ではありません<use>)。したがって、これらの疑似クラスを適用するためのフックはありません:hover

多分私の問題に対する他の解決策がありますか?

4

3 に答える 3

35

use を介して参照される要素をアドレス指定することはできません。仕様は次のように述べています。

CSS によるスタイリングをサポートするユーザー エージェントの場合、参照される要素を公開されていない DOM ツリーに概念的にディープ クローニングすると、参照される要素とそのコンテンツの CSS カスケード ([CSS2]、第 6 章) から生じるプロパティ値もコピーされます。CSS2 セレクターは、元の (つまり、参照されている) 要素に適用できます。これは、これらの要素が正式なドキュメント構造の一部であるためです。CSS2 セレクターは (概念的に) 複製された DOM ツリーに適用できません。これは、そのコンテンツが正式なドキュメント構造の一部ではないためです。

それにもかかわらず、Firefox は、use ワームホールを介して含まれる「仮想」要素への対処をサポートしています。他のすべてのブラウザはそうではありません。

参照されている要素に塗りつぶし/ストロークの値を指定し、ホバー時に要素のプロパティcurrentColorを変更した場合、ブラウザーがサポートするのは、塗りつぶしまたはストロークの色の変更です。そのようです:color<use>

<svg version="1.1" width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

  <style type="text/css">
    #p0 {fill:currentColor}
    #use1:hover {color:green}
    #use2:hover {color:red}
    #use3:hover {color:blue}
  </style>

  <defs>
    <polygon id="p0" points="100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" class="active" />
  </defs>

  <g transform="translate(70,100)">
    <use xlink:href="#p0" transform="translate(40,0)" id="use1" />
    <use xlink:href="#p0" transform="translate(250,0)" id="use2" />
    <use xlink:href="#p0" transform="translate(460,0)" id="use3" />
  </g>
</svg>

これは、すべての主要なブラウザー (FF、Chrome、IE、Safari) でサポートされています。Operaだけが気に入らないようです。欠点はもちろん、この方法では 1 つの色しか変更できないことです。

したがって、色を変更するだけであれば、別の方法としてフィルターを使用することもできます。たとえば を使用する<feColorMatrix>と、次のように、カラー マトリックスを使用してある色を別の色に変換できます。

<svg version="1.1" width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

  <style type="text/css">
    #p0 {fill: currentColor}
    #use1:hover {filter: url(#filter1)}
    #use2:hover {filter: url(#filter2)}
    #use3:hover {filter: url(#filter3)}
  </style>

  <defs>
    <g id="p0">
      <polygon points="100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" fill="red" />
      <rect width="50" height="70" fill="green" />
      <circle cx="-20" cy="-30" r="30" fill="blue" />
    </g>
  </defs>

  <filter id="filter1">
    <feColorMatrix type="matrix" in="SourceGraphic" values="0 1 0 0 0 
                     1 0 0 0 0 
                     0 0 1 0 0 
                     0 0 0 1 0" />
  </filter>
  <filter id="filter2">
    <feColorMatrix type="matrix" in="SourceGraphic" values="0 0 1 0 0 
                     1 0 0 0 0 
                     0 1 0 0 0 
                     0 0 0 1 0" />
  </filter>
  <filter id="filter3">
    <feColorMatrix type="matrix" in="SourceGraphic" values="0 1 0 0 0 
                     0 0 1 0 0 
                     1 0 0 0 0 
                     0 0 0 1 0" />
  </filter>

  <g transform="translate(70,100)">
    <use xlink:href="#p0" transform="translate(40,0)" id="use1" />
    <use xlink:href="#p0" transform="translate(250,0)" id="use2" />
    <use xlink:href="#p0" transform="translate(460,0)" id="use3" />
  </g>
</svg>

ただし、Opera ではまだ運が悪く、今回は IE9 と Safari にも満足できませんでした。しかし、Opera と Safari では可能だと思いますが、100% 正しくないことをしただけです。

于 2012-12-02T21:48:24.823 に答える
2

これは仕様によるようです:

CSS によるスタイリングをサポートするユーザー エージェントの場合、参照される要素を公開されていない DOM ツリーに概念的にディープ クローニングすると、参照される要素とそのコンテンツの CSS カスケード ([CSS2]、第 6 章) から生じるプロパティ値もコピーされます。CSS2 セレクターは、元の (つまり、参照されている) 要素に適用できます。これは、これらの要素が正式なドキュメント構造の一部であるためです。CSS2 セレクターは (概念的に) 複製された DOM ツリーに適用できません。これは、そのコンテンツが正式なドキュメント構造の一部ではないためです。

use:hover および/または [] 属性セレクター構文を使用していくつかの回避策を試しましたが、ほとんど運がありませんでしたが、解決策があるかもしれません。

于 2012-12-02T21:28:44.687 に答える
1

多分これが役立つかもしれません: https://codepen.io/AmeliaBR/post/customizable-svg-icons-css-variables

    <svg  xmlns="http://www.w3.org/2000/svg" 
     viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet"
     class="raw">
  <g id="palette">
  <path d="M5,90
           C5,45 40,-5 75,10 
           C110,25 80,95 60,95
           C50,95 50,75 30,75
           C20,75 17,95 12,95
           C10,95 5,95 5,90 Z"/>
    <g  style="fill:currentColor;">
  <path d="M30,50 
           c-10,0 -20,20 -5,15
           s15,-15 5,-15z
           "/>
  <path  d="M45,30 
           c-10,0 -15,15 -5,15
           s10,-15 5,-15z
           "/>
  <path  d="M70,20 
           c-10,0 -20,15 -5,15
           s10,-15 5,-15z
           "/>
  <path  d="M75,45 
           c-10,0 -20,15 -5,15
           s15,-15 5,-15z
           "/>
  <path  d="M65,65 
           c-10,0 -15,25 -5,20
           s10,-20 5,-20z"/>
    </g>
  </g>
</svg>
<svg class="icon-style-A">
    <use xlink:href="#palette"/>
</svg>

<svg class="icon-style-B">
    <use xlink:href="#palette"/>
</svg>

<svg class="icon-style-C">
    <use xlink:href="#palette"/>
</svg>

    svg {
  display:inline-block;
  height:100px; 
  width:100px;
  margin:10px;
  border:1px solid;
  background:#eee;
}
svg.raw {
/* Default styles for the initial SVG.
 * Because they are defined on the <svg>,
 * not the individual graphics elements, 
 * they will NOT be inherited by the <use> references.
 */
  fill:rgba(255,250,220,0.4);
  stroke: rgba(0,0,0,0.7);
  stroke-width:2;
}
svg.icon-style-A {
/* Set the fill, stroke, and color properties to be 
   inherited by the <use> element:
 */
  fill:burlywood;
  color:blueviolet;
  stroke:#222; 
  stroke-width:0.5px;
}
svg.icon-style-B {
/* Set the color properties:
 */
  fill:blanchedalmond;
  color:lavender;
  stroke:white;
  stroke-width:1px;
/* set some icon styles on the <svg> itself: */
  background:aliceblue;
  border-radius:20%;
  border:none;
  box-shadow:royalblue 0 0 2px;
}
svg.icon-style-C {
/* Set the color properties:
 */
  fill:beige;
  color:green;
  stroke:#aaa; 
  stroke-width:1.5px;
/* icon styles for the <svg> itself: */
  background:#222;
  border-radius:10%;
  border:solid gray;
}

あまり柔軟ではありませんが、私のプロジェクトではうまくいきました。

于 2014-11-21T16:04:34.590 に答える