When I apply a filter to darken the background of an image to make the text readable, it applies to everything within the div.
.blog-container{
height: 400px;
position: relative;
display: inline-block;
color: #fff;
width: 280px;
background-size: 100% 100%;
border: 1px solid #000;
border-radius: 20px;
background-image: url("https://images.unsplash.com/photo-1688297969967-302de9c8bd5b?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D");
}
.blog-container:hover{
cursor: pointer;
transition: 0.5s;
filter: brightness(55%) saturation(140%); /* only way I've managed to darken the background */
}
.blog-title, .blog-desc{
width: 260px;
position: absolute;
bottom: 8px;
left: 18px;
opacity: 0;
}
.blog-title{
font-weight: 200;
font-size: 25px;
bottom: 45px;
}
.blog-container:hover .blog-title {
-webkit-animation: slide-up 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0s forwards;
}
.blog-container:hover .blog-desc{
-webkit-animation: slide-up 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s forwards;
}
@-webkit-keyframes slide-up {
0% { -webkit-transform: translateY(80%); opacity: 1 }
100% { -webkit-transform: translateY(0); opacity: 1 }
}
I'm expecting that when I hover over the div, the background-image darkens and the text slides in and is visible
Good effort! You're experiencing this issue because of how CSS inherently works: when you apply styling to a parent element, it naturally affects all the children inside it. This includes any filters or effects you add.
Here's my suggested approach:
To get around this, we should introduce a kind of 'intermediary' element. I've used
.blog-container::beforein this case, to dynamically generate an additional element. (You can read more about this approach in the MDN doc's - CSS ::before).We need to ensure we apply our visual changes at the same hierarchical level as your other child elements, like the title and description.
This
::beforeelement is set toposition: absolute, while its parent.blog-containerisposition: relative;. This allows us to position the::beforeelement independently of the document flow. (MDN Doc's - CSS Position)Then, we ensure this pseudo-element covers the entire parent (See Snippet). Don't forget to set
overflow: hiddenon the parent to prevent any spillover.Now that we've done that we can target
::beforeelement's hover effect to tell it what to do when the element has hover; independently of other children. - Magic!!Lastly, we sort out the stacking order. We do this by adjusting the
z-indexproperties. We set the z-index of the::beforeelement and the textual elements you want to appear on top. This ensures that the text is always visible and unaffected by the background effect.