CSS Border Tricks with Collapsed Boxes

By YUI TeamMarch 8th, 2011

These tricks will help you achieve designs without resorting to the use of images, CSS3 gradient or extraneous markup. By collapsing boxes with zero line-height and height values, we can display content outside of the content box, over borders.

Bi-color background

This example does not include IE 6/7 workarounds (check the source code of this demo page for IE fixes).

Bi-color background screenshot

.parent {
  display:inline-block;
  text-align: center;
  border: 1px solid #cecece;
}
.child {
  display:inline-block;
  line-height: 0;
  height: 0;
  border-top: 1em solid #ffc;
  border-bottom: 1em solid #fdcf46;
  padding:0 .6em;
  vertical-align:bottom;
}

<ul id="menuBar-A">
<li><a href="#">About Us</a></li>
<li class="selected"><a href="#">Contact Us</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Products</a></li>
</ul>

Dots and pipes between list items

This example shows properly across browsers after some simple IE fixes.

Dots and pipes screenshot

ul.one,
ul.two {
    margin-left:0;
    display:inline-block;
    *display:inline;
    zoom:1;
    height:12px;
    line-height:12px;
    padding:0;
}

li {
    float:left;
    display:inline;
    height:2px;
    line-height:2px;
    position:relative;
    top:.3em;
}

ul.two {border-left:1px solid #333;}

ul.one li {border-left:2px solid #333;}

ul.two li {border-right:2px solid #333;}

ul.one li.first-child,
ul.two li.last-child {
    border:0;
}

a {
    color:#000;
    padding:.4em .9em;
    *position:relative;
}

<div id="menuBar-B">
<ul class="us">
<li><a href="#">About Us</a></li>
<li class="selected"><a href="#">Contact Us</a></li>
</ul>
<ul class="ourOffer">
<li class="services"><a href="#">Services</a></li>
<li><a href="#">Products</a></li>
</ul>
</div>

Left and right-pointing triangles

This example does not include IE 6/7 workarounds (check the source code of this demo page for IE fixes).

Left and right-pointing triangles screenshot

#box {
  line-height: 0;
  height: 0;
  border: .4em solid transparent;
  border-left-color: #333;
  border-right-color: #333;
  padding: 0 .3em;
  display: inline-block;
}

<ul id="menuBar-C">
<li><a href="#">About Us</a></li>
<li class="selected"><a href="#">Contact Us</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Products</a></li>
</ul>

IE 6 and border transparency

IE 6 does not support the keyword "transparent" for border color. When you use this value, IE 6 draws a black border.

The fix for this is to use the chroma filter which displays a specific color of the content of the object as transparent. For example, to create a right pointing arrow you could use this rule:


#Box {
  height: 0; 
  width: 0;
  border: 10px solid transparent;
  font-size: 0;
  _border-color: pink;
  _filter: chroma(color="pink"); 
  border-left-color: #333;
}

The font-size declaration is another workaround for IE 6. It is to make sure this browser does not increase the height of the box.

Stop the presses! I just learned a new trick (thank you Chungho Fang):

The magic [to create border transparency in IE] is to set ‘border-style’ to either dashed or dotted


That’s it! This is just one more way to use borders to achieve image-less design.

Further reading


About the author:
Thierry Koblentz is a front-end engineer at Yahoo!

He owns
TJK Design,
ez-css.org and
css-101.org. You can follow Thierry on Twitter at
@thierrykoblentz
.

8 Comments

  1. Great! But what about Opera?

  2. @Cuprum

    Opera appears to misplace the text. Putting it either above the content box if the line-height is set to 0 or below it if the line-height is not zeroed out.

    Somebody should file a bug ;-)

    As a side note, I can often make things work in all browsers (including IE6), but I’d hit a wall with Opera.
    This browser is really a pain. It has issues, but we can’t fix it like we do with IE6/7 (because we can’t target versions). On top of that, it does not have much market share so why should we waste time?

    Thanks for your feedback

  3. David Hucklesby said:
    March 14, 2011 at 10:57 am

    It seems that Opera does not like the zero line-height. I substituted a line-height of 0.1 which seems to fix Opera. AFAICT this only affects IE 8, which is easier to fix than Opera, methinks.
    Cordially, David

  4. Hi David,

    That’s a great find, thanks a lot for sharing.

  5. Good post, but stop fixing for IE6.

  6. Hi David,

    What does this construction means (from your ul.two class):

    display:inline-block;
    *display:inline;

    I’m curious about the star keyword… Thanks!

  7. Hi Paul,

    In these rules, there are two different CSS filters (CSS hacks), one is called the star property hack, the other one is called the underscore property hack.

    They work like this:

    *property:value; /* IE5/6/7 see this */
    _property:value; /* IE5/6 see this */

    If we put them in this order it is to make sure the second declaration overwrites the value given to IE7.

    You could try this:

    color:blue; /* blue in all browsers */
    *color:yellow; /* switching to yellow for IE less than 8 */
    _color:green; /* switching to green for IE less than 7 */

    Note that these hacks are reliable, but the CSS validator will flag them as errors (because this is not proper CSS syntax).

  8. I found a rendering bug with CSS triangles that I haven’t found mentioned elsewhere. Firefox 4 on XP gets weird.

    Here’s a demo: http://zevbrokeit.posterous.com/nubs-problem

    Do you have any suggestions?