Nightfirecat
Nightfirecat

Reputation: 11610

How can I create this angled shadow (without images)?

I'm looking to reduce external dependencies - particularly by replacing images with CSS effects wherever possible, such as in this case:

angled shadow example

The HTML and CSS (as this fiddle shows) is as follows.

HTML

<div id="one">
  <div></div>
</div>

CSS

#one{
  width: 940px;
  height: 350px;
  padding: 0 10px;
  margin: 10px 0;
  position: relative;
}

#one{
  background-image: url("http://webhost.ischool.uw.edu/~joatwood/portfolio/images/slider-shadow.png");
}

#one > div{
  background-color: purple;
  width: 100%;
  height: 100%;
}

What I'm looking to achieve is to get these three things:

  1. A slanted shadow which comes off the element only on the left and right edges (can't hide overflow otherwise, other pseudo-elements within this element must extend beyond its edges)
  2. The shadow should fade from black to white as it is farther from the middle vertically
  3. The shadow shouldn't use straight edges - it should be slightly blurry, like a shadow would be if you applied box-shadow: 5px 5px 5px

I've tried two methods so far, neither of which have been entirely successful:

  1. I used transform: skewX on two container-sized pseudo-elements with gradient backgrounds - it succeeded completely at #1 and #2, but I can't figure out a way to achieve #3 with it.
  2. I used transform: rotate on the afore-mentioned pseudo-elements and tried applying some box shadows to emulate the blurriness - this attempt only succeeded with #3, and didn't work at all as far as #1 and #2 are concerned.

I'm fine with using CSS3, so long as it works in current major browsers (Firefox, Chrome), but I cannot apply any pseudo-elements to the inner <div> because they're being used for another design element on the page.

Upvotes: 4

Views: 348

Answers (2)

Josh Crozier
Josh Crozier

Reputation: 241128

Not really going to explain much, as you already know how it all works. For those that don't - basically, I added a linear-gradient background on the parent. Then I overlayed CSS triangles (added via :before/:after) on each side in order to achieve the desired look.

jsFiddle example - looks quite similar to me.

It will work in all major browsers. Though it does look nicer in Chrome, as FF generates jagged edges on the triangles.

HTML

<div id="two">
  <div></div>
</div>

CSS

#two {
    width: 940px;
    height: 350px;
    padding: 0;
    margin-left: 10px;
    position: relative;
    background: rgb(255,255,255);
    background: -moz-linear-gradient(top,  rgba(255,255,255,1) 2%, rgba(0,0,0,1) 40%, rgba(0,0,0,1) 60%, rgba(255,255,255,1) 98%);
    background: -webkit-linear-gradient(top,  rgba(255,255,255,1) 2%,rgba(0,0,0,1) 40%,rgba(0,0,0,1) 60%,rgba(255,255,255,1) 98%);
    background: linear-gradient(to bottom,  rgba(255,255,255,1) 2%,rgba(0,0,0,1) 40%,rgba(0,0,0,1) 60%,rgba(255,255,255,1) 98%);
}

#two > div {
    background-color: purple;
    width: 920px;
    height: 100%;
    margin: 0px auto;
}

#two:before, #two:after {
    content: "";
    width: 10px;
    height: 0px;
    border-top: 175px solid transparent;
    border-bottom: 175px solid transparent;
    position: absolute;
    top: 0;
}

#two:before {
    left: 0px;
    border-left: 10px solid white;
}

#two:after {
    right: 0px;
    border-right: 10px solid white;
}

Let me know what you think - as far as I can see they look the same. The gradients could be tweaked a little to make them identical.

Upvotes: 1

Michael Chambers
Michael Chambers

Reputation: 74

<style type="text/css">
#container {
    width: 350px;
    height: 250px;
    position: relative;
}
#box {
    height: 100%;
    width: 100%;
    background-color: #909;
    position: absolute;
}
.shadow {
    width: 10px;
    height: 50%;
    position: absolute;
    background: -moz-linear-gradient(top,  rgba(0,0,0,0) 0%, rgba(0,0,0,0.9) 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0.9))); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  rgba(0,0,0,0) 0%,rgba(0,0,0,0.9) 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  rgba(0,0,0,0) 0%,rgba(0,0,0,0.9) 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  rgba(0,0,0,0) 0%,rgba(0,0,0,0.9) 100%); /* IE10+ */
    background: linear-gradient(to bottom,  rgba(0,0,0,0) 0%,rgba(0,0,0,0.9) 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#e6000000',GradientType=0 ); /* IE6-9 */
    z-index: -1;
}
#TL {
    transform:rotate(-2deg);
    -ms-transform:rotate(-2deg); /* IE 9 */
    -webkit-transform:rotate(-2deg); /* Safari and Chrome */
    left: -3px;
}
#TR {
    transform:rotate(2deg);
    -ms-transform:rotate(2deg); /* IE 9 */
    -webkit-transform:rotate(2deg); /* Safari and Chrome */
    right: -3px;
}
#BR {
    transform:rotate(178deg);
    -ms-transform:rotate(178deg); /* IE 9 */
    -webkit-transform:rotate(178deg); /* Safari and Chrome */
    right: -3px;
    bottom: 0px;
}
#BL {
    transform:rotate(182deg);
    -ms-transform:rotate(182deg); /* IE 9 */
    -webkit-transform:rotate(182deg); /* Safari and Chrome */
    left: -3px;
    bottom: 0px;
}
</style>

<div id="container">
    <div id="box"></div>
    <div class="shadow" id="TL"></div>
    <div class="shadow" id="TR"></div>
    <div class="shadow" id="BR"></div>
    <div class="shadow" id="BL"></div>
</div>

Upvotes: 0

Related Questions