Wednesday, 17 March, 2021 UTC


Summary

SVG icons are increasing in popularity and many developers need to implement different scenarios that require embedding them in AJAX controls. That led us to create this blog post and bring some clarity to the matter.

In this blog we will show you the main advantages of customizable SVGs (Scalable Vector Graphics) compared to the widely used font icons. You will find a brief pros-and-cons comparison along with a few examples of how to utilize the extra flexibility of SVGs in some of the components in the Telerik UI for ASP.NET AJAX suite.
We have initially started the topic of using custom icons in Telerik UI for ASP.NET AJAX Controls with 4 Ways to Embed Font Awesome in Telerik UI for ASP.NET AJAX Controls. In this article, we are diving deeper into the topic and introducing the more flexible and complex SVG icons.
Do you like the responsiveness of the SVG logo above? Go ahead and find out how to achieve the same thing and use it in your Telerik application.
Here Is What We Will Cover:
  1. Comparison of SVG and font icons
  2. Embed an SVG into a page
  3. Multicolor SVG icon in Telerik RadToolBar
  4. Dynamically styled SVG icons in Template—RadGrid
  5. Responsive SVG icons in RadTabStrip
  6. Additional SVG Icon Resources
  7. Conclusion
Comparison of SVG and Font Icons
Although we are comfortable with the popular and easy-to-use font icons, it seems that we can achieve a lot more with the SVG ones.
The main benefit of SVGs is the full control over the graphics they provide. With the help of CSS and JavaScript, SVG icons can be multicolored, dynamically styled and even animated. That makes them suitable for almost everywhere an icon is needed.
In addition, the better accessibility support is a great advantage of the SVGs in cases when accessibility compliance is required.
The table below gives an overview of the main differences between SVG and Font Icons:
SVG icons Font icons
Representation Vector graphic Font glyph
Use in the Browser Treated as graphic file Treated as text
Manipulation Controlled with JavaScript and CSS Controlled with CSS font styles
Fallback Broken image. Alternate text is displayed. Register as font item. Rendered incorrectly – accessibility issue
Pros
  • CSS and JS control
  • Layers
  • Lives in the DOM
  • Accessibility support
  • Easy to implement
  • Solid browser support
  • Established standard
Cons
  • Inconsistent Browser support
  • Unfamiliar process
  • Monochromatic
  • Not proper graphics
  • Workaround for high resolution

Embed SVG into a Page
With the increasing browser support of the SVG, there appear to be multiple ways to bring the vector graphics into a web page. Still, there are two main conceptually different approaches—inline as part of the DOM and externally referenced with URL or a path to the file. The customizability of the SVG depends on the approach for adding the SVG:

Add Icon with URL

Adding the icon with its URL is done the same way as is adding any other image to the page. Using the URL of the SVG file as image or background image can be easily achieved in the markup declaration of the page or added with some CSS.
Here is the content of the “SVGs/ProgressLogo.svg” file that we will use as image inside the button:
<img  src="SVGs/ProgressLogo.svg"  Height="150px"  alt="Progress logo"  />  
Or :
<style>
.logo{
background-image:url("SVGs/ProgressLogo.svg");
}
</style>
However, manipulating the inner parts of the SVG with CSS or JavaScript is not possible after the image is loaded. Loading the SVG from external resource requires an additional http request, which is a disadvantage of this method in terms of performance.

Add Icon Inline

The inline approach is slightly more complex but allows a lot more runtime customizability of the icon. The SVG in this case is part of the DOM and can be processed with JS and CSS as any other html element.
Options for loading the SVG icon as part of the DOM include:
  • Declaring it in the markup of the page. Wherever template fields are exposed (for example a ContentTemplate) and native HTML is allowed, it is perfect to add the SVG directly to the page structure:
