Post Archive

› October 17, 2005

Introducing DomCorners

  • Reported by Alessandro

DomCorners is a very simple technique for getting rounded corners, which has been presented on pro.html.it, the italian portal I write for, on the 31 of August 2005. When I developed it in July, I wanted to get a lightweight solution, simple to use and flexible. So I started thinking and came up with a solution that relies entirely on javascript and images, it's unobtrousive, has very good browser support and is very minimal.

And yes, it uses images. This may sound weird to the people who know about my work on Nifty Corners. While I simply love them, in developing DomCorners I nearly forgot about them and started with a very different approach, with simplicity as my main goal. The basic inspiration of DomCorners is Douglas Livingstone's four corners. It all started when I realized that a single image could be used to light up the technique. So here is the bare-bones HTML and CSS example of the technique. The markup looks like this:

<div id="box">
<b class="btop"><b></b></b>
content here...
<b class="bbot"><b></b></b>
</div>

Here's the CSS for rounded corners:

b.btop, b.btop b, b.bbot, b.bbot b{
    display: block;height: 10px;font-size: 1px;
    background-image:url(rc.png);
    background-repeat: no-repeat}
b.btop b{background-position: 100% -10px}
b.bbot{background-position: 0 -20px}
b.bbot b{background-position: 100% -30px}

And finally the single image used wich combines the four corners, starting from the top left, then top right, bottom left and finally bottom right:

image for rounded corners

Next step obviously was to cut off extra markup and CSS. Have a look on the basic example which uses only javascript, mainly built with DOM. If you see the HTML code of the example, in the head section you'll notice these lines:

<script type="text/javascript" src="domCorners.js"></script>
<script type="text/javascript">
if(DomCheck()){
DomCorners("box","rc.png",10);
}
</script>

The first line embeds the small general javascript, while the others are for getting rounded corners on the specific page. I left them embedded for demonstration: obviously you could move these lines in an external javascript too, for example in domcorners.js.

The embedded script after a check for the DOM availability calls the DomCorners function to round the element. The function needs three parameters: the first one is the ID of the element to round, the second one is the image to be used and the third one is the height (in pixels) of a single rounded corner in it.

A few words about the script: I've provided a commented version, which is less than 30 lines. The DomCorners function performs a check a predefined intervals of 50ms to see the availability in the DOM of the element with a given ID. If it's ok, it simply inject the elements for rounded corners with the needed style declarations. After 200 tries (10 seconds) the function stop trying so you can call it even on a page where the given ID doesn't exist being sure it won't loop endlessy. A timer-based approach makes the script run faster than the onload and makes DomCorners a plug-and-run solution that won't give conflicts with other scripts.

Now let's see the second example, a two column liquid layout which uses DomCorners and just five images. The embedded script on the page is as follows:

if(DomCheck()){
DomCorners("header","head.png",10);
DomCorners("content","content.png",10);
DomCorners("menu","side1.png",10);
DomCorners("links","side2.png",10);
DomCorners("footer","footer.png",5);
}

Each call to the DomCorners function has the purpose of rounding an element, and as in the first example parameters are in order id, image to be used, and height in pixel of a single corner: notice that the footer has smaller corners than the other elements.

And finally the third example which uses just two gifs partially white and partially transparent. In this case you don't have to prepare an image that matches the background each time, since transparency will do everything: just be sure to use muted-tone backgrounds because GIFs are in fact aliased corners.

Even in this case, let's see the javascript calls:

if(DomCheck()){
DomCorners("header","transparent.gif",5);
DomCorners("content","transparent.gif",5);
DomCorners("menu","transparent.gif",5);
DomCorners("links","transparent.gif",5);
DomCorners("footer","small.gif",2);
}

That's it. Finally, a small note on compatibility: support of the script should be extended to browsers with a minimum of CSS and DOM capablities: the examples of this article have been tested on IE5, IE5.5 and IE6 and the latest versions of Opera, Firefox and Safari. Enjoy!

Comments

1. October 17, 2005 09:50 PM

Quote this comment

Mike Rundle Posted…

This technique sounds pretty cool, but I have to ask, what's up with the HTML? It's possibly the worst code I've seen ever posted on web-graphics. B tags instead of strong, no text inside of them, what gives?

2. October 17, 2005 11:05 PM

Quote this comment

Nate Posted…

Hi Mike, the b tag code isn't really *in the markup* so to speak - it's inserted post-haste via the Javascript. If you look at the markup in the examples, it's clean. I think one could argue that even so, the inserted code should be valid, but I'm guessing that Alessandro chose this method because it's somewhat shorter.

