CSS Design: Creating Custom Corners & Borders

We’ve all heard the rap:

Article Continues Below

“Sites designed with CSS tend to be boxy and hard-edged. Where are the rounded corners?”

Answer: the rounded corners are right here. In this article, we’ll show how customized borders and corners can be applied to fully fluid and flexible layouts with dynamic content, using sound and semantically logical markup.

The markup#section1

In the example markup below, XHTML line breaks have been inserted to pad out dummy paragraphs:

<h2>Article header</h2>

<p>
A few paragraphs of article text.<br />
A few paragraphs of article text.
</p>

<p>
A few paragraphs of article text.<br />
A few paragraphs of article text.
</p>

<p>
A paragraph containing author information
</p></code></pre><h2>The hooks</h2>If we want full control of the layout, we need to make sure we have enough elements we can target with our CSS. Let’s call these elements “hooks.” Our markup needs just a few more.First of all, let’s wrap the whole article in a containing <code title="structural division">div</code>, and then wrap each structural section in an appropriate element:<pre><code><strong>
<div class="Article">
  <h2>Article header</h2>  <div class="ArticleBody">
    <p>
      A few paragraphs of article text.<br />
      A few paragraphs of article text.
      </p>    <p>
      A few paragraphs of article text.<br />
      A few paragraphs of article text.
      </p>
    </div>
  <div class="ArticleFooter">
  <p>
    A paragraph containing author information
    </p> 
    </div>
  </div>

If we examine the markup, we’ll see that we have given ourselves at least five hooks, which is all we need to place customized graphics in each of the four corners (and left side) of our article.

See Step 1primary markup.

The design#section2

First let’s decide on some basic layout parameters. Our graphic designer gave us this mockup for reference:“I want the borders and corners to look something like this,” he said. He also told us to be aware of the fact that all articles may have different widths and heights, and that he still wasn’t sure what kind of background he wanted the articles to have. In fact, he wasn’t even sure those were the borders he wanted.

“Could you leave that open, or make it so that it’s easy to change?” he asked.

The process#section3

We intend to keep the number of hooks as low as possible, so we’ll have to pay extra attention when we start to prepare the images for our solution, and make sure that the graphics we need are suitable to be hooked up to elements already present in our document.

We have a div containing the whole article. That’ll do for our top left corner and top and left sides. Header elements are block-level by default, and we’ll take advantage of their behavior: they extend to the full width of their parent element. So we’ll use the <h2> element for our top right corner.

We’ll use our article-footer div for the bottom left corner — and the contained paragraph for our bottom right corner.

Step 1.1 shows how we slice up the sketch.

Note: Obviously, you can use any element to hook graphics up with. Your document’s markup is unlikely to exactly match the structure used in our example. For all we know, you may only have a single paragraph of text to which you hope to apply customized corners and borders. You can easily do so.As stated earlier, all you need is at least four structural elements. (Depending on the height of your element you may require five.)

If necessary, these elements could be nonsemantic divs, each with its own class. Just remember that for a div element to be rendered, it must contain content to manifest its presence. Also keep in mind that if your content lends itself to common structural elements such as headers, paragraphs, and so on, you can and should use those instead of relying on nonsemantic divs.

The styles#section4

To continue, let’s turn on element borders and set a relative width for the div that contains the whole article, to see how things behave:

div.Article {
  width:35%;
  border: 1px solid red; }
div.Article h2 {
  border: 1px solid blue; }
div.ArticleBody {
  border: 1px solid black; }
div.ArticleFooter {
  border: 1px solid blue; } 
div.ArticleFooter p {
  border: 1px solid magenta; }

See Step 2basic element behaviour

Nothing really surprising here. We do, however, take notice of the gaps appearing before and after our div class=“ArticleBody”. Ignoring that problem for now, we’ll go on and write ourselves a style sheet:

body {
  background: #cbdea8;
  font: 0.7em/1.5 Geneva, Arial, Helvetica, sans-serif;
  }
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;
  }
div.ArticleBody {
  background: 
 url(images/custom_corners_rightborder.gif) 
  top right repeat-y;
  }
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;
  }

See Step 3first attempt.

Not bad at all! Actually better than we expected. Obviously we need to add some padding to our respective elements to make the layout look better — and then there are those pesky gaps to fix. The gaps are caused by the carriage returns inserted by our paragraph (block) elements. We could avoid using paragraph elements altogether and thereby bypass the problem, but — for reasons well-known to ALA readers —  we prefer to keep our markup structurally clean and logical. It isn’t our data’s fault that we are lazy stylers.

In our first pass, we assumed that a carriage return must equal 1.5em, as that was the value we specified for our line-height. Therefore our first attempt was to add a margin-top:-1.5em to our ArticleBody and ArticleFooter. It worked perfectly in most standards-compatible browsers — all except the ones used by the 94% of internet users on this planet (no names, please).After testing, trial, error, rinse, and repeat we find that we must use at least a margin-top:-2em to be sure that the elements touch and the gap closes:

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;
  }

Step 4 looks like we’re finally there!

Backward compatibility?#section5

