Post on 11-Jul-2016
description
transcript
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
SPEAKING WORKSHOPS ARTICLES ABOUT ME HIRE ME
Structuring, Grouping,and Referencing in SVG— The <g> , <use> ,<defs> and <symbol>
???????????
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
<defs> and <symbol>Elements
Published July 3, 2014 | Estimated Reading Time: 16 min
SVG comes with its own ways for structuring a document by
means of certain SVG elements that allow us to define, group,
and reference objects within the document. These elements
make reusing elements easy, while maintaining clean and
readable code. In this article we'll go over these elements,
highlighting the difference between them and the advantages
of each one.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
Grouping with the <g> element
The ‘g’ in <g> stands for ‘group’. The group element is used for logically grouping
together sets of related graphical elements. In terms of graphics editors, such as
Adobe Illustrator, the <g> element serves a similar functionality as the Group
Objects function. You can also think of a group as being similar to the concept of
a layer in a graphics editor, since a layer is also a grouping of elements.
The group element is used for logically grouping
together sets of related graphical elements.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
The <g> element groups all of its descendants into one group. It usually has an
id attribute to give that group a name. Any styles you apply to the <g> element
will also be applied to all of its descendants. This makes it easy to add styles,
transformations, interactivity, and even animations to entire groups of objects.
For example, the following is an SVG bird. The bird is made up of several shapes
such as circles and paths.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
If you wanted to move the entire bird from one place to another in Illustrator,
you will also want to group the elements together so that you wouldn’t have to
select each and every one of them every time you wanted to do so.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
Grouping in SVG using the <g> element works the same way. In this example
we’ve grouped the elements of the body together, the elements of the head
together, and then we grouped the two groups into one group with an id of
bird .
<svg width="1144.12px" height="400px" viewBox="0 0 572.06 200">
<style>
svg{background-color:white;}
#wing{fill:#81CCAA;}
#body{fill:#B8E4C2;}
#pupil{fill:#1F2600;}
#beak{fill:#F69C0D;}
.eye-ball{fill:#F6FDC4;}
</style>
<g id="bird">
<g id="body">
<path d="M48.42,78.11c0-17.45,14.14-31.58,31.59-
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
If you were to change the fill color of the #body group, the fill color of all the
elements inside the group will change to the color you specify. This is very
convenient.
Grouping elements is very useful, not just for organizational and structural
purposes. It’s particularly useful for when you want to add interactivity or
transformations to an SVG graphic that is made up of several items. You can
associate those items together in a group and then define transformations to
31.58s31.59,14.14,31.59,31.58c0,17.44-14.14,31.59-31.59,31.59
S48.42,95.56,48.42,78.11"/>
<path d="M109.19,69.88c0,0-8.5-27.33-42.51-18.53c-
34.02,8.81-20.65,91.11,45.25,84.73
c40.39-3.65,48.59-24.6,48.59-
24.6S124.68,106.02,109.19,69.88"/>
<path id="wing"
d="M105.78,75.09c4.56,0,8.84,1.13,12.62,3.11c0,0,0.01-0.01,0.01-
0.01l36.23,12.38c0,0-13.78,30.81-41.96,38.09
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
move, scale, or rotate all the items together so that their spatial relations to one
another are maintained.
If you wanted to scale the entire bird up and make it twice its size, you will be
able to do it with one line of CSS if all the elements are grouped together.
Grouping makes interactivity, in particular, more convenient. You can attach
mouse events to the entire bird and have it respond to the events as a whole
group, instead of having to apply the same interactions and/or transformations
to every element in that group.
#bird {
transform: scale(2);
}
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
The <g> element has one more important and great feature: it can have its own
<title> and <desc> tags that help make it more accessible to screen readers,
and overall make the code more readable to humans as well. For example:
Reusing elements with the <use>element
<g id="bird">
<title>Bird</title>
<desc>An image of a cute little green bird with an orange
beak.</desc>
<!-- ... -->
</g>
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
Often times, there are elements that are repeated in a graphic. If you’re working
in Illustrator and you want to repeat an element somewhere in the graphic, you
would copy the element and then paste it and use it wherever it is you want to
use it. Copying and then pasting an existing element is more convenient than
having to recreate that element from scratch.
The <use> element lets you reuse existing elements, giving you a similar
functionality to the copy-paste functionality in a graphics editor. It can be used
to reuse a single element, or a group of element defined with the <g> element.
The <use> element lets you reuse existing
elements, giving you a similar functionality to the
copy-paste functionality in a graphics editor.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
The <use> element takes x , y , height , and width attributes, and it
references other content using the xlink:href attribute. So if you have defined
a group somewhere with a given id , and you want to reuse it somewhere else,
you give its URI in an xlink:href attribute, and specify the x and y location
where the group’s (0, 0) point should be moved to.
For example, if we were to create another bird in our SVG canvas, we could reuse
the existing bird like so:
Note that you can reference any SVG element inside the xlink:href attribute,
<use x="100" y="100" xlink:href="#bird" />
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
even if that element is in an external file. The referenced element or group does
not have to exist in the same file. This is great for organizing files (for example
you could have a file for reusable components) and for caching the used files. If
the bird in our example were created in a seperate file called animals.svg for
example, we could have referenced it like so:
However, referencing external SVG in <use> doesn’t work in most versions of IE
(up to IE 11). I recommend you read this article by Chris Coyier for details and
fallback mechanisms.
Now, those of you with a sharp bird’s eye (pun not intended), may have noticed
that I said that the x and y attributes of <use> specify the location where the
group’s upper left corner should be moved to. Moving an element means that
<use x="100" y="100" xlink:href="path/to/animals.svg#bird" />
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
you’re starting from its current position and then changing it to another one.
Had I said “should be positioned at”, it would have implied that the element will
be positioned according to the coordinate system in use on the entire canvas,
right?
As it turns out, the x and y coordinates are a shorthand for translating an
element using the transform attribute. More specifically, the above <use>
use is equivalent to:
<use xlink:href="#bird" transform="translate(100, 100)" />
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
This fact means that the position of the new reused element is relative tothe position of the original element that we’re reusing. This isn’t always
optimal and can have some drawbacks.
The x and y coordinates are a shorthand for
translating an element using the transform
attribute.
Another drawback of the <use> element is that the “copies” of the original
element will have the exact same styles as the original element. Whenever you
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
apply any style or transformation changes to the #bird group in the above
example, all the copies of the bird will get the same styles and transformations.
You can use an element and apply an independent transformation to it. For
example, the following line will reuse the bird, but it will make it half its original
size using a scale transformation:
However, you cannot override the styles of the original element (such asfill and strokes) on the copy. This means that if you want to create multiple
birds or multiple icons (if you’re working with icons) and you want every icon to
have a different color, this won’t be possible with the <use> element (unless the
original element is defined inside a <defs> element without these styles applied
to it. See next section for more information).
<use x="100" y="100" xlink:href="#bird" transform="scale(0.5)" />
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
The <use> element allows you to reuse an element that is already rendered
on the canvas. But what if you want to define an element without displaying it,
and then draw it at specific positions when you need or want to? This is where
the <defs> element comes in.
Reusing Stored elements with the<defs> element
The <defs> element can be used to store content that will not be directly
displayed. In other words, the <defs> element is used to define elements
without directly rendering them. This stored hidden content can then be
referenced and displayed by other SVG elements, which makes it ideal for things
such as patterns that contain reusable graphics.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
The <defs> element is used to define elements
without directly rendering them [..] and that
element will serve as a template for future use.
So, using <defs> we can define an element that we want to use. This element
can be anything, ranging from a group of elements like the bird we saw earlier, to
a clipping path, mask, or a linear gradient. Basically, anything that we want to
define and store away for later use can be defined inside the <defs> element,
and that element will serve as a template for future use, or as a tool that is
available for use whenever needed. The template is never rendered, only
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
instances of it are displayed.
The following is an example defining an SVG gradient, and then uses it as a fill
color for a simple SVG rectangle:
<svg>
<defs>
<lineargradient id="gradient">
<stop offset="0%" style="stop-color: deepPink">
<stop offset="100%" style="stop-color: #009966">
</stop></stop></lineargradient>
</defs>
<rect stroke="#eee" stroke-width="5" fill="url(#gradient)">
</rect></svg>
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
Defining the linear gradient inside the <defs> element like that ensures that the
gradient will not be rendered unless it is referenced somewhere it is needed.
In the previous section we mentioned two drawbacks of the <use> element:
The position of the new element is relative to the position of the original
element.
The styles of the original element cannot be overridden in the individual
copies.
That, in addition to the fact that the re use d element will be rendered on the
canvas.
All of these drawbacks can be avoided using the <defs> element. Not only is the
original element not rendered, but when you want to reuse an element inside
<defs> , the position you specify for each instance will be set relative to the
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
origin of the user coordinate system, not relative to the position of the original
element (which makes sense considering the original element is a template that’s
not even rendered on the canvas).
In this example we have a tree. The tree is made up of a bark and a group of
leaves. The leaves are grouped into a group with id="leaves" , and then this
group is grouped with the bark into the larger tree group.
<svg width="500.79px" height="200px" viewBox="0 0 500.79 200">
<style type="text/css">
#leaves{fill:#8CC63F;}
#bark{fill:#A27729;}
</style>
<g id="tree">
<path id="bark" d="M91.33,165.51c0,0,4.18-27.65,1.73-35.82l-
18.55-25.03l3.01-2.74l17.45,19.87l1.91-37.6h4.44l1.83,24.53
l15.26-16.35l3.27,4.36l-16.07,19.34c0,0-2.72,0-
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
And this is how the tree looks like:
1.09,19.34c1.63,19.34,3,29.7,3,29.7L91.33,165.51z"/>
<g id="leaves">
<path class="leaf" d="M96.97,79.07c0,0-14.92,4.34-23.52-
14.05c0,0,19.4-7.98,24.37,11.9c0,0-9.68-3.57-13.07-6.73
C84.75,70.2,91.82,77.99,96.97,79.07z"/>
<path class="leaf" d="M74.07,100.91c0,0-15.94-1.51-17.2-
22.39c0,0,21.62-0.27,18.83,20.66c0,0-7.92-7.1-9.97-11.41
C65.73,87.77,69.55,97.92,74.07,100.91z"/>
<!-- ... -->
</g>
</g>
</svg>
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
If we were to wrap the #tree group in a <defs> element, the tree would no
longer be rendered on the canvas.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
Now the tree serves as a template for use. We can use it using the <use>
element just like we would use any other element. The only difference in this
case is that the x and y attributes are now set relative to the user coordinate
system, not relative to the position of the used element.
<svg width="500.79px" height="200px" viewBox="0 0 500.79 200">
<style type="text/css">
#leaves{fill:#8CC63F;}
#bark{fill:#A27729;}
</style>
<defs>
<g id="tree">
<!-- ... -->
</g>
</defs>
</svg>
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
For example, if we were to create three copies of the tree and position them on
the SVG canvas, and assuming in this case that the user coordinate system
matches the viewport’s height and width with the origin being on the top left
corner of the SVG viewport, we’d get the following code with the following result:
<use xlink:href="#tree" x="50" y="100" />
<use xlink:href="#tree" x="200" y="100" />
<use xlink:href="#tree" x="350" y="100" />
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
As you can see in the image above, each of the trees was positioned relative to
the origin of the coordinate system which in this case is the upper left corner of
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
the SVG. So the upper left corner of each tree is positioned at its own ( x , y )
position in the user coordinate system, independent of the other trees and
independent of the tree template defined inside <defs> .
When you use <defs> to reuse an element, you can apply different styles and fill
colors to each individual tree, as long as these styles are not defined on theoriginal tree template. If the tree inside <defs> has styles applied to it, those
styles still won’t be overridden by any new ones. So <defs> is great for creating
minimal templates and then styling the copies as needed. Without <defs> , this
wouldn’t be possible with <use> alone.
Note that elements inside the <defs> element are prevented from becoming
part of the rendering tree just as if the defs element were a g element and the
display property were set to none . However, that the descendants of a defs
are always present in the source tree and thus can always be referenced by
other elements; thus, the value of the display property on the defs element
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
or any of its descendants does not prevent those elements from being
referenced by other elements, even if it is set to none .
Grouping elements with the<symbol> element
The <symbol> element is similar to the group element <g> —it provides a way
to group elements together. However, it differs from the group element in two
main things:
The <symbol> element is not rendered. It is actually similar to <defs> in this
manner. It is only displayed when it is use d.
A <symbol> element can have its own viewBox and preserveAspectRatio
attributes. This allows it to fit into the viewport it is rendered into any way you
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
want it to, instead of fitting in the default way.
<symbol> is then mostly suitable for defining reusable elements (or symbols). It
also serves as a template that is instantiated using the <use> element. And
having viewBox and preserveAspectRatio attributes, it can scale-to-fit within
a rectangular viewport defined by the referencing <use> element. Note that
symbol elements define new viewports whenever they are instanced by a use
element.
`symbol` elements define new viewports
whenever they are instanced by a `use` element.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
This feature is great because it allows you to define elements that are
independent of the viewport they’re rendered into, hence allowing you to make
sure the symbol you’re referencing will always display a certain way inside the
viewport.
You need to be familiar with the way the viewBox works, and the values of the
preserveAspectratio attribute to make the best use of this feature. Chris
Coyier wrote an article explaining why the <symbol> element can be a good
choice for icons, and how to use it.
I will also be writing an extensive article about the `viewport`, `viewBox`, and
`preserveAspectRatio` attributes that explains how these attributes work together and how
they can be used to control and scale graphics in SVG, so stay tuned for that if you're
interested.
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
Update: UPDATE: Article is live here: Understanding SVG Coordinate Systems and
Transformations (Part 1) – The viewport, viewBox , and preserveAspectRatio
Note that the display property does not apply to the symbol element; thus,
symbol elements are not directly rendered even if the display property is set
to a value other than none , and symbol elements are available for referencing
even when the display property on the symbol element or any of its ancestors
is set to none .
Wrapping up
All of these elements are container structural elements in SVG that helps make
reusing elements easier while keeping the code cleaner and more readable. And
each of the elements we went over in this article has its own use cases. Now that
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
you know what each one does and how they differ, you can decide for your own
which one to use, depending on your needs. That said, don’t forget to keep your
SVGs accessible at all times.
I hope you liked this article and found it useful. Thank you for reading!
Find similar articles under: #SVG
Enjoyed this article and think your next project could
benefit from my skill set? Get in touch!
pdfcrowd.comopen in browser PRO version Are you a developer? Try out the HTML to PDF API
This is the online studio and blog of SaraSoueidan—award-winning freelance front-enddeveloper, author and speaker.
Follow @SaraSoueidan
Subscribe to the RSS feed.
About Me
Speaking & Workshops
Contact
© 2016 Copyright Sara Soueidan. All rights reserved.