252

I have the following CSS:

box-shadow: inset 0px 0px 2px #a00;

Now I am trying to extract that color to make the page colors 'skinnable'. Is there any way of doing this? Simply removing the color, and then using the same key again later overwrites the original rule.

There doesn't seem to be a box-shadow-color, at least Google turns nothing up.

fregante
  • 29,050
  • 14
  • 119
  • 159
Epaga
  • 38,231
  • 58
  • 157
  • 245

5 Answers5

365

Actually… there is! Sort of. box-shadow defaults to color, just like border does.

According to http://dev.w3.org/.../#the-box-shadow

The color is the color of the shadow. If the color is absent, the used color is taken from the ‘color’ property.

In practice, you have to change the color property and leave box-shadow without a color:

box-shadow: 1px 2px 3px;
color: #a00;

Support

  • Safari 6+
  • Chrome 20+ (at least)
  • Firefox 13+ (at least)
  • IE9+ (IE8 doesn't support box-shadow at all)

Demo

div {
    box-shadow: 0 0 50px;
    transition: 0.3s color;
}
.green {
    color: green;
}
.red {
    color: red;
}
div:hover {
    color: yellow;
}

/*demo style*/
body {
    text-align: center;
}
div {
    display: inline-block;
    background: white;
    height: 100px;
    width: 100px;
    margin: 30px;
    border-radius: 50%;
}
<div class="green"></div>
<div class="red"></div>

The bug mentioned in the comment below has since been fixed :)

fregante
  • 29,050
  • 14
  • 119
  • 159
  • 3
    There is a bug in Chrome 22 (canary) in CSS animations causing box-shadow to not inherit the animated `color` property. https://code.google.com/p/chromium/issues/detail?id=133745 – David Murdoch Jun 20 '12 at 16:50
  • 24
    Good hack, if there is no text in the element. – Ivin Oct 25 '12 at 20:50
  • 16
    Yeah, otherwise you'd have to wrap it up and reapply `color` to the child element. – fregante Oct 27 '12 at 16:01
  • 3
    I can confirm it's the same for IE10. – MaxArt May 02 '13 at 10:03
  • 1
    Has w3c become mad? Why they want us to use this kind of hacks? Is it so difficult to make `box-shadow` a shorthand property? – Oriol Aug 08 '13 at 15:39
  • 5
    Thanks for a sensible and **relevant** answer. +10 to you! – kumarharsh Sep 25 '13 at 12:31
  • 1
    @Oriol: A "hack" is by definition an unintended way of achieving something by abusing other intended behavior. I don't think box-shadow not being a shorthand is relevant at all to the fact that its default color is `currentColor`, and I certainly don't think they *wanted* authors to resort to such hacks. They just didn't design `box-shadow` with this use case in mind for whatever reason. That being said, there is nothing stopping you from proposing making `box-shadow` a shorthand in Background and Borders 4. I'd love to see if they have any reason against it. – BoltClock Mar 07 '15 at 05:41
  • @kumar_harsh: This answer is only sensible and relevant to **you** presumably because you were in the exact situation described in the above comments - or otherwise didn't need to account for the color property or were able to work around it. It's unfair to call it those things in a generalized manner because it only works in certain situations, not all. – BoltClock Mar 07 '15 at 05:56
  • 2
    FWIW, I upvoted this answer as well as the accepted one. If you *cannot* work around being forced to change the color of the element's text content against your will, then this answer will not work for you, but that does not make it any less useful in situations where you *can* use it, and neither does that make it *better* than the accepted answer or make the accepted answer wrong. – BoltClock Mar 07 '15 at 06:01
  • @BoltClock Yep, I sounded a little raw in my comment with the generalization. But the core of that comment was that although Andy's answer was correct on all counts, it didn't help the issue the OP was facing. This answer did. That's all. – kumarharsh Mar 07 '15 at 09:35
  • @ivin even if you have text in that element, you can work around it without necessarily adding a wrapper. smth like h1,h2,p{ //override color; }. It's not perfect but still way better than working around the lack of color property for the box shadow – Vincent Dec 10 '22 at 07:37
  • Hmm, works fine, but what if we have text in this element that should NOT have the same color like the shadow? – Radon8472 Feb 20 '23 at 09:20
178

No:

http://www.w3.org/TR/css3-background/#the-box-shadow

You can verify this in Chrome and Firefox by checking the list of computed styles. Other properties that have shorthand methods (like border-radius) have their variations defined in the spec.

As with most missing "long-hand" CSS properties, CSS variables can solve this problem:

#el {
    --box-shadow-color: palegoldenrod;
    box-shadow: 1px 2px 3px var(--box-shadow-color);
}

#el:hover {
    --box-shadow-color: goldenrod;
}
Andy E
  • 338,112
  • 86
  • 474
  • 445
  • 8
    That's a great use of variables! Let's hope that they'll be [supported](http://caniuse.com/css-variables) in all browsers within the next few years :/ – fregante Aug 18 '15 at 00:10
  • 7
    As of 2019, [all major browsers support CSS variables](https://caniuse.com/#feat=css-variables). –  Jun 24 '19 at 14:24
  • 3
    ... unless you have to support IE still – Cam Jackson Dec 11 '19 at 08:00
  • 2
    Won't work if you don't control the original rule. I think it's a glaring lack in the CSS spec that this color can't be set individually. – silverwind Dec 10 '20 at 09:05
6

You can do this with CSS Variable

.box-shadow {
    --box-shadow-color: #000; /* Declaring the variable */
    width: 30px;                
    height: 30px;
    box-shadow: 1px 1px 25px var(--box-shadow-color); /* Calling the variable */

}

.box-shadow:hover  {
    --box-shadow-color: #ff0000; /* Changing the value of the variable */
}
Sandeep Sherpur
  • 2,418
  • 25
  • 27
4

You could use a CSS pre-processor to do your skinning. With Sass you can do something similar to this:

_theme1.scss:

$theme-primary-color: #a00;
$theme-secondary-color: #d00;
// etc.

_theme2.scss:

$theme-primary-color: #666;
$theme-secondary-color: #ccc;
// etc.

styles.scss:

// import whichever theme you want to use
@import 'theme2';

-webkit-box-shadow: inset 0px 0px 2px $theme-primary-color;
-moz-box-shadow: inset 0px 0px 2px $theme-primary-color;

If it's not site wide theming but class based theming you need, then you can do this: http://codepen.io/jjenzz/pen/EaAzo

jjenzz
  • 1,519
  • 1
  • 14
  • 19
-7

A quick and copy/paste you can use for Chrome and Firefox would be: (change the stuff after the # to change the color)

-moz-border-radius: 10px;
-webkit-border-radius: 10px;
-khtml-border-radius: 10px;
-border-radius: 10px;
-moz-box-shadow: 0 0 15px 5px #666;
-webkit-box-shadow: 0 0 15px 05px #666;

Matt Roberts' answer is correct for webkit browsers (safari, chrome, etc), but I thought someone out there might want a quick answer rather than be told to learn to program to make some shadows.

andytuba
  • 187
  • 9