If you’ve been viewing this example in Netscape 4.x, you’ve probably noticed that the page shows up blank. We’ve found no way to get this technique to work acceptably in NS 4.x, so instead we’re going to hide the styles that the browser in question cannot render properly. NS 4.x does not understand style tags with media=“all” specified and we’ve taken advantage of that in the example that follows. We’ve made two style tags, one with styles we want all browsers to render, and another we intend to hide from NS 4.x. Even though it breaks our heart to do so, we’ve also changed our font size specification from ems to pixels. You wanted backward compatibility — you’ve got it.

Step 5graceful degradation in NS 4.x

The real world#section6

“Yeah — but we want to see real-world applications, mate,” you say. We anticipated that and provided an example of the technique applied in a more advanced context. We borrowed an already thoroughly tested layout from Alex Robinson, and applied our styles to it — and we’re glad we did!Our first attempt unleashed a cavalcade of calamities in IE6/Win, triggering bugs affecting z-index stacking level of our elements. Entire elements disappeared; margins acted like children kept up long past their bedtime. It was a mess.

Then we learned that a simple position:relative and a well positioned <br /> could fix everything. View the source in Step 6 for further investigation.

Step 6our attempt at applying our technique to a full-fledged layout with headers, columns, and footers

Limitations#section7

If you have been paying attention, you probably realize this example only plays well with surrounding, solid-color backgrounds. With this method we need to cover the graphics from the top left corner with the graphics in the top right corner.

If we made the top right corner graphic transparent, the top left graphic beneath it would show. Same goes for the bottom. And that is indeed a limitation. Perhaps in a Part II edition of this article we will show how to work with gradient backgrounds.Meanwhile, this article demonstrates a generic method, with backward compatibilty and sound markup in mind, and it is our sincere hope that this will inspire a lot of offspring and ideas — perhaps even some that avoid the need to work with solid background colors.

Acknowledgements#section8

Brian Alvey for discussions, insisting on graceful degradation and real world examples, and David Schontzler  for helping a Danish dude write technical text in English.

Editor’s note#section9

While we were preparing this ALA issue for publication, designer Ryan Thrash came up with a nearly identical approach to the problem of creating rounded CSS boxes based on semantically correct markup. Thrash and Madsen came up with their approaches independently of each other; both authors acknowledge the influence of Douglas Bowman’s previous ALA articles, Sliding Doors of CSS (20 October 2003) and Sliding Doors of CSS II (30 October 2003).Independently of all that, ALA systems designer Brian Alvey previously crafted a different approach to rounded corners, which may be seen at Weblogs, Inc. It’s all good. — Ed.

