Ricardo Amaral Ricardo Amaral - 2 months ago 13
HTML Question

How to create a table inner bevel in HTML/CSS?

I'm designing this forum layout where I come up with a nice design to draw the forum tables, however, I'm not sure that this can be easily done in HTML/CSS.

Before I continue to draw the whole layout, I need to know if this is achievable and how, otherwise, I'll have to ditch this effect and rethink things...

For instance, the design I currently have is this one:

Sample Table

The rows on this example have all the same height but this is just an example. The real table will actually have different row heights and the code needs to take that into account...

How can this be done?

Answer

CSS can do something like that very easily, provided you don't have to scale the gradient vertically as the table size increases. Below is an example you could use that would give you the effect you depicted above.

UPDATE: I somehow didn't see the bevels (I guess I have to blame it being too late at night and my vision being too blurry). I had to zoom in to really see them, but I've updated my solution to fit. You need to add an extra "div" tag to make this solution work, but it is possible, although I don't think it works too the extent that your image shows. It will work fairly decently though. Down below I include some jQuery script that will remove the need for an extra <div /> tag.

For markup, you'd use something like this:

<table cellspacing="0">
    <tr><td class="side"><div class="bevel">lorem</div></td><td class="side"><div class="bevel">ipsum</div></td><td class="main"><div class="bevel">dolor sit amet, consectetur</div></td></tr>
    <tr><td class="side"><div class="bevel">lorem</div></td><td class="side"><div class="bevel">ipsum</div></td><td class="main"><div class="bevel">dolor sit amet, consectetur</div></td></tr>
    <tr><td class="side"><div class="bevel">lorem</div></td><td class="side"><div class="bevel">ipsum</div></td><td class="main"><div class="bevel">dolor sit amet, consectetur</div></td></tr>
</table>

And in your stylesheet you'd use something like this:

td {
    border: 1px solid #777;
}

.bevel {
    background: url('img.png') top left repeat-x;
    margin: -1px;
    border-top: 1px solid #fbfbfb;
    border-left: 1px solid #fbfbfb;
    border-right: 1px solid #bfbfbf;
    border-bottom: 1px solid #e8e8e8;
}

.side {
    width: 30px;
}

.main {
    width: 170px;
}

table {
    border-collapse: collapse;
    border-spacing: 0;
}

For the image, make it 1px wide. It will repeat itself to fit the width of the cell. If you want the gradient to stretch vertically, you're out of luck. CSS can not scale images, only repeat them. In order to make a vertically scaled background image, you'd need to either have nightmarish markup, or some sort of JavaScript to make it work.

To get rid of the <div /> tag soup, you can use jQuery to insert the tags so you don't clutter up your source. All you need to do is add an 'outerBevel' class to the <td /> tags instead, then call this jQuery script (if you're using jQuery. I'm sure other JavaScript APIs can do similar things):

$('.outerBevel').wrapInner('<div class="bevel"></div>');