18 March 2009
SVG_roundies enables web developers to add rounded corners to HTML boxes in a minute. It is a lightweight Javascript-only library based on the W3C standard SVG and has been tested in Firefox, Opera, Safari and Chrome. SVG_roundies' counterpart for Internet Explorer is DD_roundies. When both libraries are used together rounded corners can be seen in all major browsers. If Javascript is disabled both libraries degrade gracefully as the usual HTML boxes with their sharp corners are displayed. Neither SVG_roundies nor DD_roundies require web developers to change their document structure, create graphics or use special CSS properties.
This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
SVG_roundies is a port of Drew Diller's excellent DD_roundies library. While DD_roundies uses Microsoft's VML to add rounded corners to boxes and thus only works in Internet Explorer this library is based on the W3C standard SVG.
SVG is supported by Firefox, Opera, Safari and Chrome but not by Internet Explorer. That said in practice you want to use DD_roundies and SVG_roundies together. As SVG_roundies is a port of DD_roundies both libraries provide the very same interface and produce the same results. Only their implementation differs. If you know DD_roundies you can use SVG_roundies in a minute.
Please note that Firefox and Safari support their own CSS properties -moz-border-radius and -webkit-border-radius to add rounded corners to boxes. For those browsers you don't really need to use SVG_roundies. As Opera doesn't support a CSS property for rounded corners yet SVG_roundies is required for this browser.
If you use DD_roundies and SVG_roundies together you can choose if you want to use the CSS properties or a SVG graphic in Firefox and Safari. DD_roundies can set the CSS properties -moz-border-radius
and -webkit-border-radius
for you.
SVG_roundies does not try to detect the browser and will always create a SVG graphic. If you want to use SVG_roundies only for some browsers you need to detect the browser yourself. As there are many scripts available on the Internet there is no need to invent another browser detection routine for this library.
You use SVG_roundies the very same way you use DD_roundies:
<html> <head> <script type="text/javascript" src="SVG_roundies_0.0.2a.js"></script> <script type="text/javascript"> window.addEventListener('load', function() { SVG_roundies.addRule('p', '10px 0px'); }, false); </script> </head> <body> <p style="background-color: red; border: solid 3px blue; font-size: 3em">Hello, world!</p> </body> </html>
In a SVG-capable browser you'll see a red box with a blue border and a rounded top-left and bottom-right corner. In other browsers the result is undefined. That's why you want to detect the browser and version before you call SVG_roundies.addRule()
!
If you want to use DD_roundies and SVG_roundies together your code could look like this:
<html> <head> <script type="text/javascript" src="DD_roundies_0.0.2a.js"></script> <script type="text/javascript" src="SVG_roundies_0.0.2a.js"></script> <script type="text/javascript"> function roundify(selector, radius) { if (DD_roundies.IE6 || DD_roundies.IE7 || DD_roundies.IE8) { DD_roundies.addRule(selector, radius); } else { SVG_roundies.addRule(selector, radius); } } if (window.addEventListener) { window.addEventListener('load', function() { roundify('p', '10px 0px'); }, false); } else { window.attachEvent('onload', function() { roundify('p', '10px 0px'); }); } </script> </head> <body> <p style="background-color: red; border: solid 3px blue; font-size: 3em">Hello, world!</p> </body> </html>
Now you'll see a red box with a blue border and a rounded top-left and bottom-right corner in Internet Explorer and in all other browsers.
Please note that while SVG_roundies tries to be compatible with DD_roundies there are a few differences:
SVG_roundies does not accept a third argument in addRule()
. It does not try to detect the browser and does not add CSS properties like -moz-border-radius
and -webkit-border-radius
. It is a SVG-only library.
SVG_roundies does not support changing an <a>
element dynamically with a:focus
and a:hover
. First there is no standardized event to detect hovering. Second Firefox and Opera don't report CSS properties set with a:focus
(Safari doesn't even raise an onfocus
event).
While you can pass any selector to DD_roundies.addRule()
you must pass a tag name to SVG_roundies.addRule()
. SVG_roundies uses document.getElementsByTagName()
to find the box it should add rounded corners to. It would be nice if SVG_roundies could use document.querySelectorAll()
. But this function is not yet available in many browsers. For example Firefox will support it in version 3.1 and Opera in version 10 for the first time. As SVG_roundies should work today and with today's browser versions in the future it uses document.getElementsByTagName()
by default. Once document.querySelectorAll()
can be assumed to be available in most browsers in the wild the implementation of SVG_roundies will be updated (but don't expect this to happen in 2009).
Not everybody will be happy to pass a tag name as a selector (in fact I want to pass something else most of the time). That's why it is possible to link another function into SVG_roundies. This could be a querySelectorAll()
implementation provided by another Javascript library. Or it is a function implemented ourselves:
<html> <head> <script type="text/javascript" src="SVG_roundies_0.0.2a.js"></script> <script type="text/javascript"> SVG_roundies.querySelectorAll = function(selector) { var headings = document.evaluate('//*[contains(@class, "' + selector.substr(1) + '")]', document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null) var results = new Array(); var oneheading; while (oneheading = headings.iterateNext()) results.push(oneheading); return results; } window.addEventListener('load', function() { SVG_roundies.addRule('.roundify', '10px 0px'); }, false); </script> </head> <body> <p class="roundify" style="background-color: red; border: solid 3px blue; font-size: 3em">Hello, world!</p> </body> </html>
The box is now found through the class roundify and will have again a rounded top-left and bottom-right corner.
If you implement your own function I strongly recommend to design the interface similar to document.querySelectorAll()
. This will make it easier to update your code in the future and use the browser supplied implementation of document.querySelectorAll()
one day.
SVG_roundies tries to support Firefox, Opera, Safari, Chrome and any other SVG-capable browser on all platforms they are supported on. As IE does not support SVG you should use DD_roundies to add rounded corners for this browser.
The current version 0.0.2a has been tested with:
Firefox 3.0.6 (Windows XP SP3)
Opera 9.62 (Windows XP SP3)
Opera 9.63 (Windows Vista Business)
Opera 10 alpha (Windows XP SP3)
Opera 9 for Nintendo Wii
Safari 4 Public Beta (Windows XP SP3, Mac OS X 10.5)
Safari 3.2 (iPhone OS)
Chrome 1.0.154.48 (Windows XP SP3)
Known issues | Browsers affected |
---|---|
If two boxes with rounded corners are nested and the outer box has a border Opera moves the inner box to the wrong position. The recommended work-around is obviously to make sure the outer box doesn't have a border. - As it seems like this is really a bug in Firefox, Safari and Chrome. I've filed those bugs to Bugzilla@Mozilla and WebKit Bugzilla. The current version of SVG_roundies behaves as if this is a bug in Opera though (as the presentation in Opera is wrong). | Opera 9.x, Opera 10 alpha |
If you change CSS properties of a box dynamically SVG_roundies is automatically notified and updates the SVG graphic accordingly. However this does not work in Safari (which doesn't fire the event DOMAttrModified) neither in Chrome (probably for the same reason). | Safari 4 Public Beta, Chrome 1.0.154.48 |
If you change CSS properties dynamically and reset padding for example the change is reflected in the SVG graphic. However if you have another box with rounded corners on the same page the second SVG graphic is not updated. This is a problem when the size is changed (because of setting padding for example) and all elements on the page move. Other SVG graphics which are all absolutely positioned don't move though because they don't know they should. DD_roundies uses the onmove event which is only supported by Internet Explorer. Any ideas which event handlers could be used in Firefox/Opera/Safari/Chrome? | all |
Adding rounded corners to the elements <table> , <tr> , <td> and <option> is disabled as it doesn't work in any browser correctly (it's disabled in DD_roundies, too). |
all |
Just like DD_roundies the library SVG_roundies is also free under the MIT license.
Copyright (c) 2008-2009 Drew Diller, Boris Schaeling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
You can download a compressed and uncompressed version of SVG_roundies. The current version is 0.0.2a (which is also the first version of SVG_roundies).
If you wonder about the strange version number: I use the same version number as Drew does for DD_roundies. If you use DD_roundies 0.0.2a you know that SVG_roundies 0.0.2a supports the very same interface and produces the very same results.
Let's suppose you want to add rounded corners to <p>
which is formatted like this:
<p style="background-color: red; border: solid 3px blue; font-size: 3em">Hello, world!</p>
SVG_roundies dynamically creates a SVG graphic and adds it to the document structure. In order to create the right SVG graphic it will look for certain CSS properties. If the background color of <p>
is red after all you want the box with rounded corners to be red, too.
It should be noted that you can set as many CSS properties as you like. You don't need to take SVG_roundies into consideration when you design your pages! SVG_roundies will work out of the box and does not require you to add, remove or reset CSS properties. Even if SVG_roundies can't find the CSS properties it looks for the library will work as expected. If you don't set a background color for example the rounded box will be transparent.
SVG_roundies will look for the following CSS properties:
background-color
background-image
border-color
border-left-width
border-top-width
border-right-width
border-bottom-width
opacity
z-index
SVG_roundies creates a SVG graphic depending on the values of those CSS properties. The library will insert a <svg>
element before <p>
and set various SVG attributes and CSS properties. Here is what's happening exactly:
A new <svg>
element is inserted before <p>
. The CSS property position
is set to 'absolute'. The z-index is the same as of <p>
.
The CSS property position
of <p>
is set to 'relative' if it is set to 'static'. This is required to move <p>
to the front of <svg>
. Otherwise the SVG graphic hides <p>
and you can't read the text.
The CSS property background-color
of <p>
is set to 'transparent'. The background-color
is used to add and set the fill attribute in the first <path>
element (there are two <path>
elements in <svg>
). (If a background-image
is used or an <img>
element should get rounded corners it is a bit more complicated as a few more SVG elements have to be inserted.)
The CSS property border-color
of <p>
is set to 'transparent'. The border-color
is used to add and set the fill attribute in the second <path>
element (set to 'none' if no border-color
has been set).
The CSS properties left
, top
, right
and bottom
are set for <svg>
. As the CSS property position
has been set to 'absolute' before this moves <svg>
to the very same position of <p>
.
The paths are calculated. The attribute d
of the two <path>
elements is set.
The value of the CSS property opacity
of <p>
is set for the attribute opacity
of <svg>
.
As you've seen SVG_roundies sets and changes some CSS properties of <p>
:
position
: relative
background-color
: transparent
background-image
: none (only set if a background-image
is used)
border-color
: transparent
If you have Javascript code which needs to use the original values of those CSS properties you should run this code before you call SVG_roundies.addRule()
. If you need to use the original values later in a dynamic web application you must save the values somewhere when your web application starts.
The new document structure looks like this (the question marks are automatically calculated values):
<svg xmlns="http://www.w3.org/2000/svg" style="position: absolute; z-index: auto; left: ?px; top: ?px; width: ?px; height: ?px" opacity="1"> <path fill="red" d="?"/> <path fill="blue" d="?"/> </svg> <p style="background-color: transparent; border-color: transparent; border-width: 3px; position: relative; font-size: 3em">Hello, world!</p>
Copyright © 2009 Boris Schäling