145

I have an element with text in it. Whenever I decrease the opacity, then I decrease the opacity of the WHOLE body. Is there any way I can just make the background-image darker, and not everything else?

background-image:url('http://fc02.deviantart.net/fs71/i/2011/274/6/f/ocean__sky__stars__and_you_by_muddymelly-d4bg1ub.png');
TylerH
  • 20,799
  • 66
  • 75
  • 101

11 Answers11

288

Just add this code to your image css

 body{
 background:
        /* top, transparent black, faked with gradient */ 
        linear-gradient(
          rgba(0, 0, 0, 0.7), 
          rgba(0, 0, 0, 0.7)
        ),
        /* bottom, image */
        url(https://images.unsplash.com/photo-1614030424754-24d0eebd46b2);
    }

Reference: linear-gradient() - CSS | MDN

UPDATE: Not all browsers support RGBa, so you should have a 'fallback color'. This color will be most likely be solid (fully opaque) ex:background:rgb(96, 96, 96). Refer to this blog for RGBa browser support.

UPDATE 2023: All modern browsers now supports RGBa : caniuse link

Reign.85
  • 2,420
  • 1
  • 28
  • 28
shin
  • 3,491
  • 1
  • 12
  • 17
  • 1
    Any cross browser issues with this? – Jon P Apr 22 '14 at 00:47
  • 13
    what is the property if we want to specify separately background-image and this? – Petruza Jan 13 '16 at 19:33
  • 2
    @Petruza it seems that we have no choice but use this syntax. Read the [reference](https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient): _"Because s belong to the data type, they can only be used where s can be used. For this reason, linear-gradient() won't work on background-color and other properties that use the data type"_ – Marco Panichi Sep 28 '18 at 13:25
29

Setting background-blend-mode to darken would be the most direct and shortest way to achieve the purpose however you must set a background-color first for the blend mode to work.
This is also the best way if you need to manipulate the values in javascript later on.

background: rgba(0, 0, 0, .65) url('http://fc02.deviantart.net/fs71/i/2011/274/6/f/ocean__sky__stars__and_you_by_muddymelly-d4bg1ub.png');
background-blend-mode: darken;

Can I use for background-blend

random_user_name
  • 25,694
  • 7
  • 76
  • 115
  • 4
    edge or IE11 is not really a browser – stackdave Dec 11 '19 at 04:30
  • 6
    Actually, this is the best answer, but if we don't want to touch background image url declaration (like `background` or `background-image`), this is perfect: `background-color: #0005; background-blend-mode: darken;` – Krzysztof Przygoda Nov 20 '21 at 01:14
25

when you want to brightness or darker of background-color, you can use this css code

.brighter-span {
  filter: brightness(150%);
}

.darker-span {
  filter: brightness(50%);
}
Trung
  • 1,819
  • 1
  • 13
  • 10
  • 1
    Thanks, I didn't know about css [filters](https://css-tricks.com/almanac/properties/f/filter/). In case it helps someone, here's [Can I Use](https://caniuse.com/#feat=css-filters) status (March, 2020). – Reed Dunkle Mar 08 '20 at 14:30
  • 6
    Note that this will brighten/darken everything (including text) inside of the element with these classes. – Heretic Monkey Jul 06 '22 at 14:11
21

Use an :after psuedo-element:

.overlay {
    position: relative;
    transition: all 1s;
}

.overlay:after {
    content: '\A';
    position: absolute;
    width: 100%; 
    height:100%;
    top:0; 
    left:0;
    background:rgba(0,0,0,0.5);
    opacity: 1;
    transition: all 0.5s;
    -webkit-transition: all 0.5s;
    -moz-transition: all 0.5s;
}
.overlay:hover:after {
    opacity: 0;
}

Check out my pen >

http://codepen.io/craigocurtis/pen/KzXYad

curtybear
  • 1,458
  • 2
  • 20
  • 39
8

It might be possible to do this with box-shadow

however, I can't get it to actually apply to an image. Only on solid color backgrounds

body {
  background: #131418;
  color: #999;
  text-align: center;
}
.mycooldiv {
  width: 400px;
  height: 300px;
  margin: 2% auto;
  border-radius: 100%;
}
.red {
  background: red
}
.blue {
  background: blue
}
.yellow {
  background: yellow
}
.green {
  background: green
}
#darken {
  box-shadow: inset 0px 0px 400px 110px rgba(0, 0, 0, .7);
  /*darkness level control - change the alpha value for the color for darken/ligheter effect */
}
Red
<div class="mycooldiv red"></div>
Darkened Red
<div class="mycooldiv red" id="darken"></div>
Blue
<div class="mycooldiv blue"></div>
Darkened Blue
<div class="mycooldiv blue" id="darken"></div>
Yellow
<div class="mycooldiv yellow"></div>
Darkened Yellow
<div class="mycooldiv yellow" id="darken"></div>
Green
<div class="mycooldiv green"></div>
Darkened Green
<div class="mycooldiv green" id="darken"></div>
3

You can use backdrop-filter: brightness(50%);

Warning:

  • "Because it applies to everything behind the element, to see the effect you must make the element or its background at least partially transparent".

  • Unfortunately for firefox, this requires at this time: User must explicitly enable the feature

Mulaga
  • 103
  • 8
2

You can use a container for your background, placed as absolute and negative z-index : http://jsfiddle.net/2YW7g/

HTML

<div class="main">
    <div class="bg">         
    </div>
    Hello World!!!!
</div>

CSS

.main{
    width:400px;
    height:400px;
    position:relative;
    color:red;
    background-color:transparent;
    font-size:18px;
}
.main .bg{
    position:absolute;
      width:400px;
    height:400px;
    background-image:url("http://fc02.deviantart.net/fs71/i/2011/274/6/f/ocean__sky__stars__and_you_by_muddymelly-d4bg1ub.png");
    z-index:-1;
}

.main:hover .bg{
    opacity:0.5;
}
Yooz
  • 2,506
  • 21
  • 31
2

Just to add to what's already here, use the following:

background: -moz-linear-gradient(rgba(0,0,0,.7),rgba(0,0,0,.7));
background: -webkit-linear-gradient(rgba(0,0,0,.7),rgba(0,0,0,.7));
background: linear-gradient(rgba(0,0,0,.7),rgba(0,0,0,.7));
filter: unquote("progid:DXImageTransform.Microsoft.gradient( startColorstr='#b3000000', endColorstr='#b3000000',GradientType=0 )");

...for cross-browser support of a 70% linear-gradient overlay. To brighten the image, you can change all those 0,0,0's into 255,255,255's. If 70% is a bit much, go ahead and change the .7. And, for future reference check out this: http://www.colorzilla.com/gradient-editor/

Alex Price
  • 83
  • 1
  • 6
2

For me the filter/gradient approach didn't work (perhaps due to the existing CSS) so I have used :before pseudo styling trick instead:

.eventBannerContainer {
    position: relative;
}
.eventBannerContainer:before {
    background-color: black;
    height: 100%;
    width: 100%;
    content: "";
    opacity: 0.5;
    position: absolute;
    display: block;
}
/* make any immediate child elements above our darkening mask */
.eventBannerContainer > * {
    position: relative;
}
Daniel Sokolowski
  • 11,982
  • 4
  • 69
  • 55
0

Based on Alex Price's answer I made an scss mixin:

@function decToHex($dec) {
    $dec: round($dec);
    $hex: "0123456789ABCDEF";
    $first: (($dec - $dec % 16)/16)+1;
    $second: ($dec % 16)+1;
    @return str-slice($hex, $first, $first) + str-slice($hex, $second, $second);
}

@mixin darken-bg ($darkAmount) {
    $filterHex: decToHex(255 * $darkAmount);
    background: -moz-linear-gradient(rgba(0, 0, 0, $darkAmount),rgba(0, 0, 0, $darkAmount));
    background: -webkit-linear-gradient(rgba(0, 0, 0, $darkAmount),rgba(0, 0, 0, $darkAmount));
    background: linear-gradient(rgba(0, 0, 0, $darkAmount),rgba(0, 0, 0, $darkAmount));
    filter: unquote("progid:DXImageTransform.Microsoft.gradient( startColorstr='##{$filterHex}000000', endColorstr='##{$filterHex}000000',GradientType=0 )");
}

/* usage */
.some-div {
    @include darken-bg(0.2);
}

decToHex based on Pierpaolo Cira answer

-1

This is the easiest way I found

  background: black;
  opacity: 0.5;