Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to have a drop shadow be a gradient?

Tags:

css

I'm trying to figure out if this is possible with css. I want a square that has a drop shadow. At the bottom of the square, the drop shadow is completely visible. At the top of the square, no drop shadow should be apparent. This would be a gradient so being in between the top and bottom, the drop shadow would be half visible.

Any ideas on how to achieve this?

like image 906
Matthew Avatar asked Aug 25 '12 01:08

Matthew


People also ask

Can Box shadow be a gradient?

Now, if we want to add a gradient-y box shadow behind this box, we can do it using a ::before pseudo-element around it and makes it looks like a shadow. As you can tell, since we want a gradient shadow, we're using linear-gradient as the background of the pseudo-element.

How do you make a gradient shadow?

Approach: Here are the steps required to get the desired linear-gradient shadow: Make an HTML file, with the button, card, banner or the thing that you want to make shadow of. Make a pseudo class in stylesheet and make the position absolute of the pseudo class relative to the parent element.

Can background color be a gradient?

Just as you can declare the background of an element to be a solid color in CSS, you can also declare that background to be a gradient. Using gradients declared in CSS, rather using an actual image file, is better for control and performance.


2 Answers

It is possible to emulate that using a gradient on an absolutely positioned pseudo-element, with a z-index such that it appears underneath its parent element.

HTML:

<div class='e'></div>

CSS:

.e {
    position: relative;
    width: 10em;
    height: 10em;
    margin: 1em;
    background: lemonchiffon;
}
.e:before {
    position: absolute;
    z-index: -1;
    top: 10%; left: 10%;
    width: 100%;
    height: 100%;
    background: linear-gradient(transparent, navy);
    content: '';
}

If you want the shadow to have a faded edge, then you'll have to give the pseudo-element an inset shadow (same colour as the background of .e's parent).

box-shadow: inset 0 0 .5em .5em white;

Note that this won't work in IE9 and older. You can use filter gradients for those, but not on pseudo-elements, so what you would have to do in this case would be to add a child to the element (just for IE) and style it just like you style the pseudo-element.


EDIT: If you want this to work over an image, gradient background, then I'm afraid it's a bit trickier and it cannot be done using just CSS in IE9 and older. However, in the current versions of the other browsers, this can be achieved using a linear gradient and three radial gradients.

Relevant CSS:

.e {
    width: 25em; /* give it whatever width and height you like */
    height: 25em;
    /* make padding on right and bottom larger by adding the amount taken by
     * the "shadow"
     */
    padding: 5% 10% 10% 5%;
    box-sizing: border-box;
    /* change navy to red in each of these at one time to see what each
     * gradient covers
     */
    background:radial-gradient(at top right, navy, transparent 70.71%) 0 100%,
        radial-gradient(at top left, navy, transparent 70.71%) 100% 100%,
        radial-gradient(at bottom left, navy, transparent 70.71%) 100% 0,
        linear-gradient(navy, transparent) 50% 100%;
    background-repeat: no-repeat;
    background-size: 95% 95%, 5%, 5%, 5% 95%, 90% 5%;
}
like image 90
Ana Avatar answered Nov 02 '22 07:11

Ana


I just had to mock this up for one of my dev's... Maybe useful to someone:

Code Pen
http://codepen.io/anon/pen/aOpOMV

HTML

<div class="element">
  <div class="inner">
    lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah lorem ipsum blahblah 
  </div>
</div>

CSS

.element {
  width:500px; min-height:500px; box-shadow:0 0 8px 0 rgba(0,0,0,.4); margin:0 auto; position:relative;
}
.element:before {
  position:absolute; bottom:0; width:100%; height:80%; content:''; background: linear-gradient(transparent 0%,#fff 100%);transform:scale(1.2);
}
.inner {
  position:relative; z-index:2; padding:20px;
}

NOTE: width / height aren't needed.. just there for mocking

like image 40
Roi Avatar answered Nov 02 '22 07:11

Roi