- Elements
- Remove XML comments
- Remove XML declarations
- Remove non-SVG elements
- Remove unused referenced elements
- Convert basic shapes into paths
- Remove
title
element - Remove
desc
element - Remove
metadata
element - Remove duplicated
linearGradient
elements - Remove duplicated
radialGradient
elements - Remove duplicated
feGaussianBlur
elements - Ungroup groups
- Ungroup
defs
element - Group elements by equal styles
- Merge gradients
- Regroup gradient
stop
elements - Remove invalid
stop
elements - Remove invisible elements
- Resolve
use
elements
- Attributes
- Remove
version
andbaseProfile
attributes - Remove non-SVG attributes
- Remove unreferenced
id
attributes - Trim
id
attributes - Remove text-related attributes if there is no text
- Remove unused coordinate attributes
- Remove attributes with default values
- Remove an unused
xmlns:xlink
attribute - Remove attributes that doesn’t belong to this element
- Remove inheritable gradient attributes
- Join presentational attributes
- Apply transformations to gradients
- Apply transformations to shapes
- Remove unresolved classes from
class
attributes
- Remove
- Paths
- Output
- Other
We can remove all XML comments from SVG document since they are not rendered either way.
Note: all comments from the style
attribute will be removed anyway.
CLI argument: --remove-comments
Before (243B) | After (194B) |
---|---|
<!-- Comment -->
<svg>
<!-- Comment -->
<circle style="/* comment */stroke:black"
fill="green" cx="50" cy="50" r="45"/>
</svg> |
<svg>
<circle style="stroke:black" fill="green"
cx="50" cy="50" r="45"/>
</svg> |
Removes XML declarations from SVG document.
svgcleaner
will remove all declarations, even though they are only allowed
at the start of the document.
CLI argument: --remove-declarations
Before (164B) | After (109B) |
---|---|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg/> |
<svg/> |
We can remove any XML elements with non-SVG tag names, since they are not rendered either way.
Note: elements from the SVG Tiny 1.2 and SVG 2.0 (unreleased) will also be removed.
CLI argument: --remove-nonsvg-elements
Before (178B) | After (163B) |
---|---|
<svg>
<myelement/>
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
<svg>
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
We can remove any referenced elements from the SVG document if no other elements are linked to them.
A link can be established via IRI or FuncIRI.
Also, we can remove any unreferenced elements inside the defs
elements,
since they are not rendered either way.
Note: the font-face
element should be ignored, because it applies to the whole
document and not to a specific node.
CLI argument: --remove-unused-defs
Before (637B) | After (387B) |
---|---|
<svg>
<defs>
<g fill="red">
<circle id="circle1" fill="url(#rg1)"
cx="50" cy="50" r="50"/>
<circle id="circle2" fill="url(#rg2)"
cx="50" cy="50" r="50"/>
</g>
<radialGradient id="rg1">
<stop offset="0" stop-color="yellow"/>
<stop offset="1" stop-color="green"/>
</radialGradient>
<radialGradient id="rg2">
<stop offset="0" stop-color="red"/>
<stop offset="1" stop-color="blue"/>
</radialGradient>
</defs>
<use xlink:href="#circle1"/>
</svg> |
<svg>
<defs>
<circle id="circle1" fill="url(#rg1)"
cx="50" cy="50" r="50"/>
<radialGradient id="rg1">
<stop offset="0" stop-color="yellow"/>
<stop offset="1" stop-color="green"/>
</radialGradient>
</defs>
<use xlink:href="#circle1"/>
</svg> |
All basic shapes can be represented as path
.
circle
, ellipse
and rounded rect
are ignored, because their path representation will
always be bigger than original.
Note: shapes may render a bit differently depending on your user agent. You can use shape-rendering attribute to tweak it.
CLI argument: --convert-shapes
Before (547B) | After (465B) |
---|---|
<svg id="svg1">
<rect id="rect1" x="10" y="10"
width="80" height="80"/>
<line id="line1" stroke="red" x1="10"
y1="90" x2="90" y2="10"/>
<polyline id="polyline1" stroke="blue"
fill="none"
points="10 10 30 10 30 30
50 30 50 50"/>
<polygon id="polygon1" stroke="green"
fill="none"
points="10 10 10 30 30 30
30 50 50 50"/>
</svg> |
<svg>
<path id="rect1"
d="M 10 10 H 90 V 90 H 10 Z"/>
<path id="line1" stroke="red"
d="M 10 90 L 90 10"/>
<path id="polyline1" stroke="blue"
fill="none"
d="M 10 10 30 10 30 30
50 30 50 50"/>
<path id="polygon1" stroke="green"
fill="none"
d="M 10 10 10 30
30 30 30 50 50 50 Z"/>
</svg> |
We can remove all title elements since they are not rendered either way.
But since this element can be used by render software - this action is optional.
CLI argument: --remove-title
Before (191B) | After (163B) |
---|---|
<svg>
<title>svgcleaner</title>
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
<svg>
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
We can remove all desc elements since they are not rendered either way.
But since this element can be used by render software - this action is optional.
CLI argument: --remove-desc
Before (189B) | After (163B) |
---|---|
<svg>
<desc>svgcleaner</desc>
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
<svg>
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
We can remove all metadata elements since they are not rendered either way.
But since this element can be used by render software - this action is optional.
CLI argument: --remove-metadata
Before (580B) | After (315B) |
---|---|
<svg xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata id="metadata1">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
<svg xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
An SVG can contain a lot of linearGradient
elements, which may render exactly the same.
So we can remove duplicates and update links in elements, that uses them.
CLI argument: --remove-dupl-lineargradient
Before (721B) | After (487B) |
---|---|
<svg>
<defs>
<linearGradient id="lg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<linearGradient id="lg2">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<linearGradient id="lg3"
xlink:href="#lg2"/>
</defs>
<circle fill="url(#lg1)"
cx="50" cy="50" r="45"/>
<circle fill="url(#lg2)"
cx="100" cy="50" r="45"/>
<circle fill="url(#lg3)"
cx="150" cy="50" r="45"/>
</svg> |
<svg>
<defs>
<linearGradient id="lg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
</defs>
<circle fill="url(#lg1)"
cx="50" cy="50" r="45"/>
<circle fill="url(#lg1)"
cx="100" cy="50" r="45"/>
<circle fill="url(#lg1)"
cx="150" cy="50" r="45"/>
</svg> |
An SVG can contain a lot of radialGradient
elements, which may render exactly the same.
So we can remove duplicates and update links in elements, that uses them.
CLI argument: --remove-dupl-radialgradient
Before (658B) | After (424B) |
---|---|
<svg>
<defs>
<radialGradient id="rg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</radialGradient>
<linearGradient id="lg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<radialGradient id="rg2"
xlink:href="#lg1"/>
</defs>
<circle fill="url(#rg1)"
cx="50" cy="50" r="45"/>
<circle fill="url(#rg2)"
cx="100" cy="50" r="45"/>
</svg> |
<svg>
<defs>
<radialGradient id="rg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</radialGradient>
</defs>
<circle fill="url(#rg1)"
cx="50" cy="50" r="45"/>
<circle fill="url(#rg1)"
cx="100" cy="50" r="45"/>
</svg> |
An SVG can contain a lot of feGaussianBlur
elements, which may render exactly the same.
So we can remove duplicates and update links in elements, that uses them.
CLI argument: --remove-dupl-fegaussianblur
Before (439B) | After (363B) |
---|---|
<svg>
<defs>
<filter id='f1'>
<feGaussianBlur stdDeviation='2'/>
</filter>
<filter id='f2'>
<feGaussianBlur stdDeviation='2'/>
</filter>
</defs>
<circle filter="url(#f1)" fill="green"
cx="50" cy="50" r="45"/>
<circle filter="url(#f2)" fill="green"
cx="100" cy="50" r="45"/>
</svg> |
<svg>
<defs>
<filter id='f1'>
<feGaussianBlur stdDeviation='2'/>
</filter>
</defs>
<circle filter="url(#f1)" fill="green"
cx="50" cy="50" r="45"/>
<circle filter="url(#f1)" fill="green"
cx="100" cy="50" r="45"/>
</svg> |
Groups, aka g
element, is one of the main SVG structure blocks,
but in a lot of cases they do not impact rendering at all.
Groups are useless: - if the group is empty - if the group has only one children - if the group doesn’t have any important attributes
Then we can ungroup it and remove.
CLI argument: --ungroup-groups
Before (276B) | After (234B) |
---|---|
<svg>
<g>
<circle fill="green" r="45"
cx="50" cy="50"/>
<g>
<circle fill="#023373" r="45"
cx="100" cy="50"/>
</g>
</g>
</svg> |
<svg>
<circle fill="green" r="45"
cx="50" cy="50"/>
<circle fill="#023373" r="45"
cx="100" cy="50"/>
</svg> |
If the defs
element contains only referenced
elements - it can be ungrouped.
Unsupported by: QtSvg ⇐ 5.7 (pattern
with image
child renders incorrectly)
CLI argument: --ungroup-defs
Before (361B) | After (330B) |
---|---|
<svg>
<defs>
<radialGradient id="rg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</radialGradient>
</defs>
<circle fill="url(#rg1)" r="45"
cx="50" cy="50"/>
</svg> |
<svg>
<radialGradient id="rg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</radialGradient>
<circle fill="url(#rg1)" r="45"
cx="50" cy="50"/>
</svg> |
If a continuous range of elements contains equal, inheritable attributes - we can group such elements and move this attributes to a new or an existing parent group.
Note: this option is mostly poinless when XML indent is enabled,
so you should use it with Sets XML nodes indent/--indent
option equal to -1
or 0
.
CLI argument: --group-by-style
Before (291B) | After (290B) |
---|---|
<svg>
<circle fill="green" r="45"
cx="50" cy="50"/>
<circle fill="green" r="45"
cx="100" cy="50"/>
<circle fill="green" r="45"
cx="150" cy="50"/>
</svg> |
<svg>
<g fill="green">
<circle r="45"
cx="50" cy="50"/>
<circle r="45"
cx="100" cy="50"/>
<circle r="45"
cx="150" cy="50"/>
</g>
</svg> |
Many SVG editors split gradient implementation into two parts:
one element with stop
children elements and one that linked to it.
It can be useful if we have a lot of gradients with equal stop’s, but if we have only one - it
became pointless.
This option fixes it.
CLI argument: --merge-gradients
Before (430B) | After (361B) |
---|---|
<svg>
<defs>
<linearGradient id="lg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<linearGradient id="lg2"
xlink:href="#lg1"/>
</defs>
<circle fill="url(#lg2)"
cx="50" cy="50" r="45"/>
</svg> |
<svg>
<defs>
<linearGradient id="lg2">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
</defs>
<circle fill="url(#lg2)"
cx="50" cy="50" r="45"/>
</svg> |
If two or more gradients have equal stop
elements - we can move this elements
into a new linearGradient
and link gradients to this new gradient.
CLI argument: --regroup-gradient-stops
Before (589B) | After (522B) |
---|---|
<svg>
<defs>
<linearGradient id="lg1">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<linearGradient id="lg2">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
</defs>
<circle fill="url(#lg1)"
cx="50" cy="50" r="45"/>
<circle fill="url(#lg2)"
cx="100" cy="50" r="45"/>
</svg> |
<svg>
<defs>
<linearGradient id="lg3">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<linearGradient id="lg1" xlink:href="#lg3"/>
<linearGradient id="lg2" xlink:href="#lg3"/>
</defs>
<circle fill="url(#lg1)"
cx="50" cy="50" r="45"/>
<circle fill="url(#lg2)"
cx="100" cy="50" r="45"/>
</svg> |
We can remove duplicated stop
elements inside gradients.
CLI argument: --remove-invalid-stops
Before (528B) | After (387B) |
---|---|
<svg>
<defs>
<linearGradient id="lg1">
<stop offset="-1" stop-color="yellow"/>
<stop offset="0" stop-color="yellow"/>
<stop offset="0.5" stop-color="green"/>
<stop offset="0.5" stop-color="green"/>
<stop offset="1" stop-color="yellow"/>
<stop offset="10" stop-color="yellow"/>
</linearGradient>
</defs>
<circle fill="url(#lg1)"
cx="50" cy="50" r="45"/>
</svg> |
<svg>
<defs>
<linearGradient id="lg1">
<stop offset="0" stop-color="yellow"/>
<stop offset="0.5" stop-color="green"/>
<stop offset="1" stop-color="yellow"/>
</linearGradient>
</defs>
<circle fill="url(#lg1)"
cx="50" cy="50" r="45"/>
</svg> |
The collection of algorithms that detects invisible elements and removes them.
Unsupported by: QtSvg ⇐ 5.7
CLI argument: --remove-invisible-elements
Before (335B) | After (173B) |
---|---|
<svg>
<linearGradient id="lg1"/>
<clipPath id="cp1"/>
<circle fill="green"
cx="50" cy="50" r="45"/>
<circle fill="green" clip-path="url(#cp1)"
stroke="url(#lg1)"
cx="100" cy="50" r="45"/>
</svg> |
<svg>
<circle fill="green"
cx="50" cy="50" r="45"/>
</svg> |
We can replace use
element with linked element if it used only by this use
.
CLI argument: --resolve-use
Before (252B) | After (196B) |
---|---|
<svg>
<defs>
<circle id='circle1'
fill="green" cx="50"
cy="50" r="45"/>
</defs>
<use xlink:href='#circle1'/>
</svg> |
<svg>
<circle id='circle1'
fill="green" cx="50"
cy="50" r="45"/>
</svg> |
Remove version
and baseProfile
attributes from the svg
element.
Some applications can rely on them, so someone may want to keep them. Even though they usually useless.
CLI argument: --remove-version
Before (206B) | After (173B) |
---|---|
<svg version="1.1" baseProfile="tiny">
<circle fill="green"
cx="50" cy="50" r="45"/>
</svg> |
<svg>
<circle fill="green"
cx="50" cy="50" r="45"/>
</svg> |
We can remove any non-SVG attributes since they are not rendered either way.
Note: attributes from the SVG Tiny 1.2 and SVG 2.0 (unreleased) will also be removed.
CLI argument: --remove-nonsvg-attributes
Before (192B) | After (173B) |
---|---|
<svg>
<circle fill="green" my-attribute="hi!"
cx="50" cy="50" r="45"/>
</svg> |
<svg>
<circle fill="green"
cx="50" cy="50" r="45"/>
</svg> |
We can remove id
attribute from an element if this id
doesn’t use in any IRI/FuncIRI.
Note: since svgcleaner
works only with static/local SVG data and does not support
SVG scripting via script
element, we can only assume that id
is not used.
CLI argument: --remove-unreferenced-ids
Before (319B) | After (286B) |
---|---|
<svg id="svg1">
<circle id="circle1" fill="green"
cx="50" cy="50" r="50"/>
<circle id="circle2" fill="#023373"
cx="100" cy="50" r="50"/>
<use id="use1" x="100" xlink:href="#circle1"/>
</svg> |
<svg>
<circle id="circle1" fill="green"
cx="50" cy="50" r="50"/>
<circle fill="#023373"
cx="100" cy="50" r="50"/>
<use x="100" xlink:href="#circle1"/>
</svg> |
Renames elements id
attribute to a shorter one. All IRI and FuncIRI will be updated too.
Shorter name generated by encoding a serial number of this id
attribute using a range of
acceptable chars: a-zA-Z0-9. Given that first char can’t be 0-9.
For example: 1 → a, 51 → aa, 113 → ba and so on.
CLI argument: --trim-ids
Before (521B) | After (450B) |
---|---|
<svg id="svg1">
<defs id="defs1">
<linearGradient id="linearGradient1">
<stop id="stop1" offset="0"
stop-color="yellow"/>
<stop id="stop2" offset="1"
stop-color="green"/>
</linearGradient>
<radialGradient id="radialGradient1"
xlink:href="#linearGradient1"/>
</defs>
<circle fill="url(#radialGradient1)"
cx="50" cy="50" r="45"/>
</svg> |
<svg id="a">
<defs id="b">
<linearGradient id="c">
<stop id="d" offset="0"
stop-color="yellow"/>
<stop id="e" offset="1"
stop-color="green"/>
</linearGradient>
<radialGradient id="f"
xlink:href="#c"/>
</defs>
<circle fill="url(#f)"
cx="50" cy="50" r="45"/>
</svg> |
We can remove text-related attributes, when there is no text.
But since attributes like a font
can impact a length
values with a em
/ex
units
- it’s a bit more complicated. Also, the text itself can be defined in many different ways.
CLI argument: --remove-text-attributes
Before (247B) | After (232B) |
---|---|
<svg>
<circle fill="green" font="Verdana"
cx="50" cy="50" r="45"/>
<text y="30" x="30" font-size="14pt">
Text
</text>
</svg> |
<svg>
<circle fill="green"
cx="50" cy="50" r="45"/>
<text y="30" x="30" font-size="14pt">
Text
</text>
</svg> |
Many of coordinate attributes can be calculated using their neighbor attributes, so there is no need to keep them.
CLI argument: --remove-unused-coordinates
Before (207B) | After (199B) |
---|---|
<svg>
<rect x="10" y="10" width="80"
height="80" fill="green"
rx="10" ry="10"/>
</svg> |
<svg>
<rect x="10" y="10" width="80"
height="80" fill="green"
rx="10"/>
</svg> |
We can remove attributes with default values if they are not covered by the parent elements. Some attributes do not support an inheritance, so we can remove them without checking a parent elements.
In the example below we have a circle
element with a fill
and a stroke
attributes,
which have default values. We can’t remove a fill
from a circle
, because than the rect
will be filled with a red, but a stroke
can be easily removed.
CLI argument: --remove-default-attributes
Before (215B) | After (201B) |
---|---|
<svg>
<g fill="red">
<circle fill="black" stroke="none"
cx="50" cy="50" r="45"/>
</g>
</svg> |
<svg>
<g fill="red">
<circle fill="black" cx="50"
cy="50" r="45"/>
</g>
</svg> |
We can remove a xmlns:xlink
attribute if document doesn’t use an element
referencing via the xlink:href
.
CLI argument: --remove-xmlns-xlink-attribute
Before (163B) | After (120B) |
---|---|
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
<svg>
<circle fill="green" cx="50" cy="50" r="45"/>
</svg> |
Remove attributes that doesn’t belong to current element and have no effect on rendering.
Unlike other cleaning options for attributes, this does not change attributes that can be used during rendering.
CLI argument: --remove-needless-attributes
Before (358B) | After (266B) |
---|---|
<svg>
<clipPath id="cp1">
<rect fill="red" stroke="red"
stroke-width="50" width="75"
height="75"/>
</clipPath>
<circle fill="green" d="M 10 20 L 30 40"
clip-path="url(#cp1)"
cx="50" cy="50" r="45"/>
</svg> |
<svg>
<clipPath id="cp1">
<rect width="75" height="75"/>
</clipPath>
<circle fill="green" clip-path="url(#cp1)"
cx="50" cy="50" r="45"/>
</svg> |
Gradients can inherit attributes via xlink:href
attribute, so we can
remove attributes that already defined in the parent gradient.
Currently, only an gradientUnits
attribute is processed.
Unsupported by: QtSvg ⇐ 5.7, Inkscape ⇐ 0.91 r13725
CLI argument: --remove-gradient-attributes
Before (641B) | After (530B) |
---|---|
<svg>
<linearGradient id="lg1"
gradientUnits='userSpaceOnUse'>
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<linearGradient id="lg2"
gradientUnits='userSpaceOnUse'
xlink:href="#lg1"/>
<linearGradient id="lg3"
gradientUnits='userSpaceOnUse'
xlink:href="#lg2"/>
<radialGradient id="rg1"
gradientUnits='userSpaceOnUse'
xlink:href="#lg3"/>
<circle fill="url(#rg1)"
cx="50" cy="50" r="45"/>
</svg> |
<svg>
<linearGradient id="lg1"
gradientUnits='userSpaceOnUse'>
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<linearGradient id="lg2"
xlink:href="#lg1"/>
<linearGradient id="lg3"
xlink:href="#lg2"/>
<radialGradient id="rg1"
xlink:href="#lg3"/>
<circle fill="url(#rg1)"
cx="50" cy="50" r="45"/>
</svg> |
SVG presentational attributes can be set via separated attributes and via style
attribute.
If we have less than 5 presentational attributes - it’s better to store them separately.
Otherwise style
is shorter.
Possible values:
-
no - do not join presentational attributes
-
some - join presentational attributes when there are 6 or more of them
-
all - join all presentational attributes. May produce a bigger file but can be used as a workaround of some viewers bugs.
Default: some
There is no example, because a style with 5 attributes will be a huge, nonbreakable line, which will break the layout.
Transformations that contain only translate, rotate and/or proportional scale parts can be applied to some gradients.
CLI argument: --apply-transform-to-gradients
Before (460B) | After (414B) |
---|---|
<svg>
<linearGradient id="lg1" x1="40" y1="30"
x2="90" y2="30"
gradientTransform="translate(10 20)"
gradientUnits="userSpaceOnUse">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<circle fill="url(#lg1)"
cx="50" cy="50" r="45"/>
</svg> |
<svg>
<linearGradient id="lg1" x1="50" y1="50"
x2="100" y2="50"
gradientUnits="userSpaceOnUse">
<stop offset="0"
stop-color="yellow"/>
<stop offset="1"
stop-color="green"/>
</linearGradient>
<circle fill="url(#lg1)"
cx="50" cy="50" r="45"/>
</svg> |
Transformations that contain only translate, rotate and/or proportional scale parts can be applied to some shapes.
This option will apply transformations to: rect
, circle
, ellipse
and line
.
CLI argument: --apply-transform-to-shapes
Before (238B) | After (190B) |
---|---|
<svg>
<circle fill="green" stroke-width='0'
transform="translate(10 10) scale(2)"
cx="20" cy="20" r="22"/>
</svg> |
<svg>
<circle fill="green" stroke-width='0'
cx="50" cy="50" r="44"/>
</svg> |
The class
attribute can contain a list of class selectors,
but not all of them may link to the style sheet defined in the file.
This option will remove such selectors.
Note: you can’t prevent class attribute resolving anyway. This option should be used
just to keep unresolved classes in the class
attribute when you define them elsewhere.
So you should disable it to get such behavior.
CLI argument: --remove-unresolved-classes
Before (246B) | After (173B) |
---|---|
<svg id="svg1">
<style>
.fill1 {fill:green}
</style>
<circle class="fill1 stroke1 other"
cx="50" cy="50" r="50"/>
</svg> |
<svg>
<circle fill="green"
cx="50" cy="50" r="50"/>
</svg> |
Since segments of the path data can be set in absolute and relative coordinates - we can convert all of them into relative one, which is generally shorter.
CLI argument: --paths-to-relative
Before (285B) | After (276B) |
---|---|
<svg>
<path d="M 750 150 L 800 200 L 850 150
L 850 250 L 850 350 L 800 300
L 750 350 L 750 250 Z"
transform="scale(0.1)"
fill="green"/>
</svg> |
<svg>
<path d="m 750 150 l 50 50 l 50 -50
l 0 100 l 0 100 l -50 -50
l -50 50 l 0 -100 z"
transform="scale(0.1)"
fill="green"/>
</svg> |
The collection of algorithms that removes unneeded segments from paths.
NOTE: can be used only with --paths-to-relative
.
CLI argument: --remove-unused-segments
Before (190B) | After (157B) |
---|---|
<svg>
<path stroke="red"
d="M 10 10 L 10 50 L 10 10 M 50 50 L 50 50"/>
</svg> |
<svg>
<path stroke="red" d="M 10 10 V 50 Z"/>
</svg> |
Some segments can be represented using different segment types keeping a resulting shape exactly the same. We only use conversions that make path notation shorter.
Currently supported conversions are:
-
LineTo → HorizontalLineTo
-
LineTo → VerticalLineTo
-
CurveTo → HorizontalLineTo
-
CurveTo → VerticalLineTo
-
CurveTo → LineTo
-
CurveTo → SmoothCurveTo
CLI argument: --convert-segments
Before (264B) | After (246B) |
---|---|
<svg>
<path fill="none" stroke="red"
stroke-width="2"
d="M 10 15 C 10 15 72.5 10 72.5 55
C 72.5 100 135 100 135 55 L 10 55"/>
</svg> |
<svg>
<path fill="none" stroke="red"
stroke-width="2"
d="M 10 15 S 72.5 10 72.5 55
S 135 100 135 55 H 10"/>
</svg> |
Transformations that contain only translate, rotate and/or proportional scale parts can be applied to some paths.
This usually creates bigger files, so it’s disabled by default. But it some cases it can be useful.
CLI argument: --apply-transform-to-paths
Before (202B) | After (166B) |
---|---|
<svg>
<path stroke="red"
transform="translate(10 20)"
d="M 10 0 L 30 40"/>
</svg> |
<svg>
<path stroke="red"
d="M 20 20 L 40 60"/>
</svg> |
By SVG spec we are allowed to remove some symbols from path notation without breaking parsing.
CLI argument: --trim-paths
Before (250B) | After (226B) |
---|---|
<svg>
<path fill="green" stroke="red"
stroke-width="2"
d="M 30 60 a 25 25 -30 1 1 50,-20
l 0.5 0.5 l 30 60 z"/>
</svg> |
<svg>
<path fill="green" stroke="red"
stroke-width="2"
d="M30 60a25 25-30 1 1 50-20l.5.5l30 60z"/>
</svg> |
Elliptical arc curve segment has flags parameters, which can have values of 0
or 1
.
Since we have fixed-width values, we can skip spaces between them.
Unsupported by: Inkscape ⇐ 0.91 r13725, QtSvg ⇐ 5.7, librsvg ⇐ 2.40.13
CLI argument: --join-arcto-flags
Before (230B) | After (228B) |
---|---|
<svg>
<path fill="green" stroke="red"
stroke-width="2"
d="M 30 60
a 25 25 -30 1 1 50 -20"/>
</svg> |
<svg>
<path fill="green" stroke="red"
stroke-width="2"
d="M 30 60
a 25 25 -30 1150 -20"/>
</svg> |
If path segment has the same type as previous - we can skip command specifier.
CLI argument: --remove-dupl-cmd-in-paths
Before (240B) | After (234B) |
---|---|
<svg>
<path d="M 10 10 L 90 10 L 90 90
L 10 90 L 10 10 z"
fill="none" stroke="red"
stroke-width="2"/>
</svg> |
<svg>
<path d="M 10 10 L 90 10 90 90
10 90 10 10 z"
fill="none" stroke="red"
stroke-width="2"/>
</svg> |
By SVG spec: 'if a moveto is followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit lineto commands'.
CLI argument: --use-implicit-cmds
Before (213B) | After (209B) |
---|---|
<svg>
<path fill="green" stroke="red"
stroke-width="2"
d="M 10 10 L 50 50 L 120 50"/>
</svg> |
<svg>
<path fill="green" stroke="red"
stroke-width="2"
d="M 10 10 50 50 120 50"/>
</svg> |
Use #RGB notation instead of #RRGGBB when possible.
NOTE: by default all color stored as #RRGGBB, since libsvgdom
doesn’t stores
colors original text representation.
CLI argument: --trim-colors
Before (165B) | After (162B) |
---|---|
<svg>
<circle fill="#00ff00" cx="50" cy="50" r="45"/>
</svg> |
<svg>
<circle fill="#0f0" cx="50" cy="50" r="45"/>
</svg> |
Ensures that the output file has a newline at the end of the file, following the POSIX standard for text files. There is no visual change in the image, but it will behave better with command-line tools, and won’t show warnings when viewed on GitHub. Disabled by default because it slightly increases the file size.
CLI argument: --append-newline
Before (209B) | After (210B) |
---|---|
<svg>
<circle fill="green" cx="50"
cy="50" r="45"
transform="translate(25)"/>
</svg> # Error: No newline at end of file. |
<svg>
<circle fill="green" cx="50"
cy="50" r="45"
transform="translate(25)"/>
</svg> |
Simplify transform matrices into short equivalent when possible.
CLI argument: --simplify-transforms
Before (216B) | After (209B) |
---|---|
<svg>
<circle fill="green" cx="50"
cy="50" r="45"
transform="matrix(1 0 0 1 25 0)"/>
</svg> |
<svg>
<circle fill="green" cx="50"
cy="50" r="45"
transform="translate(25)"/>
</svg> |
Reduce the numeric precision of the specific coordinate attributes.
This includes: x, y, dx, dy, x1, y1, x2, y2, r, rx, ry, cx, cy, fx, fy, width, height, and translate part of transforms.
Range: 1..12
Default: 6
Reduce the numeric precision of the specific properties attributes.
This includes: stroke-dashoffset, stroke-miterlimit, stroke-width, opacity, fill-opacity, flood-opacity, stroke-opacity, stop-opacity, font-size.
Range: 1..12
Default: 6
Set numeric precision of the a, b, c, d values of transforms.
Range: 1..12
Default: 8
We can reduce the numeric precision of path’s coordinates without breaking it.
Range: 1..12, where
-
8..12 is basically lossless
-
4..7 will give an actual impact on the file size
-
1..3 is very dangerous and will probably break your file
Default: 8
CLI argument: --paths-coordinates-precision
Before (285B) | After (272B) |
---|---|
<svg>
<path d="M 10.000001 10.000005
L 89.99999 10.11111
L 89.997777 90.0005
L 10.123456789 90 L 10 10 z"
fill="none" stroke="red"/>
</svg> |
<svg>
<path d="M 10 10.00001
L 89.99999 10.11111
L 89.99778 90.0005
L 10.12346 90 L 10 10 z"
fill="none" stroke="red"/>
</svg> |
Set separator for attributes with number list values.
Like stroke-dasharray
or points
.
Possible values:
-
space
-
comma
-
comma-space
Default: space
CLI argument: --list-separator
Before (173B) | After (168B) |
---|---|
<svg>
<polygon fill="green" points="10, 10, 10, 30, 30, 30"/>
</svg> |
<svg>
<polygon fill="green" points="10 10 10 30 30 30"/>
</svg> |
Set indent for XML nodes.
-
none - no indention and new lines
-
0 - no indention
-
1..4 - indent with n spaces
-
tabs - indent with tabs
Default: none
CLI argument: --indent
Before (178B) | After (166B) |
---|---|
<svg>
<g>
<circle fill="green" cx="50" cy="50" r="45"/>
</g>
</svg> |
<svg><g><circle fill="green" cx="50" cy="50" r="45"/></g></svg> |
Most of the cleaning options are enabled by default. This flag allows to disable them all at once.
It can be useful if you need only few cleaning options.
Note that this flag applies only to options with the <FLAG>
type.
Options like indent
will still use default values.
CLI argument: --no-defaults