CSS Drop Shadows
I’m working on the CSS3 Backgrounds and Borders module with Bert Bos, and I’d like to start a new Q&A series because I think we need some help: This time I’ll ask the questions, and you give me answers. Ok? :) Since the CSS Working Group Blog currently doesn’t accept comments, CSS3.info has kindly allowed me to cross-post so you can write back. The first issue is a complicated one, so I’ll start with an easy question. The topic is drop shadows.
In the latest public working draft we have a box-shadow property. The point is, obviously, to be able to draw a drop-shadow for a CSS box. It starts to get complicated once you ask “what happens when there are semi-transparent parts of the box?” At first we figured ‘box-shadow’ should just draw the shadow as if the box was opaque. Then Dave Hyatt, who had started implementing this, started questioning that logic. We’ve got proposals for a ‘border-shadow’ property to shadow just the border and a ‘background-shadow’ property to shadow just the background color (but not the image?), etc. We could also just “shadow everything drawn in this element”. This all sounds rather complicated to me so I want to step back and ask:
What do you, the web designers of the world, want to do with shadows? What’s the end result you want to get?
Show me. Post a few links to stuff from your portfolio that uses anything beyond pure text shadows, even if it’s all done with pure Photoshop(/Painter/GIMP) graphics. Draw (or explain) a picture of what you want to achieve. Then maybe we can figure out how best to make it happen in CSS.











