It seems like some design bureaus are just hellbent on making it difficult for developers to realise their designs via html/css. I am currently trying to convert some design images into usable html/css, and in one case I had to make a box with rounded corners, all borders had a shaded shadow, the inner content had a gradient background and the box was required to handle dynamic width. The only thing that makes this tricky is that the borders and corners needs a shaded shadow and the fact that the box is required to support dynamic width.

After some experimentation I ended up with this html:

<div class="shadebox-wrapper">
  <div class="shadebox-wrapper2">
    <div class="shadebox-wrapper3">
      <div class="shadebox">                        
        <div class="shadebox-header">
          <b class="shadebox-tlc"></b>
          <b class="shadebox-trc"></b>        
        <div class="shadebox-inner">
          Lorem uipsad asd asd asd as
          asdassdasd asd asd
          dasdaasd  asd asd
          asdasdsd dsd 
        <div class="shadebox-footer">
          <b class="shadebox-blc"></b>
          <b class="shadebox-brc"></b>    

As you can see there is a lot of noise html that is only there to have elements to use in the css. For example the div wrappers are for the gradient background and the left, right and top borders. The corners are handled by absolute positioned "b" elements (absolute relative to the container). Although a lot of html I was actually quite pleased I managed to get it done in a short time and that it looked good in Firefox and IE7. Here is how it looked:


The shaded border shadow is quite subtle and can be hard to see on some monitors. Initially I wanted to use a JQuery Corner plugin because it gets you so much cleaner html but there is no one (that I know of) that supports the kind of shadows I needed. However it is very easy to manipulate html with jquery so I though I would give it a try and see how I could dynamically insert all the div wrappers and other needed elements.

This is the html I was aiming for:

<div class="shadebox">

  <div class="shadebox-inner">
    Lorem uipsad asd asd asd as
    asdassdasd asd asd
    dasdaasd  asd asd
    asdasdsd dsd 

And this is the javascript code that makes it possible:

<script type="text/javascript">
  $(document).ready(function() {
      "<div class='shadebox-wrapper'>" +
      "<div class='shadebox-wrapper2'>" +
      "<div class='shadebox-wrapper3'>" +
    $('.shadebox').prepend("<div class='shadebox-header'><b class='shadebox-tlc'></b><b class='shadebox-trc'></b></div>");
    $('.shadebox').append("<div class='shadebox-footer'><b class='shadebox-blc'></b><b class='shadebox-brc'></b></div>");


This is by no means an optimal solution, I am not that fond of concatenating strings to generate html via javascript, but the html I have to write and maintain in template views is drastically reduced, easier to read and maintain. One downside is of course that it will not look correct if javascript is turned off, and some might not like the magic :)

Here is the CSS:

.shadebox { background: url(../_images/shadebox/shadebox-bb.gif) repeat-x bottom; }
.shadebox h2 { padding-left: 10px; color: #004684; margin: 0px;}
.shadebox-header { height: 10px; position: relative; }                
.shadebox-footer { height: 10px; position: relative; }                    

.shadebox-header { background: url(../_images/shadebox/shadebox-top.gif) repeat-x top; }            
.shadebox-wrapper { background: url(../_images/shadebox/shadebox-background.gif) repeat-x 0px 10px;}
.shadebox-wrapper2 { background: url(../_images/shadebox/shadebox-lb.gif) repeat-y left; }            
.shadebox-wrapper3 { background: url(../_images/shadebox/shadebox-rb.gif) repeat-y right; }                        
.shadebox-inner { padding: 10px; }
.shadebox-header b, .shadebox-footer b { position: absolute; width: 10px; height: 10px; }

.shadebox-tlc { left:  0px; top: 0px; background: url(../_images/shadebox/shadebox-tlc.gif) no-repeat; }            
.shadebox-trc { right: 0px; top: 0px; background: url(../_images/shadebox/shadebox-trc.gif) no-repeat; }
.shadebox-blc { left:  0px; top: 0px; background: url(../_images/shadebox/shadebox-blc.gif) no-repeat; }                        
.shadebox-brc { right: 0px; top: 0px; background: url(../_images/shadebox/shadebox-brc.gif) no-repeat; }

I think using javascript like this is is a pretty decent solution to work around the current shortcomings of html/css. But It can, as so much else, probably be overused :)


Pete said...

Unless I'm missing something in the spec, you ought to be able to do that with (a jQuery rounded-corner plugin that uses canvas) and a pixel-wide gradient-background repeated-x...? If I _haven't_ missed something, then that will work without your needing to make images for anything bar the gradient background.

Torkel Ödegaard said...

Pete that plugin locks good, but I could not figure out how to get it to make a border that fades out into a shadow.

shereen said...

that's really neat, i'll give this a shot and see how it works. thanks for the post!

Jim Cook said...

Minor can chain the three method calls into one:


[Can't figure out how to leave a proper code fragment using blogger comments.]

blsYAHU said...

There is also a jquery tag creator which makes things easier and more consise than string concats.

Torkel Ödegaard said...

Ah, I forgot that you could chain jquery calls!

Thanks for the tips!

Matt said...

Would you be willing to supply a link to a page that showcases this functionality or otherwise link to the image files you used? I love the effect you've been able to create but I wasn't able to ascertain where those gifs might be. Thanks for any help you can provide

Robert F. Crocker said...

didn't work for me said error 01 please what does that mean responsive web development

Kamal said...

Great work.Very neat way of coding.

Javascript Training