96 Reader Comments

  1. This is a great extension on the Sliding Doors. After Douglas Bowman’s article I had crafted a resizable box with rounded corners ( http://www.andreas-kalt.de/roundedbox/ ). My approach works well for single boxes but not unfortunately for entire page layouts.

    So this article takes the final step in making the whole thing truely versatile.

    Andreas

  2. It’s a limitation of the design – you can only stretch the design as far as the graphic you made for it… in this case it isn’t big enough for such high resolutions and fails in all browsers.

  3. It’s comforting to see, after last issues’s debacle, an Editor’s Note respecting what I’ll call, for lack of a better term, ‘prior art’ related to Madsen’s article. Anybody who’s still bitter (for some reason) about the JIR article should take note of this and be at ease.

    Thanks for another great issue!

  4. CSS needs a ‘extend’ mechanism for background images. A ‘fit’ mechanism would also be useful. And IE needs to support RGBA 8-bit and 32-bit PNGs.

  5. For those who are looking for a quick review, this technique…

    Works in Win2K IE6.0, IE5.5, IE5.0, FireBird 0.7, NN 7.01;

    Displays all styles except for background images in Win2K NN 4.79; and

    Degrades gracefully in Win2K NN 3.0, IE 4.01, and IE 3.01 (why yes, I do have a lot of obselete browsers installed)

    This is a fantastic technique, and I plan on using it on the redesign I’m working on for this high school‘s website (for the sidebar).

  6. This doesn’t work correctly on IE6. I’m not talking about stretching the window too much, just the opposite.

    While slowly resizing the window, table cells jump around the screen from left to right and back! Nice ideas, but unusable commercially.

  7. noOne said:

    >>Table cells you say…
    >>That explains a lot.

    Did you view source? There are no table cells.

  8. I seem to have problems when vertically resizing the page in IE6/win2k. on some occasions the page is fine, on other the boxes shift almost completely off the screen and have a tendancy to ‘break apart’.

    It seems there is a big flaw in IE6’s renedring on this technique. Gotta love IE6 😀

  9. I’ve e-mailed the Trashbox guy that’s also noted in this article, and we tried to come up with a way of making the thing transparent. We didn’t succeed in that plan as there will always be at least one corner that has an “underlapping” (add to dictionary 😉 ) background showing up.. err, under.

    I’d love to start using the box models for the websites I make, but without proper CSS3 support I feel we’re playing with something that isn’t even halfway there.

    Besides that, who ever said tables were wrong anyway? The W3? May-be so, but they also recommend a lot of other stuff that none of the popular browsers have implemented yet.

    For now I will stick to my tables to fix these kind of problems, professionally. In my spare time I’ll play around with the limitations and “out of the box” thinking of the “box” model 😉

    Great article!

  10. To clarify re: the resize bug.

    The bug occurs on every vertical resize of the browser window, unless there is a horizontal resize at the same time.

    Very odd…

  11. Michael Ward is right. Does the same for me in ie6. I checked ie5.5 & 5.01 and they are fine. Tested in Win98SE.

    Odd indeed.

  12. I like this yet another ‘sliding doors’ method.

    However, have anyone thought of combining all the images into one? Maybe let’s combine custom_corners_topleft.gif, custom_corners_topright.gif, custom_corners_rightborder.gif, custom_corners_bottomleft.gif, and custom_corners_bottomright.gif into one huge image file (custom_corners.gif?).

    I’m not sure if this will work, but it’s worth a try.

  13. Lim Chee Aun

    I did some work on rounded corners using the combination of one image and pixy’s technique for just changing the background position and came up with
    http://www.quinncrowley.com/rounded.htm
    It seems OK in Firebird, ie5 and ie6 and does not require a massive image to ajust for large screen resolutions. I also do not get the vertical resizing issue using this approach.

  14. Lim:

    You could use a single image as a CSS background for a DIV, but that DIV would not be stretchable … not liquid. One of the design goals of Custom Corners was to make a squashable, stretchable layout.

  15. >> However, have anyone thought of combining all
    >> the images into one?

    This will only work if you know exactly the size of the box. If the box will ever change sizes – for example, get taller as more content is added – the backround image is unable to scale with the text, and therefore part of the text will be outside of the box – in this example, below it.

    The entire point of using this technique is to account for possible changes in the size of the box or its content.

  16. It’s not only in IE where this example doesn’t scale very well. It seems Andreas’ example is actually better at this.

    And this is actually when I make the window smaller…say 600 px or less

    As for the argument of smaller images: it is better to use small images repeatedly than to make images big enough that they scale along, as you’ll allways find a point where it’s too small.

  17. Looks good, but it’s got the same “ghost-padding” i’m trying to work around for days:

    It only shows in ie6 look at column two and you will see the text is about two or three pixels more to the right then the last four lines of the blind text.

    So if anyone knows a work around, i’ll be glad to learn.

    PS: i made a screenshot
    http://www.23q.de/ghost.html

  18. Lim: Your single image version is neat, but the markup reflect the design and it’s not really in XHTML + CSS track. The method depicted in the article may have little problems in a buggy browser but its markup is clean and meaningful. Any other CSS could be applied without altering the markup.

  19. I’m sure about this.. if custom_corners_rightborder.gif is neccesary to ‘occupy’ the ‘longer’ container, isn’t there should be custom_corners_leftborder.gif (where is it?)too.

  20. First of all – thanks alot for your nice comments.

    Second – most of the “bugs” and/or problems related to this technique, are caused by the background images used for the examples weren’t made big enough to suit resolution of 1280 and above. So it’s not really a bug – it’s just the images being to small, when either the browser window is squashed together – or being “too” wide.
    If you want to use this technique, just make sure to make the graphics big enough 🙂

    I’m using a slightly different technique on my own website, where I’ve added another “body” div, in which I’m repeating a background image along the y-axiz because I’m anticipating some longer articles and pieces. View source for reference.

    Anyways – thank you all, and thanks to ALA for handing me the microphone for a short while 🙂

  21. Lim,

    In Søren’s example, the image “custom_corners_topleft.gif” is what provides the left edge of the div. Therefore, you do not need to have a seperate image for the left edge.

  22. PO1 – agreed, my single image version does not create semantically good markup, mainly because I was more focused on the end result than the underlying structure (which is not a good thing). Soren’s example has excellent markup but does rely on multiple images sized to accomodate large resolutions.

  23. Andreas,

    Your Ghostpadding is actually the IE Three Pixel Text-Jog bug identified by Big John. You can read more about it at PIE: http://www.positioniseverything.net/explorer/threepxtest.html

    Ruth,

    Are you sure the design does not work as intended in IE4.01? I had no problems with Step 5 in that browser, however Step 6 shows problems with Alex Robinson’s “3Col_NN4_FMFM – header” design. From my tests on Mac OS 10.2, the design works fine on OmniWeb 4.5, IE 5.23, Opera 6.03, Camino 0.7, Firebird 0.7, Netscape 7.1 and Mozilla 1.5. Safari 1.0 doesn’t show the rounded corners except for the bottom left corner; must be some background positioning problem although I didn’t find any reference to it on Mark Pilgrim’s safari bug list (http://diveintomark.org/safari). Safari 1.1, though, checks out ok (thanks to the guys at iCapture: http://www.danvine.com/icapture/).

    Lim,

    I for one would just make custom_corners_topright.gif as tall as custom_corners_topleft.gif and not place a repeating background image on ArticleBody. This would also counter the problem of ArticleFooter growing a bit and losing part of its right border.

  24. Daniel, you’re right. IE 4.01 correctly displays Step 5, and chokes on Step 6. Not sure why I made that mistake – probably a combination of having almost a dozen browser windows open at once and the fact that I was still pre-coffee.

  25. I was wondering about something like this after reading the sliding doors article, just never had time to investigate it. I think I’m going to use this technique on my personal site. Thanks a bunch Søren.

    -jowe

  26. This is a hack and an ugly one at that. Tables are a much more intuitive way of creating a layout compared with this. The more we rely on hacks to produce effects the more difficult it will be to teach (X)HTML/CSS to anyone. If students have to become experts in the history of browser bugs just to get a web page to work they ain’t gonna bother and (X)HTML/CSS will become the province of a few experts. Keep it simple!

    Stick to tables for layout. M$ has kicked CSS to death with its refusal to support the standards. CSS is drowning in hackery. Worse still, there seems to be a culture of hack fame developing around CSS whereby an individual has his name carved into the history of CSS (Tantek etc.) by inventing a hack. We should be disappointed by the hacks we have to use to get CSS to work, not jump up and down with excitement.

  27. While I disagree with Garry Heaton about the tables, I whole heartedly agree about the culture of hack fame. It also applies to tutorials or articles. Write an article about a certain CSS technique, get loads of people to read it, then you become famouse as the only person to in the world to have “created” the technique.

  28. < This is a hack and an ugly one at that. Feel free to elaborate on how this is a "hack"? This is all done with CSS1 - and kept very simple. The only hacks occur in step 6 where we apply the technique to an advanced layout. And those were necessary to get IE to play well with this, because the layout (not the technique) triggered bugs - but the hacks have nothing to do with the technique itself. Re: "hack fame" I honestly do not see what the "hack" is? And rest assure - I do NOT claim to be the inventor of a "new" technique. This article just demonstrates what can be accomplished with background images and CSS, ie. making customized borders and corners, inspired by the great "Sliding doors" article. Some might find it useful. You didn't - and that is really okay. But I must object to you calling this "a hack and an ugly one at that". Kind regards, Søren

  29. I’m still looking for a reliable three column CSS layout for the company I work for’s site. I still don’t like it when columns don’t size correctly if the data is to large. It would also be nice if there was something that allowed the columns to be the same height.

  30. My apologizes Søren. My comments were not directed at you or your well written article. Nor did I call anything “a hack and an ugly one at that”. I was only commenting that there is a developing culture of hack fame (for a lose of better words). Nonetheless, your inspiration by the great article shows this to be true. I think the community of web developers should be careful of such things.

  31. Gary Heaton’s post sounds just a touch biased. I would bet that explaining this technique to a brand new student of web design/formatting/whatever would be as simple or perhaps even more simple than explaining tables. I don’t find table’s intuative at all. Tables require knowledge of certain bugs as well. I think your criticism is selective, and not very forward thinking.

  32. Phillip wrote …

    >>> Much simpler to just use:

    >>> border: 2px solid white;
    >>> border-radius: 2em;
    >>> -moz-border-radius: 2em;

    yes, if you only want it to work in Mozilla

  33. I discovered the solution to the IE6 resize problem, when sizing multiple floated columns with percentages. If your percentages add up to 100%, your boxes will look fine but when you resize you’ll get an occasional flicker. If you fudge the figures so the percentages add up to 99.9%, the flicker will disappear, but the boxes will look identical. Apparently IE6 rounds up a little TOO far in some cases.

    : Bat :

  34. I’ve been experimenting. I combine all the images into one, named/converted it as custom_corners.png (about 816x618px). Then I use the step 4 example page and only modify the CSS codes as follows:

    body {
    background: #cbdea8;
    font: 0.7em/1.5 Geneva, Arial, Helvetica, sans-serif;
    }
    div.Article {
    background: url(images/custom_corners.png) top left no-repeat;
    width:35%;
    }
    div.Article h3 {
    background: url(images/custom_corners.png) top right no-repeat;
    font-size:1.3em;
    padding:15px 15px 0 0;
    margin:0 0 0 15px;
    }
    div.ArticleBody {
    background: url(images/custom_corners.png) 100% -15px no-repeat;
    margin:0 0 0 15px;
    padding:15px 15px 15px 0;
    }
    div.ArticleFooter {
    background: url(images/custom_corners.png) bottom left no-repeat;
    }
    div.ArticleFooter p {
    background: url(images/custom_corners.png) bottom right no-repeat;
    padding:0 15px 15px 0;
    display:block;
    margin:0 0 0 15px;
    }

    You know what? It works, too. Tested on Mozilla Firebird 0.7 and IE6.

  35. First, “Creating Custom Corners and Borders” is not about hacks. It’s a method of creating a particular kind of layout and pairing it with lean, semantic markup. Good CSS layout is about creating a tight, clean, underlying (X)HTML structure and then doing the minimum that is required to bring that structure to visual life. The CSS file(s) and image file(s) controlling the layout are downloaded once and stay cached in the visitor’s browser, saving considerable bandwidth over oldschool table design methods.

    Further, the same structure can be displayed multiple ways (including text-only) — another advantage over table layouts, which don’t travel well outside the realm of traditional visual browsers, and which also don’t lend themselves to the needs of screen reader users unless a lot of additional work is done.

    If this article were about using tables to create rounded corner effects, it would contain just as much code and just as many image files (if not more). Those who complain that this article is unnecessarily complex would find that a table layout with rounded corners was equally complex — at least when described step by step in a tutorial.

    The fact that the technique involves the creation of small image files that must be combined to create a visual effect is not a problem in the article and it is not a problem in CSS; table layouts require the creation of many small pieces joined together; so do most Flash layouts. Web designs are made of parts just as movies are made of film clips edited together and banjos are made of wooden bridges, sounding boards, tuning pegs, and strings. You can’t carve a playable banjo out of soap; you can’t create many web layouts without images and snippets of code.

    Having nothing to do with this article, there are CSS hacks out there and there is an appreciation of those hacks in some web design and development circles. Recently an article in a leading web design magazine complained about these hacks, but the author of that article — or at least, some of his readers — seemed to misunderstand why the hacks are out there.

    The hacks are not out there because people like creating hacks. They are not out there so the people who created them can become famous. They are out there because more and more designers want to harness the benefits of standards-based design, but find their efforts stymied by bugs or flaws in one browser or another.

    Before we gang up on the browser makers, note that when they began truly supporting standards circa 2000, they were creating software to support CSS layouts that didn’t yet exist. Few people were using CSS at all; those who did used it only in timid and limited ways (because existing browsers didn’t support anything more than that). The browser makers to the best of their ability gave us the support they thought we would need; but they didn’t have sophisticated CSS layouts on which to test their work. Thus the browsers we have are riddled with small problems through no fault of the manufacturers.

    When a designer or developer discovers that a layout won’t work in IE5/Win or Opera 6 or some other browser, he or she has a choice:

    S/he can go back to tables (abandoning the benefits of standards-based design).

    Or s/he can go ahead with the layout, using a CSS hack to force the misbehaving browser to display the layout the same way other standards-compliant browsers do.

    Those who create CSS hacks do so to solve problems for their users. If they publish those hacks, they also solve the same problem for tens of thousands of unknown colleagues.

    Ever since the second web designer on earth viewed source on the first web designer’s site, web design has always been about sharing this kind of information so we can all get our jobs done. Freely sharing techniques in this way is generous and non-competitive. If a hack saves a thousand layouts and if the creator of that hack gains a little recognition for solving a problem that plagued many of us, ain’t nothin’ wrong with that.

    But CSS hacks are one thing; methods of CSS layout are another. “Creating Custom Corners…” is about a method of CSS layout. Confusing hacks with methods is unhelpful.

  36. Oftentimes, we want layouts with fluid heights but fixed width (say 800px). For such cases, it is much simpler and cleaner to use just two images, one each for top and bottom of the div, and one more for div background (with repeat-y).

    div.Article {width: 800px; background url(articlebg.gif) repeat-y}
    Where the gif is
    (shadow)|— 800px width —|(shadow)

    div.Article h2 {margin:0; padding: 0; /* flush it to the top of div.Article */
    background: url(rounded_top.gif) no-repeat}

    div.ArticleFooter {margin: 0; padding: 0
    background: url(rounded_bottom.gif) no-repeat}

    This will keep things much more simple if fixed width is desired… and there will be no peek-a-boo, once the design is finalized.

  37. Oftentimes, we want layouts with fluid heights but fixed width (say 800px). For such cases, it is much simpler and cleaner to use just two images, one each for top and bottom of the div, and one more for div background (with repeat-y).

    div.Article {width: 800px; background url(articlebg.gif) repeat-y}
    Where the gif is
    (shadow)|— 800px width —|(shadow)

    div.Article h2 {margin:0; padding: 0; /* flush it to the top of div.Article */
    background: url(rounded_top.gif) no-repeat}

    div.ArticleFooter {margin: 0; padding: 0
    background: url(rounded_bottom.gif) no-repeat}

    This will keep things much more simple if fixed width is desired… and there will be no peek-a-boo, once the design is finalized.

  38. If your purpose is to have a 100% css positionning site…this hint is great…

    if your purpose is to have a layout that reacts the way u want this is not a good thing…..

    it doesn’t work when the width is set to 100%…
    and it’s not a satisfying solution to make huge grazphics (in pixel size) to achieve what u can do with html tables and 1 dot graphics….

  39. … in the CSS!

    Seems to me you can either hack the HTML, by using inappropriate tables on every page of your site, or you can hack a single CSS file and leave your HTML clean & semantic.

    I know which one I prefer!

  40. While this is one of the better rounded corner solutions i’ve seen so far, I’m concerned about its dependence on image size for scaling. Why cache a 800+ x 800+ pixel image multiple times across a single page just so the boxes scale properly?

    A great solution, although full of “hacks”, is http://www.albin.net/CSS/roundedCorners/ . It’s not nearly as elegant as that which you’ve provided, but it does allow slightly more flexibility. Any thoughts? One problem I have with the albin.net technique is my embedded divs (placed within the content of the cell) blow the borders off in IE6/PC.

  41. When using fancy dropshadowed borders, I can see the value in this, but it just seems a bit odd to require a gigantic background if all the user needs is a single-pixel border.

  42. Mozilla supports corner radius attributes for block elements. Looks like they are thinking ahead! You could just be nice to all your mozilla users and have perty rounded corners for just them. 🙂

  43. Great article! Alistapart needs more like this.

    Hangon: I tend to disagree. Large images are only one possible application of using a technique like this. I’ve done something similar on a site I’m developing for someone else ( http://www.redbear.us/rbii/ ) using a series of small images for the corner. The markup involved?

    Absolutely no CSS hacks and no useless markup (for the part involving the rounded corners, that is- still need to clean up the site a bit). You simply cannot emulate a design effect like this elegantly with table hacks and 1-px images.

  44. I have to mirror Chris Hunt’s sentiment about CSS hacks. If the only two choices I have are to use presentational markup in a design or to add a few extra rules to a style sheet, I know what choice I’m going to make.

    True, I’d rather not have to resort to them, but it’s not a perfect world. I still have a much easier time developing CSS-heavy sites than I ever did with tag soup, and it usually doesn’t take that much effort to ensure that the design works fine on a broad range of browsers.

  45. If the incentive for authors is to become famous, I’m all for it. If that’s what it takes to get cross-browser solutions that allow us other (maybe not so talented) authors to create elegant sites, I say go for it! I also have to agree with Chris Hunt’s sentiment about CSS hacks. I would rather have the hacks in the CSS than in the HTML.

  46. If you open step 6 in IE, and size the window such that column 2 is longer than column one, you will notice that a line or two lower than column one column 2s contents kick over a few pixels. I noticed this as I was attempting to convrt a test site to a multi column floating layout. I could not find a work around for IE. This is not a problem in Mozilla.

    Any suggestions would be appreciated

  47. > Stick to tables for layout. M$ has kicked CSS
    > to death with its refusal to support the
    > standards. CSS is drowning in hackery. Worse
    > still, there seems to be a culture of hack
    > fame developing around CSS whereby an
    > individual has his name carved into the
    > history of CSS (Tantek etc.) by inventing a
    > hack. We should be disappointed by the hacks
    > we have to use to get CSS to work, not jump up
    > and down with excitement.

    For some reason I can’t really comprehend, this feeling you also share is gaining momentum.

    I wrote something about some time ago at
    http://www.aplus.co.yu/Techs/47/ but it still puzzles me when I read something like this.

    Why are you really against hacks? Have troubles implementing them? Then join the club, as only a handfull of people in the world are intimate with hack implementation.

    But that is not the reason to advocate against them. Aren’t 1px gif and horrible table layouts also hacks. Consider what would you have to do using tables to achieve this kind of box:
    – 3 rows for header, with middle cell (in all 3 rows) being 100% width and edge cells being there just as place holders for corner gprahics
    – 3 rows in the middle, 2 edges and content of the box
    – 3 rows at the bottom, just to close up the rounded box

    9-cell table with just 2 cells containing actual content? How is that different – it is a hack of different sort, but the one we are all used to. And you download all that markup each time – compared to the fact that CSS is cached.

    Personally, I would use rounded corners described in the articles only if client INSISTED to have ROUNDED columns in FLUID layout.
    In all other cases this markup can be much simpler (when you have fixed width box, which usually happens).

    Nevertheless, I welcome this article, as it saves me the time of developing the same thing when I encounter such spec.

  48. > Consider what would you have
    > to do using tables to achieve
    > this kind of box:

    Using the method in the article, the background images have to be as big as the content. Try adding some more paragraphs to the 6th example, and the design runs out of background image.

    At least the table method you quoted works, and works everywhere.

    In developing CSS solutions, some people appear to have forgotten this. If you are going to give someone code which they can copy paste, they are going to expect it to work consistently. This method fails that test.(make the browser window too large in demo 6 for example.)

    The simple fact is that if you want a fully fluid box with rounded corners and side borders, you *have* to use 9 images. (4 corners, 4 sides, 1 in the centre for colour safety)

    This method only has 5 images. Oops.

    As IE/Win does not support content: url(), this means that all the images must be put in as backgrounds, which means we need 9 tags to style, or 9 “hooks”. That’s 9 divs inside each other, or a set of divs above the content in the box, and a set after.

    For the first method, see:

    http://www.fczbkk.com/css/ramceky.html

    For the second method, see:

    http://www.redmelon.net/tstme/4corners/

    (You’ll have to view source on both examples, as both are demonstrations only)

    Douglas

  49. I don’t know how much of a difference it will make, but I do know that mozilla’s rendering engine (gecko) prefers tiling 32px images over 1px images. At least, that’s what the mozilla skin optimization guide says. The right side image would therefore work better in mozilla if it were 32px high.

  50. Not because of the way it looks nor the glitches that occur because of the size of the images.

    Everyone is raving about how important is to avoid extraneous html tags and “semantically logical markup”. What about semantically logical css? In this example the h1 for the article header gets the image for the top-right corner as its background. The ArticleFooter gets the bottom right image. What happens when we come across an article that has no footer? The problem is not this article’s, but rather with the stage css is at this point.

    Instead of setting different styles to different parts of the layout to come with the correct appearance (something like 9 nested div’s each having a different border, as someone suggested), css should allow a sigle element to have several backgrounds, or allow margins to be specified with images and not only width, color, etc.

    So instead of the many styles needed for the look the author wants to show, we would need only similar to the following:

    div.Article {
    background:
    white url(image/back.gif) repeat,

    top left url(image/leftedge.gif) repeat-y,
    top left url(image/topedge.gif) repeat-x,
    top right url(image/rightedge.gif) repeat-y,
    bottom left url(image/bottomedge.gif) repeat-x,

    top left url(image/topleftcorner.gif) no-repeat,
    top right url(image/toprightcorner.gif) no-repeat,
    bottom left url(image/bottomleftcorner.gif) no-repeat,
    bottom right url(image/bottomrightcorner.gif) no.repeat
    }

    so a

    is self-contained, and it’s look doesn’t depend on the elements that are inside of it.
  51. This sure seems like a lot of complicated stuff which is prone to error. Why not be patient and wait for CSS-3 where this enhanced functionality is better defined?

  52. 3 years of table hacking is enough for me. I spent over a thousand days nesting tables and futsing with borders and spacer.gifs and more nesting and nowrap and all that other table crap.

    Now we use all CSS for our layouts. Days of work have turned to hours, which gives us time to focus on better logic and actually implementing features instead of screwing with tables.

    Yes I’d trade CSS hacks for table hacks any day. Much less of a pain in my rear.

  53. Not only do rounded boxes serve no functional purpose, but they are about as ‘in’ as acid-washed blue jeans.

    While the method itself is brilliant One of the the biggest benefits of the entire standards-compliant, css evolution—is the aesthetic it fosters. Boxy is where it’s at right now. Sharp, clean, minimal, elegant.

    The American Arts and Crafts Movement of the mid 1800’s encouraged “honesty” in construction and finishing, calling for solid wood and rectangular joinery. The De Stijl Movement of the early 1900’s, was obsessed with pure colors, forms, and right-angle geometry. Elementary, economic, functional and un-monumental forms were essential.

    Limited browser support was the best thing that ever happened to web design. It forced us to simplify.

    Leave the rounded corners to the slice-and-dice table hackers of 1999 and embrace the zeitgeist, baby.

  54. > Not only do rounded boxes serve no functional
    > purpose, but they are about as ‘in’ as
    > acid-washed blue jeans.

    Hehe 🙂
    Using “rounded corners” as an example in the article, served the purpose well – to demonstrate what the technique “does”. But please note that the headline of the article is “Custom corners & Borders”, which means that nothing has to be “round”; it can be anything you want it to be.

  55. “Limited browser support was the best thing that ever happened to web design. It forced us to simplify.”

    If anything limited support caused more problems. People wanted MORE MORE MORE. And when MS attempted to give them all the bells and whistles while the standards bodies tried to put something more realistic together and NS sat on it’s hands. That’s why we have these hacks today is because one group had a vision of the web that was entirely contrary to how people really wanted to use it – aesthetics, art history, and good design principles aside.

  56. I like this, but what if you are using a style for media=”print”? won’t the borders you add in media=”all” then show up in your print style sheet?

    i suppose you could specify no borders/backgrounds in your print style sheet.

    oops, i answered my own question. but i’ll post it anyhow in case anybody else has the same one.

    Thanks for the great trick.

  57. I worked with Ryan Thrash over a month ago
    on this method, and we discovered that Gecko
    often mars the corners effect under certain
    text/height conditions. It’s due to the “1px
    rounding error” that happens often in Gecko
    browsers.

    http://www.positioniseverything.net/round-error.html

    http://www.positioniseverything.net/gecko/mozshift.html

    I’d be very suprised if this problem has been
    negated here. It’s quite persistent. Ryan was unable to solve it, which didn’t suprise me.

  58. Trying to line up the elements in a pixel perfect arrangement, would make the bug you mention, cause problems in Gecko based browsers.
    My solution was to make sure that the elements overlap with at least 1 px – and that seems to have “solved” it.

  59. I have to agree that I find the table solution to this problem simple and elegant. Moreover, I find the table solution perfectly logical and self-explanatory.

    Please, realize I am not trying to discount the CSS approach. There seems to be a push toward a logical usage of html tags such that table tags, for example, are only used to present tables of data. I cannot totally agree with this. I think a table is a logical solution to this problem. I know logically that the entire structure (border+content) must be presented as an invisible grid. In my mind, grid=table. Logically. When I see “div” I think of an amorphous division. This may be arguing semantics, but lets face it, div-table arguement at its root is largely semantic. Sure, sure. Screen readers, lynx, etc. Don’t forget, using tables doesn’t rule out CSS. You can always assign a class to the table tag, and there’s your easy CSS updating.

    Great article, but I really can do this in seconds flat with tables, whereas I would have to fiddle with divs for hours to ensure the positioning is correct across various browsers.

  60. Great, works really well, but shouldn’t this be do-able without having to put empty article footer

    s and

    s everywhere, just so they can serve as hooks on which to hang the bottom images of the box? My boxes/menus etc would not have author information at the bottom, so these tags are empty and only there for markup purposes. Aren’t we sposed to be getting away from that? Excellent stuff tho, I’m just being picky.

  61. I had no time to read all of the previous entries so i’ll just ask:
    can you make a css box that has corners that look like this? —-> / and that would make the square box look more like an octagon (kinda like this –> /¯)

  62. I’m going to have to concur that CSS, in its current phase, just isn’t up to the task when it concerns constructing interfaces laid out in graphical frames. Soren’s article, while creative, only reinforces the fact that CSS was developed by purists and not by designers (perhaps to keep people from mucking up logical structure rather than as an aid for designers). When you have to use placeholder paragraph and header tags just to position pieces of images; and some of the physical image sizes actually consume three times the bandwidth than a whole table solution, you know that there’s a problem. Throw in the monkey wrench that was so generously provided by Microsoft’s IE, and it seems self-defeating to utilize CSS if you require image based flexible layouts. We are all effectively applying the same workaround mentality with CSS that we have been using for HTML and this, of all things, was what CSS was suppose to have addressed.

    Until we are able to use multiple background images in a single div tag, rounded frames will continue to be a nuisance on pure CSS layouts. For the time being, the safest bet is to stick with tables in tandem with CSS for sites where puzzle-piecing image slices are required.

  63. Almost every designer seems to be kind of upset with Microsoft Internet Explorer because, although used by 94% of Internet users(could we call it the “majority”?), does not parse the CSS as dictated by whoever decide that CSS should make 94% comply with what the other 6% say is acceptable. I fail to see the logic of creating a standard which goes against the trend of the users. When I code a page I want the end-user to see my product and I little care about the Mozilla vs.Explorer with Opera as a referee! Could the W3C take into account the facts of life?

  64. What facts of life are those? Microsoft does not own the universe, and just because the current MS browser does not quite support standards they had as much of a chance as anyone else to put input into does not mean those standards are wrong, only that they are not currently supported by a browser that is used by a great many people, and is essentially only avalible for one operating system.

    Bugs are a fact of life in any code, but especially in anything as complex as IE. I may be wrong but I can’t think of anything recent and CSS-based where MS’s reaction was “go away — our way is better.”

    “The facts of life” are unless you never want the feature set of any browser to change at all, there will always be bugs in the browsers and they will not be consistant from one browser to another, and of course not one browser version to another.

  65. I do not remember saying that Microsoft own anything. The question I am asking is why ignore the majority of users when standards are made. And by the way MS reaction is exactly what Netscape used to have when they were the 300 pound “Godzilla” in the world of browsers. I only want to go about my coding business and be as efficient as possible and be able to have a page that renders with any browser without being plain vanilla text. I was so happy when I first heard about CSS and I dreamed that it would work with any browser. CSS 3 is on the horizon and my dream is still a dream. Yes, bug are a fact of life. So what? We try to feed them rather then debugging?

  66. if it only worked correctly on IE6!!!

    You guys are wasting a lot of time on this, as I did. I spent several days trying to get this to work on IE6, but no dice.

    I have concluded that since it doesn’t work correctly on IE6, it’s pretty much useless.

    Nice idea, though.

  67. These things seem to be gems, every single one of them. The more I get into CSS (thanks to alistapart.com and sitepoint.com) the more upset I am with MSIE not being up to CSS standards.

  68. This technique works great for me.

    But one thing I can’t get to work — and I’m surprised no one mentioned it — is that if you try to put a right-aligned image in the body of the box, the box doesn’t grow vertically to accomidate the full size of the image.

    Any ideas how to fix this?
    -Hank

  69. I’m VERY new to CSS, 4 days, in fact.

    I’ve learned more on this site than any other about HTML, CSS and Webdesign. I find the writing to be intelligent, informative and even a wee bit creative betimes.

    I will attempt to employ some of these techniques in me own pages, which shall remain unidentified for now. (I’ve only 15 days of HTML thus far.)

    Five stars, Angus!!

    Happy Dae

  70. Add me to the ALA’s Admirers group!

    great articles, even greater suggestions and ‘idea-generator’…

    My issue with the rounded corners stuff as presented here is that I either have to provide HUGE images to cover every possible window-size, or that I am forced to limit the box to a specific maximum height/width.

    Too bad you don’t make use of the browsers abilities to actually repeat backgnd images.

    Right now, I am tryin’ to get a fully fluid, indefinitely resizable rounded-corner-box (with 9 Backgnd images — which could be reduced to 3: the combined corners, top- and bottom edges, the right and left edges), and there seems to be quite some differences between MS and the rest of the world. (On my side, everything works flawless unless I touch the MS-Universe).

    But then, I even have difficulties to find myself a box of there to do the checklist.

    Once the cross-platform -Browser compatibility issues will be solved (if this is possible at all), I consider to create some script (thru innerhtml or somesuch) that will generate the extra html needed to render the boxes edges and corners, so that all I’ll have to throw into the page is the actual content, like,

    boxed

    any help or hints/pointers are welcome, of course!

    best
    david. )

  71. Is anyone else getting a problem where andy imiges held inside the Articlebody box is not being displayed, is there a solution?

  72. I have tried your method using only 3 images for the boxes. Two of the boxes are also using an image replacement technique. I am also limited to using standard (for our company) classes and minimal ids. I got everything working finally in Safari, Mozilla, ie5.2 mac and ie5.5 pc, except… once I adjusted for the pc, the content in two of my boxes become overlapped or disappear! Any suggestions are greatly appreciated.

  73. For those with high resolutions or designs simply wanting to keep image size down, what would you recommend doing about the possible and eventual break between the left and right corners?

  74. I wasn’t able to get the borders to work. The top left and bottom left over-lapped the right side. The footer “p” extended too far to the left out of the boxed area. How can I make this work and how can I make my own gif designs?

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA

Nothing Fails Like Success

Our own @zeldman paints the complicated catch-22 that our free, democratized web has with our money-making capitalist roots. As creators, how do we untangle this web? #LetsFixThis