Connect
To Top

Universal Method of Block Decoration

I asked my readers to think out a technique for laying out blocks with rounded-off corners and shadows. Take a look at the solutions I received, and you will see that most of them are very much alike: four elements in the corners and a somewhat odd-looking result, though there are some differences in block placement. Let’s take a detailed look at the way those techniques work and also find out why this article isn’t simply titled “Creating rounded-off blocks with shadows.”

First, we must pose the problem. Let’s say we have a block with rounded corners and a shadow:

There is some content of undefined width and height inside the block, and the shadow is semi-transparent; the block’s width may be either predefined (in pixels or in percent) or automatic (width: auto). Our goal is to find the optimal method of laying out such blocks. By “optimal” I mean the least number of graphics files used, compatibility with all modern web browsers, and as few customizations for specific web browsers as possible. One way or the other, all these things have influence on our solution’s performance and robustness, especially if it’s used in a large project.

However, I should note that the indefiniteness of content block size is within a certain limit, say 1000 pixels by 1000 pixels. Actually, what I’m going to tell you about are some small context popups, which various websites are overfilled with. Therefore, if you need to add a shadow to a block containing the website’s main content, you should look for some other method.

Simple method

Take a close look at the example above, and you will easily find a simple and optimal solution: dividing the decorations into four areas and showing specific fragments of the same background image in each of them:

  • Area 1: horizontally and vertically stretchable, background-position: top left
  • Area 2: fixed width, vertically stretchable, background-position: top right
  • Area 3: horizontally stretchable, fixed height, background-position: bottom left
  • Area 4: fixed width and height, background-position: bottom right.

As you can see, this method is extremely primitive, but there is a thing to note: the blocks must be horizontally stretchable not to the container width but to the container width less the side block width (areas 2 and 4). The same applies to the vertical stretchability. However, this task is done easily as block size can be set not only using the CSS properties width and height, but also using combinations of left/right and top/bottom of absolutely-positioned elements. Take a look at this sample code:
[php]<style type="text/css">
.shadowed {
position: relative;
left: 200px;
top: 100px;
padding: 10px;
width: 30%;
max-width: 450px;
}

.sh {
position: absolute;
background: url(./shadow.png) no-repeat;
z-index: -1;
}

.tl {
/* setting height */
top: -6px;
bottom: 12px;

/* setting width */
left: -11px;
right: 14px;
}

.tr {
width: 25px;
top: -6px;
bottom: 12px;
right: -11px;
background-position: top right;
}

.bl {
left: -11px;
right: 14px;
bottom: -16px;
height: 28px;
background-position: bottom left;
}

.br {
width: 25px;
height: 28px;
right: -11px;
bottom: -16px;
background-position: bottom right;
}
</style>
<div class="shadowed">
Hello world
<div class="sh tl"></div>
<div class="sh tr"></div>
<div class="sh bl"></div>
<div class="sh br"></div>
</div>
[/php]
Open the example in any modern browser, and you’ll see that everything works perfectly. However, as it frequently happens, some time ago the Redmond guys decided to make our jobs more challenging and launched Internet Explorer 6, which has the following limitations:

  • Stretching with top/bottom and left/right doesn’t work
  • The bottom and right properties work incorrectly (element position is measured from the container’s even width/height)
  • Semi-transparent PNG images cannot be placed and positioned as you would do with ordinary background images.

Basically, all these problems can be solved easily using expressions and DD_belatedPNG, but this solution is too heavy for the big ol’ IE6, especially if you have more than one such block on the page. Let’s try to find another solution, and exercise our brains too.

Horizontal stretchability

First, we’ll think out another method of stretching a block horizontally. Let’s set the first block’s width at 100%. The result is as expected: the block can be stretched to the container width.

By moving Block 1 the right-decoration width to the left, we clear a place for Block 2. If we use overflow: hidden for the parent block, its salient left part will be hidden. That’s just what we need: when the container is stretched, both blocks occupy all the width available while being joined to each other.

The example above is oversimplified: I assumed that the container starts where the shadow ends. Actually, the shadow must overstep the block bounds, and that’s a real problem as using overflow cuts the shadow off:

