XING Devblog

A flexible shadow with background-size

| Posted by

When we launched the new design for our website last year, our visual designers came up with a nifty shadow element. This element was originally intended to be used below the business cards of user profiles and below group logos. The shadow being purely decorative, we decided to go with the pseudo-element :after. We knew that IE6 and IE7 couldn’t handle those but decided that this was a small price to pay compared to having to add useless markup only to display a decorative element.

This is what our old solution looked like:

HTML

<div class="card-shadow">
  New elements now can be as width or narrow as they want.
</div>

CSS

.two-col-content:after,
.card-shadow:after {
  background: url(data:image/png;base64, foobar) no-repeat;
  bottom: -6px;
  content: ".";
  display: block;
  height: 6px;
  left: 0;
  position: absolute;
  text-indent: -9999px;
  width: 100%;
}
 
.fullsize-grid .card-shadow:after {
  background: url(data:image/png;base64, foobar) no-repeat center top;
}
 
.fullsize-grid .two-col-content:after {
  background: url(data:image/png;base64, foobar) no-repeat;
}

We only had two images in the beginning, both with a white background but with different widths. We implemented each as a background image of the pseudo-element using base64 encoded images (see also: base64 and Data URI scheme). One reason for this approach was that we simply didn’t have a sprite wide enough to host the images.

Over time, our visual designers increasingly expanded the use of the smaller shadow to function as a visual separator. More and more base64 encoded images had to be integrated: full-size, full-size-marketing, half-width, third-width. And with both, white and grey backgrounds. We knew it was time put our foot down and save our CSS from blowing up.

This simple CSS3-based solution came to mind:

HTML

<div class="shadow">
  Wonderful CSS3-card-shadow. Fully flexible. But no IE ...
</div>
 
<div class="shadow-gray">
  Same here, but this box is placed on a gray background, so the horizontal gradient should be gray as well.
</div>

CSS

.shadow:after,
.shadow-gray:after {
  bottom: -7px;
  content: ".";
  height: 6px;
  position: absolute;
  text-indent: -9999px;
  width: 100%;
 
  background-image: -webkit-linear-gradient(left, rgba(255,255,255,1), rgba(255,255,255,0), rgba(255,255,255,1));
  background-image:    -moz-linear-gradient(left, rgba(255,255,255,1), rgba(255,255,255,0), rgba(255,255,255,1));
  background-image:     -ms-linear-gradient(left, rgba(255,255,255,1), rgba(255,255,255,0), rgba(255,255,255,1));
  background-image:      -o-linear-gradient(left, rgba(255,255,255,1), rgba(255,255,255,0), rgba(255,255,255,1));
}
 
.shadow-gray:after {
  background-image: -webkit-linear-gradient(left, rgba(205,205,205,1), rgba(205,205,205,0), rgba(205,205,205,1));
  background-image:    -moz-linear-gradient(left, rgba(205,205,205,1), rgba(205,205,205,0), rgba(205,205,205,1));
  background-image:     -ms-linear-gradient(left, rgba(205,205,205,1), rgba(205,205,205,0), rgba(205,205,205,1));
  background-image:      -o-linear-gradient(left, rgba(205,205,205,1), rgba(205,205,205,0), rgba(205,205,205,1));
}
 
.shadow:before,
.shadow-gray:before {
  bottom: -6px;
  content: ".";
  height: 6px;
  position: absolute;
  text-indent: -9999px;
  width: 100%;
 
  background-image: -webkit-linear-gradient(top, rgba(150,150,150,1), rgba(150,150,150,0));
  background-image:    -moz-linear-gradient(top, rgba(150,150,150,1), rgba(150,150,150,0));
  background-image:     -ms-linear-gradient(top, rgba(150,150,150,1), rgba(150,150,150,0));
  background-image:      -o-linear-gradient(top, rgba(150,150,150,1), rgba(150,150,150,0));
}
Screenshot CSS3-shadows

Fig. 1: CSS3 shadows, using :before and :after. Two classes are necessary if you want to have the shadow on an background, that isn’t white.

Browser issues: The usual suspect

The above solution is beautiful and elegant – but it doesn’t work on any version of the Internet Explorer. Even the IE9 can’t apply a background gradient to a pseudo-element. To deal with that, we offered our visual designers to put a filter on the parent element. However, that would only have solved part of the problem, the vertical gradient. Just like a box-shadow. So why not a box-shadow? Because we don’t have an explicit IE9.css – and we don’t want one, either. One IE filter should do.

Our UX guys wanted more than just a simple gradient below the parent element. That meant: back to base64. And since we could live with the fact that IE6 and IE7 don’t support :after, we decided to take a more universal base64 approach. This time we chose a png-24 because that got us half transparency. And we need that in order to be able to display the same image on grey and on white backgrounds.

So all we had to do now was to tell the CSS that we want the background image to inherit the width of its parent element.

HTML

<div class="shadow">
  New elements now can be as wide or narrow as they want.
</div>

CSS

.shadow:after,
.two-col-content:after {
  background: url(data:image/png;base64, longer-foobar) no-repeat;
  -webkit-background-size: 100% 6px;
     -moz-background-size: 100% 6px;
       -o-background-size: 100% 6px;
          background-size: 100% 6px;
 
  bottom: -6px;
  content: " ";
  display: block;
  height: 6px;
  left: 0;
  position: absolute;
  width: 100%;
}

IE9 displays everything correctly. IE8 can apply the :after, but not the background-size. We talked with our visual designers again who reassured us that this is a purely decorative element that doesn’t need to be supported by every single browser. Therefore, IE7 and IE8 will simply show a dark line below the parent element (in an separate ie.css).

Our way to finding a solution for a flexible shadow showed us again that it is very well possible to achieve satisfactory results if all teams involved (frontend engineers and visual designers in this case) discuss pros and cons from both a technical and a design perspective. What we got out of it is the use of state-of-the-art technologies as well as a nifty shadow element. True, it’s not supported by all browsers, but that was a price both teams were more than willing to pay. In short: It really helps if you talk to one another.

About the author

Nils LaukNils Lauk works as a Frontend Architect at XING. He loves semantics and accessibility. He's also a big fan of microformats and microdata. XING Profile »


4 thoughts on “A flexible shadow with background-size

  1. Thank you, will try to use it in next projects. I also like Google Mail and Google Reader solution, but they have banned shadows even in IE9, not only in IE7-8 :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>