CSS3 question: box-shadow without the element being visible?

KevySaysBeNice

[H]ard|Gawd
Joined
Dec 7, 2001
Messages
1,452
Hi all!

I'm trying to figure out if there is a way that I can make a box-shadow behind an "invisible" element.

For instance, I'd like to do something like this:
Code:
/* this doesn't seem to work */
#onlyshadow
{
  -moz-box-shadow:0px 0px 10px gray;
  background-color:rgba(0,0,0,0);
  width:100px;
  height:20px;
  float:left;
}
There I tried to use the CSS3 RGBA value and make the element transparent that way, but the element (a div) still was visible through the shadow. If I set a vertical offset in my box shadow, then the shadow remains and the element is invisible, but I'd like to animate the shadow property via JS and as the blur increases if I don't adjust the vertical offset as well then I run into the same problem.

I've tried making the div have a background url('blank_pixel.png'); (so using a blank pixel as the background) but I get the same exact thing. The div is transparent, but when it's on top of the box-shadow you can still see the "silhouette" of the div.

Any bright ideas?

Thanks for the help!
[/code]
 
I am struggling with understand what you are trying to accomplish. Can you provide a drawing of you are you looking for?

Is this what you wanted?

Code:
#fakeShadow {
    -moz-box-shadow:0px 0px 20px 10px #333333;
    width: 100px;
    height: 0px;
    float: right;
}
 
I can do better!

I'm experimenting with CSS3 and jQuery, and I wanted to try to make a pure CSS3/jQuery button array on a "for fun" project I'm working on. This has probably been done before, better, etc, but for the moment let's pretend it hasn't. My goal is to use no images, and fairly simple JS that degrades well in IE/etc.

You'll notice that my example below works (make sure you look at it in firefox or it will not be pretty). But, You'll notice that the #shadow style has a relative position and a -19px bottom position. I then move the box shadow offset up 20 pixels, so basically I'm moving the element itself down 20 pixels, and the box shadow UP 19 pixels. I do this because without doing this, the div (even though it's "invisble, and there is no content, background, etc) shows up when on top of the box shadow. Hopefully that makes sense.

As for the sketch, I'm starting with this:
(sorry, I'd just host the html file somewhere but I can't at the moment).
(if you mess with the #shadow properties, you'll notice that removing the box shadow offset as well as the bottom:-19px; results in the shadow being in the correct place, but the #shadow div being visible in the box shadow)
Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript"></script>
<title>Shadow | Sand</title>
<script>
$(function() {
	
	$("#button").hover(function() {
	
		$("#content").stop().animate({
		top:-6
		}, 100);		
		$("#shadow").stop().animate({
			
			//MozBoxShadow:"0px 30px 15px gray",
			MozBoxShadow:"0px -20px 6px gray"
		}, 100, function(){
			
		});
	
	}, function(){
		
		$("#content").stop().animate({
		top:0
		}, 100);		
		$("#shadow").stop().animate({
			
			MozBoxShadow:"0px -20px 4px gray"
		}, 100, function(){
			
		});
		
	});

});
</script>
<style>
body 
{ 
	padding:50px; 
	background: #D4D0C8;
}


#button
{
	width:110px;
	text-align:center;
	margin-left:auto;
	margin-right:auto;
	height:25px;
	padding:5px;
	
}

#content
{
	padding:5px;
	float:left;
	width:100px;	
	-moz-border-radius:4px;
	background: -moz-linear-gradient(center bottom , rgb(245, 245, 245) 25%, rgb(219, 219, 219) 65%, rgb(240, 240, 240) 87%) repeat scroll 0% 0% transparent;
	font-family:arial, helvetica, san-serif;
	font-size:110%;
	font-weight:bold;	
	position:relative;	
	z-index:10;
}

#shadow
{	
	float:left;
	width:110px;
	height:5px;
	left:0px;
	position:relative;
	bottom:-19px;
	-moz-box-shadow:0px -20px 4px gray;
	z-index:0;
}



</style>
</head>
<body>


<br /><br /><br /><br /><br />
<div id="button"><div id="content">hi</div><div id="shadow"></div></div>

</body>
</html>
 
Looks pretty good. So you want the button to move up and down via the mouseover but the shadow to stay exactly where it is at all times? If so, try this test: Simply rename your div id="shadow" to id="fakeshadow" for testing purposes. This will prevent your jquery from doing anything with the shadow.

Add the following to the css section:
Code:
#fakeshadow {
    -moz-box-shadow:5px 3px 12px 4px #666666;
    width: 100px;
    height: 0px;
    float: left; 
}

