demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Photograph of a Chinese model dressed as a princess reclining on a wooden bench
A single image element enhanced with CSS framing effects

Sophisticated Image Matting Effects With CSS

css / images

Estimated reading time: 3 minutes

When creating image framing effects most designers opt for one of two choices: create the result entirely in , or draw “boxes inside boxes” that are then manipulated with . In a previous article I demonstrated how to create complex framing effects by using border-image; in this article, I’ll approach the more subtle art of matting.

“Matting”, as referenced in the art framing industry, is the separation of artwork from its frame by a series of mounts. These mounts are often made from cardboard in different colors and textures. The goal of this article to recreate that visual effect on a web page without adding any elements around an image; the only markup will be:

<img class="mat" src="chinese-princess.jpg" alt="Photograph of a Chinese princess reclining on a wooden bench">

First, let’s consider the CSS properties that can create the appearance of a “box” around an image. The is an obvious place to start, with border providing a baseline effect and padding between the border and the element adding the visual appearance of an inset box. To this we can add an inset box-shadow to create the impression of an interior frame, and outline for the very exterior.

Naturally we want the image and its mattes to be , so our initial CSS is:

img.mat { box-sizing: border-box; width: 80%; height: auto;
display: block; margin: 4rem auto; padding: 10%;
background: #F4F0EC; border: 8px solid #333;
box-shadow: 0 0 0 50px rgba(125,135,18,0.3) inset;  }

(Note that I’ve used box-sizing: border-box to make the relative scale of effects easier to apply).

The trick is that the inset shadow is not provided with a horizontal or vertical offset or any kind of blur: only the spread, inset and color values are in effect to define an interior frame.

We can enhance the impression of “depth” on the frame by placing a second, more traditionally styled shadow on the interior while at the same time adding texture to the matting through a combination of and rgba:

img.mat {
box-sizing: border-box; width: 80%; height: auto; display: block;
margin: 4rem auto; padding: 10%;
background-image: url(cardboard.jpg);
background-repeat: no-repeat; background-size: contain;
border: 8px solid #333;
box-shadow: 0 0 0 50px rgba(125,135,18,0.3) inset,
0 0 30px rgba(0,0,0,0.8) inset;
}

The final step would be adding outline to the image to create a visual frame on the outside. This should be considered carefully, for several reasons:

  • outline has important uses in
  • Firefox currently treats outline slightly differently from other browsers: it has a default offset value of 12px, and the outline will be pushed outwards by any exterior box-shadow.

With those points in mind, the final code for the matting effect seen at the top of this article is:

img.mat3 {
-moz-box-sizing: border-box; box-sizing: border-box;
width: 100%; height: auto; display: block; padding: 10%;
background-color: #A67B5B; background-image: url(cardboard.jpg);
background-repeat: no-repeat; background-size: cover;
border: 6px double #483C32;
box-shadow: 0 0 0 50px rgba(244,240,236,0.4) inset,
0 0 0 11px rgb(180, 130, 90),
0 0 30px rgba(0,0,0,0.8) inset;
-webkit-box-shadow: 0 0 0 50px rgba(244,240,236,0.4) inset,
0 0 0 11px rgb(180, 130, 90),
0 0 30px rgba(0,0,0,0.8) inset,
0 30px 20px rgba(0,0,0,0.3);
outline: 2px solid #333; outline-offset: 0px;
}

This is of course just the start: there are many possible alternatives, which I hope this article has inspired you to explore.

Photograph by Bin Suzhou, licensed under Creative Commons. Play with this code on CodePen

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.