Xavier
Xavier

Reputation: 1207

svg how to add a border on a svg symbol?

I'm using a big svg that contains flags of countries, eg

<symbol viewBox="0 0 640 480" id="flag-be">
   <g fill-rule="evenodd" stroke-width="1pt">
      <path d="M0 0h213.34v480H0z" />
      <path fill="#ffd90c" d="M213.34 0h213.33v480H213.33z" />
      <path fill="#f31830" d="M426.67 0h213.34v480H426.66z" />
   </g>
</symbol>

It works great and I can simply svg use #flag-be and voila, got a my flag.

<svg class="icon flag-be"><use href="#flag-be"></use></svg>

However, I'd like to add a border around the flags (because some that have a lot of white looks strange without it), ideally something that can be set via css only

It works fine when I have each flag into separate svgs (using border), but I failed to make it work when I use several flags as part of a single svg containers (a graph)

What's the easiest? whould I add a a new element in each symbol for the border? What's the most flexible to style "used" symbols in a svg?

Upvotes: 1

Views: 3444

Answers (1)

ccprog
ccprog

Reputation: 21811

Neither <svg> nor <use> nor <g> elements are graphical elements. Trying to set a style altering the graphical appearance on them will only lead to the style being inherited by its children. So, if you set a stroke on <use>, it will be inherited by all the path elements, and you get a border around every flag field.

(A point to remember: Content cloned with a <use> element can inherit styles, but they cannot be targeted with CSS selectors.)

So why does setting a border work on the outermost <svg> element? Because that element is treated as part of the HTML namespace and rendered as if it was an ordinary <span>, while for its children in the SVG namespace the border property has no meaning.

In your use case, you need to add a graphical element surrounding the whole flag. Probably at the point of use, like this:

<svg ...>
    ...
    <svg class="icon flag-be" width="24" height="16">
        <use href="#flag-be" />
        <rect width="100%" height="100%" style="fill:none;stroke:black;stroke-width:1" />
    </svg>
    ...
</svg>

Note the inner <svg> element. Its purpose is to give a reference to the percentage width and height of the <rect>. Otherwise, they would be computed in relation to the outer <svg>.

Currently, width and height must be set as attributes on an inner <svg> element. SVG 2 defines them as presentation attributes that can be set with CSS, but some browsers still only allow that on outer <svg> elements.

Upvotes: 4

Related Questions