<telerik:RadButton  ButtonType="LinkButton"..>
<ContentTemplate>
<svg  xmlns="http://www.w3.org/2000/svg"...>
<path  .../>  
...
</svg>
</ContentTemplate>
</telerik:RadButton>  
  • Nesting it in an <object> tag. (See Using SVG as an <object>.)
  • Adding an SVG icon to the DOM runtime. Although this is possible, it can be quite tricky, as it requires some JavaScript proficiency and could lead to performance issues. Therefore, we shall not deal with that approach in this blog.
Multicolor SVG Icon in Telerik RadToolBar
The SVG is based on XML and all elements of the graphic are defined with separate XML tags, recognized by the browsers. This structure provides the opportunity to apply attributes or assign classes for each piece of the SVG and style it independently from the rest of the image.
Let’s use a multicolor Progress logo in a RadToolBarButton inside a RadToolBar control.
This example shows how to use the SVG as a static icon in the ToolBarButton Template, so it is suitable for referencing the SVG icon as an image using its URL.
Multiple colors in the SVG declaration below are achieved by setting different fill (color) and stroke (border color) attributes to the separate <path> elements:
ProgressLogo.svg
<svg  xmlns="http://www.w3.org/2000/svg"  width="100%"  height="100%"  viewBox="0 0 49 60.3">
  <path  fill="#333"  stroke="#5ce500"  d="M11.2 14.9L0 21.3l17.4 10.1v20.1l11.2-6.4c.5-.3.9-1 .9-1.6V24.4L13 14.9c-.5-.3-1.3-.3-1.8 0z"></path>
  <path  fill="#5ce500"  stroke="#333"  d="M12.1 48.4V34.5L0 41.5zM25 .2c-.5-.3-1.3-.3-1.8 0L10.7 7.4l24.1 13.9v27.9L47.3 42c.5-.3.9-1 .9-1.6V13.6L25 .2z"></path>
</svg>
Basic declaration of the RadToolBar and our target RadToolBarButton:
<telerik:RadToolBar  ID="RadToolBar1"  runat="server">
  <Items>
    <telerik:RadToolBarButton  ImageUrl="SVGs/ProgressLogo.svg"  Height="50"  Width="50"  ></telerik:RadToolBarButton>
  </Items>
