SVG Заполнение не применяется в FireFox

Я не могу понять, почему Firefox использует стандартный цвет svg fill вместо заполнения класса.

Вот 3 заливки при просмотре инспектора FF:

CSS

SVG вставляется через

<svg class="icon">
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag"></use>
</svg>

Он должен отображать заливку .skip-link.icon white (#fff), но на самом деле она использует заливку SVG # 002649; Если я изменю .skip-link.icon на .skip-link svg, тогда он отлично работает. Почему я не могу использовать класс и вместо этого, но явно указать элемент

Я пропустил что-то очевидное о том, как Firefox заполняет SVG? Этот CSS отлично работает в других браузерах.

Ответ 1

Если поведение было уникальным для Firefox до версии 56, это было потому, что #menu-bag относится к элементу <symbol>.

В спецификациях говорится, что повторно используемый <symbol> должен быть реализован так, как если бы он был заменен вложенным <svg>. Firefox использовал это буквально в тени DOM. Теневой DOM не отображается в вашем инспекторе DOM, но он зависит от селекторов CSS.

Это означает, что этот код:

<a href="#" class="skip-link">
    <svg class="icon">
        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag"></use>
    </svg>
</a>

WA реализованы следующим образом:

<a href="#" class="skip-link">
    <svg class="icon">  
        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag">
          <!--Start of shadow DOM boundary-->
          <svg><!-- replacement for <symbol> -->
             <!-- graphics content -->
          </svg>
          <!--End of shadow DOM boundary-->
        </use>
    </svg>
</a>

svg.icon соответствует вашему правилу .skip-link .icon (и, как указывает Кайл Митт, это правило всегда будет иметь приоритет над вашим правилом a:hover svg). Это значение также наследуется элементом <use>.

Тем не менее, shadow-DOM <svg> не получает унаследованное значение, потому что оно написано непосредственно с помощью правила svg. Когда вы меняете селектор на .skip-link svg или когда вы запускаете правило a:hover svg, тогда скрытый внутренний элемент получает непосредственно применяемый стиль, потому что этот SVG также является потомком ссылки.

Как заметил Роберт Лонгсон в комментариях, это не то, как он должен работать. Это побочный эффект того, как Firefox реализовал элементы <use> как полные клонированные деревья DOM, которые просто скрылись от вашего инспектора DOM.

Вот "рабочий" пример вашей исходной проблемы. Скажем, в Chrome, Safari, Opera, Firefox 56+ или IE вы увидите зеленый круг, который не изменяется при его зависании, но в Firefox до версии 56 вы увидите синий круг, который становится красным на парения/фокус.

svg {
    fill: navy;
}
a:hover svg, a:focus svg {
    fill: red;
}
.skip-link .icon {
    fill: green;
}
.icon {
    height: 50;
    width: 50;
}
 <a href="#" class="skip-link">
        <svg class="icon">
            <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag" />
        </svg>
</a>
<svg height="0" width="0">
    <symbol id="menu-bag" viewBox="-10 -10 20 20">
        <circle r="10" />
    </symbol>
</svg>

Ответ 2

Более универсальный вариант, основанный на ответе @AmeliaBR, заключается в том, чтобы просто сделать что-то в соответствии с:

svg use svg { 
    fill: inherit;
}

который заставит теневой элемент наследовать цвет заливки.

Ответ 3

Роберт прав, что <use> не всегда применяется последовательно. Конечно, когда вы используете SVG в качестве изображения, он не знает, как применять любые правила CSS, которые вы добавили на свою страницу.

Но здесь есть много других вещей, которые могли бы решить стиль элемента, поэтому пример может быть полезен.

Здесь фрагмент фрагмента, чтобы сосредоточить наше обсуждение.

svg {
  fill: blue;
}
a:hover svg {
  fill: red;
}
.skip-link .icon {
  fill: purple;
}

.green {
  fill: green;
}
<a href="#" class="skip-link">
  <svg xmlns="http://www.w3.org/2000/svg"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       class="icon" >

    <def>
      <text id="text" >use xlink</text>
      <text id="over" class="green">use xlink override</text>
    </def>
    
    <text x="5" y="15" >Plain</text>
    <use  x="5" y="30" xlink:href="#text" />

    <use  x="5" y="50" xlink:href="#over" />
    <text x="5" y="65" class="green" >class="green"</text>
    <text x="5" y="80" fill="orange" >fill="orange"</text>

  </svg>
</a>

Ответ 4

Установите цвет заливки по умолчанию svg в теге body или html, и он будет наследоваться по умолчанию, но вы можете легко переопределить его, используя только класс.

body {
    fill: black;
}
.green {
    fill: green;
}
.red {
    fill: red;
}

Теперь просто используйте класс цвета для изменения цвета заливки. Добавьте класс цвета в svg или в span или другой элемент, обертывающий svg. Работает и в Firefox.

<a href="#" class="skip-link green">
    <svg>
        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag" />
    </svg>
</a>
<svg height="0" width="0">
    <symbol id="menu-bag" viewBox="-10 -10 20 20">
        <circle r="10" />
    </symbol>
</svg>

Ответ 5

Мой случай не совсем такой, но я все равно разделяю его. Я использую svg в качестве фонового изображения, как в примере ниже (гуглил, не помню где). А в Firefox были проблемы с "заливкой" цвета.

  • В качестве значения заполнения я должен был написать его в режиме RGB и работать правильно (fill: rgb (237, 237, 237);).
  • Если бы я написал в HEX (fill: #ededed;), он бы не отображался.
  • Если бы я написал, например, "fill: blue;" это также показало бы должным образом.

    .a-class {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none' height='130' style='background:var(--main-lt-green); fill:rgb(237, 237, 237);'><polygon points='100 0 100 10 0 10'></polygon></svg>");
    background-repeat: no-repeat;
    background-size: 100% 100px;
    background-position-y: top;
    margin-top: -100px;
    padding-top: 100px;
    

    }