I didn't spend time fine tuning the shadow, i only made it look close to your original. you can dial it in closer if warranted.
 
I had a little fun with your code:

Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript"></script>
<title>Shadow | Sand</title>
<script>
$(function() {
    
    $(".button").hover(function() {
    
        $(this).children(".content").stop().animate({
        top:-40
        }, 250);        
        $(this).children(".fakeshadow").stop().animate({
            
            //MozBoxShadow:"0px 30px 15px gray",
            top: 20,
            left:  20            
        }, 250, function(){
            
        });
    
    }, function(){
        
        $(this).children(".content").stop().animate({
        top:0
        }, 100);        
        $(this).children(".fakeshadow").stop().animate({
            top:30,
            left:0
        }, 100, function(){
            
        });
        
    });

});
</script>
<style>
body 
{ 
    padding:50px; 
    background: #D4D0C8;
}


.button
{
    width:110px;
    text-align:center;
    margin-left:auto;
    margin-right:auto;
    height:25px;
    padding:5px;
    float: left;
    
}

.content
{
    padding:5px;
    float:left;
    width:100px;    
    -moz-border-radius:4px;
    background: -moz-linear-gradient(center bottom , rgb(245, 245, 245) 25%, rgb(219, 219, 219) 65%, rgb(240, 240, 240) 87%) repeat scroll 0% 0% transparent;
    font-family:arial, helvetica, san-serif;
    font-size:110%;
    font-weight:bold;    
    position:relative;    
    z-index:10;
}
.fakeshadow {
    -moz-box-shadow:10px 3px 12px 4px #666666;
    width: 100px;
    height: 0px;
    top: 30px;
    position: relative;
}
.shadow
{    
    float:left;
    width:110px;
    height:5px;
    left:0px;
    position:relative;
    bottom:-19px;
    -moz-box-shadow:0px 20px 4px gray;
    z-index:0;
}



</style>
</head>
<body>


<br /><br /><br /><br /><br />
<div class="button"><div class="content">hi</div><div class="fakeshadow"></div></div>
<div class="button"><div class="content">bye</div><div class="fakeshadow"></div></div>
<div class="button"><div class="content">foo</div><div class="fakeshadow"></div></div>
<div class="button"><div class="content">bar</div><div class="fakeshadow"></div></div>

</body>
</html>
 
Sweet, very cool!

Only thing though - using that technique, I don't get much (any?) control over the size of the shadow (right?)...

I don't know if you notice, but in my JS I'm animating the shadow on hover as well. As the image raises, the box-shadow blurs further (to give the impression of the object moving away and the shadow reacting as it should). This bit is sort of the "point" of this little exercise, so I'm hoping to keep that! I'll also probably widen the shadow as the button lifts, by expanding the div (animate the width to say, 110% or something).


Thanks for the input!! <3
 
Although, as it turns out, I don't think the shadow is actually being animated, it's just being changed :/

Any thoughts on this issue? From what I understand, jQuery actually doesn't support animation of elements that aren't supported by all of it's targeted browsers (in other words, Internet Explorer in this case). I was frankly surprised that this worked at all.