Actually, there is a simple solution: let’s frame Block 1 and Block 2 with another block, for which we use width:100%; overflow: hidden, while setting top and side paddings equal to the shadow’s height and width, respectively. As we have set the width, the side paddings will increase the block size as required and the shadow will be fully visible. By removing the main container’s overflow: hidden property, we gain an additional benefit: now we can place some internal element (such as a Close button) outside the container.

If we add padding for the internal container, we’ll encounter another problem: Block 1 is smaller than required. However, as the internal container’s width is set, we can set it as needed using the padding-right property:

Image

As you know, semi-transparent PNG images cannot be used for background if you want IE6 to display the page properly; the AlphaImageLoader filter should be used for that purpose, but it cannot be positioned as you would usually do with a background image. Luckily, the unconventional block-stretching method we used at the previous step will help us to solve the problem. As you might remember, we moved Block 1 the right-decoration width to the left, so the decoration was cut off. If we move the right decoration to the very beginning of the sprite, we can lay the same image on both blocks:

At Block 1, the right decoration will be hidden by the container’s overflow:hidden property; the width of Block 2 will be equal to the right decoration’s width, so the decoration only will be shown. Now if we move the bottom part to the top, we can lay the same sprite on all the four blocks:

Surely, blocks 1 and 2 must be moved the bottom-decoration height up.

Placement of blocks on the right and at the bottom

I’ve already mentioned that IE6 handles the CSS properties right and bottom nonstandardly, and that’s a problem as we are using semi-transparent elements. Any seam between blocks, even 1 pixel in width, will be clearly visible.

The nuisance caused by the right property can be easily fixed: use margin-left:100% instead, which places the block exactly at the right edge, while left lets you position the block as needed. Using the bottom property is somewhat complicated; so far, I don’t know any working methods rather than letting the content move the block down as needed. At the previous step, we added a wrapper with two blocks inside; now we will add content there and place the bottom blocks beneath the wrapper.

It is this wrapper that will define the height at which blocks 3 and 4 are positioned. According to the CSS specifications, an element with the position: absolute property and with undefined top/right/bottom/left positioning properties must be placed in the same location of the document stream where a static element would be placed. It’s very convenient because it lets us use various tricks such as having remote elements anchored to a specific word in the text (for example, take a look at the remote element for the Moscow Hyatt Hotel at the Federation Tower website).

This wrapper has the overflow: hidden property, which does two jobs: hides unnecessary pieces of internal decorative blocks and defines the formatting context, meaning that no internal margins will protrude outside; therefore, the exact positioning of the bottom blocks is secured.

Bottom blocks

As you probably remember, we’ve removed the container’s overflow: hidden property. Therefore, it looks like we need to add another wrapper to stretch blocks 3 and 4 in the same way we’ve stretched blocks 1 and 2. However, there is a CSS property often neglected by web developers — that’s clip, and it’ll help us to hide the protruding left side.

The result

Hopefully, you’ve grasped the idea behind most of the solutions I’ve received from my readers. To sum up, the layout of decorating blocks involves five elements and a picture. The elements are placed as follows: A wrapper contains the upper-left and upper-right corners and the content. The wrapper has the overflow: hidden property, which both hides the decorating blocks’ salient parts and defines the formatting context. The wrapper also defines the vertical position of the two bottom blocks. The bottom-left block’s left protrusion is cut off with the clip property. We’ve set the sprite in such a way that we needn’t specify its background-position (which wouldn’t work in IE6 anyway; we’re going to use filters in that case). The block was turned inside out: its bottom moved to the top, and its right part, to the left.

Finally, here’s my own solution. As you can see, it’s a cross-browser method. To make it compatible with IE6, I only added the padding property for some blocks (it can be done using an expression once).

This method is handy for decorating any block, if you need to cover its four sides uniformly. For example, you can add a quasi-3D look to a flat and dullish book cover, as it was done at the iMobilco site (to tell the truth, a somewhat different method is used there due to the website’s technical peculiarities)

The method’s only drawback is complexity of calculating element paddings: it’s based on the whole decoration’s size in some cases and on a part of that size, in others. However, those calculations can be easily semi-automated, meaning that it would be nice to have an online service for making such decorations quickly.

More inSplashnology

Privacy Preference Center

Necessary

Advertising

Analytics

Other