Подтвердить что ты не робот

Элемент SVG USE и стиль наведения

Я пытаюсь использовать CSS :hover pseudoclass для стилей элементов SVG, встроенных в тег <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>

Я хочу, чтобы он работал так, что когда пользователь помещает указатель мыши над внедренным элементом, его внутренний элемент с классом "active" изменит его стиль. Он работает, когда я вставляю одну фигуру из <defs> напрямую и применяю класс CSS к <use>, который его внедряет. Но он не работает ни для каких классов или идентификаторов внутри группы, встроенной в <use>.

Как это исправить?

Или, может быть, есть лучший способ сделать это?

Мне нужно изменить только эту конкретную часть внутри внедренного объекта, когда пользователь зависает, а не целая группа. Это потому, что в разных частях этой группы были применены разные стили, и они должны меняться по-разному, когда они зависают от мыши.

Изменить: что я хочу получить

То, что я хочу получить, - это способ вставить один "объект библиотеки" из <defs> во многие разные места моего документа SVG. Некоторые части этого объекта должны быть оформлены с использованием пользовательских цветов из CSS, потому что мне нужна легкая настройка этих цветов без изменения кода объекта библиотеки.

И тогда мне нужно сообщить пользователю, когда указатель мыши находится над таким "активным" объектом, по-разному ставя его части: некоторые яркие очертания здесь и там, чтобы показать форму кликабельных областей, когда курсор мыши над ними.

К сожалению, я не могу применить стиль к подэлементам элементов <use>, потому что они не являются подэлементами <use> в DOM (как уже упоминалось ранее). Я могу применить некоторые стили к элементам внутри раздела <defs>, потому что они находятся в DOM, и они адресуются с помощью селекторов CSS, но их нельзя зависнуть, потому что они невидимы, поэтому применение псевдонимов :hover к они не работают. И это не работает, если этот класс применяется к <use>, потому что тогда я не могу подбирать соответствующие подэлементы (они не являются подэлементами <use>). Поэтому у меня нет привязки для применения этих :hover псевдокласса к.

Может быть, есть другое решение моей проблемы?

4b9b3361

Ответ 1

Вы не можете обратиться к элементу, на который ссылается с помощью использования. Спецификации говорят:

Для пользовательских агентов, поддерживающих Styling with CSS, концептуальное глубокое клонирование ссылочного элемента в дерево, не подвергнутое экспонированию, также копирует любые значения свойств, полученные в результате каскада CSS ([CSS2], глава 6) для ссылочного элемента и его содержание. Селекторы CSS2 могут применяться к исходным (то есть ссылочным) элементам, поскольку они являются частью формальной структуры документа. Селекторы CSS2 не могут применяться к (концептуально) клонированному дереву DOM, поскольку его содержимое не является частью формальной структуры документа.

Тем не менее, Firefox поддерживает обращение к "виртуальным" элементам, которые включены через использование червоточины. Все остальные браузеры этого не делают.

Что больше поддерживает браузер, это изменение цвета наполнения или поглаживания, если вы укажете ссылочному элементу значение заливки/хода 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>

Ответ 2

Это, по-видимому, соответствует спецификации:

Для пользовательских агентов, поддерживающих Styling with CSS, концептуальный глубокий клонирование ссылочного элемента в непокрытое дерево DOM также копирует любые значения свойств, полученные в результате каскада CSS ([CSS2], глава 6) по ссылочному элементу и его содержимому. Селекторы CSS2 может применяться к исходным (то есть ссылочным) элементам, поскольку они являются частью формальной структуры документа. Селекторы CSS2 не могут быть применены к (концептуально) клонированному дереву DOM, поскольку его содержимое не являются частью формальной структуры документа.

Я пробовал несколько обходных решений с использованием синтаксиса селектора атрибутов: hover и/или [] и мало повезло, но там может быть решение.

Ответ 3

Возможно, это может помочь: http://codepen.io/AmeliaBR/thoughts/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;
}

Не очень гибкий, но он работал для моего проекта.