~~ CornerZap ~~
This script is another implementation of the ideas first presented by Alessandro Fulciniti with his Nifty Corners, version one and two. The basic idea is to generate round corners in HTML pages without the need of images; only JavaScript and CSS (and a fairly recent browser) are required. The original scripts are already quite useful, but this one is completely rewritten and has several advantages:
- Arbitrary radius for each corner
- Automatic detection of foreground and background colors, and transparency
- Support for DIVs with fixed height
- Border of arbitrary width
- Debugging info to detect insufficient padding
- padding can be used freely within elements
- Specification of rounding looks very much like a CSS declaration
- Better documented code
- Cross browser compatibility (works on Firefox 1.5, Mozilla 1.7.12, Safari 2.0.3, Konqueror 3.5.1, Opera 8, IE 6, IE 5.5)
See a Demonstration (besides this page of course). This script has about 19 kB of code (compressed about 10 kB) and is therefore considerably larger than Alessandro's code.
Usage is as follows:
- Add the cornerzap.css and cornerzap.js to the HTML header.
- Arrange for CZapper() to be called at page load time.
Example:
<head>
<style type="text/css">
@import "cornerzap.css";
h1 { background-color: #cde; text-align:center; padding:3px 0; }
</style>
<script type="text/javascript" src="cornerzap.js"></script>
<script type="text/javascript">
window.onload = function() {
CZapper("h1 {}"); CZapDebug();
}
</script>
</head>
<body>
<h1> Hello, World! </h1>
</body>
</html>
The elements receiving rounded borders should have a top and bottom padding that is at least as large as the space needed by CornerZap; otherwise, the size of the element would grow, and the resulting layout would be changed. CZapDebug() shows warning messages about such cases. See the result. Note that the size of the H1 tag increases slightly after rounding the corners, and the ensuing warning message. By increasing the padding (in the CSS declarations) of H1 by at least the suggested amount, this problem goes away.
These are the externally useable functions:
- CZapper(string): it accepts a CSS-like string and can therefore add various kinds of corners to various elements.
- CZapDebug(): Shows warning messages, call this after all calls to CZap/CZapper. You can remove this call after your layout is perfect.
The string argument to CZapper looks like a CSS declaration, e.g.
The selectors work like in CSS, e.g. tag, tag#id, #id, tag.class, .class, #id .class etc, while the declaration can use any of the keywords listed here:
- tl, tr, bl, br
- Apply to the given corner(s): top left, top right, bottom left, bottom right. Each one can be followed by a radius (in pixels), like this: CZap("h1", "tl:5; br:9");. You can not specify the radius in other units than pixels.
- top, bottom, left, right
- Shorthand notation for two corners at a time, e.g. top is the same as tl and tr combined. These parameters can also be followed by a radius.
- all
- Apply to all corners. This is the default. Can be followed by a radius.
- border
- Add a border; you can optionally specify a width (default is 1) and a color (default is #777), like this: CZap("div.mytag", "border:1 #f00;");
- smooth
- Add an anti-aliasing effect to the borders. This cannot be used when the foreground is transparent. It can be combined with border:n, though, which has the effect of automatically calculating a border color.
- fg, bg, fgtop, fgbottom
- Explicitely specify the foreground color (fg, this is the "inside") and the background color (bg, the "outside"). As a special case, fg can be transparent (usually automatically detected). In this case, the tag has a background image that should extend into the rounded area. This cannot be used with smooth for technical reasons. As a temporary workaround, the foreground color can be specified differently for top and bottom. This should soon be integrated into the top and bottom keywords.
- width, height
- Informs CZapper that the element has a fixed width and/or height. This will result in more accurate sizing of the element and correct positioning of the lower corners.
Default values
- Corner radius: 5 pixels
- All four corners are rounded
- No border
- No anti-aliasing
- Foreground: the foreground of the element
- Background: that of the enclosing element
Hints, Limitations
While developing and testing this script, I have noted various caveats. To spare you falling into these traps too, I describe them here.
- All values for the radius look nice, with the possible exception of 4.
- When using Konqueror, transparent background is reported as black (#000000), which is therefore treated as transparent. So avoid using completely black background, but use something like #000001 instead.
- Note that each element that is rounded is modified like this: all child nodes are removed, a <span> element is added, and the child nodes are put back into that span. Then, one B element is added before and after the SPAN to achieve the rounding effect. This may mess up your CSS formatting, especially CSS2 selectors containing ">" and the like.
- You can't place anything in the vertical space that is created by adding the corners, unless you use some absolute positioned elements. This wasted area increases as the radius increases.
- The vertical space needed is whatever is largest: left radius, right radius, border width. Top and bottom sides can have different heights of course.
- If you add margin-bottom:1px; or the like to the CSS entry .czap *, then you can see how the rounded corners are composed of individual one pixel high lines.
- A note on padding: you can apply CSS padding to the containing element as usual, and in fact you should. The number of pixels used by the rounded border will be subtracted from the padding. This means that if this padding is as large or larger than the space needed for the rounded corner, then the total size of the layout will not change regardless whether JavaScript is available or not.
- If you want a different foreground color for the top and bottom
corners, use fgtop and/or fgbottom like this:
#content { top:15; bottom:25; fgtop:#c3d9ff; border:2; }
Hints for IE
IE has certain, uh, "features", which makes it difficult to develop for. If you can use Firefox or other Gecko based browsers, but alas, many uninitiated folk are (still) using IE...
- When you find that clear:both has no, or an unsatisfactory
effect (which usually is to make elements following floating elements appear
below them, and not besides them), try this:
<br style="clear:both" />That's right, write the same line twice.
<br style="clear:both" /> - Do not use the <pre> tag, unless you want to have your rendering fubar. The same goes for the CSS attribute white-space:pre.
- When the width sinks below a certain minimum, the display of the borders is messed up. Unfortunately a proper min-width is difficult with IE (see this article).
- When using a border on a nested div you may have to insert a between the two closing div tags to avoid a break in the border.
- These bugs are not affected by using strict HTML or XHTML, but I guess you should use that anyway.