3. October 18, 2005 07:47 AM

Quote this comment

Tom Posted…

Nice article, I have hesitated using many of the rounded corner techniques due to bloatedness. This one is pretty clean. I like the use of the DOM to get the job done.

There does seem to be an issue in FireFox in your last example with the corners not fully being at the bottom of the box, so you get a wierd horizontal line. I've seen this behavior before in FF and it can be a real pain to solve. Here is a screenie:

Screen shot

I included a little blowup and arrows to show what I mean. I don't see that on the first example for some reason. Nice job. If that could be solved this would be pretty bulletproof.

Tom

4. October 18, 2005 11:08 AM

Quote this comment

Craig Snyder Posted…

This is a very interesting technique but it seems to me that Nifty Corners has the advantage in every respect. I am also viewing the Firefox "misbehavior".

5. October 18, 2005 12:51 PM

Quote this comment

Alessandro Fulciniti Posted…

Mike, the point it that an empty element couldn't have a semantical meaning so I used a presentational tag such as b (as I did in the html example of nifty corners) since it's short and it's inline, so it could be inserted in every kind of element. Obviously the <b> soup disappear in the js-powered version, but I think it was important to show the html+css version in order to let people understand better how the script works.

Tom, could only guess that the exceeding stripe it's due to the famous Gecko 1px rounding error... and I think the problem it's not in the script itself, but the page CSS.

Craig, obviously Nifty Corners are too far easy and versatile since no images at all are involved. DomCorners are just a little toy but might be useful when you want to get bigger corners, better antialiasing or simply a lighter solution.

6. October 18, 2005 02:41 PM

Quote this comment

Mike Rundle Posted…

Thanks Alessandro, that cleared it up. Only 1% bad now ;)

7. October 18, 2005 04:12 PM

Quote this comment

lurker Posted…

Scrolling the text size reveals a few slight glitches...

8. October 20, 2005 04:33 AM

Quote this comment

richard Posted…

Uh, is this what I think it is? This technique has been published in 2002 by FCZBKK, wasn't it?

9. October 20, 2005 07:21 AM

Quote this comment

Nate Posted…

Richard - this is not that.

10. October 23, 2005 04:55 AM

Quote this comment

Jacob Posted…

Tom, could only guess that the exceeding stripe it's due to the famous Gecko 1px rounding error... and I think the problem it's not in the script itself, but the page CSS.

The line is almost certainly by Gecko's 1px rounding error. The solution is to ensure that all sizes are whole pixel values and the bug disappears. This means all sizes - including margins, padding, borders, line height etc. Sometimes you can avoid problems whilst still having odd sizes but it gets complex.

By the way, the guys at Mozilla are working on a correction for this bug - it's filed on Bugzilla somewhere but I've lost the link I'm afraid.

Nice technique for making corners by the way - this is by far the cleanest solution I've seen.

11. November 13, 2005 07:25 AM

Quote this comment

Posted…

I'm not sure I understand this .. but would it allow a border on the box?

12. November 15, 2005 05:26 AM

Quote this comment

Matthew Posted…

