Just a student Just a student - 1 year ago 73
CSS Question

CSS reference to SVG filter in separate element

Playing around with SVG filters, I ran into an issue with referencing an SVG filter from CSS. In some situations, applying a filter will remove the element to which the filter is applied from the page. I thought that there could be 2 causes:

  1. the fact that I was adding the filters dynamically using D3JS;

  2. the fact that I am referencing the filters in CSS, defined in a separate file.

To test this, I created a MWE that demonstrates the issue. For me, this renders in Firefox and Chrome with nothing in the left box and a gray circle (the expected result) in the right box. This eliminates cause 1, I think. After I did this, I tried:

  1. Referencing using
    , so with a leading dot. This did not change the result.

  2. Moving the
    in the same
    element as where the circle is. This fixes the issue.

My question: is it still possible to somehow reference a filter that is defined in a separate SVG element? I would very much prefer to do it that way in my application. I have read that there are problems with external files, but a different element in the same file should surely be possible?

Answer Source

I think the problem is the display:none in the hidden class, you can use another way to hidden, this for example:

svg.hidden {

var svg = d3.select('#container').append('svg'),
    defs = svg.append('defs'),

svg.attr('width', 400).attr('height', 200);

dsFilter = defs.append('filter').attr('id', 'grayscale-d3')
  .attr('type', 'matrix')
        '0.3333 0.3333 0.3333 0 0 ' +
        '0.3333 0.3333 0.3333 0 0 ' +
        '0.3333 0.3333 0.3333 0 0 ' +
        '0      0      0      1 0')

svg.append('text').attr('x', 2).attr('y', 2).text('appended by D3');
svg.append('circle').attr('class', 'd3').attr('cx', 200).attr('cy', 120).attr('r', 60);
body {
  margin: 0;
  font-size: 0;

circle {
  fill: #bada55;
  stroke: #000;
  stroke-width: 1px;
circle.of {
  filter: url('#grayscale-of');
circle.d3 {
  filter: url('#grayscale-d3');

svg {
  display: inline-block;
  margin: 1rem 0 0 1rem;
  border: 1px solid #000;
svg.hidden {

text {
  dominant-baseline: text-before-edge;
  font-size: 1rem;
<script src="https://d3js.org/d3.v3.min.js"></script>
<svg class="hidden">
    <filter id="grayscale-of">
      <feColorMatrix values="0.3333 0.3333 0.3333 0 0
                             0.3333 0.3333 0.3333 0 0
                             0.3333 0.3333 0.3333 0 0
                             0      0      0      1 0"
<div id="container">
  <svg width="400" height="200">
    <text x="2" y="2">already in page</text>
    <circle class="of" cx="200" cy="120" r="60" />

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download