Best way to style SVG without having them inline - html
I have a menu with about 10 items. Each item has its own icon. This icon is a SVG file.
For example:
<li class="active">
<a href="/home">
<svg version="1.1" id="svg-menu-home"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="31px" height="31px" viewBox="-8 -8 31 31"
overflow="visible" enable-background="new -8 -8 31 31" xml:space="preserve">
<mask maskUnits="userSpaceOnUse" x="0" y="0" width="15" height="15" id="maskTop">
<polygon fill="#FFFFFF" points="12,6.036 2,6.036 2,14.036 6,14.036 6,9.036 8,9.036 8,14.036 12,14.036"/>
<polygon fill="#FFFFFF" points="7,0.036 0,7.036 14,7.036"/>
</mask>
<rect mask="url(#maskTop)" fill="#939598" width="15" height="15"/>
</svg>
<span>Home</span>
</a>
</li>
When a user interacts with the menu item I can assign a class etc to it (hover, select, active).
Having the entire source inline seems to be the only way I can change SVG using CSS, such as:
<style>
li.active svg polygon {
fill: red;
}
</style>
The problem is:
Having any significant number of SVG files inline makes code unreadable, and
Doesn't make it easy to maintain the SVG if you reference it elsewhere.
I would much rather make reference to the file src the way you would an IMG (<img src="x.jpg"/>) and avoid a Javascript dependent solution.
However all the ways I've seen don't allow for CSS styling of the SVG element (or require JS).
Any thoughts/workarounds?
Probably not the most elegant solution, but you could organize them into php includes:
<?php include 'inc/svg-menu-home.svg.php'; ?>
I think is not a bad way to have a look over http://raphaeljs.com/ . It helped me to create this http://screencast.com/t/rNr0Cbqkb ( every area is a svg )
Related
How do you add a link inside an SVG image file?
I'm having trouble trying to place a clickable link within my SVG image. I've read a few articles but I still cannot seem to get the hang of it, I would greatly appreciate if anyone could guide me on what I may be doing wrong & how I can resolve the issue with my code, Thank you. I'll add a snippet below: <div class="apps"> <svg id="app-button" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <path d="M0 0h24v24H0V0z" fill="none" /> <path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0 -6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h- 4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z" /> </div>
Links can be placed inside an svg element by use of the xlink namespace, see https://www.w3.org/wiki/SVG_Links. For the example in the question you could use something like this, <div class="apps"> <svg id="app-button" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <a xlink:href="http://localhost"> <path d="M0 0h24v24H0V0z" fill="none" /> <path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0 -6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h- 4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z" /> </a> </svg> </div> By placing a reference to the xlink namespace in the svg element (xmlns:xlink="http://www.w3.org/1999/xlink") we can use an anchor element like <a xlink:href="...">...</a> around whatever part of the svg image we wish to make clickable. In this case only the paths are clickable, not the entire svg viewbox as would be the case if we wrapped the whole <svg>...</svg> in a standard html anchor element.
there's no need to add link to svg just enclose them inside anchor tag <a href="somelink.com"> <svg></svg> </a>
SVG Spritesheets using SYMBOL CSS SVG Fragment in CSS as background: url or similar? if not why?
Can we do this? Use SYMBOL CSS SVG Fragment USE in CSS as background: url or similar? It seems to me, all other things being equal, SYMBOL use does not work, where G with separate viewbox works. If this cannot be done, why? Is there a better way to do SVG Spritesheets? SYMBOL has an ID, has a viewBox..am I doing somthing wrong or using symbol inc. viewbox, VS, separate viewbox & g = Does Not Work? oO Am I doing somthing wrong, or, does the below CSS SVG fragment usage only work with the separate viewbox and G (and not work with symbol with viewbox)? SYMBOL SVG <symbol xmlns="http://www.w3.org/2000/svg" transform="rotate(360)" viewBox="0 0 24 24" id="basket"> <path fill="none" stroke="#626262" stroke-width="2" d="M2 12h20l-2 11H4L2 12zm18-4l-6-7M4 8l6-7M1 8h22v4H1V8zm7 7v5m8-5v5m-4-5v5"></path> <path fill="rgba(0, 0, 0, 0)" d="M0 0h24v24H0z"></path> </symbol> ..VS.. G & VIEWBOX SVG <view id="icon-clock-view" viewBox="0 0 32 32" /> <g id="icon-clock"> <path d="M20.6,23.3L14,16.7V7.9h4v7.2l5.4,5.4L20.6,23.3z M16-0.1c-8.8,0-16,7.2-16,16s7.2,16,16,16s16-7.2,16-16S24.8-0.1,16-0.1z M16,27.9c-6.6,0-12-5.4-12-12s5.4-12,12-12s12,5.4,12,12S22.6,27.9,16,27.9z"/> </g> CSS .icon-clock {background: url(https://example.com/svg-defs.svg#icon-clock-view) no-repeat;} .basket {background: url(https://example.com/svg-defs.svg#basket) no-repeat;}
This seems to works great. Using 'name' as example to follow. Wrap <path>(s) & </path> within <symbol> </symbol> I did not use <g> Add id="name" to <symbol> e.g. <symbol id="name"> Outside the symbol tags, add a <view> and a <use>. The URL, where the complete file is uploaded to, and view ID will become your SVG Fragment. <view id="icon-name-view" viewBox="0 1240 16 16" /> <use xlink:href="#icon-name" width="16" height="16" x="0" y="1240" id="name"></use> Change the viewbox to locate the SVG in the spritesheet, here I'd used Y axis, this particular SVG is located at Y axis 1240. Save the SVG Spritesheet to say, svg-defs.svg. In your CSS use the SVG spritesheet URL with the Fragment Ident e.g. background: url(https://example.com/svg/svg-defs.svg#icon-name-view) no-repeat; To change colours I was using filter, e.g. filter: invert(80%) sepia(21%) saturate(872%) hue-rotate(44deg) brightness(84%) contrast(91%); Positioning can be done with the ViewBox's but I also used transform, translate. transform: translateY (10px); Hope you find this useful, I hope to write a complete guide and will link it when I do. Thank you.
svg not sharp, but blurry
For whatever reason these svg files, seems blurry, and not 100% sharp in all browsers. These are svg files, and are enclosed within elements that are scaled to pixels, in other words using px and not % - hence no browser bitmap errors. Any idea as to why this is happening? This is one of the svg files; <?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 361.5 192.5" style="enable-background:new 0 0 361.5 192.5;" xml:space="preserve"> <style type="text/css"> .st0{fill:none;} .st1{fill:#FC5500;} .st2{fill:#FFFFFF;} .st3{fill:#FB5500;} </style> <g> <path class="st0" d="M-9.4-6.3c126,0,252,0,378,0c0,68.7,0,137.3,0,206c-126,0-252,0-378,0C-9.4,131-9.4,62.4-9.4-6.3z"/> <path class="st1" d="M-0.2,112.1c0-8,0-15.9,0-24.4c112.3,0,224.3,0,336.7,0c0-29.4,0-58.4,0-87.7c8.4,0,16.4,0,25,0 c0,46.8,0,93.7,0,140.6c-2.4-0.3-2.5-2.5-3.2-4c-3.7-9-10.3-15-19.3-18.5c-15.2-6-31.2-6.7-47.2-5.5c-7.8,0.6-15.6,1.5-23.1,4.1 c-24.8,8.7-33.9,38-18.3,59.2c5.8,7.8,14.5,10.9,23.4,13.4c2,0.6,4.9-0.1,5.6,3.1c-13.9,0-27.9,0-41.8,0 c-8.1-5.7-14.1-13.6-21.4-20.2c-1.7-1.5-3.8-2.8-4.1-5.5c0.5-2.5,2.8-3.1,4.7-3.9c9.5-4.3,14.3-11.9,14.5-22.1 c0.2-10.1-4.8-17.3-13.9-21.8c-8.5-4.2-17.6-5.3-26.7-5.5c-20.8-0.4-41.6-0.1-62.5-0.1c-1.7,0-3.3,0-4.8,0.8 c-1.6,2.3-1.1,4.9-1.1,7.3c0,21.2,0,42.3,0,63.5c0,2.6,0.5,5.4-1.7,7.6c-32,0-64,0-96.1,0c-3.2-6.9-1.5-13.8-0.9-20.2 c3.1-2.6,6-2.3,8.8-2.3c12.7-0.1,25.3,0,38-0.1c7.8-0.1,15.3-1.6,22.2-5.3c17.8-9.6,18.8-33.3,1.7-44.3c-8.9-5.7-19.1-6.7-29.3-6.9 c-19.3-0.3-38.7,0.1-58-0.1C4.6,113.4,2,113.8-0.2,112.1z"/> <path class="st2" d="M120.6,192.5c0-26.6,0-53.3,0-80.7c29.5,1.5,58.7-2.6,87.6,2.2c13.5,2.2,24.2,9.5,24.9,25.1 c0.6,14.2-6.8,23.1-20.2,27c8.3,8.8,16.5,17.6,24.7,26.4c-11.2,0-22.5,0-33.7,0c-4-1.4-6-5-8.7-7.9c-12.1-13.2-6.6-11-23.7-11.2 c-5.5-0.1-10.9,0-16.4,0c-2,0-4-0.2-6,1c-1.5,3.5-0.5,7.4-0.8,11.1c-0.2,2.4,0.3,5-1.7,7.1C138,192.5,129.3,192.5,120.6,192.5z"/> <path class="st2" d="M203.8,0.7c-4.9,6.4-10,13.1-15.2,20c-18.4,0-36.7,0-55,0c-4.1,0-9-0.2-8.9,5.9c0,6.1,4.8,5.9,9,6 c16.8,0.2,33.7-0.4,50.5,0.6c12.5,0.7,22.4,6.1,22.6,20.9c0.2,14.6-7.3,24.7-22.5,25.3c-28.5,1.2-57.1,0.3-85.9,0.3 c5-6.5,10.1-13.2,15.3-20c19.3,0,38.4,0.1,57.6-0.1c4.4,0,11.3,1.9,11.3-5.3c0.1-7.7-7-5.4-11.6-5.5c-16.1-0.4-32.4,0.3-48.4-0.9 c-13-1-21.7-8.1-21.9-22.5c-0.2-14.9,8.5-23.6,22-24.3C149.5-0.2,176.6,0.7,203.8,0.7z"/> <path class="st2" d="M279.5,192.5c-31.5-9.3-41.2-22.1-36.9-48.9c2.8-17.6,15-26,31-29.7c18.9-4.4,38-4.4,57-0.2 c15.1,3.4,26.5,11.3,31,27c0,7.6,0,15.2,0,22.9c-2.8,16.5-15.6,27.1-34.6,28.6c-1,0.1-2-0.2-2.9,0.3 C309.1,192.5,294.3,192.5,279.5,192.5z"/> <path class="st2" d="M77.2,20.7c-17.1,0-33.9,0-51.1,0c0,3.2,0,6.3,0,9.8c20.5,0,41.1,0,62.9,0c-5.3,6.7-9.8,12.4-14.4,18.2 c-16.2,0-32.1,0-48.5,0c0,3.6,0,7,0,10.8c22,0,44.1,0,67.6,0c-5.9,7.7-11,14.5-16,21.1c-26,0-51.6,0-77.6,0C0,53.7,0,27,0,0 c30.7,0,61.4,0,93,0C87.6,7.1,82.5,13.8,77.2,20.7z"/> <path class="st2" d="M-0.2,112.1c25.3,0.1,50.6-0.4,75.9,0.7c20.2,0.9,32.8,13.2,32.7,29.5c-0.1,16.5-13.5,28.5-34.1,29.3 c-16.3,0.6-32.6,0.1-49.7,0.1c0,7.4,0,14.1,0,20.9c-8.1,0-16.3,0-24.8,0C-0.2,165.6-0.2,138.8-0.2,112.1z"/> <path class="st2" d="M233.3-0.2c18.6,0,37-0.5,55.3,0.1c21,0.7,34.6,13.1,34.6,30.5c0,17.4-13.8,29.5-35.4,30.1 c-15.1,0.5-30.3,0.1-45.9,0.1c0,6.7,0,13.1,0,19.8c-8.6,0-16.6,0-25,0c0-13.4,0-26.6,0-40.7c22.6,0,45.3,0,68.1,0 c5.2,0,10.8-0.6,12.4-6.2c2.6-9.1-3-12.6-11.1-12.7c-22.7-0.2-45.5-0.1-69.4-0.1C222.7,13.3,227.9,6.6,233.3-0.2z"/> <path class="st1" d="M146.7,192.5c0-6.8,0-13.6,0-20.8c13.2,0,26.1,0,39.7,0c5.6,6.6,11.6,13.7,17.6,20.8 C184.9,192.5,165.8,192.5,146.7,192.5z"/> <path class="st3" d="M323.9,192.5c17.1-3.7,32.3-9.9,37.6-29c0,9.5,0,18.9,0,29C349,192.5,336.4,192.5,323.9,192.5z"/> <path class="st3" d="M145.8,150.8c0-5.7,0-11.4,0-17.1c17.9,0,35.6-0.2,53.3,0.2c4.4,0.1,7.8,3.1,7.7,8.3c-0.1,6-4.5,8.4-9.3,8.5 C180.4,151,163.3,150.8,145.8,150.8z"/> <path class="st1" d="M302.2,173.1c-6-0.4-11.4-0.7-16.9-1.1c-12.8-1.1-18.4-8-18.1-20.9c0.3-12.7,7.6-17.4,19-18.6 c11.1-1.1,22.3-1.2,33.4,0.1c11.3,1.3,17.2,7.1,17.3,19c0.1,11.8-5,18.7-16.7,20C314.1,172.4,307.9,172.7,302.2,173.1z"/> <path class="st3" d="M25.1,133c15.6,0,30.9-0.2,46.2,0.1c5.6,0.1,11.1,1.8,11.2,8.7c0.2,7.1-5.2,9.3-11.1,9.4 c-15.3,0.3-30.6,0.1-46.3,0.1C25.1,145.5,25.1,139.6,25.1,133z"/> </g> </svg>
If you want your SVG to be at its sharpest, then design it so that its shapes - especially the horizontal and vertical parts of the shapes - are on pixel boundaries. For example, compare the following two examples: <svg width="50" height="50"> <rect x="9.5" y="9.5" width="31" height="31"/> </svg> <svg width="50" height="50"> <rect x="10" y="10" width="30" height="30"/> </svg> Here's what this looks like at 4X enlargement. Any time your shape passes through the middle of pixels, you will get grey pixels due to the anti-aliasing that 2D renderers use.
The response used a slightly modified code #Paul LeBeau You can use the SVG attribute - shape-rendering =" crispEdges " to disable browser anti-aliasing. https://developer.mozilla.org/ru/docs/Web/SVG/Attribute/shape-rendering crispEdges Indicates that the user agent shall attempt to emphasize the contrast between clean edges of artwork over rendering speed and geometric precision. To achieve crisp edges, the user agent might turn off anti-aliasing for all lines and curves or possibly just for straight lines which are close to vertical or horizontal. Also, the user agent might adjust line positions and line widths to align edges with device pixels. <svg width="50" height="50"> <rect x="9.5" y="9.5" width="31" height="31" shape-rendering="crispEdges"/> </svg> <svg width="50" height="50"> <rect x="10" y="10" width="30" height="30"/> </svg> The image is increased 4 times No gray pixels are observed. Update 2019 by comments There is no universal, 100% solution to the pixelation problem. Since the rendering depends on the installed operating system, its settings, the video card and which browser is used. You can use an integrated approach made up of all the answers of this topic: Use integer svg image coordinate values by answer #Paul LeBeau If you take a finished image with fractional values, you can process it with SVG optimizer Set the integer value of viewBox by answer #AKX Use the attribute shape-rendering ="crispEdges" If a design change is possible, avoid contrasting border colors. For example, use a dark gray color instead of a black and white combination or use shades of gray instead of a pure white background.
I tried the SVG on a page and it doesn't look really blurry to me. However, you could try editing the viewbox to have an integer size -- i.e. turn viewBox="0 0 361.5 192.5" into viewBox="0 0 362 193" -- that might make a difference.
it might be caused by use of borders and shadows in creation of the svg. I avoid those myself as they are sometimes blurry. Shadow if needed can be created as another path with transparency and offset.
Chrome v49 letter-spacing in SVG with transform matrix
Chrome v49 broke letter-spacings in SVG when used in combination with matrix transformation and translations: Living example: https://jsfiddle.net/75fpn6de/6/ SVG: <svg height="300px" version="1.1" width="100%" xmlns="http://www.w3.org/2000/svg"> <g transform="matrix(0.20695652173913043,0,0,0.20695652173913043,0,10.881739130434767)"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" version="1.1" viewBox="0 0 2500 2794" width="2500" height="2794"> <g transform="translate(1436.5 1087) rotate(0)"> <text xmlns="http://www.w3.org/2000/svg" fill="#ed7373" y="237" style="font-family: 'Great Vibes';" font-size="237" letter-spacing="0.1em" text-anchor="middle">Some text</text> </g> </svg> </g> </svg> CSS: #import url(https://fonts.googleapis.com/css?family=Great+Vibes); Am I doing anything wrong here (like breaking some specs) and Chrome got more "restrictive" or is it a newly introduced bug in Chrome? FYI: The example is (obviously) only a small part of a bigger SVG which is dynamically generated by the server and I can't just change the nesting and the usage of the transform matrix & translate functions.
I had the very same issue, and even if I couldn't find anything about this issue in the changelog, it seems it has been fixed in Chrome 50.
Define an inline svg completely with css instead of in the html file itself
I have an html file that uses inline svg. I use this so I can add classes to my svg and style them with CSS. The following snippet works: <div> <svg class="icon" viewbox="0 0 512 512"> <path d=" ... "/> </svg> </div> Howeever, the tag can be quite long if the svg is complex. I'm currently using this svg in 3 different locations, and everytime I need to copy paste the entire path. It would be better if I could define the path only 1 time, preferabvly in a css class like this: <div> <svg class="icon" viewbox="0 0 512 512"> <path class="compleximage"/> </svg> </div> .compleximage { d: ... ; } But this doesn't seem to work. Maybe I'm getting it wrong syntactically, or maybe it can't be done this way. If so, are there ways other to prevent having to copy/paste the svg in my html files? I'm trying to follow the "0,1 or infinite" design pattern, and copy/pasting code 3 times break that.
You can use the use tag to display the path in more than one place. Just give the path an id attribute and then refer to that in the xlink:href of the <use> element. Something like <defs> <path id="image1" d="..." /> </defs> <use x="20" y="10" xlink:href="#image1" /> <use x="50" y="50" xlink:href="#image1" /> etc.
In HTML5 you can do it. Please try this: <svg width="100" height="100"> <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" /> </svg> On the other hand, you can create your own SVG and get it via <img src="" />. Sample below: <img class="papa" src="http://s.cdpn.io/3/kiwi.svg"> Reference here: (1) http://css-tricks.com/using-svg/ Another reference here how to change it via css: (2) http://codepen.io/chriscoyier/pen/evcBu
You cannot set svg attributes using CSS. You can only set styles like stroke, fill, etc. The only way would be to use javascript to set those paths dynamically. I would recommend jQuery. this link should be helpful for using jQuery to modify svg files. Modify a svg file using jQuery