Have you ever seen an element on a page with transparent borders? I think Facebook originally popularized it giving birth to lightbox plugins like Facebox. I don’t think Facebook sports the look anymore, but it’s still rather neat.
You might think it would be as simple as this:
#lightbox {
background: white;
border: 20px solid rgba(0, 0, 0, 0.3);
}
However, setting a transparent border on an element will reveal the elements own background underneath the border.
In the screenshot above, the borders use RGBa to be transparent, but they appear solid gray because they are only revealing the solid white background of itself below.
Fortunately there is a CSS3 property to save us! It’s called background-clip
and it’s used specifically to specify which portion of the box model should be utilized to display the background. It does what it sounds like it does, it cuts off the background at the specified portion of the box. There are three values it can have, and vendor prefixes do get involved. Here are the three settings it could have. You wouldn’t use them all at once, this is for convenience of displaying only:
#lightbox {
-moz-background-clip: border; /* Firefox 3.6 */
-webkit-background-clip: border; /* Safari 4? Chrome 6? */
background-clip: border-box; /* Firefox 4, Safari 5, Opera 10, IE 9 */
-moz-background-clip: padding; /* Firefox 3.6 */
-webkit-background-clip: padding; /* Safari 4? Chrome 6? */
background-clip: padding-box; /* Firefox 4, Safari 5, Opera 10, IE 9 */
-moz-background-clip: content; /* Firefox 3.6 */
-webkit-background-clip: content; /* Safari 4? Chrome 6? */
background-clip: content-box; /* Firefox 4, Safari 5, Opera 10, IE 9 */
}
Here are the schematics:
So I’m sure you see where I’m going here… if we set the background-clip
to the padding-box
, the white background will end before the border and the transparency will lay over other content acheiving the look we are going for!
Related: background-origin
In our lightbox example, it’s most likely that the background is a solid color. In that case, background-origin
is rather irrelevant, as nobody will ever be able to tell where the color “started” from. However, if the background of the element is an image, it can be quite important where the origin point of the background starts.
This is related to background-clip
, because if the background-clip
is the padding-box but the background-origin is left at the default border-box
, some of the background-image
will be cut off, which may or not be desireable.
Here is the schematic:
And a visual example:
Browser Compatibility
Works in: Safari 5, Chrome 7, Firefox 3.6+, Opera 10, IE 9
I only tested these modern browsers and support is good. It may (and likely does) go back a bit further in the non-IE browsers.
If you’d more complete browser compatibility, you can always go with the double-div method.
<div id="lightbox">
/* Set transparent background with PNG
add padding to push inside box inward */
<div id="lightbox-inside">
/* Set white background in here */
</div>
</div>
Another advantage to the double-div method is that you could achieve truly rounded borders. Unfortunately with the background-clip method, the outer border is round but the edge of the background stays straight-cornered.
Too bad we don’t have something like background-radius
to fix it:
#lightbox
border-radius: 16px;
padding: 8px;
/* NOT REAL */
background-radius: 8px;
}
Weirdnesses
20px of border was fine, but when I tried 30px, these mini boxes of death showed up in Safari 5.
In Chrome, little diagonal lines were present at any border width up to 20px.
Above 20px border, the corners completely darken.
Without border-radius, darkened corner boxes are always visible.
Thanks
Thanks to Alex Hall for the original idea and help.
Here’s a simple demo showing the different values of background-clip as well:
Check out this Pen!
and background-origin:
Check out this Pen!
Chris,
Great article, and the tip will certainly come in handy!
Thanks,
David
Chris –
The last two screenshots, I assume are related to the one above them. Meaning that the last two are in Chrome. Just wanted a little clarity.
Thanks
Beautiful. Crazy that I was just trying out rgba yesterday and wondering why the hell transparency didn’t work.
Do you have a screenshot of what this looked like in IE 7/8?
In IE8 the border is solid.
“Works in: Safari 5, Chrome 7, Firefox 3.6+, Opera 10, IE 9”
That’s neat. But the cons really weird. Those black line and box are an odd problem. I guess its maybe on the browser side problem to render the CSS
This is a really cool idea. I could think of display data linked via text i.e. a dictionary definition, photo details etc. Unfortunately IE is left in the dust with these cool visual styles. However I’ve stumbled across PIE CSS3 for IE! This allows support for RGBA value and other CSS3 properties. I haven’t had a chance to test it out myself, but I’m working on it and looking forward to it!
Chris, to solve the inner corner not being rounded, set the border-radius to twice the size of the border.
Gold star ++
The same CSS came to my mind. Why not use border, RGBa color und border-radius?
One other gotcha on this; you need to make sure you set the background-color attribute, and not just the background attribute, otherwise the background will continue to flow through the border. (atleast on firefox 3.6.10)
so
background: #fff;
will not work, whereas:
background-color: #fff;
Will work!
Awesome article, Chris, thanks for this. :-)
Yes indeeder. The demo example has that in the CSS, but thanks for pointing it out specifically. You can also get it to work in WebKit by going:
But at the moment that breaks Gecko, so best to use separately.
Ahhh, that’s good to know. I was unaware that the box-sizing values were available to use in the background attribute.
Nice. :-)
In my example I’m using *just* background: #fff and it works fine?
http://www.devseo.co.uk/examples/facebook-style-overlay-css/
You also specified padding-box in the background attribute, which I was unaware of until Christ mentioned it above.
Good idea though, both of you, I will indeed remember this!
Chris, not christ. Sorry about that, Chris.
Mini boxes of death!
I’m just so happy that IE9 is supporting all this. It’ll make our job easier.
“…transparent border on an element will reveal the elements own background…”
Would the use of outline rather than border not overcome this problem?
However, I realise that outline would not permit the coolification by addition of radius.
You can use outline radius (at least with Mozilla) to the outline property:
https://developer.mozilla.org/en/CSS/-moz-outline-radius
and
http://blogs.sitepoint.com/2010/04/13/towards-a-cooler-focus-caret/
However, I found that it was actually easier to use border because the outline property did some weird things, like sitting way outside the region of the element!
supercool, I did those with underlaying transparent div, for compatibility’s sake, but this will be neat once we get rid of that IE<9 basterds (wishes, nobody can take them from me! :D )
FYI Facebook didn’t develop Facebox.
he said he thought FB originally started the “transparent border” thing (I’m not sure either), which led to things like Facebox.
Very nice Chris.
As a side note. From working with Chris I can tell he takes great lengths to study every aspect of something before he writes a tutorial on it so almost everything he teaches is the best way to do something too.
This site is a great resource for web designers and developers..I just Loved it! thank you Chris.
Nice tips; though I think that using a double div with a transparent png border might be more graceful on IE; the RGBa value being the problematic property. With a PNG double div you’ll at least retain the transparent effect, but keeping graceful degradation in mind you could do some very slick looking modals in this method, or :focus and :hover effects.
I am with this idea. Chris’ idea about the transparent border is freaking awesome, but to bleeding edge for sites that have heavy legacy users.
Sorry,
but I just don’t understand what the big deal is, and what transparent borders would be needed it anyways?.
Transparencies are the new drop shadows. That’s all.
It’s more for the fact that rgba can’t simply be added to borders and they just work because the background colour sits underneath the border (effectively making it not transparent but changing the shade). Using the methods above you can get around this little issue.
awesome, great, superb article………………………..help more intrested crew wit articles like dis……hats off really great
Hi Chris,
Did you report the bugs to the Chrome and Safari teams respectively (if they’re not already reported)? :)
Nicely illustrated article btw, I could never explain things so good myself. :)
Excellent effect the transparent borders, especially with the inner rounded too! Thank you for the CSS3. LT
Really neat trick, I had been trying to get transparent borders on a lightbox I am developing… Another possible route I was trying is a transparent div as the parent… it also had the bonus of having rounded corners inside of rounded corners.
After going over this a few times, I’ve got to say, there is just way too much cross-browser weirdness going on there..
Here’s my version. Works in IE6+, FF, Safari, Chrome.
http://blog.pressedweb.com/demos/facebook_border/
Impressed. Very impressed.
But you’re using three elements to create that one box, the method Chris uses has just one element.
However, I realise that this method won’t work on anything but the latest browsers and your version is the cleanest method I could think of that would work across all platforms, so very nice job!
Nice explain the background-clip and background-origin by using image.
Very Nice and more help full
I apologize if my question is irrelevant to the original intent of your article, but if I may ask, what was the original solution Facebook used and did it degrade gracefully?
OK this makes a lOT of sense dude. Wow.
Lou
http://www.online-privacy.eu.tc
Thanks for sharing your expertise. I wish there were was a better implementation of this great CSS feature without the developer jumping though hoops. I can already see most designers using the double div method.
thanks for the compatibility screenshots
is it more compatible or as compatible as using background:url(whitealpha.png);
thanks…
All I need new is a client who wants transparent borders enough to pay me to do all this? One day!
For the life of me I can’t get this too work. I even copied your css from the demo, I always get this result – http://drp.ly/1TXs
Set that inner white block (blockquote p I believe) to have that stroke’s bg color.
Right now it’s picking up it’s default bg or something.
CSS getting awesome day by day. What if there is no browser war? Still we need to consider old styles to make sure our web apps has a consistent look among browsers. Some client that much crazy (or we?) like using still ie6. Thanks for the post.
Love your article.
Thanks a lot!
Its amaizing!
Thanks for sharing.
As sloppy as it is, for compatibility reasons, could you make two divisions?
#border (set background image to a transparent black png, and give it the same padding as the border width.)
#popup (white background, inside border division.)
Not all IE versions will support this, but I guess it could be a simple solution in some cases.
Nice thing to implement :) but i couldnot reproduce this on IE7
Very nice, thanks for sharing.
very nice indeed! something new to play with.
using rgba definitions is better. at last, this is supported by only modern browsers too.
I couldn’t find this anywhere so I thought I’d share… This gives a semi transparent border outline around a box while retaining the 100% transparency of the inside box…essentially giving a ‘window’ to peer through the 50% transparency box.
Using SASS allows you to change the width of the ‘border’ by changing only 1 line of code. Gotta love SASS
Setup the ‘Window’:
The SASS / CSS (I’ve included the long version of the border for clarity). This uses a white png image with 50% transparency.
Quite a few lines of code, but the result is pretty.
Enjoy :)
Hi, chris, thanks for sharing :)
I found that there is a little mistake in the background-origin pic, the default value of background-origin should be “padding-box” instead of “border-box”.
Another approach would to use a box shadow without blur:
border-radius: 10px;
background: #FFFFFF;
box-shadow: 0px 0px 0px 10px rgba(0,0,0,0.30);
Any downsides I’m overlooking?