Supported CSS3 Features

The following sections describe in detail the exact levels of support PIE has for certain CSS3 properties.

border-radius

PIE fully supports the border-radius property as defined in the CSS3 Backgrounds and Borders module specification.

border-radius: [ <length> | <percentage> ]{1,4} [ / [ <length> | <percentage> ]{1,4} ]?

Only the shorthand version is supported; the longhand border-top-left-radius etc. properties are not. The shorthand syntax does support different radii per corner, though:

border-radius: 5px 10px 15px 20px; (top-left, top-right, bottom-right, bottom-left).

The rounded corners are applied to the element's background area (including solid background colors, background images, and background gradients), the element's border, and the box-shadow if specified.

Both the standard border-radius property name as well as a custom prefixed -pie-border-radius property name are recognized; if both are present then the prefixed value will take precedence. It is recommended to only use the standard unprefixed property when possible (in addition, of course, to -moz- and -webkit- prefixed properties as necessary), since the CSS3 spec for this property seems fairly solidified, and because there are no known incompatibilities between PIE's implementation and the standard.

Notes on other browsers:

Elliptical radii (the optional set of values after the slash) are only supported in Firefox versions 3.5 and up. As of the current release (3.6), percentage values for vertical radii are incorrectly calculated relative to the width of the box whereas the CSS3 spec says they should be relative to the height. PIE handles this correctly.

WebKit deviates significantly from the CSS3 spec: the shorthand property cannot be used to specify different radii per corner, so you must use the separate longhand properties if you want to do that. It also does not support percentage values at all. (TODO: check this in WebKit nightlies and recent Chrome, I think these may now match the spec and drop the prefix.)

box-shadow

PIE supports the box-shadow property syntax as of its last appearance in the CSS3 Backgrounds and Borders module. It was removed from the spec due to, as far as I can tell, some questions around how it should behave in conjunction with semi-transparent background images. The plan seems to be to add it back in at some point in another (perhaps new) CSS3 module, but I have not yet seen that happen. Regardless, this is an extremely useful property which has widespread support (via prefixed properties) in other browsers, so PIE includes support as best it can.

box-shadow: none | <shadow> [,<shadow>]*
    where <shadow> = inset? && [ <offset-x> <offset-y> <blur-radius>? <spread-radius>? && <color>? ]

Both the (ex-)standard box-shadow property name as well as a custom prefixed -pie-box-shadow property name are recognized; if both are present the prefixed value will take precedence. It is recommended to use the non-prefixed property when possible, since there are no known incompatibilities between PIE's implementation and others which use the non-prefixed property, such as Opera.

When used in conjunction with border-radius, the shape of the shadow matches the shape of the rounded border box.

When using the blur radius parameter, the strength and size of the blur as rendered by PIE should match that of other browsers almost identically, however you may notice some slight differences due to rounding, particularly when the blur is very small (this should not be more than a one-pixel difference).

