Tech 75
Tech 75

Reputation: 573

using css to control size and colour of an svg

I painstakingly created a search icon and exported it as an svg. This now appears on the header of a website but I am trying to have css control of the size and colour of it so I can size the icon responsively, match the colour of text on the site, and also have some kind of rollover colour change or lightening/darkening when users roll over the icon. I don't want to use inline svg but I am happy to use either the img-src or object techniques below.

<a href="#" onClick={this.onSearchClick} title="Search site">
<img src="//example-image-server/i/search_classic.svg" height="20" alt="Search the site"/>
<object type="image/svg+xml" data="//example-image-server/i/search_classic.svg" height="20" className="search-classic">Your browser does not support SVGs</object>
<span>Search</span>

Without using javascript, how do I control both colour and size.

I have tried creating a css class "search-classic" and setting fill: value but it has no effect.

Please note this code is for React, so uses className="search-classic" instead of just class="search-classic"

Upvotes: 1

Views: 1339

Answers (2)

Alexandr_TT
Alexandr_TT

Reputation: 14545

The author of the question writes:

I don't want to use inline svg but I am happy to use either the img-src or object techniques below. I have tried creating a css class "search-classic" and setting fill: value but it has no effect.

Let me offer you an action plan:

If I understand you correctly, you want to change the styles of the icon from the external style sheet.

  • Modifying the SVG file icon

    1. Add in the first line of your SVG icon file an indication of which style sheet will be used:

<?xml-stylesheet type="text/css" href="svg.css" ?>

This should be exactly the first line, otherwise problems may arise.

  1. Wrap your svg code with <symbol> tags and assign it a unique identifier.

    1. Remove all styles of svg elements, since they have higher priorities than the styles of external tables CSS

  <?xml-stylesheet type="text/css" href="svg.css" ?>
<svg  version="1.1"  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
	 width="48px" height="48px" viewBox="0 0 48 48">
<symbol id="searchIcon" viewBox="0 0 48 48">
	 <path id="myPath" d="M35,40H11v-0.051C5.947,39.447,2,35.186.... z"/>
</symbol> 
  	</svg>  

  • Adding an SVG file to HTML

Suppose you assign the edited file the name sprite.svg
In your case, adding to HTML is done only through the tag <object>
This command should be located higher in HTML than the command to call the icons from the sprite.

<object type="image/svg+xml" data="sprite.svg">
   Your browser does not support SVG
</object>
  • Calling an icon from the sprite

<svg viewBox="0 0 24 24"> <use xlink:href="sprite.svg#searchIcon"></use> </svg>

  • Adding rules for forced inheritance to an external table CSS

Once you use the <use> command, your SVG falls into the shadow DOM and you need to add the following CSS

see the article by Sara Soueidan in the section "Styling Content with the CSS all Property"

path#myPath {
    fill: inherit;
    stroke: inherit;
    stroke-width: inherit;
    transform: inherit;
    /* ... */
}

Pain is universal, tested in practice

svg path {
    fill: inherit;
    stroke: inherit;
    stroke-width: inherit;
    transform: inherit;
    /* ... */
}    

After all the items in the plan have been executed, the icon will obediently accept the styles from the external table CSS.

Upvotes: 1

Barthy
Barthy

Reputation: 3231

I'll just quote what is the result of 2 google searches. Please do your own research before asking questions.

Using SVG as an <object>

[…] You can link to an SVG file and retain the ability to affect its parts with CSS by using <object>. […] But, if you want the CSS stuff to work, you can't use an external stylesheet or <style> on the document, you need to use a <style> element inside the SVG file itself.

<svg ...>
  <style>
    /* SVG specific fancy CSS styling here */
  </style>
  ...
</svg>

[…] SVG has a way to declare an external stylesheet, which can be nice for authoring and caching and whatnot. This only works with <object> embedding of SVG files as far as I've tested. You'll need to put this in the SVG file above the opening <svg>

<?xml-stylesheet type="text/css" href="svg.css" ?>

Source: "Using SVG" — CSS-Tricks

Appendix 1

I looked at the codepen project you provided in the comments. Let's take the following file and fix it:

<svg xmlns="http://www.w3.org/2000/svg" width="136" height="136" viewBox="0 0 136 136">
  <style type="text/css" media="screen">
      <![CDATA[
      g {
          fill: yellow;
          stroke: black;
          stroke-width: 1;
          transition: fill 1s linear 0s;
      }
      g:hover {
          fill: blue;
      }
      ]]>
  </style>
  <path d="M121…Z"/>
</svg>

You are trying to style g, which is an SVG group. A group could contain multiple paths, circles, squares, etc. Unfortunately, you don't have any group in this SVG icon. You only have a path.

Additionally, to enable the :hover selector, you would have to enable pointer-events on the elements. This document should provide more information on that.

All in all, here is a working example:

<svg xmlns="http://www.w3.org/2000/svg" width="136" height="136" viewBox="0 0 136 136">
  <style type="text/css" media="screen">
      <![CDATA[
      path { /* TARGET THE CORRECT ELEMENT */
          fill: yellow;
          stroke: black;
          stroke-width: 1;
          transition: fill 1s linear 0s;
          pointer-events: all; /* ENABLE POINTER EVENTS */
      }
      path:hover { /* TARGET THE CORRECT ELEMENT */
          fill: blue;
      }
      ]]>
  </style>
  <path d="M121…Z"/>
</svg>

Upvotes: 3

Related Questions