In qooxdoo 0.8 we will introduce the concept of widget decorators. This has already been described in an earlier blog article. Decorators allow a widget's background to be styled independent of the widget's content. To demonstrate the flexibility of the decorator concept I have written a decorator, which uses native CSS rounded borders in Firefox and Safari/Webkit and emulates the same behavior in Internet Explorer. The screenshot shows the same qooxdoo 0.8 application in Internet Explorer 7, Firefox 3 Beta 3, WebKit r30082 and Firefox 2.0.11.

Rounded borders screen shot

The widget shown in the screen shots is generated by the following snippet of qooxdoo code:

 
doc = new qx.ui.root.Application(document);
 
var border = new qx.ui.decoration.RoundedBorder().set({
  radius: [10, 20, 30, 40],
  width: [3, 10, 20, 5],
  color: ["red", "green", "yellow", "blue"],
  backgroundColor: "gray"
});
 
doc.add(new qx.ui.basic.Label().set({
  html: qx.bom.client.Engine.NAME,
  decorator : border,
  width: 140,
  height: 100,
  padding: 20
}), 10, 10);

I think the most interesting question is about the IE implementation. Since IE has no native CSS rounded border support, the borders must be rendered using a different technique. A common approach is to render the borders using pixel-sized DIV elements like e.g. RUZEE.Borders does. We have used a different and in my opinion much more powerful approach.

We use VML to render the background including the border. The VML code is dynamically created and inserted into the decoration DIV using plain innerHTML. Since the decorator is informed about size changes by the qooxdoo layout engine, it can update its borders accordingly. The rendering quality is amazing and looks pretty much like the best native browser implementation of Firefox 3. This is the code automatically generated and applied by qooxdoo:

 
<style>v\: * { behavior:url(#default#VML);display:inline-block }</style>
 
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<div style="left: 10px; width: 140px; position: absolute; top: 10px; height: 100px">
<div style="z-index: 10; left: 25px; width: 85px; position: relative; top: 23px; height: 37px" usehtml="true">mshtml</div>
<div style="z-index: 5; left: 0px; position: absolute; top: 0px">
    <v:group style="left: 0px; width: 140px; position: absolute; top: 0px; height: 100px; antialias: true" coordsize = "140,100">
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "gray" path = " m10,1 ns l120,1 qx139,20 l139,70 qy110,99 l40,99 qx1,60 l1,10 qy10,1 x e"></v:shape>
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "red" path = " m10,3 ns at5,3,15,13,10,3,5,3 wa0,0,20,20,0,0,10,0 wa100,0,140,40,120,0,140,0 at110,3,130,23,130,3,120,3 x e"></v:shape>
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "green" path = " m130,13 ns at110,3,130,23,130,13,130,3 wa100,0,140,40,140,0,140,20 wa80,40,140,100,140,70,140,100 at110,60,130,80,130,80,130,70 x e"></v:shape>
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "yellow" path = " m120,80 ns at110,60,130,80,120,80,130,80 wa80,40,140,100,140,100,110,100 wa0,20,80,100,40,100,0,100 at5,40,45,80,5,80,25,80 x e"></v:shape>
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "blue" path = " m5,60 ns at5,40,45,80,5,60,5,80 wa0,20,80,100,0,100,0,60 wa0,0,20,20,0,10,0,0 at5,3,15,13,5,3,5,8 x e"></v:shape>
    </v:group>
  </div>
</div>
 

Generated HTML for Internet Explorer

The first two lines are required to enable VML support and are only added once into a page. Note that only one of the DIV elements contains VML code. The rest is typical HTML code generated by the qooxdoo GUI toolkit, which does all the layouting itself, just using JavaScript. It consists of a couple of nested, absolutely positioned DIV elements with the appropriate CSS styles applied.

The code for Firefox is much simpler and just sets the browser-specific CSS styles:

 
<div style="position: absolute; z-index: 0; left: 10px; top: 10px; width: 140px; height: 100px;">
<div style="position: relative; z-index: 10; left: 25px; top: 23px; width: 85px; height: 37px;">gecko</div>
<div style="border-style: solid; border-color: red green yellow blue; border-width: 3px 10px 20px 5px; z-index: 5; position: absolute; left: 0pt; top: 0pt; -moz-box-sizing: border-box; width: 100%; height: 100%; background-color: gray; -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 20px; -moz-border-radius-bottomright: 30px; -moz-border-radius-bottomleft: 40px;"></div>
</div>
 

Generated HTML for Firefox

Native browser support

The quality of rounded border implementations differ a lot between browsers. The CSS3 draft defines the property border-radius and a property for each corner like border-top-left-radius. These properties take two values, one for the horizontal radius and one for the vertical radius. That way it is possible to define (quarter-)elliptical borders. If only a single value is given, the border is (quarter-)circular.

Current browser implementations

  • Firefox 2: Firefox supports only circular borders. Border definitions always take a single parameter - the radius. The CSS property is called -moz-border-radius and -moz-border-radius-topleft, respectively. -moz-border-radius supports the CSS shorthand mode. If only one parameter is given, the radius of all four border is identical. If four parameters are defined, the radius for all four corners is set individually. The rendering quality is very poor since Firefox 2 does not use anti-aliasing to render the border (cf. screen shot).
  • Firefox 3: The same as Firefox 2 but borders are rendered using anti-aliasing, which looks much better (thanks to the Cairo 2D graphics library).
  • Safari/WebKit: The CSS property names differ from the W3C spec (-webkit-border-radius and -webkit-border-top-left-radius). Besides that, WebKit implements pretty much the CSS3 standard. Rendering looks fine as long as all border widths are equal. If they differ, the rendering looks quite ugly (cf. screen shot). This has already been reported in the WebKit Bugzilla and hopefully is going to be fixed soon.
  • Opera: Opera also does not support CSS rounded borders but there is a description online on how to emulate them using SVG backgrounds.
  • Internet Explorer: No native support either. I suppose the VML approach presented here works only well in the controlled environment of the qooxdoo widget toolkit, but I may be proved wrong.