A List Apart

Menu
Issue № 172

CSS Design: Creating Custom Corners & Borders Part II

by Published in CSS, HTML, Graphic Design, Layout & Grids · 56 Comments

A note from the editors: While useful for its time, this article no longer reflects modern best practices.

Part I showed how to apply customized borders and corners to liquid CSS layouts. The technique works well, as long as your design uses solid background colors. But what if you want to use patterned or gradient backgrounds? In Part II, we’ll extend the technique so you can do just that.

A design problem

We’ve received another directive from our hypothetical graphic designer of Part I. Encouraged by the results of our previous collaboration, he has attached a new sketch he wants us to incorporate. (That’s it on the left. Four rounded corners against a tall, gradient background.)

[Image shows a white box with rounded corners on a graduated background.]

“It’s easy to change, right?” he asks.

“Piece of cake,” is our initial response.

We’ll start off by slicing up the new sketch, and deal with technicalities later.

See Step 2.1the sliced-up sketch.

Why it doesn’t work

The styles for our previous attempt at customized borders and    corners looked like this:

div.Article {
  background:
  url(images/custom_corners_topleft.gif)
  top left no-repeat;
  width:35%;
  }
  div.Article h2 {
  background:
  url(images/custom_corners_topright.gif)
  top right no-repeat;
  font-size:1.3em;
  padding:15px;
  margin:0;
  }
  div.ArticleBody {
  background:
  url(images/custom_corners_rightborder.gif)
  top right repeat-y;
  margin:0;
  margin-top:-2em;
  padding:15px;
  }
  div.ArticleFooter {
  background:
  url(images/custom_corners_bottomleft.gif)
  bottom left no-repeat;
  }
  div.ArticleFooter p {
  background:
  url(images/custom_corners_bottomright.gif)
  bottom right no-repeat;
  display:block;
  padding:15px;
  margin:-2em 0 0 0;
  }

This technique works by placing background images in elements that follow each other in a document structure. These elements are marked up in the same stacking level, but will display stacked on   top of each other in the order in which they appear in the   document.

The first element to occur   is placed “under” any following element   unless a specific z-index value tells   the user agent to do otherwise.

In our example,   the large top left background   image is placed within the first element to appear   in our box, which means that our <h2>   and all following elements with background images   will appear on top of it, thereby hiding the   right and bottom corners (and sides) of the top   left background image.

So if we’re going to use borders and corners that   require transparency — like a rounded corner box   that floats freely on a gradient background —  our technique will prove inadequate.   Let’s see what it looks like.

See Step 2.2The new graphics applied to the old CSS

How to make it work

The fix is easy. We’ll use relative positioning   to nudge around the boxes that contain the background   images.

[Image shows a white box on a graduated background. The top right corner juts beyond the boundaries of the rest of the box.]

In this illustration, we’ve outlined   our div.Article with a solid black,   and our div.Article h2 with a solid red to show the technique we’re using. We’ve moved the div.Article h2 block containing our top right background image 14px to the right by giving it a right:-14px value and positioning it relative to its parent element. (14px is the width of the top right background image.)

We’ll simply apply the same principle to all other   elements we need to move, using the width or height   of the background image we want to reposition to determine how much to move each element.

div.Article h2 {
  background: 
  url(images/custom_corners_topright.gif)
  top right no-repeat;
  font-size:1.3em;
  padding:15px;
  margin:0;
  position:relative;
  right:-14px;
  padding-left:0; 
/* Compensation for the 
repositioned box */
  }
div.ArticleBody {
  background:
  url(images/custom_corners_right.gif)
  top right repeat-y;
  margin:0;
  margin-top:-2em;
  padding:15px;
  position:relative;
  right:-14px;
  padding-left:0;
  }
div.ArticleFooter {
  background:
  url(images/custom_corners_bottomleft.gif)
  bottom left no-repeat;
  position:relative;
  top:12px;
  }
 
div.ArticleFooter p {
  background:
  url(images/custom_corners_bottomright.gif)
  bottom right no-repeat;
  padding:15px;
  display:block;
  margin:-2em 0 0 0;
  position:relative;
  right:-14px;
  padding-left:0;
  }

See Step 2.3Now we’re really getting there

We’ll have to compensate for the repositioned    elements in our final layout calculation, but this    really is all there is to it.

The grand finale

Now we’ll apply our technique to a more complex layout.    This time we’re demonstrating it on a three-column layout with a header from Owen      Briggs. We’ve included three alternate stylesheets for browsers that support style switching (like      Mozilla Firebirdfox),      to demonstrate the drastic design impact that customized borders and corners can have      on your next project.

We’ve also added      a fresh new div to the long center      column, and given it the class name, ArticleLongContent.      We use this div to wrap our ArticleBody if the contents of the article grow too long for our top left background image to cover.

The class contains the following style:

div.ArticleLongContent {
   background: url
 (../images/custom_corners_leftborder.gif)
   top left repeat-y;
  }

See step 2.4Our technique applied to a layout with 3 columns and header

Acknowledgements

Thanks to Inge Jørgensen and Stephen Paul for alternate graphical examples, Brian Alvey for letting me abuse his Browsercam account, and all the people who brought up interesting points in the discussion of Part I of this article.

56 Reader Comments

Load Comments