You remember that kid at school sitting in the back of the classroom whom nobody ever talked to? Everybody knew he was there, most of them knew his name but nobody wanted to be teamed with him when it was time for teamwork because they all wanted to work with their long time friends.
Some of you reading this are probably saying… Dude, that kid was me man!
Then one day, during art class, your best buddy wasn’t there and you had no one else to work with besides this loner sitting in the back. That’s when you finally found out that he was one of the coolest kids at school, with the sharpest collection of crayons.
That is exactly the relationship I had with SVG. I knew it existed, I had a brief idea of what could be done with it, but I was relying on my CSS skills to do my work. Then on a recent project, I faced a challenge that seemed way too complicated to overcome using CSS alone. It was at that moment that I decided to dig deeper and learn more about SVG.
This post is the first of a series about SVG. The content of this article is not specific to GWT. It’s an introduction to SVG basics for readers who, like me, hadn’t really looked into it before. My next article will build on this introduction, and explore some more advanced and more interesting topics.
1 – What is SVG ?
SVG stands for “Scalable Vector Graphics” and it is a vector-based XML graphics format that has a bunch of predefined elements and properties.
Since it’s vector-based, it can be resized without losing quality. This means you can scale your SVG graphic to any size you like and it will always look as sharp as a Japanese blade. Hellooo responsive and retina display!
Among its advantages:
- It has decent browser support (IE9 and up, and Android 4.3 and up).
- The file size is generally smaller than bitmap images.
- Text in the SVG can always be selected and edited.
- Each graphic element with the SVG can also be independently selected and manipulated without impacting the rest of the SVG.
2 – Coordinates and prime elements
The <svg> tag defines the canvas of your SVG file. The SVG coordinate system is not a Cartesian system. When you use Cartesian coordinates, the point (0,0) is at the bottom left corner of the space. The X axis increases as you go right, and the Y axis increases as you go up.
The SVG coordinate space places the (0,0) point in the top left corner of the space. The X axis increases as you go right and the Y axis increases as you go down.
The primary graphic elements in SVG are: <circle>, <ellipse>, <line>, <path>, <polygon>, <polyline>, <rect> and <text>. You can group these elements, give them style attributes, transform them and animate them. You can also use an .svg file created in a drawing tool like Illustrator or Inkscape and add it to your html file.
That is pretty clear but also kind of simple. So put on your hip-waders and let’s get down in some weeds.
3 – How to use SVG
First of, you must create the <svg> element, declare the xml namespace and give it a width and an height. These dimensions represent the viewport of the SVG.
-by default the dimension are in pixels but you could use other unit such as: em, ex, in, cm, mm, pt, pc, %.
Then you need to add a title and a description.
Now we can add our first elements. The syntax is quite simple. In the following code example, even if you’ve never seen SVG elements before, you will probably still have a pretty good idea of the SVG graphic elements that are being defined here.
The X and Y define the position of the bottom left corner of text.
The X and Y define the position of the top left corner of the rectangle. The width and the height obviously set its dimensions. You can also have rectangles with border-radius. In that case, you can add an RX and RY attributes which define the radius of the border. So the whole thing would look like this:
The coordinates of the circle are set by defining its centrepoint and its radius. The centerpoint is defined using its CX and CY attributes, and the R stands for its radius. So for this example, we would have a circle with its center at 85px left and 300px from the top with a radius of 68px.
Same as for the circle but this time we add an RY for the Y radius.
(X1 Y1) are the coordinates of where the line start and the (X2 Y2) is the coordinates of where it ends.
Polylines are composed of a series of points (X,Y X,Y …) that are connected by a line between each one of them.
A polygon is almost the same as a polyline. The difference is that it encloses itself by connecting the last point to the first one.
Paths are a little bit more complex to create from scratch and I highly recommend to use a drawing tool such as Illustrator or inkscape for those. That will save you a lot of headaches. However, it is still helpful to understand how paths work. That understanding can simplify your life in the future.
So here we go…
Paths contain a “d” attribute that defines the path data, using commands that mix lines and curves to create shapes. Every command has a capital letter for absolute coordinate (absolute to the <svg> element) or a lowercase for relative coordinate (relative to the current coordinate).
Here is a list of the commands you can use to create a path.
- (M or m) = moveto, this is the point where your Path starts.
- (L or l) = lineto, draws a line from the current coordinate to a new one.
- (H or h) = horizontal line, draws an horizontal line from the current coordinate to a new one.
- (V or v) = vertical line, draws a vertical line from the current coordinate to a new one.
- (C or c) = Cubic bezier, draws a curve from the current coordinate to a new one using 2 control points.
- (S or s) = Cubic bezier, draws a curve from the current coordinate to a new one using 2 control points; but the first control point is the reflection of the last control point of the current coordinate.
- (Q or q) = Quadratic bezier, draws a curve from the current coordinate to a new one using 1 control point.
- (T or t) = Quadratic bezier, draws a curve from the current coordinate to a new one using 1 control point; but the control point is the reflection of the last control point of the current coordinate.
- (A or a) = Arc, draws an arc based on a segment of the intersection between 2 ellipsis
- (Z or z) = close the path Some of these definitions might sound complicated, but I’ll show you in detail how every one of them actually works.
(M or m) sets the coordinates (200,200) at which the path will start in your svg canvas.
(L or l) draws a line from the current coordinates (200,200) to a new ones (250,250).
(H or h) draws an horizontal line from the current coordinates (200,200) to (250) on the X axis.
(V or v) draws a vertical line from the current coordinates (200,200) to (250) on the Y axis.
So far so good? Here comes the heavy part.
Cubic bezier draws a curve from the current coordinate to a new one with two control points. The first coordinate (50,50) represent the control point of the curve’s origin. The second coordinate (150,50) defines the second control point and the last coordinates (150,100) represent the final point of the curve.
The “S” command also draws a Cubic bezier curve. The first control point is a reflection of the control point of the current coordinates, so we don’t need to set the coordinates. The first coordinates (250,150) define the control point of the point where the curve will end and (250,100) are the coordinates of where the curve ends.
A quadratic Bezier draws a curve from the current coordinates with one control point. The first coordinates (100,40) represent the position of the control point and (150,100) are the coordinates of the end of the curve.
The “T” command also draws a quadratic bezier curve. The only control point is the reflection of the control point of the current coordinates so we don’t need to specify any of them. All we have to do is specify the coordinates of the end of the curve (250,100).
Arc creates 2 ellipses that overlap each other at two intersections, creating four possible arcs. It is based on two pairs of coordinates, the first one (M140,100) which is the starting point of the arc and the second one (260,170) represents the endpoint of the arc. These two pairs of coordinates represent the intersection of the two ellipses.
- The numbers following the “A” represent the radius (rx,ry) of the ellipses.
- The number that stands by itself (0) defines the x-axis-rotation for the arc.
- The next set of numbers (1,1) represents the large-arc-flag and the sweep-flag and they can only be set to 1 or 0.
- The large-arc-flag defines if you want to see the biggest part of the arc or the smallest part of the arc; 0 being the small part and 1 being the larger one.
- The sweep-flag defines the direction of the arc; 0 being “counterclockwise” and 1 being “clockwise” starting from the starting point.
Congratulations, weed waders! We have shapes and we know how they are defined, but if you are like our designer you probably find them a little boring. Let’s look at how to give your elements a bit more style.
3 – Adding style to elements
By default, SVG has presentation attributes that can be added directly to elements, and those presentation attributes can also be set via CSS. For this example, we’ll draw 3 circles and see how we can add style to them.
Nothing too complicated here, right? Note that presentation attributes are overridden by CSS. So if you have:
The fill of the circle will be red. Here is the list that represents the cascade, as what’s on top get overridden by what’s below.
- User agent styles
- Presentation attributes
- External styles
- Document Styles
- Inline Styles
- Overwrite styles
- Computed Style
Creating a basic shape with SVG and adding style to it is kind of simple, but it might get a little bit harsh if you want to create a more complex shape. Remember earlier when I said that you could use an .svg file created from a drawing tool? For the last part of this post, I’ll show you how we can add those in our html.
4 – Add SVG images in the html
There are different ways you can load an SVG image in your HTML. You can use the old and simple <img> tag, use the css background-image property, use it “inline” directly in the html, and you can also use the <object> element.
4.1 – Load via the <img> tag
Nothing new here, right? it uses the same syntax as adding any other image using the <img> tag.
4.2 – background-image
Well that was quite easy wasn’t it? Note the fallback if you need to support older browsers. The use of the <img> tag and the background-image property is cool and quite simple and they will behave just like any other image file, but it would be cooler if we could have the ability to modify the image with CSS right? Let’s see how we can achieve that.
4.3 – inline SVG
To use your SVG inline in your html, you need to open your .svg file in a text editor and copy-paste the code right in your html.
This complicated attribute might look familiar to you by now. With what you read about <path> and the commands found in the “d” attribute, you have acquired enough knowledge and to have an idea of what it contains. And as we saw in the previous section, we can use CSS to style the elements.
4.4 – <object>
For the <object> element, you just have to add the following lines of code, and add the path to your svg file in the data attribute.
The cool thing about using the <object> element is that it provides a fallback in case the browser doesn’t support SVG (IE8 and down and Android 2.3 and down). If you want to add some CSS to your SVG inside the <object> element, you can do it by adding the <style> element inside your .svg file like so:
This is cool and it works just fine, but if you are like me and prefer to have an external stylesheet, you can add the following line
<?xml-stylesheet type="text/css" href="youCssFile.css"?> in your .svg file, right under the xml declaration
<?xml version="1.0" encoding="utf-8"?> and you’ll be able to control it as you wish.
SVG is easy to use once you take the time to understand how it works. In this article I’ve only presented the basics of SVG. That gives you enough knowledge to start playing with it and learning about it on your own, but in terms of what I now know about the potential of this format, it really is only the tip of the iceberg.
In my next article, we’ll go a little deeper with the use of CSS with SVG. See you next time and until then, take care of yourself.