Home | Ruby |     Share This Page
Round Table Corners using Graphics
All content Copyright © 2006, P. Lutus

Introduction | The Basic Idea | The Ruby Script | Usage Notes

Introduction
Irony wakeup call: Since writing this method that creates round corners on tables using graphics, I have written what I regard as a much better method, using pure CSS, no graphics, no tables, no JavaScript. I recommend the new method (described here), and this page remains only for historical purposes. By the way, the colored tables on this page represent the old method, but they are wrapped in a container using the new method.

You can make round table corners in an HTML page using a variety of methods, but each method has drawbacks:

  • A pure-CSS (Cascading Style Sheet) method, or some combination of CSS and JavaScript like Nifty Corners, eliminates the need for any graphic images, but in exchange, these methods are quite complicated and don't work with all browsers.
  • Using little graphic images at each table corner is the simplest and most compatible method, but you first have to create those little graphic images, with the desired radius and color, for each different table style.
I personally think the second approach is better, because it doesn't need to know what browser your visitor is using. It also adheres to the time-honored KISS (Keep It Simple, Stupid) principle. So I decided to write a Ruby script that generates the little corner graphic images.

This method works best in Linux, where there is a rich environment of utilities to help you develop Web content, but it can also be made to work in Windows, with some extra effort to overcome the deep hostility to personal creativity that is built into that operating system.

This method needs a Ruby interpreter, also it needs the ImageMagick graphic tool library. Both of these are available on a typical Linux installation by default. For Windows, you will most likely have to download and install both of them.

NOTE: This technique is only necessary because HTML and CSS are still in a fairly primitive state. A round-cornered table feature is expected to be included in a future CSS version.

The Basic Idea
This method uses a special HTML table format, fairly easy to understand, that has reserved locations for four graphic images to represent the corners:


<table cellpadding=0 cellspacing=0 border=0>
	<tr>
		<td>Graphic</td>
		<td bgcolor="#ffffff"></td>
		<td>Graphic</td>
	</tr>
	<tr>
		<td bgcolor="#ffffff"></td>
		<td bgcolor="#ffffff">Content</td>
		<td bgcolor="#ffffff"></td>
	</tr>
	<tr>
		<td>Graphic</td>
		<td bgcolor="#ffffff"></td>
		<td>Graphic</td>
	</tr>
              </table>
NOTE: The reason the desired background color must be specified in several "<td>" tags rather than once in the "<table>" tag is because my Ruby script (see below) creates transparent GIF graphic images, which have the advantage that the table will render correctly regardless of the page's overall color.

The above HTML produces this basic layout:

GraphicGraphic
Content
GraphicGraphic
When the four corner slots marked "Graphic" are filled with appropriate graphic image tags, you get this:

Content
Important Layout Note: To avoid an imperfect layout on some browsers, when you want to specify an explicit width for one of these rounded-corner tables, don't put the "width" specifier in the "<table>" tag, put it in the first placeholder "<td>" tag instead:

Wrong:

<table cellpadding=0 cellspacing=0 border=0 width="100%">
              
Right:


<td>Graphic</td>
<td bgcolor="#ffffff" width="100%"></td>
<td>Graphic</td>
              
 
The Ruby Script
Here is my Ruby script that creates the corner graphics:


#!/usr/bin/ruby -w

# build four graphic images for rounded table corners

if(ARGV.length < 2)
   puts "usage: radius bgColor [basename]"
   exit 0
end

# the default transparent color

$transColor = "#000000"

def createConvert(prefix,data,name)
   # build an XPM graphic file's contents
   xpm = prefix + data.join(",\n") + "\n};\n"
   # pipe result to "convert", part of ImageMagick
   com = "convert - -transparent #{$transColor} #{name + '.gif'}"
   File.popen(com,"w") { |p| p.print xpm }
end

# read options, set up

(radiusStr,bgColorStr,baseName) = ARGV

baseName = "roundCorner" if !baseName

radius = radiusStr.to_i

right = Array.new
left = Array.new

# Generate quarter-circle graphic image

0.upto(radius-1) { |y|
   row = "\""
   0.upto(radius-1) { |x|
      qx = x.to_f / radius
      qy = Math.sqrt(1.0-(qx*qx)) * radius
      row += (qy > y)?".":" ";
   }
   row += "\""
   right.push(row)
   left.push(row.reverse)
}

# Create XPM graphic file content

header = "/* XPM */\nstatic const char *grfixname[] = " +
"{\n/* columns rows colors chars-per-pixel */\n"

prefix = header + "\"#{radius} #{radius} 2 1\",\n"
# define XPM bg color
prefix += "\"  c #{$transColor}\",\n"
# define XPM fg color
prefix += "\". c ##{bgColorStr}\",\n"
prefix += "/* pixels */\n"

# create the four graphic images

createConvert(prefix,left.reverse,baseName + "TL")
createConvert(prefix,left,baseName + "BL")
createConvert(prefix,right.reverse,baseName + "TR")
createConvert(prefix,right,baseName + "BR")
              

You can simply copy the script from your display, or click here to download it as a file.

 
Usage Notes
Copy the script and put it anywhere that will give you easy access to it, example /usr/local/bin. Give it a memorable name like "tablecorners.rb". Give it executable permissions.

To use the script, move to the directory where the graphics are to be be stored and type something like this:

$ tablecorners.rb 16 ffffcc yellow
            
(Don't type the '$', that's just a reminder that we're in a shell session)

The three script arguments are:

  • The corner radius, an integer.
  • The graphic color, expressed in hexadecimal.
  • An optional base name for the graphic files.

Those familiar with HTML page development will have no problem acquiring an appropriate hexadecimal color number for the graphics. If you plan on making a number of tables with different colors, enter a base name as shown to avoid losing track of which file sets are for which table color.

On being invoked using the example arguments, the script will produce four files:

  • yellowBL.gif
  • yellowBR.gif
  • yellowTL.gif
  • yellowTR.gif

The uppercase letters refer to the quadrant the graphic is intended for — "TL" means "Top Left", etc..

Each file contains a quarter-circle rendered in the specified color, with the specified radius. The area outside the quarter-circle is set to a transparent color so you can change the peripheral color (that of the table's container) without having to regenerate the corner graphics.

Potential Problems

  1. Make sure you have the required support elements: a recent Ruby interpreter and the ImageMagick utilities.

  2. If you are running Windows, you may have to edit the script to make it work in that environment. Specifying the location of the Ruby interpreter in the script's first line, and specifying the location of the ImageMagick "convert" utility might pose problems. I would be more specific, but that would require me to run Windows.

  3. If you experience difficulty getting your tables to render exactly right, please re-read the details on this page. You might also want to look at this page's source for additional hints.

  4. Someone, somewhere, will want to use black as the table background color, but this is the default transparent color. To get around this problem, edit the script — change the value assigned to "$transColor" to some unused color value.

 

Home | Ruby |     Share This Page