</telerik:RadToolBar>
Here is the appearance we achieved with the code above:
Dynamically Styled SVG Icons in Template—RadGrid
To be able to get as much as possible out of the interactivity of SVG icons, we would need to add them as part of the DOM.
The flexibility of the popular RadGrid control gives us the chance to use a template column for embedding our special SVG buttons.
We can replace the automatically created Edit Column of a grid with a GridTemplateColumn. The ItemTemplate allows us to use pure HTML in our cell’s content so we can embed the SVG icon as an inline element:
<telerik:GridTemplateColumn UniqueName="customEditColumn" HeaderText="Edit" ItemStyle-Height="35px" HeaderStyle-Width="60px">
    <ItemTemplate>
        <telerik:RadButton ButtonType="LinkButton" CssClass="gridEditButton" runat="server" ID="RadButton1" AutoPostBack="true" CommandName='<%# RadGrid.EditCommandName %>'>
            <ContentTemplate>
                <span>
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xsl="http://www.w3.org/1999/xlink" x="0px" y="0px"
                        width="16" height="16" viewBox="0 0 40 40" class="editSVGIcon">
                        <path fill="#F5CE85" d="M5.982 29.309L8.571 26.719 13.618 31.115 10.715 34.019 2.453 37.547z"></path>
                        <path fill="#967A44" d="M8.595,27.403l4.291,3.737l-2.457,2.457l-7.026,3.001l3.001-7.003L8.595,27.403 M8.548,26.036 l-2.988,2.988l-4.059,9.474L11,34.44l3.351-3.351L8.548,26.036L8.548,26.036z"></path>
                        <path class="head" fill="#36404D" d="M3.805 33.13L1.504 38.5 6.888 36.201z"></path>
                        <path class="rubber" fill="#F78F8F" d="M30.062,5.215L32.3,2.978C32.931,2.347,33.769,2,34.66,2s1.729,0.347,2.36,0.978 c1.302,1.302,1.302,3.419,0,4.721l-2.237,2.237L30.062,5.215z"></path>
                        <path class="rubber-contour" fill="#C74343" d="M34.66,2.5c0.758,0,1.471,0.295,2.007,0.831c1.107,1.107,1.107,2.907,0,4.014l-1.884,1.884 L30.77,5.215l1.884-1.884C33.189,2.795,33.902,2.5,34.66,2.5 M34.66,1.5c-0.982,0-1.965,0.375-2.714,1.124l-2.591,2.591 l5.428,5.428l2.591-2.591c1.499-1.499,1.499-3.929,0-5.428v0C36.625,1.875,35.643,1.5,34.66,1.5L34.66,1.5z"></path>
                        <g>
                            <path class="pencilBody" fill="#FFEEA3" d="M11.346,33.388c-0.066-0.153-0.157-0.308-0.282-0.454c-0.31-0.363-0.749-0.584-1.31-0.661 c-0.2-1.267-1.206-1.803-1.989-1.964c-0.132-0.864-0.649-1.342-1.201-1.582l21.49-21.503l4.721,4.721L11.346,33.388z"></path>
                            <path class="pencilBody-contour" fill="#BB9C4A" d="M28.054,7.931l4.014,4.014L11.431,32.594c-0.242-0.278-0.638-0.59-1.261-0.748 c-0.306-1.078-1.155-1.685-1.983-1.943c-0.151-0.546-0.447-0.968-0.821-1.272L28.054,7.931 M28.053,6.517L5.56,29.023 c0,0,0.007,0,0.021,0c0.197,0,1.715,0.054,1.715,1.731c0,0,1.993,0.062,1.993,1.99c1.982,0,1.71,1.697,1.71,1.697l22.482-22.495 L28.053,6.517L28.053,6.517z"></path>
                        </g>
                        <g>
                            <path fill="#D9E7F5" d="M29.107 4.764H34.685V11.440999999999999H29.107z" transform="rotate(-45.009 31.895 8.103)"></path>
                            <path fill="#788B9C" d="M31.507,4.477l4.014,4.014l-3.237,3.237L28.27,7.714L31.507,4.477 M31.507,3.063l-4.651,4.651 l5.428,5.428l4.651-4.651L31.507,3.063L31.507,3.063z"></path>
                        </g>
                    </svg>
                </span>
            </ContentTemplate>
        </telerik:RadButton>
    </ItemTemplate>
</telerik:GridTemplateColumn>
With the help of the classes assigned to different pieces of the graphic and some CSS, we can style the button and change its appearance dynamically.
We can use the :hover pseudo element to modify the fill colors when the mouse is placed over the element.
<style>
    .RadGrid .RadButton.gridEditButton {
        border: none;
        background: none;
    }

    .editSVGIcon:hover {
        width: 20px;
        height: 20px;
    }

        .editSVGIcon:hover .rubber,
        .editSVGIcon:hover .rubber-contour {
            fill: darkred;
        }

        .editSVGIcon:hover .head {
            fill: darkblue;
        }

        .editSVGIcon:hover .pencilBody {
            fill: lightblue;
        }
