skip to Main Content

Having problems where I have a background gradient and a background image (transparent PNG) for my div, but no matter what, only the color gradient will display and not the image. If I do it as a solid color, I can get the image to display. Here’s my current CSS;

div {
  background: linear-gradient(180deg, rgba(224, 34, 153, 1) 0%, rgba(88, 0, 55, 1) 100%), url('path/to/image/png') no-repeat;
}

Any way to make this work without the addition of another div?

2

Answers


  1. These are layered atop one another with the first background you provide on top and the last background listed in the back. MDN Docs

    div {
      width: 100vw;
      height: 100vh;
      background: url('https://interactive-examples.mdn.mozilla.net/media/examples/lizard.png') no-repeat, linear-gradient(180deg, rgba(224, 34, 153, 1) 0%, rgba(88, 0, 55, 1) 100%);
    }
    
    * {
      margin: 0;
      padding: 0;
    }
    <div></div>
    Login or Signup to reply.
  2. solution as commented:

    • Given the OP example CSS simply add background-blend-mode: overlay and optionally fiddle with the rgb() color opacity value to fine-tune the end result. Depending on the required end result, you may need to swap the image and gradient in the background definition as the order does matter.

    extra

    To test the solution myself, I created a fun demo to demonstrate the difference between the original order versus the image and gradient getting swapped.

    As you can see in the demo, I used background-image instead of the shorthand background property. This will help code optimization when you want to reuse or vary on the background definition.

    Lastly, as background color I used the complementary color of the gradients purple to demonstrate a background-blend-mode with a delimited list of different blend modes (see .grad4 and .grad5).

    bonus

    Make sure to enable [class*="grad"] { background-attachment } and see what happens when the browser window gets resized…

    snippet

    .wrapper {
        /* Create a few custom properties for easy manipulation */
        --opacity : 1;
        --image   : url('https://picsum.photos/id/26/1000');
        --gradient: linear-gradient(180deg, rgb(224,34,153, var(--opacity)) 0%,
                                            rgb( 88, 0, 55, var(--opacity)) 100%);
    }
    
    /* Define background variations for demo use */
    .grad0         { background-image: var(--image) }
    .grad1         { background-image: var(--gradient) }
    .grad2, .grad4 { background-image: var(--image), var(--gradient) }
    .grad3, .grad5 { background-image: var(--gradient), var(--image) }
    
    /* Solution as commented on SO (using above custom vars, though) */
    .solution {
        background: var(--gradient), var(--image) no-repeat;
        background-blend-mode: overlay; /* mix/match the image and gradient */
        background-size: cover;         /* [OPTIONAL], just to make the image fit */
    }
    
    [class*="grad"] { /* all elements with class containing 'grad' */
        background-repeat: no-repeat;
        background-blend-mode: overlay;
    
        /* toy with these */
        background-size      : cover; /* scale to fit */
    /*    background-attachment: fixed; /* for a shared bg */
    
    }
    .grad4, .grad5 {
         /* try swapping blend modes */
        background-blend-mode: overlay, difference;
        background-color: rgb(34,224,105, var(--opacity));
        /* A bright green, the complementary color of the purple color */
    }
    
    /***************************/
    /* just demo page settings */
    /***************************/
    *    { box-sizing: border-box }
    body { margin: 0 }
    
    .wrapper {
        display: flex; flex-flow: row wrap;
        justify-content: center;
        gap: 0.5rem; padding: 0.5rem;
    }
    
    .test {
        display: grid; place-items: center;
        width: 200px; aspect-ratio: 1;
    
        font-size: calc(1.25vmin + 0.5rem);
        /* y=mx+b => y=0.0125x + 8 with (320,12)(1280,24) */
    
        color: White; border: 1px solid Black;
    }
    <div class="wrapper">
        <div class="test grad0"   >image only    </div>
        <div class="test grad1"   >gradient only </div>
        <div class="test solution">solution      </div>
        <div class="test grad2"   >image first   </div>
        <div class="test grad3"   >gradient first</div>
        <div class="test grad4"   >image first   </div>
        <div class="test grad5"   >gradient first</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search