This tutorial builds on a previous post for creating a rounded inset image from a square picture, this tutorial adds a complex border to make the image look like a stylish porthole.

Square image with no rounding or shadowing.

Before first post

After first post

Final image

The parts of the (w)hole

A side-on view of the porthole

The final image is made up of:

The original image which has a drop-shadow and border applied via css.

A 5px wide border that is grey on 3 sides and white at the top.

A dark grey 1px border to define the outer edge.

Adding content with pseudo-elements

It’s not possible to add more than one border to the div that displays the image, but we can add more items to get the additional borders we need. Doing this manually would be a pain, and would create extra html elements which we don’t need. Fortunately, we can generate everything that we need in css with the :before and :after pseudo elements. This technique is lifted wholesale from Nicolas Gallagher’s website, so look there for more detail on the technique.

Changes to the original code

The image itself is moved from the image div and put onto the pseudo :after element we create so that it appears on top of the others. All of the sizes are also changed to match the additional size needed for the borders we are adding.

The new css for the portholes is below:

Css

.image
{
/*Rounded edges*/
-moz-border-radius: 33px; /* FF1+ */
-webkit-border-radius: 33px; /* Saf3-4 */
border-radius: 33px; /* Opera 10.5, IE 9, Saf5, Chrome */

background-repeat:no-repeat;
border:1px solid #CCCCCC;
display:block;
height:66px;
overflow:hidden;
position:relative;
margin:10px;
width:66px;
z-index:1;
}

.image:before
{
content:””;

/*Rounded edges*/
-moz-border-radius: 33px; /* FF1+ */
-webkit-border-radius: 33px; /* Saf3-4 */
border-radius: 33px; /* Opera 10.5, IE 9, Saf5, Chrome */

position:absolute;
z-index:-1;
top:0px;
left:0px;
right:0px;
bottom:0px;
border:5px solid #ccc;
border-color:#fefefe #f0f0f0 #eaeaea #f0f0f0;
}

.image:after
{
content:””;
background:#fff url(../images/finance.jpg) no-repeat 0 0;

/*Shadows*/
-moz-box-shadow:inset 0px 2px 8px #333; /* FF3.5+ */
-webkit-box-shadow:inset 0px 2px 8px #000; /* Saf3.0+*/
box-shadow:inset 0px 2px 8px #333; /* Opera 10.5, IE 9 */

/*Glow effect*/
-webkit-mask-box-image:url(../images/circle60pxglow.png);

/*Rounded edges*/
-moz-border-radius: 33px; /* FF1+ */
-webkit-border-radius: 33px; /* Saf3-4 */
border-radius: 33px; /* Opera 10.5, IE 9, Saf5, Chrome */

position:absolute;
z-index:-1;
top:5px;
left:5px;
right:5px;
bottom:5px;
border:1px solid #999;
}

Internet Explorer

IE6 and IE7 don’t recognise the Pseudo elements at all which in this case means that our image won’t show at all. To work around this we can use a hack to move the background image back to the image div.

Css
Add the following to the .image{} declaration:

/*IE6/7 hacks*/
*background:#fff url(../images/finance.jpg) no-repeat 0 0;
*width:60px;
*height:60px;

Obviously if you’re using something like Modernizr or conditional comments then you need to drop the hacks and add the appropriate css elsewhere.

If you find this tutorial useful, or have a better way of doing something please let me know in the comments.

References

This design would not have been possible without this excellent article by Nicholas Gallagher:
http://nicolasgallagher.com/multiple-backgrounds-and-borders-with-css2/