PIE does not currently support the 'inset' keyword, but support is planned in a future version (see issue #3.

Notes on other browsers:

See the compatibility chart at the bottom of https://developer.mozilla.org/En/CSS/-moz-box-shadow

border-image

PIE has preliminary support for the border-image property. This property allows you to specify an image which gets divided into nine squares which are then drawn as the corners, sides, and center of the target element. The sides and center will stretch to match the size of the element.

TODO syntax, caveats, browser compatibility notes

-pie-background

PIE supports CSS3 multiple background images, linear gradients as background images, and some of the new CSS3 background aspects such as background origin and clip. Unfortunately, to get access to these post-CSS2 values, we have to put them in a property other than the standard 'background' property, because IE will attempt to parse the value internally and not allow us access to the original value string. Therefore we use a custom -pie-background property for holding these values.

Only the single -pie-background shorthand value is recognized; there are no supported corresponding longhand values (e.g. -pie-background-origin).

For backward-compatibility with browsers which do not support CSS3 backgrounds, be sure to include appropriate fallbacks. For example:

#myElement {
    background: url(bg-image.png) no-repeat #CCC; /*non-CSS3 browsers will use this*/
    background: url(bg-image.png) no-repeat, -moz-linear-gradient(90deg, #CCC, #EEE); /*gecko*/
    background: url(bg-image.png) no-repeat, -webkit-gradient(linear, left bottom, left top, from(#CCC) to(#EEE)); /*webkit*/
    -pie-background: url(bg-image.png) no-repeat, linear-gradient(90deg, #CCC, #EEE); /*PIE*/
}

While the PIE parser will allow them, the following aspects of the background shorthand will currently be ignored when rendering:

  • background-attachment (will always use 'scroll' even if 'fixed' or 'local' are specified)
  • background-size (will always use the image's intrinsic size)
  • background-repeat values of 'space' or 'round' (the other repeat values are supported)
  • background-position values with more than 2 parts

Support for these items will be added in future versions as possible.

PNG background images specified using -pie-background will be rendered with correct alpha transparency in IE6. (This will also be the case when using just the normal background-image property in conjunction with any other property which invokes PIE re-rendering of the background, e.g. border-radius or border-image.)

Notes on other browsers:

Firefox supports multiple backgrounds as of version 3.6. Safari supports them as of version 1.3. See https://developer.mozilla.org/en/CSS/Multiple_backgrounds

-pie-watch-ancestors

PIE automatically listens for any attribute or style property changes on the element to which the behavior is applied. This means that if you have scripting which modifies any of the recognized CSS3 properties on the fly, those changes will automatically be picked up and the rendering will be updated to match. For example:

/* JS: */
myElement.onclick = function() {
    this.style.borderRadius = '20px';
};

/* CSS: */
#myElement {
    behavior: url(PIE.htc);
    border-radius: 10px;
}

Assuming myElement has the PIE.htc behavior attached to it, the above code will work as expected without any extra effort from the author of the script or CSS. This seamlessness is a big part of why PIE is so easy to use.

But common best-practices in scripting dictate that instead of setting styles directly with element.style.foo, scripts should only add/remove elements' class names, letting the actual styles corresponding to those class names be maintained in the CSS. So reworking the above example:

/* JS: */
myElement.onclick = function() {
    this.className += ' poked';
}

/* CSS: */
#myElement {
    behavior: url(PIE.htc);
    border-radius: 10px;
}
#myElement.poked {
    border-radius: 20px;
}

Again, since the className is being changed on the element to which the behavior is applied, PIE will automatically be notified of the change and update the border-radius rendering to match the new value.

However, what if the className is changed not on the element itself but on one of its ancestors?

/* JS: */
myElement.onclick = function() {
    this.parentNode.className += ' poked';
}

/* CSS: */
#myElement {
    behavior: url(PIE.htc);
    border-radius: 10px;
}
.poked #myElement {
    border-radius: 20px;
}

This is a very common pattern which allows a lot of flexibility. However, in this case, PIE will not be automatically notified of the className change. To be notified, it will also have to add a listener to the ancestor element. We could brute-force this by automatically adding propertychange listeners to all the ancestors of every PIE-targeted element, but that would be bad for performance and memory usage. So instead, we have introduced a custom CSS property which allows authors to tell PIE that certain ancestors should be watched:

/* JS: */
myElement.onclick = function() {
    this.parentNode.className += ' poked';
}

/* CSS: */
#myElement {
    behavior: url(PIE.htc);
    border-radius: 10px;
    -pie-watch-ancestors: 1;
}
.poked #myElement {
    border-radius: 20px;
}

This tells PIE that it should watch for changes on ancestors one level up from the element. It will attach the propertychange listener to the element's parent and therefore be notified when the parent's className gets changed, and update the rendering correctly.

rgba color values

PIE parses RGBA color values wherever they are allowed. However it is only able to successfully render their opacity value in a few contexts. In all other contexts they will be rendered with the correct RGB color, but fully opaque. Here are the supported contexts in which the opacity will be rendered correctly:

  • The solid background-color as specified in the -pie-background property.
  • The color value of box-shadow, if the shadow has no blur.

gradients

PIE currently supports linear-gradient image values when used in the -pie-background property. Use in any contexts other than the background are not supported. The supported syntax matches that of the current CSS3 Image Values module.

linear-gradient([<bg-position> || <angle>,]? <color-stop>, <color-stop>[, <color-stop>]*);

Currently all color stops are rendered fully opaque, even if specifying an rgba color value. This is due to a limitation in VML's linear gradient syntax which does not allow setting opacity for individual color stops. (See issue #7)

Gradients containing color-stops which lie outside the bounding area of the element are not currently supported, due to limitations in VML's gradient rendering.

Radial gradients are not supported at this time; this feature is planned for a future release (see issue #2) but it may turn out to be impossible to implement due to VML's strange radial gradient behvior.

Notes on other browsers:

WebKit's gradient syntax is drastically different than that of the CSS3 spec. See the Safari documentation for their syntax

Mozilla only supports gradients (via the -moz-linear-gradient property) as of Firefox 3.6.

Opera currently has no support for CSS gradients.