I don't think this technique would allow nice borders, but is probably a bit more compact than the border technique I've been using on my current project. The link for that is below (I didn't write it, but the results are _really_ gorgeous given a nice input image - if you use it, thank Roger Johansson in the comments on that page!)

http://www.456bereastreet.com/archive/200505/transparent_custom_corners_and_borders/

13. December 23, 2005 07:10 PM

Quote this comment

alexander Posted…

This was truly brilliant, I looked at niftycorners but its way too much code.. I would never add their 174 lines of code for something as simple as rounded corners, who cares if they support IE 0.3 using 200 workarounds. I want something that works in IE 6, ff, opera and safari, and what you got here seem to do just that! Very nice job!!

14. December 30, 2005 11:43 AM

Quote this comment

sam Posted…

hi, is it possible to put vert.scrollbar in such curved box from top till bottom?

15. February 9, 2006 07:35 PM

Quote this comment

sup Posted…

I find that I often wish to round only the top or only the bottom corners of a div. In addition, I prefer to apply this type of behavior based on an element's class rather than it's id. I modified DomCorners to support these needs. Here's the code I use:

// these vars are used as masks
var _ROUND_UPPER = 1
var _ROUND_LOWER = 2;

// cls: className; used to select the elements to round
// img: imageName; name of the corner image
// mask: 1, 2, or 3 (1 for top only, 2 for bottom only, 3 for all)
// size: size (in pixels) of a single corner in the corner image
function roundCorners(cls,img,mask,size){
    if (mask == null) mask = 3;
    if (size == null) size = 10;
    var els = document.getElementsByClassName(cls);
    for (var i = 0; i < els.length; i++) {
        var el = els[i];
        var c=new Array(4);
        for(var j=0;j<4;j++){
            c[j]=document.createElement("b");
            c[j].style.display="block";
            c[j].style.height=size+"px";
            c[j].style.fontSize="1px";
            c[j].style.border="none";
            c[j].style.padding="0px";
            c[j].style.margin="0px";
            if(j%2==0)
                c[j].style.background="url("+img+") no-repeat 0 -"+ j*size + "px";
            else
                c[j].style.background="url("+img+") no-repeat 100% -"+ j*size + "px";
        }
        if (mask & _ROUND_UPPER) {
            c[0].appendChild(c[1]);
            el.insertBefore(c[0], el.firstChild);
        }
        if (mask & _ROUND_LOWER) {
            c[2].appendChild(c[3]);
            el.appendChild(c[2]);
        }
        el.style.padding="0";
        el.style.border="none";
    }
}

I call it like this:

  // round all four corners of elements whose className is myClass
  roundCorners("myClass", "myCornerImage.gif");

  // round top corners of elements whose className is myOtherClass
  roundCorners("myOtherClass", "myCornerImage.gif", _ROUND_UPPER);

the function document.getElementsByClassName is from Prototye and looks like this:

document.getElementsByClassName = function(className, parentElement) {
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
  return $A(children).inject([], function(elements, child) {
    if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
      elements.push(child);
    return elements;
  });
}

16. April 6, 2006 06:35 AM

Quote this comment

Ericson Laja Posted…

Hello buyers. These is Ericson Laja of ericsonlaja store inc.I have a good news for you.I want you to buy your phones,ipod,mp3 player,laptop at a very cheap price .If you have interest mail me at (ericsonlajastoreinc@yahoo.com)or call us (+2348025623329).The goods price are place bellow thanks for you inquiry. Best regard Ericson Laja mp3 player Mp3 Player Price List iRiver IFP-790T MP3 Player = $80 H10 6GB MP3 Player = $120 Sonic Impact Technologies 512MB MP3 Player w/ Flash Drive & Voice = $85 iriver H10 5GB MP3 Player, Gray = $110 YP-MT6X Yepp 512MB Portable Compact Digital Music MP3 Player = $70 Zen Micro 5 GB MP3 Player - Dark Blue [ Creative Labs = $100 iRiver 5 GB MP3 Player (Silver) = $110 Creative Labs NOMAD Jukebox Zen Xtra 30 GB MP3 Player = $90 Sony MZ-NH600D 1GB MP3 Player Hi-MD Walkman Digital Music Player = $90 Network Walkman NW-HD1 20GB MP3 Player = $150 Cowon iAudio X5 20GB MP3 Player = $110 Digital Audio Players from Motorola: Audio MP3 Players, Digital = $70 Gigabeat Meg-F60S 60GB MP3 Player - Gray = $155 Sony 1GB Personal MP3 Player, Network Walkman = $100 Creative Zen Micro 6GB MP3 Player (red) = $125 laptops SONY VAIO A217S-- 100GB-- 512MB RAM-- XP HOME-------------$300 SONY VAIO B1VP-- 40GB HD-- 512MB RAM-- XP PRO--------------$330 SONY VAIO T370P/L-- 60GB HD-- 512MB RAM-- XP----------------$200 SONY VAIO A215Z 60GB HD-- 512MB RAM-- XP------------------$2450 SONY VAIO A397XP-- 80GB HD-- 512MB RAM-- XP----------------$300 SONY VAIO B100B08 60GB HD-- 512MB RAM-- XP---------------$250 SONY VAIO B100B08 60GB HD-- 512MB RAM-- XP---------------$400 SONY VAIO FS295VP 80GB HD-- 512MB RAM-- XP---------------$350 SONY VAIO FS215Z 100GB HD-- 512MB RAM-- XP---------------$350 SONY VAIO A417M 80GB HD-- 512MB RAM-- XP-----------------$450 SONY VAIO B1VP-- 40GB HD-- 512MB RAM-- XP PRO-------------$200 SONY VAIO T370P/L-- 60GB HD-- 512MB RAM-- XP PRO----------$400 SONY VAIO LAPTOP-- VGN-A117S---------------$400 phones Nokia N91 220$ Nokia 6060 145$ Nokia 6111 132$ Nokia 6270 125$ Nokia 6270 115$ Nokia 6280 125$ Nokia N90 115$ Nokia N70 115$ Nokia Vertu 155$ Nokia 5140i 125$ Nokia 6230i 115$ Nokia 8800 105$ Nokia 6021 105$ Nokia 6030 115$ Nokia 6680 125$ Nokia 6681 120$ Nokia 6101 110$ Nokia 6822 110$ Nokia 7710 110$ Nokia 6170 145$ Nokia 6260 145$ Nokia 3510i 95$ Nokia 6630 120$ Nokia 9300 110$ Nokia 7260 120$ Nokia 7270 110$ Nokia 7280 120$ Nokia 6670 110$ Nokia 6020 120$ Nokia 3220 65$ Nokia N-GAGE QD 75$ Nokia 7610 120$ Nokia 9500 145$ Nokia 5140 85$ Nokia 6610i 120$ Nokia 7200 133$ Nokia 6230 145$ Nokia 6820 120$ Nokia 7600 105$ Nokia 6600 120$ Nokia 6800 105$ Nokia 6220 120$ Nokia 6620 120$ Nokia 7250i 65$ Nokia 8910i 120$ Nokia 6100 95$ SAMSUNG D600 155$ SAMSUNG P860 165$ SAMSUNG P850 sidekick 1 $110 sidekick 2 $100 Sony Ericsson K500i.....130 USD Sony Ericsson P800......200 USD Sony Ericsson P900......260 USD Sony Ericsson P910i.....270 USD Sony Ericsson T230......80 USD Sony Ericsson T310......80 USD Sony Ericsson T610......100 USD Sony Ericsson Z1010.....180 USD Sony Ericsson Z200......90 USD Sony Ericsson Z600......130 USD Sony Ericssson T630.....130 USD Sony Ericsson S700i.....170 USD Sony Ericsson S750i.....170 USD 9806LL/A) MP3 Player = USD$110 Motorola A388C......170 USD Motorola A760.......250 USD Motorola A768.......260 USD Motorola A768i......200 USD Motorola A780.......290 USD Motorola C550.......90 USD Motorola C650.......100 USD Motorola E365.......100 USD Motorola E398.......120 USD Motorola E680.......240 USD Motorola RAZR V3....270 USD Motorola V220.......170 USD Motorola V303.......100 USD Motorola V400.......150 USD Motorola V500.......150 USD Motorola V501.......200 USD Motorola V525.......150 USD Motorola V600 (OEM) w/ Bluetooth Headset..260 USD Motorola V600 OEM...180 USD Motorola V690.....170 USD Motorola V750.....180 USD Motorola V80......200 USD Motorola V80 with Bluetooth...260 USD Motorola V872.....200 USD Motorola V878....180 USD Motorola V300....150 USD Samsung D500...240 USD Samsung E600...140 USD Samsung E800...180 USD Samsung P510...120 USD Samsung SGH-D410.200 USD Samsung SGH-D500..270 USD Samsung SGH-E700..150 USD Samsung SGH-E715..170 USD Samsung SGH-P100..130 USD Samsung SGH-P400..95 USD Samsung SGH-P408..240 USD Samsung SGH-P730..150 USD Samsung SGH-S200..90 USD Samsung SGH-S300..70 USD Samsung SGH-S300M..100 USD Samsung SGH-S500...100 USD Samsung SGH-V200...110 USD Samsung SGH-X400...100 USD Samsung SGH-X430...100 USD Samsung SGH-X600...100 USD Samsung X450.......100 USD ipods Apple iPod from hp 40GB = USD$150 Apple iPod from HP 20GB = USD$120 Apple iPod U2 Special Edition 20GB = USD$130 HP Apple iPod / 40GB / Click Wheel / MP3 Player = USD$170 Apple iPod MP3 Player, 20gb = USD$115 Apple iPod Shuffle1GB MP3 Player = USD$85 Apple iPod for Windows - Digital player - 10GB Hard Drive = USD$130 Apple iPod 40GB 3rd Gen M9245LL/A A1040 = USD$140 Hewlett Packard Apple iPod from HP 20GB With Click Wheel = USD$95 Apple Ipod 20GB 4th Generation = USD$130 APPLE iPod mini Player 4G Light Blue Model M9802ZP/A = USD$93 Kingston Apple iPod from hp 40GB with Click Wheel = USD$140 iPod Mini 6GB = USD$145 iPod 60GB = USD$170 iPod Mini 4GB = USD$105 Apple iPod shuffle (512 MB - M9724LL/A) MP3 Player = USD$80 Apple iPod mini Green Second Gen. (4 GB - M9806LL/A) MP3 Player = USD$110 (ericsonlajastoreinc@yahoo.com)(+2348025623329)