</style>
By following the same approach, SVGs can be embedded in every Template field that allows using plain HTML.
Responsive SVG Icons in Telerik RadTabStrip
Making an SVG scale as its container scales might seem to be a simple task; however, due to the inconsistent behavior of the different browsers, that turns out to be quite the contrary. There are multiple resources around the web discussing this topic, so here we will simply wireframe the responsive capabilities of SVG icons.
As styles can be embedded directly inside the SVG tag, we can use that to show and hide parts of the SVG based on internally defined media queries.
In the following sample, we use the Progress logo again. This time we will use two separate symbol elements in the SVG—one with the icon and one with the text and TM sign. With the help of the symbol separation, we can generate small and full versions of the logo, which we’ll show and hide later based on the media query.
svg xmlns="http://www.w3.org/2000/svg"  width="100%" height="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
 <style>
    .small {
    visibility: hidden;
    }
    .full {
    visibility: visible;
    }

    /* On screens that are 600px or less, set the background color to olive */
    @media screen and (max-width: 150px) {
    .small {
    visibility: visible;
    }
    .full {
    visibility: hidden;
    }
    }
  </style>
  
  <symbol id="logo" viewBox="0 0 60 60">
    <path class="3" fill="#5ce500" d="M11.2 14.9L0 21.3l17.4 10.1v20.1l11.2-6.4c.5-.3.9-1 .9-1.6V24.4L13 14.9c-.5-.3-1.3-.3-1.8 0z"></path>
    <path class="4" fill="#5ce500" d="M12.1 48.4V34.5L0 41.5zM25 .2c-.5-.3-1.3-.3-1.8 0L10.7 7.4l24.1 13.9v27.9L47.3 42c.5-.3.9-1 .9-1.6V13.6L25 .2z"></path>
  </symbol>

  <symbol id="ProgressTelerikTM" viewBox="0 0 400 60" >
    <path class="1" fill="#7c878e" d="M396.7 18.4c-2 0-3.7 1.6-3.7 3.7 0 2.2 1.7 3.7 3.7 3.7s3.7-1.6 3.7-3.7c0-2.2-1.7-3.7-3.7-3.7zm0 6.8c-1.7 0-3-1.3-3-3.1s1.3-3.1 3-3.1 3 1.3 3 3.1-1.3 3.1-3 3.1z"></path>
    <path class="2" fill="#7c878e" d="M398.5 21.5c0-.9-.6-1.4-1.4-1.4h-1.8V24h1.1v-1.2h.3l.8 1.2h1.2l-.9-1.4c.4-.1.7-.5.7-1.1zm-1.6.4h-.6V21h.6c.3 0 .5.2.5.4 0 .4-.2.5-.5.5zm-103.5-7.7h-28.5v2.6h12.7v32.4h2.9V16.8h12.9zm7.4 9.1c-6.7 0-10.9 5.6-10.9 13.4 0 7.9 4.7 12.9 11.8 12.9 3 0 5.5-.7 7.4-2.2v-2.7c-2.2 1.8-4.3 2.5-7.1 2.5-5.2 0-9.2-3.6-9.2-10.4H311v-1c-.2-7.4-3.6-12.5-10.2-12.5zm-8 11.1c.7-5.5 3.9-8.6 8-8.6 5 0 7.1 4.1 7.3 8.6h-15.3zM315 12.1h2.9v37.1H315zm18.1 11.2c-6.7 0-10.9 5.6-10.9 13.4 0 7.9 4.7 12.9 11.8 12.9 3 0 5.5-.7 7.4-2.2v-2.7c-2.2 1.8-4.3 2.5-7.1 2.5-5.2 0-9.2-3.6-9.2-10.4h18.2v-1c-.1-7.4-3.6-12.5-10.2-12.5zm-8 11.1c.7-5.5 3.9-8.6 8-8.6 5 0 7.1 4.1 7.3 8.6h-15.3zm25-6.5v-4h-2.9v25.3h2.9V31.5c1.2-3.2 3.6-5.5 6.7-5.5.9 0 1.7.2 2.3.5v-2.8c-.6-.2-1.3-.3-2.2-.3-3.1-.1-5.7 2-6.8 4.5zm12.1-4h2.8v25.3h-2.8zm1.5-9.7c-1.1 0-1.9.9-1.9 1.9 0 1.1.9 1.9 1.9 1.9s1.9-.9 1.9-1.9-.8-1.9-1.9-1.9zm26.5 9.7h-3.7l-12.8 11V12.1h-2.9v37.1h2.9v-13l13.2 13h3.5l-13.8-13.8z"></path>
    <path class="5" fill="#4b4e52" d="M117.9 22.5c-4.3 0-7.7 1.6-9.8 4.7-2.3 3.2-2.6 7-2.6 9 0 8.3 4.9 13.6 12.5 13.6 9.2 0 12.5-7.4 12.5-13.8 0-3.7-1.1-7-3.1-9.4-2.3-2.7-5.6-4.1-9.5-4.1zm0 22.4c-4.2 0-6.9-3.4-6.9-8.8 0-5.5 2.6-8.9 6.9-8.9 4.2 0 6.9 3.4 6.9 8.8 0 5.5-2.7 8.9-6.9 8.9zM74.8 13.6H61.7v35.6h5.8v-14h7.4c8 0 12.4-3.9 12.4-11-.1-3.1-1.3-10.6-12.5-10.6zM74.1 30h-6.6V18.9h7.4c4.3 0 6.4 1.8 6.4 5.5 0 4-2.1 5.6-7.2 5.6zm26.6-7.3c-2.2.3-3.9 1.4-5.2 3.5V23h-5.1v26.1h5.4V37.9c0-5.2.4-9.6 5.9-9.6.6 0 1.1.1 1.7.3l.7.2 1-5.3-.4-.2c-1.2-.5-2.6-.7-4-.6zm145 12.1c-1.3-.5-4-1.2-6.1-1.7-1-.3-1.9-.5-2.5-.7-2-.6-3-1.4-3-2.6 0-2.5 3.5-2.8 5-2.8 1.8 0 4.8.5 5.3 3.5l.1.4h5.2v-.5c-.4-5.3-4-7.8-10.8-7.8-5.1 0-10.2 2.4-10.2 7.6 0 2.8 1.9 5.2 5.2 6.3 1.3.5 3.5 1.1 5.6 1.7 1.2.3 2.4.7 3.3.9 1.6.5 2.4 1.4 2.4 2.6 0 2.4-2.9 3.3-5.6 3.3-2.5 0-5.5-.7-6.2-3.9l-.1-.4h-5.2l.1.6c.5 5.4 4.6 8.3 11.4 8.3 7.7 0 11.2-4.2 11.2-8.4-.1-3-1.8-5.2-5.1-6.4zm-94-9.6c-1.7-1.8-4.1-2.7-7-2.7-7.9 0-11.5 7-11.5 13.5 0 6.6 3.6 13.4 11.5 13.4 2.7 0 5-1 6.7-2.7 0 1.2 0 2.3-.1 2.7-.3 4.3-2.4 6.3-6.5 6.3-2.3 0-4.9-.8-5.4-3.1l-.1-.5H134l.1.7c.6 4.6 4.6 7.5 10.6 7.5 5.2 0 8.9-2 10.8-5.7.9-1.8 1.3-4.4 1.3-7.8V23.1h-5.1v2.1zm-6.6 19.3c-1.9 0-6.3-.9-6.3-8.8 0-5.2 2.5-8.4 6.4-8.4 3.1 0 6.3 2.2 6.3 8.4.1 5.5-2.3 8.8-6.4 8.8zm75.6-9.7c-1.3-.5-4-1.2-6.1-1.7-1-.3-1.9-.5-2.5-.7-2-.6-3-1.4-3-2.6 0-2.5 3.5-2.8 5-2.8 1.8 0 4.8.5 5.3 3.5l.1.4h5.2v-.5c-.4-5.3-4-7.8-10.8-7.8-5.1 0-10.2 2.4-10.2 7.6 0 2.8 1.9 5.2 5.2 6.3 1.3.5 3.5 1.1 5.6 1.7 1.2.3 2.4.7 3.3.9 1.6.5 2.4 1.4 2.4 2.6 0 2.4-2.9 3.3-5.6 3.3-2.5 0-5.5-.7-6.2-3.9l-.1-.4h-5.2l.1.6c.5 5.4 4.6 8.3 11.4 8.3 7.7 0 11.2-4.2 11.2-8.4 0-3-1.7-5.2-5.1-6.4zm-19.9 0c-.3-7.3-5-12.2-11.9-12.2-4 0-7.3 1.6-9.5 4.5-1.8 2.4-2.8 5.7-2.8 9.1 0 8.1 5 13.5 12.5 13.5 5.8 0 9.8-2.9 11.2-8.3l.2-.6h-5.4l-.1.3c-1.1 3.2-3.8 3.9-5.9 3.9-4.1 0-6.7-2.7-7-7.1h18.5l.1-.5c.1-.6.1-1.5.1-2.1v-.5zm-18.4-1.6c.5-3.6 2.9-5.9 6.5-5.9 2.7 0 5.9 1.6 6.3 5.9h-12.8zm-10.5-10.5c-2.2.3-3.9 1.4-5.2 3.5V23h-5.1v26.1h5.4V37.9c0-5.2.4-9.6 5.9-9.6.6 0 1.1.1 1.7.3l.7.2 1-5.3-.4-.2c-1.2-.5-2.6-.7-4-.6zm84.8-1.2c0-.9-.6-1.4-1.4-1.4h-1.8V24h1.1v-1.2h.3l.8 1.2h1.2l-.9-1.4c.4-.1.7-.5.7-1.1zm-1.5.4h-.6V21h.6c.3 0 .5.2.5.4 0 .4-.2.5-.5.5z"></path>
    <path class="6" fill="#4b4e52" d="M255 18.4c-2 0-3.7 1.6-3.7 3.7 0 2.2 1.7 3.7 3.7 3.7s3.7-1.6 3.7-3.7c0-2.2-1.7-3.7-3.7-3.7zm0 6.8c-1.7 0-3-1.3-3-3.1s1.3-3.1 3-3.1 3 1.3 3 3.1-1.4 3.1-3 3.1z"></path>
  </symbol>

  <symbol id="complete" viewBox="0 0 400 60">
    <use xlink:href="#logo" x="0" y="0" width="60" height="60"/>
    <use xlink:href="#ProgressTelerikTM" x="0" y="0" width="400" height="60"/>
  </symbol>

  <use class="small" xlink:href="#logo" x="0" y="0" />
  <use class="full" xlink:href="#complete" x="0" y="0"/>