I’d love to be able to achieve the drop shadow effect for the portfolio images here. It is a background image at the moment.
For me a wishlist would be to be able to define the angle of the light source, distance, spread and size in that order. Light source is the only one I can’t really live without.
I’d love to do a shadow that is less traditional 5px offset with blur, and more of a diffuse shadow on boxes, as I did here
I agree with George’s parameters. that would allow enough control I think (as I can achive this with photoshop with that many handles of altering.
The syntax would most likely be identical to the one for ‘text-shadow’, so you’d get the first three, I think.
I don’t think this is something that CSS should do.
Wolf, why not?
I like the way Adobe InDesign handles drop shadows:
http://flickr.com/photo_zoom.gne?id=2117635277&size=l
You can set shadow on the object, stroke, fills, text or any combination. Very flexible.
I think it should support shadows for the box itself - shadowing the image isn’t CSS’s place. Also, the shadow should reflect the ocpaicity of the box. George’s parameters sound good :)
Hi ;)
the CSS shadow property sounds exciting - I’ve thought about this a few times…. how useful it would be, the flexibility to quickly change the angle of a drop-shadow on the visuals with CSS, without having to go through a lengthy editing process (in case of a larger number of visuals/icons affected) in a graphics package would be great :)
I might be quite naive here as I don’t know whether this is even possible at all - but I’d love the possibility to add a drop shadow to a graphic which contains transparency, ie the shadow would apply to the actual graphic and not its box - which might be absolutely impossible and sheer utopia, I realise - just thought I’d dream anyway :)
http://www.graphiceyedea.info/p_gallery/gal_main.php (and all subpages)
I created custom icons which all show a tiny drop shadow - a keen eye will notice that there are one or two of them whose shadow is at a slightly different angle (very annoying and I need to edit them in the graphic app to change this).
anyway, just my thoughts ;)
Well, yeah, but CSS isn’t a graphics program. In Photoshop you might do some extra touch-up after the drop-shadow command, but in CSS we don’t have intermediate steps. CSS syntax needs to be able to express the desired end result, not how you get there. So that’s why I’m asking for finished examples.
@KenBW2: Define “box”. :) If I have a box with a border and some text but a transparent background, what gets shadowed? If I have a box with a solid background, what gets shadowed? If I have a box with a border, some text, and a background image with variations in alpha transparency, what gets shadowed?
Box to me = border, padding, background. I suppose if the background was transparent… oh I dunno - I’d have to think about it. Probably do the border. But then you’d have to apply that as a property if you only want the border doing if the background is opaque.
May be I have to correct my Flickr-Link: http://farm3.static.flickr.com/2173/2117635277_1a7eab7efb_b.jpg
I think following the way that layer effects work in (for instance) Photoshop is a very good model, since this is most likely the effect that designers will be attempting to reproduce.
If you apply a drop shadow to an element in Photoshop, and that element is empty (say, you turn its own opacity down to zero) then what you get is what you initially describe: a shadow as if the element were itself opaque. This behaviour can, however, be changed by setting the “Layer Knocks Out Drop Shadow” checkbox, so potentially some sort of knocked-out attribute may be useful in conjunction.
Having separate attributes for backgrounds and borders could be useful, though; by setting a background-shadow of a certain radius (let’s say, 10 pixels) and then applying a border of 5px without any shadow, the shadow that appears will already be at a significantly reduced opacity at the point it becomes visible. This has the effect of altering the way the shadows blend into the corners.
I’m going to put together a few test images to illustrate what I mean by all this. I’ve not finished them yet, but they’ll be at http://www.kapowaz.net/css3/ once complete.
CSS is dead, I can’t believe anyone even uses that stuff anymore.
My thoughts (even though I work for a browser vendor) would be to follow the border of the box if it is opaque (ignoring border-image for now), so that it follows around the curve of the border-radius if that is set. If there is a border-image, then follow where the none transparent parts of the image go, so for example here you would get the shadow of the diamonds. So far this is easy and logical as it is dealing with opaque and transparent (although I don’t implement the browser, so I can’t comment if it is as easy as it sounds).
Now the difficult part - semi-transparent images or backgrounds with HSLA or RGBA or opacity. My thought here, is what happens in nature? If you have a semi transparent surface, such as coloured perspex or glass, what happens when you shine a light source on it? I’d expect the shadow to change depending on how transparent the image/background is. Where the image is full transparent you’d get the regular shadow, and where is has some opacity you may get some shadow through the image/colour. I’m not a physics expert, so I’m not 100% sure what would actually happen.
@David Storey: I’ve uploaded an example of how drop shadows would behave on an image with variable opacity. Or at least, this is how it would look if created with Photoshop (a relatively simple example).
I’d have to agree with Ben Darlow and David Storey. Give an option to pretend the block is simply opaque, or to do what Photoshop does.
What would be really fun is to have an animated SVG with transparent background on an HTML page and watch the poor browser calculate the shadows on THAT! Buahaha.
Um, I meant “what nature does”, not Photoshop.
@Fyrd: that does raise one concern I have with all this; just how much local processing is necessary for it to not grind your machine to a halt? Then again, it’ll be 2050 by the time this is actually implemented by MS, and we’ll all be viewing the web via neural implants or something.
Ben: It would be interesting to see with an image where it doesn’t go more transparent in a linear fashion. For example, a stained glass window, with a diamond pattern for example, where some bits are more opaque as they have thicker paint, some or more transparent (almost clear but not quite) and some is fully opaque (such as the leading). Even without the fully opaque leading i’d expect to see some shadow at the edges (and under?) of the more opaque colours/pattern that shows through the almost transparent colour/pattern.
Here’s an example of how Photoshop does shadows through a layer with different opacities: http://img103.imageshack.us/my.php?image=shadowys7.jpg
[...] CSS.info se nos pregunta a los desarrolladores como nos gustaría que pudieran ser la sombras de las cajas para definirlas así en en el [...]
On http://www.gamepartypro.nl/ I use a shadow that’s cast to every side. Would it be possible to make this possible in CSS3?
@Jorrit: the examples I posted previously do much the same thing. The key requirement would be to allow specifying the size (radius), translation distance from centre of element and angle of translation of the drop shadow. Having a translation distance of zero would allow a shadow to extend on all sides.
A drop shadow should be the same shape and follow the opacity of the element it is applied to. So, you have a that has a transparent background and an opaque border, it follows the text and the border. If it has a solid background color or image, it follows all three (though the text would not usually be visible then). If it has a transparent image it follows all three. If it has a semi transparent image, text, border, whatever, then it follows that opacity as well.
As for what you can then say about the shadow, I have no clue, whatever they said sounds good ;) .
It would be nice to target the shadow as a virtual element. So that it could just be styled directly.
-Adam
I recommend two types of shadow: drop-shadow and inner-shadow.
drop-shadow
drop-shadow-distance: [em|ex|percent|px|pt|picas|in|cm|mm];
drop-shadow-size: [em|ex|percent|px|pt|picas|in|cm|mm];
drop-shadow-angle: [degrees];
drop-shadow-opacity: [em|ex|percent];
drop-shadow-color: [RGB|hexadecimal|name|background|border];
inner-shadow
inner-shadow-distance: [em|ex|percent|px|pt|picas|in|cm|mm];
inner-shadow-size: [em|ex|percent|px|pt|picas|in|cm|mm];
inner-shadow-angle: [degrees];
inner-shadow-opacity: [em|ex|percent];
inner-shadow-color: [RGB|hexadecimal|name|background|border];
Application: Both shadows would be limited to block elements and would only shadow the edges of the box.
Inheritance: The property would not be inherited by it’s children. Although, if you put a shadow on a child of the shadowed element, you should be able to specify that you want to inherit the settings (like opacity, size and angle) using the inherit keyword.
Color: The color of the shadow should use traditional means (RGB|hexadecimal|name), plus you’d also be able to set it to the background or border color using those specific keywords.
Let’s not get ahead of ourselves. :) I’m looking for examples of what we want the end result to be, not how make it. Once we know where we’re going, then we can decide how to get there!
Bryan: the opacity can already be set by using either the RGBA or HSLA colour model. I’d think that the way of specifying the shadow should be the same as text-shadow, as it is already implemented by a number of browsers now, and shouldn’t be inconsistent with that. It probably wouldn’t be wise to change text-shadow too much as we’d lose the work done by the browser vendors and have versions of browsers that are incompatible.
@Brian, the only difference between your drop- and inner- shadows is that one’s inside and one’s outside, so if something like this were to be added, it seems like it’d make more sense to add one more property like drop-shadow-position with values ‘inside’ or ‘outside’.
I can’t see any use for drawing a box drop shadow inside the box. Any effect you want to achieve that way is better achieved with a background image, or by applying a drop shadow to another element inside the box.
Let drop shadows only apply to the shape of the box.
I’m probably naive (and/or paraphrasing some comments above) but it seems defining two use cases would do the job : either the box is considered opaque when creating the shadow (in which case, if the box is not opaque in other respects, the shadow would show through the box), or the actual opacity of the box (and its various contents, like a complex semi-transparent image) is used to cast the shadow.
Algorythm-wise, the second is a generalisation of the first. Take your initial “shadow mask”, move it, grow it, blur it. Either the initial shadow mask is a black rectangle, or it is a gradient of the opacity channel of the objects above it.
I was thinking something like this:
div{
dropshadow-position:bottomright;
dropshadow-color#000
dropshadow-offset:5px;
}
or
div{dropshadow:5px #000 bottomright;}
Hello
Here are some examples with Fireworks
http://designpicnic.com/web-atelier/img/css/shadow.png
Emo: That looks great. Can you do any examples using a basic object that has varying opacity, such as where part of the patter is more opaque than the rest?
First: it may be nitpicking, but why do we call this box-”shadow”? I’ve already tested and used -webkit-box-shadow to make a glow or highlight, rather than a shadow. On the other hand I can’t come up with a good alternative either …
Second: in response to the article questions, I’d be very glad with a universally working version of a drop shadow as it is implemented now in webkit. If an element would have a .5 opacity it would seem logical to me if the shadow would simply be at .5 as well, and *not* have the shadow appear through the element. CSS isn’t graphics software, so it would appear awkward to me if it started behaving like it in some occasions.
Third: in response to Paul D, inner-shadow (or -glow) could be very useful. If we can have shadows on the outside with CSS, then why not on the inside?
Photoshop addresses this issue by having an option in its layer styles called “layer mask hides effects”. It’s pretty straight forward.
My mistake. It’s actually “Layer knocks out drop shadow”.
I could imagine this as “element-shadow-knockout” or something shorter.
a bit off topic but is there anything in the spec about foreground-images or passthrough elements.
“pass-through”
For example (a bad example) what if I wanted to overlay a company logo _in front of_ the entire website so that it covered the central content area and the empty sides where the body background image is showing. So i want it to be big, very low opacity, but even though this 1 div _covers_ the entire page it doesn’t prevent a user from clicking on anything because it’s set to “pass-through”.
“foreground-image”
I had a wedding planner client who wanted some decorative vector art placed in the bottom left & top right of all the photos in their gallery. They had 1,700 photos that luckily were all the same size. If such a thing as a foreground-image existed I could have just put the displayed image in a div with a forground image of the artwork that would be displayed _in front of_ the [img] and saved myself a lot of time.
http://thinsoldier.com/csswishlist/ (old ideas)
I would definitively see the use for drawing a shadow inside the box, in order to create an embossed effect (http://en.wikipedia.org/wiki/Embossing). That’s the effect that you find in iTunes’s CoverFlow button (when :active), on http://www.apple.com menu/toolbar (:active still) and more generally through Leopard’s toolbar buttons (Safari, Finder, iCal…)
A possible syntax for that could be having a inside/outside keyword, or simply having negative offset:
box-shadow: -10px -10px 5px #888;
Think physically: 1 = Transmission + Reflection + Adsorption.
Shadow and Transparency (Transmission) are correlated.
Transparency Shadow Shadow of
===================================
1.0 1.0 rock
0.2 0.2 colored glass
0.0 0.0 nothing
Here’s my take:
Bordered box containing text & transparent background: border gets the drop shadow (designer would have to add separate text shadow as he/she wishes)
Bordered box with slightly opaque background: drop shadow applies to the box only (shadow shines through the transparent background).
Bordered box with transparent background and partly transparent background image: shadow applies only to the border (designer would have to add separate shadow to the background image as he/she wishes).
Think this owuld be the easiest to implement.
I think that CSS is an essential presentation language,
so can be difficult for browser’s engine build an exact rappresentation of opacity layers merge (like a graphical output in Photoshop, Gimp, Fireworks and so on). CSS has to remain simple and essential (shadows are needed, sure, but merging layers opacity it’s not foundamental).
So, the simplest way to achieve shadow effect trought CSS is to follow the background, and simply, his opacity. If background is set to 50% opacity, shadow set to 50% too. If there are some other boxes under this one with shadow, they are show trough background + shadow opacity.
Don’t consider shadow angle, only essentials property like offset, color and width. Obviously, shadows have to follow eventual round corner.
CSS is not a graphical IDE, is a “rude” language to draw design for rude readers (browsers).
@Nicola, Anders: You’d be surprised at what implementations can do. But the information I’m after here isn’t what implementations can do–we have implementors on the CSSWG who can answer that question with much more certaintly! The information we don’t have is what people what to *do* with shadows: what end result they want to get.
My two cents is that the box shadow’s main purpose is to give said div the feeling of hovering over the page. Given this, I believe it should only be a border issue. If someone wants their box transparent, then they see no shadow underneath. Having a transparent box and a box shadow together kind of negates the point in my book. I do think there should be an option of size, much like setting border size, along with types of shadow (ref the first two posts in thread for examples). Maybe something like:
div { box-shadow: 5px diffuse; }
Good luck with the project fantasi. Hopefully my input was helpful.
Hi Guys,
It sounds great drop-shadow in CSS on box-model, I think Fantasai’s question was:
What do you, the web designers of the world, want to do with shadows? What’s the end result you want to get?
and my answer is we can produce more beautiful designs with lesser code and ofcourse faster download-able websites (because we’ll no need to slice images for shadows) if we will have the liberty of drop-shadow in CSS.
my personal opinion is that CSS drop-shadow property should have the property of shadow-angle, shadow-opacity, shadow-size and distance just like photoshop do have.
And I think box model (div) should have the shadow property neither border nor image and you will need to add one more property (if possible) with Opacity property and that is “Fill” the Opacity property can transparent both background color and shadow and the “Fill” property will transparent the only Background color of box model or div.
Good Luck Guys CSSWG you are doing a great job!
[...] have a CSS Soap box to let everyone get their issues off their chest, and they have written posts requesting feedback from designers saying what they want from certain properties. Is that far enough? Maybe not, but it [...]
I think any block level element should be able to have a drop shadow applied. Perhaps we could take a cue from Photoshop with the attributes. Opacity / Size / Spread / Distance. It might be kinda cool if it worked like the Outline property as well, where the drop shadow would not affect layout.
[...] CSS3.info is gathering peoples opinions on how you would like to see drop shadows work in CSS3. [...]
1. distance/spread in pixels.
2. fade distance from border to edge of shadow in %. the inside border edge would default at 100% and the edge of the shadow would default at 0%. lowering the % in css would lower them all together. you could also do 2 % totals that would adjust each end independently. another way to do this would be like classifying fonts in the “small, medium, large” sense. you could do “softest, softer, soft, lighter, light, medium, heavy, heavier, heaviest” or something like that.
3. angle of shadow controlled in 2 ways. A. defining if you could make it radiate in every direction like an outer glow or weather it was more of a traditional drop shadow going in one direction and B. if it was in the traditional drop shadow sense at what angle using %’s in a clock format. 100%=12o’clock. 50%=6o’clock. 75%=9o’clock. etc…
thats what i would like to see.
With this module we’ll have at least three different choice to do drop shadows : svg filter, canvas, and css.
Does this module intend to be general purpose or simple ? I don’t see how it can be both.
And as everyone seems to want different features, if you want to content everyone, then you’re developing yet another general solution.
Do implementors really like to develop three implementations ?
Do authors really need this third coice ?
I really don’t know the answers, but as an author, I prefer to have one functional technique instead of three work-in-progress ones.
Thanks.
I really think we need to look at this from the absolute core need/use of shadows, to differentiate or separate visual layers of information.
A photo from the page it’s on, a window from the GUI, or a window from another window, a menu from the surrounding content. It’s always to make something more obvious. It’s to make it easier for the viewer/user’s mind to see what is important right now.
I totally agree with Brian’s post above, some tweaks to his concept.
I would use “offset” instead of “distance” simply because it’s already used in CSS as a keyword, where I don’t think “distance” is… and “blur” instead of “size”, as it implies soft vs hard, and a size dimension at the same time. (refer to Fireworks when adding a drop-shadow to an object)
drop-shadow
drop-shadow-offset: [em|ex|percent|px|pt|picas|in|cm|mm];
drop-shadow-blur: [em|ex|percent|px|pt|picas|in|cm|mm];
drop-shadow-angle: [degrees];
drop-shadow-opacity: [em|ex|percent];
drop-shadow-color: [RGB|hexadecimal|name|background|border];
drop-shadow (single line declaration)
drop-shadow: 10px 10px 270 30 #000;
inner-shadow
inner-shadow-offset: [em|ex|percent|px|pt|picas|in|cm|mm];
inner-shadow-blur: [em|ex|percent|px|pt|picas|in|cm|mm];
inner-shadow-angle: [degrees];
inner-shadow-opacity: [em|ex|percent];
inner-shadow-color: [RGB|hexadecimal|name|background|border];
inner-shadow (single line declaration)
inner-shadow: 10px 10px 270 30 #000;
If you wanted to combine the concept of a glow AND shadow it may not be a bad idea, all that would be needed is a thickness/width attribute and a combination of values would give you a glow or a shadow… not sure what you’d name the selector though…
I would like to make rounded corner shadows.
With CSS3 this could probably follow the new rounded cornered divs.
[...] In A Refreshed Design for 2008 by Don’t Trust This Guy, I found a glimpse of some of the new CSS3 features and possibilities including multiple background images and CSS drop shadows. [...]
I’d like to add my opinion about the opacity of shadows.
The basic behaviour of shadows should be to follow the opacity of the shadowed element as closely as possible (shadow-opacity: inherit?).
In case a opacity is set for the shadow it should overrule the opacity of the element (when concidered for shadowing) (shadow-opacity: 50%).
While the first option would create the shadow based on the exact opacity of the shadowed element, the second option would generate a shadow, which would look like the shadowed element had a (constant) opacity of 50% (independant of actual opacity).
This would leave the choice to the designer, if he wanted the shadow to follow actual opacity or if he wanted a simple (and fixed) opacity.
Perhaps I am too simplistic, but some of these comments are clearly out of hand. CSS trying to figure out how to clearly represent a drop shadow of an upper layer element through a lower layer opaqued element? Figuring out where the light source is located? Come on. This stuff is way too advanced.
CSS isn’t meant to replace all graphics. If you want something to be perfect, whip out photoshop, make it right, and put it on your page as a graphic. In my mind, CSS drop shadows should make it easy to give an object a simple drop shadow for th purpose of adding depth to an object on your page. If it starts taking longer to figure out all the properties of the drop-shadow element than it does to open photoshop and do the work there, what was the point?
(I realize that some of the issues here are important to work out, but keeping it simple and getting it out the door are important too).
[...] Drop Shadows [...]
How about something like this:
drop-shadow-width: 5px;
drop-shadow-offset: 5px;
drop-shadow-color: #333333;
drop-shadow-direction: 300; /*degrees*/
drop-shadow-transparency: 80%; /*100% equals none*/
Really, all you have to do is look at a typical image editing program and steal any of the features they offer. The less we have to open the program up the better.
I just want to be able to get rid of extra divs that are currently needed to have a drop shadow grow and shrink with the box (like this example: http://battletech.hopto.org/html_tutorials/eightcorners/template.html ). I want to save code. I would like CSS to be able to do a simple drop shadow, and I agree that CSS can do the basics. If I want a shadow to follow an image (like the diamonds discussed above) that’s the work for images, sorry. The main things I consider when making image-based borders is:
solid line or soft (fading at the edges like an actual shadow)
how far and what direction offset from the box.
I don’t ever consider borders or transparency– I consider the Edge of the element, which always includes padding and border if there is one. You guys can decide how opaque the shadow is depending on the opacity of the box, but since I currently always have to have two boxes (if I set low opacity on a div, I MUST put my non-opaque text in another container on top, which seems to be against what most people expect), it doesn’t matter to me.
I did not consider Emo’s “cast” shadow as opposed to “drop” shadow but it could be a possibility. I don’t see it that often and myself have never used it… my light sources are always from above a flat page, even with an angle.
But basically, anything that removes both images and extra containers from code is good.