But it doesn't look right if it's not being animated :(

I might be able to animate the width of the shadow instead to get the same affect, but.. it's not as nice. :/

edit: like this (you'll have to download the easing plugin here: http://gsgd.co.uk/sandbox/jquery/easing/)

Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript"></script>
<script src="./js/jquery.easing.1.3.js" type="text/javascript"></script>
<title>Shadow | Sand</title>
<script>
$(function() {
	
	$("#button").hover(function() {
	
		$("#content").stop().animate({
		top:-15
		}, 500,  'easeOutBounce');		
		$("#shadow").stop().animate({
			
			//MozBoxShadow:"0px 30px 15px gray",
			MozBoxShadow:"0px -20px 10px gray",
			width:'110%',
			left:'-5px'
		}, 500, 'easeOutBounce' , function(){
			
		});
	
	}, function(){
		
		$("#content").stop().animate({
		top:0
		}, 500, 'easeOutBounce');		
		$("#shadow").stop().animate({
			
			MozBoxShadow:"0px -20px 4px gray",
			width:'100%',
			left:'0px'
		}, 500, 'easeOutBounce', function(){
			
		});
		
	});

});
</script>
<style>
body 
{ 
	padding:50px; 
	background: #D4D0C8;
}


#button
{
	width:110px;
	text-align:center;
	margin-left:auto;
	margin-right:auto;
	height:50px;
	padding-top:35px;
	
}

#content
{
	padding:5px;
	float:left;
	width:100px;	
	-moz-border-radius:2px;
	background: -moz-linear-gradient(center bottom , rgb(245, 245, 245) 25%, rgb(219, 219, 219) 65%, rgb(240, 240, 240) 87%) repeat scroll 0% 0% transparent;
	font-family:arial, helvetica, san-serif;
	font-size:110%;
	font-weight:bold;	
	position:relative;	
	z-index:10;
}

#shadow
{	
	float:left;
	width:110px;
	height:5px;
	left:0px;
	position:relative;
	bottom:-26px;
	-moz-box-shadow:0px -20px 4px gray;
	z-index:0;
}



</style>
</head>
<body>


<br /><br /><br /><br /><br />
<div id="button"><div id="content">hi</div><div id="shadow"></div></div>

</body>
</html>
 
Yes you can still completely control the shadow. The first way if you only care about width (left to right) is to use jquery to adjust the width of the fakeshadow div. This however will not change the "blurry" factor.

Or you can simply put the MozBoxShadow back in to your animation queue:

MozBoxShadow:"10px 3px 18px 4px #666666"

And the mouse out make it the same as the original

MozBoxShadow:"10px 3px 12px 4px #666666"

Dont forget to put a comma in.

Technically this is not animating, it is just switching from 1 state to another. But as long as the switch isnt too dramatic, your eye wont notice the lack of animation.

replace the jquery from my previous post with this:

Code:
<script>
$(function() {
    
    $(".button").hover(function() {
    
        $(this).children(".content").stop().animate({
        top:-40
        }, 250);        
        $(this).children(".fakeshadow").stop().animate({
            
            //MozBoxShadow:"0px 30px 15px gray",
            top: 20,
            left:  20,            
            MozBoxShadow:"10px 3px 18px 4px #666666"
        }, 250, function(){
            
        });
    
    }, function(){
        
        $(this).children(".content").stop().animate({
        top:0
        }, 100);        
        $(this).children(".fakeshadow").stop().animate({
            top:30,
            left:0,
            MozBoxShadow:"10px 3px 12px 4px #666666"
        }, 100, function(){
            
        });
        
    });

});
</script>

as always, my example is exaggerated, you would want to tone down the actual movements.
 
Thanks again for the reply :)

I get that bit, but the issue is not with the animated shadow so much as the initial height of the shadow. In my example, the shadow is "tighter", (5px in height, plus whatever the blur adds). In your example, it's more like 10-15 pixels. In my example, the height of the div is set to 5px (which is where my height comes from), but in yours the height is set to 0px, effectively making it not there (hence it not appearing on top of the shadow). But I'd like it smaller, so that it appears that actual button is closer.

Does that make sense?
 
you can adjust the blur radius and the intensity independently. That is why the box shadow example I showed has an extra parameter compared to yours. Play with them and see if you can come up with a look that you like.

In the worst case, there is nothing that I have done that is not compatible with your original offset invisible box trick. So you can revert back to it, and set the offset far enough that it clears your shadow and then manipulate the width and height of the box separately. I would just suggest that you will get better results (in regards to animation) by moving the box itself instead of trying to manipulate the MoxBoxShadow offset parameters directly.

Bonus: If you really want to give it depth you can use -moz-transform to slant the shadow.
 
Back
Top