Adding Drop Shadow to Images And Textbox Using CSS and Tables

Examples are tested on Firefox 2.0.01 and Internet Explorer 7 on Windows XP

Here's an example of an image without a shadow:

Here's what we want to accomplish:

Or this:

This is a table containing textbox.
And shadow.

We want to add the shadow without specifying the dimensions of the box or the dimensions of the image. I know it's considered a good practice to always specify the dimensions of an image, but let's suppose that I'm tired of having to specify the dimensions - and most users now have connection fast enough that the benefit of specifying the dimensions outweigh the nuisances.

A solution using CSS and <table> is to divide the table like below:



IMAGE/CONTENT CELL

 
topRight
right
bottomLeft bottom bottomRight

There are two kind of shadow cells: one for the horizontal shadow and one for the vertical shadow. We can't use the same one beacuse for the bottom cell, we need to specify the height, and for the right cell, we need to specify the width.  For the bottomRight cell, we can use either one.

So at the minimun, we need to have four styles. You can always hardcode the styles into the table, but for re-usability, "minimum" here takes into consideration the abilty to use the styles in more than one tables.

table.shadowTable
{
  border:none;
  border-width:0px;
  border-spacing:0px;
  border-collapse:collapse;
  background: transparent;
  table-layout:auto;
  padding:0;
}

.cellPadding
{
  border:none;
  padding=0;
  background-color: transparent;
  height:5px;
  width:5px;
}

.cellHorizontal
{
  border:none;
  padding=0;
  background-color: gray;
  height:5px
}

.simepleVertical
{
  border:none;
  padding=0;
  background-color: gray;
  width:5px
}

You can see the css file here: dropShadow.css. Note that 5px is the thickness of the shadow and gray is the color of the shadow. You can use any value you want.

In our first attempt, here's the <table> that uses the above style:

<table class="shadowTable" cellpadding=0>
<tr>
  <td rowspan=2 colspan=2><img src="image.jpg"></td>
  <td class="shadowPaddingCell">
</tr>
<tr>
  <td class="shadowVerticalCell"></tr>

<!-- BOTTOM ROW-->
<tr>
  <td class="shadowPaddingCell"></td>
  <td class="shadowCellHorizontalCell"></td>
  <td class="shadowCellHorizontalCell"></td>
</tr>
<-- END OF BOTTOM ROW-->
</table>

Notice that I added cellpadding=0 in the <table> definition. This is because without it, the table with have an extra pixel around every cell even though padding:0 is already specified in the stylesheet.

The resulting table looks like this:

Screenshots: (current browsers might have different or better behavior):

There are obvious problems due to the fact that that: a) the width of bottom cell is unknown; and b) the height of right cell is unknown. 

Adding width: 100% or height:100% to the style definition did not solve the problem.  The only way to make it work is to hard code the width onto the bottom cell and hard-code the height on the right cell. This is not an acceptable solution to me. After trying various workaround, the only thing I discovered is that it is possible to solve the bottom cell problem by using a nested <table>. However, the table must have a style associated with it:

<!-- BOTTOM ROW-->
<tr>
  <td>
    <table width=100% class="shadowTable">
      <tr>
        <td class="shadowPaddingCell"></td>
        <td class="shadowHorizontalCell"></td>
      </tr>
     </table>
  </td>
  <td class="shadowHorizontalCell"></td>
</tr>

Result:

Screenshots:

As far I can find, the only way to solve this problem other than to hard-code the actual height, so I gave up this approach and went to another direction.

The good news is that there is a very simple solution to this problem by not even useing the surrounding cells to render the shadows. Instead, simply offset the image.  This is a perfectly clean approach and the only possible drawback is something on the top left area of the image might become covered by the image. 

All we need to do is to add a <img> style to offset the image as well as a table.  Note that -5 is the offset amount.  You can change it to any value you want.  Positive numbers moves the position to the right or down. 

.imageOffsetted
{
  position:relative;
  left: -5px;
  top: -5px;
}

The <table> code using the styles we defined above is just like this. 

<table cellpadding=0 class="simpleShadowTable">
  <tr><td><img class="imageOffsetted" src="image.jpg"></td></tr>
</table>

 

It's surprisingly simple and even there's still no need to hard-code the image dimensions. Textbox with shadow can also be done this way although there are better ways to handle text than using tables (for example, by using <div>). 

<table cellpadding=0 class="simpleShadowTable">
  <tr><td><div class="imageOfSimpleShadowTable">This is a table             containing textbox.<br>And shadow.</div>
  </td></tr>
</table>

The result:

This is a table containing textbox.
And shadow.

To make the box a separate background color and to add border and padding, create a separate style for text:

.textOfSimpleShadowTable
{
  border:1px dotted black;
  position:relative;
  left: -3px;
  top: -3px;
  padding: 10px;
  background: white;
  width:auto;
}

With the new style definition, the code :

<table cellpadding=0 class="simpleShadowTable">
  <tr><td><div class="textOfSimpleShadowTable">This is a table              containing textbox.<br>And shadow.</div>
  </td></tr>
</table>

produces this result:

This is a table containing textbox.
And shadow.

Download the stylesheet: dropShadow.css

So why were we talking about the other methods above?  I want to share the approach and I don't like the look of this shadow. The sharp edges and the boxy look of the shadow are ugly (especially on images).  And because there's a solution that builds from the initial approach as described in the following tutorial.