Saturday, February 19, 2011

CSS: Div w/ Border Images

What is a good way to set up a single container div with some border images surrounding it (in my case only on the left, bottom, and right sides)? I have it centered at the top of the page, overlapping everything else (so like that OSX-style slide-down dialog).

Here's the basic layout:

alt text

Here's what I've got so far (can I avoid a static width/height for the content?):

HTML:

<div class="contentbox">
 <div class="contentbox-wrapper" style="width: 400px">
  <div class="contentbox-mid" style="height: 200px">
   <div class="contentbox-w"></div>
   <div class="contentbox-content">
    Content Box Test
   </div>
   <div class="contentbox-e"></div>
  </div>
  <div class="contentbox-bottom">
   <div class="contentbox-sw"></div>
   <div class="contentbox-s"></div>
   <div class="contentbox-se"></div>
  </div>
 </div>
</div>

CSS:

.contentbox {
    width: 100%;
    position: fixed;
    z-index: 2;
}

.contentbox-wrapper {
    width: 300px;
    margin-left: auto;
    margin-right: auto;
}

.contentbox-mid {
    height: 100px;
}

.contentbox-w {
    width: 30px;
    height: 100%;
    background: transparent url("../../images/contentbox_w.png");
    float: left;
}

.contentbox-content {
    width: auto;
    height: 100%;
    background: #e8e8e8;
    float: left;
}

.contentbox-e {
    width: 30px;
    height: 100%;
    background: transparent url("../../images/contentbox_e.png");
    float: left;
}

.contentbox-bottom {
    width: 300px;
    height: 30px;
}

.contentbox-sw {
    width: 30px;
    height: 30px;
    background: transparent url("../../images/contentbox_sw.png");
    float: left;
}

.contentbox-s {
    height: 30px;
    background: transparent url("../../images/contentbox_s.png");
    margin-left: 30px;
    margin-right: 30px;
}

.contentbox-se {
    width: 30px;
    height: 30px;
    background: transparent url("../../images/contentbox_se.png");
    float: right;
    position: relative;
    bottom: 30px;
}
From stackoverflow
  • While none of this is recommendable (mixing markup and design), it's often not the integrator who gets the final word. However, you should still attempt to keep everything as clean as possible.

    Your structure is pretty much the only kind of structure you can use to your ends, although if your width is static (300px?), I'd advise you to have your div background as one larger image repeated vertically.

    You'd then have a kind of footer within your div, where you could put the two bottom corners and the bottom picture all in one single image. Instead of having 5 divs inside one, you'd only have one. Note that in bigger environment, this also means the user can download 2 more images in parallel (4 max from a single host), making the overall download of the page faster.

    This obviously doesn't work if your width is relative to the parent or can change in any manner though.


    EDIT: as it happens you specified the width is variable, I don't think there's a cleaner light way to do it HTML-wise.

    However, if you still want to maximize the speed of download for the images, consider using sprites: the east and west side images can be put inside the same bigger image: the only thing you modify is the background position:

    background-position: 32px 0px; /* this should move the background to the right */
    

    The advantage is you only need one picture, less connections are needed to download them for the client (faster) and it takes as much place.

    Hope this helps.

    Wilco : That's the thing - your suggestion is exactly what I've used elsewhere. However in this case, the width and height are variable.
    Wilco : ... thanks for the input though!
    I GIVE TERRIBLE ADVICE : Good to know. I believe you have what could be the optimal way to do it without getting in too much hackery. Updated with some additional information you could find useful though.
  • You can achieve this with a bit less markup by using the "sliding doors" technique. Basically, you just make sure that the images for each corner are large enough that they will still overlap a little when the box is at the maximum size you ever expect it to be. See this example for a box with images on all four sides:

    <style>
    div.box { float: left; }
    div.tl { background: transparent url('topleft.gif') no-repeat top left; padding-top: 8px; padding-left: 8px; }
    div.bl { background: transparent url('bottomleft.gif') no-repeat bottom left; height: 8px; padding-left: 8px; }
    div.tr { background: transparent url('topright.gif') no-repeat top right; padding-right: 8px; }
    div.br { background: transparent url('bottomright.gif') no-repeat bottom right; padding-right: 8px; }
    </style>
    
    <div class="box">
        <div class="tr">
            <div class="tl">
                Lorem ipsum dolor sit amet...
            </div>
        </div>    
        <div class="br">
            <div class="bl"></div>
        </div>
    </div>
    

    For a box with images on only three sides the code would be even simpler as you'd only need two divs to attach your images to:

    <style>
    div.box { float: left; }
    div.bl { background: transparent url('bottomleft.gif') no-repeat bottom left; padding-left: 8px; }
    div.br { background: transparent url('bottomright.gif') no-repeat bottom right; padding-right: 8px; }
    </style>
    
    <div class="box">
        <div class="br">
            <div class="bl">
            Lorem ipsum dolor sit amet...
            </div>
        </div>
    </div>
    

    These examples will give you a stretchy box that can grow as much as you want provided that the size of the images containing the corners and borders is sufficient. Note also that the "padding" set on the containing divs should be no less than the width/corner radius of your images, though it can certainly be greater should you wish. Below are a couple of images to illustrate the method. Happy coding!

    The corner/border graphics

    Images overlapping

0 comments:

Post a Comment