2

I'm currently attempting to get the background image of #InnerImage to fade out. Here is the code for #InnerImage:

<div id="InnerImage" style="background-image:url('imgurl.com'););background-repeat:no-repeat;background-position:50% 0%;">

Here's the code that I'm using:

#OuterImage #InnerImage {
    -webkit-animation: 3s ease 0s normal forwards 1 fadein;
    animation: 3s ease 0s normal forwards 1 fadein;
}

@keyframes fadein{
    0% { opacity:0; }
    66% { opacity:0; }
    100% { opacity:1; }
}

@-webkit-keyframes fadein{
    0% { opacity:0; }
    66% { opacity:0; }
    100% { opacity:1; }
}

I'm running into an issue where the code is making every other child(?) div within #InnerImage fade out as well, but I only want the background-image to fade.




I have two questions:
1) I did read that it was not possible for background-image opacity changes that the above code is performing. Is there a work around for this?
2) How do I go about making it so that after the image has been faded in, it fades back out in an infinite loop?

[EDIT]

#OuterImage #InnerImage{
    -webkit-animation: 3s ease 0s normal forwards 1 fadein;
    animation: 3s ease 0s normal forwards 1 fadein;
    animation-iteration-count: infinite;
}

@keyframes fadein{
    0% { opacity:0; }
    66% { opacity:0; }
    100% { opacity:1; }
}

@-webkit-keyframes fadein{
    0% { opacity:0; }
    66% { opacity:0; }
    100% { opacity:1; }
}


#OuterImage #InnerImage::before { 
background: url('imgurl.com') no-repeat center left;
  content: "";
  position: absolute;
  /* the following makes the pseudo element stretch to all sides of host element */
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  transition: opacity 1s ease 2s;
  z-index: 1;
}
#OuterImage #InnerImage {
  position: relative;}
#OuterImage #InnerImage * {
  position: relative;
  z-index: 2;
}
#OuterImage #InnerImage
lolikols
  • 87
  • 1
  • 5
  • 24

2 Answers2

7

Answer to your first question:

Put the background-image on a pseudo element ::before instead:

#InnerImage::before {
  background: url('imgurl.com') no-repeat center left;
  content: "";
  position: absolute;
  /* the following makes the pseudo element stretch to all sides of host element */
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: 1;
}

This requires to set position: relative; on #InnerImage:

#InnerImage {
  position: relative;
}

and you need to make sure all other child elements are above the pseudo element using z-index (which only applies the way you need if you position those elements):

#InnerImage * {
  position: relative;
  z-index: 2;
}

Notice: #OuterImage #InnerImage can be safely shortened to #InnerImage since there may be only one element on a page with any given id value anyway. Also I'd advise not to use id selectors in CSS unless you know for sure why you are doing it.

Regarding your animation, it seems like you want it to start only after two seconds have gone by. This can be achieve using a transition like this:

transition: opacity 1s ease 2s;

where 1s is transition-duration and 2s is transition-delay.

https://developer.mozilla.org/en/docs/Web/CSS/transition

Example:

#InnerImage::before {
  background: url(http://lorempixel.com/300/200) no-repeat center left;
  content: "";
  position: absolute;
  /* the following makes the pseudo element stretch to all sides of host element */
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  transition: opacity 1s ease 2s;
  z-index: 1;
}
#InnerImage {
  position: relative;
  width: 300px;
  height: 200px;
}
#InnerImage * {
  position: relative;
  z-index: 2;
}

#InnerImage:hover::before {
  opacity: 0.25;
}
<div id="InnerImage">
  <h2>Hey!</h2>
  <button>noop</button>
</div>

If you want a permanently on-going fadein-fadeout, you'll have to go with an animation instead of a transition.

#InnerImage::before {
  background: url(http://lorempixel.com/300/200) no-repeat center left;
  content: "";
  position: absolute;
  /* the following makes the pseudo element stretch to all sides of host element */
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  animation: 3s ease 0s normal forwards 1 fadein;
  animation-iteration-count: infinite;
}
#InnerImage {
  position: relative;
  width: 300px;
  height: 200px;
}
#InnerImage * {
  position: relative;
  z-index: 2;
}
@keyframes fadein{
    0% { opacity:0; }
    50% { opacity: 1; }
    100% { opacity:0; }
}
<div id="InnerImage">
  <h2>Hey!</h2>
  <button>noop</button>
</div>
connexo
  • 53,704
  • 14
  • 91
  • 128
  • connexo, thank you. I did try this code but nothing is happening. No animations or anything. – lolikols Dec 15 '16 at 14:44
  • Sorry, I guess I should be more specific. So for this line: #InnerImage { position: relative; width: 300px; height: 200px; } I removed the width and height since it was making my background image into a cube and it's a banner instead :). But some of the formatting is off. Some child elements are now misaligned, and the transitions are not working. – lolikols Dec 15 '16 at 14:52
  • A transition needs a triggering event. In the example I used `:hover` for that. Since you described you want an infinite loop you'll probably have to go with the animation. – connexo Dec 15 '16 at 15:09
  • Regarding the dimensions I chose, those were just arbitrarily chosen values for having a working example. Adjust to your needs. – connexo Dec 15 '16 at 15:14
  • Added a second snippet that uses an infinite animation. – connexo Dec 15 '16 at 15:21
  • connexo, thanks! The code I was using before made the background image (it was alright part of the website) fade away. It looks like your code applies the background image again in a fading animation. Is there a way to change this? Also some of the child elements are misaligned now. I'm not quite sure where in your code this is happening. – lolikols Dec 15 '16 at 15:55
  • I fixed the child elements using position: absolute and such. Still curious about the backgroundimage though. – lolikols Dec 15 '16 at 16:01
  • I don't understand what you are asking with regard to the `background-image`, but I'm almost 100% sure it does not have *anything* to do with your original question, right? When have we reached the point where you will say "Okay, Im good to go further on my own now from here"? – connexo Dec 15 '16 at 16:48
  • connexo, so in my original question I asked "I'm running into an issue where the code is making every other child(?) div within #InnerImage fade out as well, but I only want the background-image to fade." I already have the background image put in there through HTML. So the question was how do I get it to fade in and out while it's already there. Your code, while it works beautifully, it adds the background image and fades it in and out. – lolikols Dec 15 '16 at 19:52
3

To animate in an infinite loop you can use the animation-iteration-count property and set the value to infinite.

#OuterImage #InnerImage {
  -webkit-animation: 3s ease 0s normal forwards 1 fadein;
  animation: 3s ease 0s normal forwards 1 fadein;
  animation-iteration-count: infinite;
}

Changing the opacity of an element will effect all child elements there is no way around that.

A work around you may consider is to create a element inside #InnerImage that solely handles the background. You set the background div to be position absolute, with a z-index of 0, then animate only this div. That way the other elements will not change in opacity as the animation changes.

#InnerImage {
    height:200px;
    position:relative;
}

.bg {
    position: absolute;
    height: 100%;
    width: 100%;
    background: red;
    z-index: 0;
    animation-name: fadein;
    animation-duration: 6s;
    animation-fill-mode: forwards;
    animation-iteration-count: infinite;
}

.content {
  position: relative;
}


@keyframes fadein{
    0% { opacity:0; }
    50% { opacity:1; }
    100% { opacity:0; }
}
<div id="InnerImage">
  <div class="bg"></div>
  <div class="content">other content</div>
</div>

Note in the example the text content does not fade while the background does

bob
  • 983
  • 11
  • 21