</svg>
Let’s use that logo as a tab in a full-width RadTabStrip control.
<telerik:RadTabStrip runat="server" ID="RadTabStrip1" MultiPageID="RadMultiPage1" Width="100%">
    <Tabs>
        <telerik:RadTab Width="25%" CssClass="logoBar"></telerik:RadTab>
        <telerik:RadTab Text="Tab 2" Width="25%"></telerik:RadTab>
        <telerik:RadTab Text="Tab 3" Width="25%"></telerik:RadTab>
        <telerik:RadTab Text="Tab 4" Width="25%"></telerik:RadTab>
    </Tabs>
</telerik:RadTabStrip>
.logoBar .rtsLink {
    color: transparent;
    background-image: url("SVGs/ProgressLogoFull.svg") !important;
    background-size: 80%;
    background-repeat: no-repeat;
    background-position-x: center;
    background-position-y: center;
}
The result:
Additional SVG Icon Resources
Here are some other useful resources with details on creating and using responsive SVG icons:
  • Making SVGs Responsive with CSS
  • SVG & media queries
  • Using SVG with Media Queries
And more about SVGs and SVG icons:
  • Using SVG - CSS Tricks
  • How to Use SVG Images in CSS and HTML – A Tutorial for Beginners
  • Use Illustrator & Spritebot to generate some SVG icons and use them in a website
Conclusion
The possibilities that SVGs offer are a lot more than demonstrated in this blog. Customizability and fancy UX can be taken to the next level with some JavaScript and animations. Although inconsistent browser support makes this quite complicated now, we hope this will change in the near future and using SVGs will be a part of our daily routine.
In this post we have picked just three scenarios for integrating SVG icons in Telerik AJAX Controls. But if you want to use SVG icons with any of the other 120 Telerik ASP.NET AJAX controls, feel free to leave a comment below or submit a ticket to the Telerik Support Team!
You can learn more about Telerik UI for ASP.NET AJAX and start a free trial here.
Start a Free Trial