Let me start with a question – which image format should I use: bitmap or vector, PNGs, JPEGs…?
If you spend any time developing content for the web, then I am sure you’ve asked yourself this question countless times: there is a whole array of different formats that we can use, all of which have their own particular qualities! There isn’t a single image format that is ideally suited to the web, which encompasses the best qualities of all image types, although Google has tried to push this with the WebP format, which hasn’t received widespread adoption among other browser providers.
In many cases, I suspect that either JPEG or PNG images would be favored; these are perfect for complex images where detail is essential (such as photographs). However, if you need to display clear line drawings, or 2D images, for example, then these formats aren’t ideal. There are several reasons why, but one of the key weaknesses is maintaining quality – try resizing a schematic saved as a PNG, and the quality soon becomes very poor! There has to be a better way surely…?
Indeed there is – let me introduce you to the world of SVG, or Scalable Vector Graphics. Some people might associate them with applications such as Adobe Illustrator – it’s a perfectly valid assumption; Illustrator is a market-leading product, even if it is something of a heavyweight application. However, there is a whole lot more to working with SVG images – over the course of this book, we’ll see how easy it is to manipulate them using nothing more than just a text editor and a browser. There’s lots to cover, so without further ado, let’s make a start on exploring the benefits of using SVG images in our projects.
The Benefits of Using SVG
For anyone working with a new format for the first time, I am sure there will be one overriding question – what makes it so special? What makes this such a useful format to learn?
SVG-based images do not lose quality when they are resized or zoomed in the browser;
SVG images can be animated using JavaScript or CSS;
SVG images integrate with the DOM very well, and they can be manipulated using JavaScript or CSS;
SVG images can be indexed by search engines, which is perfect for SEO purposes;
SVG images can be printed at any resolution.
This means we can create some really powerful designs that can be easily manipulated and which scale well. The question is – how do SVG graphics manage to retain such a level of clarity, compared to images that lose quality as soon as you try to resize them?
Clearly far easier to use and understand! It’s important to get an understanding of what to expect though, as we can manipulate the contents of any SVG image (more on this later in the book).
For now, let’s try a simple change, using the kiwi bird image.
CHANGING A COLOR IN AN SVG IMAGE
- 1.
Go ahead and open up a copy of the kiwi image in a text editor.
- 2.
Look for this line of code, on or around line 7:
<ellipse fill="#C6C6C6" cx="283.5" cy="487.5" rx="259" ry="80"/> - 3.
Go ahead and change the color to a different HEX value – I’ve picked a random purple, using #834DCF;
- 4.
Save the file, then preview the results in a browser – if all is well, you should see something akin to the screenshot shown in Figure 1-3.
See how easy it was? Yes, the code may look archaic, but don’t worry – as we go through some of the elements in more detail throughout this book, things will become clearer and easier to understand.
Try running through the steps again, but this time choose different colors – you will see that the image is updated but will also retain the same level of clarity throughout.
Okay – let’s change tack: now that we’ve completed our first edit, it’s time we took a look at how the SVG format stacks up against other image formats and see why there are occasions where SVG images will give a superior result compared to standard images.
Comparing Formats
When working on the web, we have a number of image formats we can choose from to display visual content. In many cases, it’s likely that JPEG or PNG will be selected – these formats represent the best choice for size and support in today’s modern browsers, when working with photo-based imagery. However, in a world where websites must be accessible on different devices, these formats do not scale well if we need to use line-based drawings; we’ve already covered how SVG can help in this respect.
Resolution independence – with many image formats, we might have to download extra data or assets to fix resolution-based issues. A great example is when using retina screens, which require us to apply a @2x hack to force higher-resolution images to be displayed. This isn’t the case with SVG images; these can be fully resized, irrespective of device or resolution used, and without the need for additional tags.
Accessible DOM API – SVG elements can be manipulated using nothing more than standard JavaScript or CSS; this could be as simple as changing colors (as we saw back in the exercise “Changing a Color in an SVG Image”) or as complicated as attaching event handlers to perform specific events.
No unnecessary HTTP requests – unlike standard images, SVG images are created using XML and CSS. This avoids the need for the browser to request an image from the server, making it faster and more user friendly.
Content can be indexed, scaled, searched, scripted, and compressed.
We can create images using nothing more than a text editor – yes, it might be easier to create them in a suitable graphics application. However, let us not forget that the key principle I outlined earlier: Why download and install a graphics package if we can achieve the same result in a text editor that we already have?
Logos and icon with strong, geometric, vector-friendly designs;
Graphics that need to be displayed in multiple sizes and screens;
Graphics that respond to their device;
Graphics that need to be edited, updated, and redeployed.
Comparison of Image Formats and Their Uses
Category | Palette | Used for | |
---|---|---|---|
JPG / JPEG | Lossy | Millions of colors | Still Images, Photography |
GIF | Lossless | Maximum 256 colors | Simple animationsGraphics with flat colorsGraphics without gradients |
PNG-8 | Lossless | Maximum 256 colors | Similar to GIFBetter transparency but no animationGreat for icons |
PNG-24 | Lossless | Unlimited colors | Similar to PNG-8Handles still images and transparency |
SVG | Vector/lossless | Unlimited colors | Graphics/logos for webRetina/high-dpi screens |
WebP | Lossless | Unlimited colors | Similar to PNGs, but typically 26% smaller in size – take-up isn’t so extensive, with only Chrome and Opera supporting the format at present |
Note
Lossy images do not retain all of the data in an image, particularly when converted to JPEG; other formats retain data (i.e., are lossless), but do not offer capabilities such as built-in animation or clear scalability.
Okay – enough theory , methinks! Let’s move swiftly on, and turn our attention to more practical matters.
We’re at the point where we need to ensure we have the right tools in place – some of you may think this requires an array of different applications to be set up: as some might say, not if we can help it! True, there are some tools we can install if we decide to develop more advanced solutions, but for now, there is very little that we need to install. Let’s take a look at what we do need, in more detail.
Setting Up a Working Environment
Now that we’ve been introduced to the SVG format, it’s time to get stuck into developing code! We’ve already run through a basic edit using nothing more than a text editor; there are a few more tools we will need, though, in order to complete the exercises in this book.
Before we touch on what we need, there is a key principle I want to share: where possible, we will try to avoid downloading extra tools, and make use of what we already have available in our working environment. There’s a good reason for taking this approach – I’m a great believer in keeping things simple, and not introducing extra tools unless they are needed. There is a trade-off in taking this approach, where some tasks may not immediately be possible, but hopefully we can keep this to a minimum!
We need a decent text editor – there are dozens available online. My personal preference is Sublime Text 3 (available from http://www.sublimetext.com/3 ), although feel free to substitute if you already have a favored editor.
We will make use of Node.js later in the book – this is to automate some of the more menial tasks such as optimizing our images. This can be downloaded from https://nodejs.org/en/ – you can use default settings where prompted during the installation.
We need to create a folder for our code – for the purposes of this book, I will assume it is called svgbook; please alter accordingly if yours is different.
In our project folder, we need to add a couple of extra folders – go ahead and create one called css, and another called font; both should be at the same root level.
An optional extra is to download a font for our demos, to provide a little styling – we’ll make use of PT Sans from FontSquirrel, available at https://www.fontsquirrel.com/fonts/pt-sans . Feel free to skip this step if you want to – the demos will work perfectly fine without it.
- Last, but by no means least, we need to stock up on SVG images that we can use (I would suggest that around six should be sufficient). There are dozens available on the Internet – here are a few links you can try, to help get you started:
Note
Where possible, I have included relevant source images in the code download; if this hasn’t been possible, it will be noted in the text.
Hopefully you’ve managed to get everything set up, or have suitable tools in place – the key here is that we don’t need anything complex when working with SVG images; it’s all about simplicity, and working with what works best for your development environment .
Support for SVG
Okay – we’ve been introduced to SVG as a format, have tools in place, and touched on a basic edit of an existing image; what next? Ah yes – browser support!
The only real concern we may have as developers is if we still have to develop for IE8 or older; the SVG format is not supported, so a fallback alternative will need to be used such as PNG images. Hopefully this isn’t too much of an issue, as usage for IE8 is currently less than 1% – this will be one less headache when support for this browser is finally killed off!
In short, support is widespread for most devices – where you might come unstuck is if you are still using anything older than Android 2.3, which doesn’t support SVG as a format. This was introduced (in part) from 2.3 onwards, with more recent versions offering full support for the format.
Creating a Basic Example
So far we’ve explored some of the theory and possible uses for the SVG format – it’s time we stopped talking, and got stuck into writing some code! Over the next couple of pages, we will knock up a really simple example; this will provide a taster of what to expect in Chapter 2, where we will look at some more in-depth examples. Let’s explore what is involved in more detail, to add a basic SVG image to a web page:
CREATING A BASIC EXAMPLE
- 1.
We’ll start by opening a new file, then adding the following code, saving it as simpleexample.html in our project folder :
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Beginning SVG: Creating a simple example</title></head><body><h2>Beginning SVG: A Simple Example</h2><link rel="stylesheet" href="css/simpleexample.css"></body></html> - 2.
Before the closing </body> tag, go ahead and add this code block:
<svg><circle cx="60" cy="60" r="50" stroke="black" stroke-width="5" fill="silver"/></svg> - 3.
The keen-eyed among you will spot that we’ve referenced a style sheet – for this, go ahead and copy the font file from the code download that accompanies this book, and save it into our project’s font folder.
- 4.
In a new file, add the following code:
@font-face { font-family: 'pt_sansregular'; src: url('../font/pt_sansregular.woff') format('woff'); font-weight: normal; font-style: normal;}body { font-family: 'pt_sansregular', sans-serif; padding: 2rem;}circle { stroke: #000000; stroke-width: 4; fill: #cdc7c7; } - 5.
Save this as simpleexample.css in the css subfolder we’ve just created in the previous step.
- 6.We can now preview the results in a browser – if all is well, we should see something akin to the screenshot shown in Figure 1-6.
See how easy it is? Granted, this was a very simple example, but it proves that we only needed to use a standard text editor, with no graphics package in sight. The gray and black colors used were purely for the purposes of viewing the results in print, but we could easily have used different colors – this is limited only by your imagination. The key here is to understand how it works: let’s take a quick look in more detail.
Understanding How It Works
The SVG viewport – this controls the size of the window, through which we may view a particular SVG element;
We can restrict this by specifying a viewbox attribute – whereas the viewport can be enormous, the viewbox limits the extent of what we see.
In many cases, these two will be aligned – they work in a similar fashion to Google Maps, where we can zoom into a specific region. The visible, scaled-up area will be restricted to this region; the rest of it is still available but will be hidden as it sits outside of the boundaries of the viewport area.
The cx and cy values indicate how far across to render the circle, with the r value controlling its radius. So, to translate our code into plain English, it will be rendered 60 units to the right (from top left), and 60 units down. The r value controls how big our circle will appear on screen – it goes without saying that the higher the number, the larger the circle!
One thing we must note – many values you will see in SVGs are often rendered with or without unit identifiers. If units have not been specified, then the value is assumed to be equivalent to the same value in pixels.
Adding Fallback Support
Our example is very straightforward, and will work in all recent browsers from the last two to three years. However, it won’t work in old browsers such as IE8 – if we’re working with a (in this case relatively) new format, how would we provide fallback support? This opens up a real can of worms – should one offer support? Or should we set the experience to degrade gracefully? How about displaying an alternative in PNG format, for example?
The most important question is – how many visitors might this affect? If the analytics for our site shows a really small number, then we might decide to simply do nothing. This may seem harsh, but it is important to weigh up the economic benefits of implementing a solution, if we’re only doing it for a small number of people. If that small number brings in a substantial amount of revenue though, then yes, we may be obligated to implement a solution!
If the SVG content is merely a text label that can be displayed using an alt tag instead, then we may decide to do away with support; if necessary, we can add in standard CSS to provide some background styling instead.
Should we degrade the experience gracefully, to encourage users to update browsers to more recent versions? This isn’t always possible – some companies may require the use of older browsers for security reasons, which will have an impact on whether we can provide such a graceful exit.
Do our processes allow for the automatic production of images in different formats? This might seem a little odd to ask, but if we can automate this process, then it reduces the manual effort required and makes implementing a solution easier.
We might consider implementing a solution whereby any image link automatically includes the same image in two formats – if we happen to use a browser that doesn’t support SVG, then it will automatically fall back to using the alternative format. The downside of this is that we may end up with some browsers downloading multiple versions of the same image, which has potential resource considerations.
If we do have to provide fallback support, then we have a number of options available to us, such as using background images or adding the code inline to our application. Each has its own merits, so let’s take a look at some of these in more detail.
Types of Fallback
No feedback – we’ve already touched on this, but if the content is visible without the SVG image (through an alt tag, for example) then we may find that a fallback isn’t necessary.
Text fallback – if we have an image or icon where an alternative text label could be used, then we should consider adding suitable text through the image’s alt tag.
Image fallback – in many cases, developers are likely to use this route when providing a fallback; a PNG or GIF image will work, but with the consequential trade-off in increased file sizes and poorer resolution.
Interactive fallback – if we have to replace an interactive SVG, a PNG isn’t likely to do it justice; we may have to resort to rewriting code using a library such as Raphaël (http://dmitrybaranovskiy.github.io/raphael/). It’s an option to bear in mind, although working through it in detail will fall outside of the scope of this book
This leaves us with two viable options for implementing a fallback for any SVG image we use, namely text and image. What does this mean in practice? Well, let’s take a look at the options:
Implementing a Fallback Image
The downside of using the JavaScript approach means we trigger multiple (unnecessary) requests for images that are not supported; we also have to use some workarounds to ensure images are displayed to the correct scale on screen.
Adding SVGs as Background Images
If a browser supports multiple backgrounds, it will support SVG and therefore use the latter option; for those browsers that only support one background, the first url(...) value will be used, and the rest of the rule will be ignored.
It’s worth noting that we could use <object> or <embed> to add SVG images , but this route has fallen out of favor – the near universal support of SVG makes this redundant for most browsers. If it has to be used, then it should be reserved for older browsers such as IE8 that do not support it natively without plug-in support.
Managing Inline Support
Although some might prefer the options we’ve just covered (for their concise approach), adding SVG images inline remains the most popular – it gives us the most flexibility in terms of controlling style and content using CSS and JavaScript.
This works very well, using the principle that if the SVG format isn’t supported, then code will either be ignored or treated as plain HTML. This means that in our example, the plain text included at the start of the SVG will be displayed, along with the fallback link at the end.
Note that the text within <text> tags will not be displayed in a fallback – this is considered invalid by older browsers so will equally be ignored.
We can also develop our example to use either the SVG <desc> or <use> tags; for more details on how, I would recommend checking out the article on CSS Tricks by Amelia Bellamy-Royds at https://css-tricks.com/a-complete-guide-to-svg-fallbacks/ . It’s a couple of years old but still contains some useful tips! It’s worth noting that we may also need to use JavaScript to test for support – the Modernizr library contains a neat example of how, although we can equally test using plain vanilla JavaScript.
The self-styled web spinner, Taylor Hunt, also has an intriguing article on the use of the SVG <switch> statement; this effectively uses the same principle, but varies content based on matching conditions. You can see the details on Codepen at https://codepen.io/tigt/post/inline-svg-fallback-without-javascript-take-2 .
There is one more area we should cover – the SVG format is perfect for creating and managing icons . It’s essential that we maintain an equally efficient fallback if we have to work on older browsers; this means simply switching formats within an <img> tag may not work so well. Let’s round out our coverage of providing fallback support, by briefly covering the options available to us, when setting up a fallback for icons.
Supporting an Icon System
When adding images to a page, we clearly have to be careful about sizes, quantities, location and such – I need hardly say that poorly sized images will kill page speed! To help with this, we might decide to use sprites, particularly when using icons – combining multiple images into one sprite will indeed reduce requests for resources. The SVG format is perfectly suited to creating sprites – question is, how should we provide a fallback for them?
We could simply use background images as fallback support, but these would need to be CSS sprites so we can maintain a “one request per image sprite” approach.
An alternative might be to use an icon font as a fallback. We will need to provide an empty element, but support for @font-face in older browsers is more extensive than SVG , so might be a useful option to take.
We could automate Use Grunticon (available at http://www.grunticon.com/ ), which starts with an empty element and progressively enhances up to SVG, while handling fallbacks (through a JavaScript test). We’ll work on the concept of automating icon support for SVG in more detail, in Chapter 3, “Working with Images and Text.”
Ultimately, it’s up to us as developers to decide the most appropriate route to take – this will depend on the level of fallback support we need to provide, and whether we can reduce this by designing out those areas that will give cause for concern in older browsers.
We’ve covered a number of options available for maintaining fallback support – part of this will also entail optimizing content to ensure we make it accessible to older browsers. We’ll cover this in more detail in Chapter 7, “Optimizing SVG.”
Summary
The discovery of, and getting to grips with, a new technology opens up a world of possibilities when developing our projects – let’s take a moment to explore what we’ve covered through the course of this chapter.
We kicked off our journey into the world of SVG with a gentle introduction to the format, to explore some of the benefits of using this format, and to see how it stacks up against other image formats. We then worked our way through a quick example of changing the color in part of an SVG image – this was to show that although we are working with XML code, it is still very easy to alter an image.
Next up came a look at setting up our working environment – we covered how we only need a minimal toolset to work with SVG, and that some of the tools we will use are optional extras, depending on our project requirements.
We then switched to exploring browser support for SVG images – we explored how most modern browsers will support this format natively, and that in the worked example, we can simply use an image tag to insert SVG images into the page without a problem. We also touched briefly on the SVG viewport and viewbox, to understand how these play a pivotal role in positioning SVGs on the page.
We then rounded out the first part of our adventure with a look at providing fallback support for the format. In many cases, we explored how this shouldn’t be necessary, but in the event it is, we examined a few tips we can use to either degrade the experience gracefully, or provide an alternative on the page.
Phew – we’ve covered a lot, but we’re just getting started! The next stage in our process is to understand how we can add shapes (both basic and more complex) to the page; we’ll explore this and more in the next chapter.