How to easily set a fade effect for featured images in WordPress

Ever since working through the mdn web doc modules for CSS I’ve been incorporating more and more here at Click Press Play. I’ve also wanted to document what I’ve learned through research, troubleshooting, and implementation here more as well. I never thought something like setting a fade and transition would frustrate me to no end, but then I’m learning that there’s always a curve ball just around the bend in web development.

This was ultimately a reminder in the importance of selector specificity, and never discounting simple errors. To get right to it, here’s the code:

/*.post-image is the CSS selector (class) for featured images in WordPress */
.post-image {
  opacity: 1; 	
  transition: opacity 3s;
	
}
.post-image:hover {
	
  opacity: .7;
  transition: opacity 1s;
	
	
}

As mentioned above, .post-image is the selector that refers to featured images in WordPress. More specifically, it’s the class for featured images for your blog posts index and category page archives. At least in GeneratePress, the code above will not affect featured images on actual post pages. The selector for featured images within actual post pages is .featured-image.

What the code above does is alter the opacity on when hovering over a featured image so that it produces a sort of fade effect. Initially I had used transition: 3s; but I believe that best practice is to write out transition: opacity 3s; instead.

Normal opacity featured image vs fade effect after hovering (forgive the misalignment…)

The transition shorthand actually encompasses four different sub-properties. They are:

Mozilla offers a fantastic overview of CSS transitions on the related mdn web docs page. What made everything click for me was landing on a great little CSS Tricks article. To boil it down, the following code controls the transition when taking your mouse off the image (back to the original opacity):

/* Mouse out/off transition */
.post-image {
  opacity: 1; 	
  transition: opacity 3s;
	
}

And this code controls the transition from baseline opacity to that when the image is hovered over:

/* Mouse on/hover transition */
.post-image:hover {
	
  opacity: .7;
  transition: opacity 1s;
	
	
}

If you notice, the CSS Tricks article includes the code:

-webkit-transition: padding 2s;

And:

-webkit-transition: border-radius 2s;

It’s no longer necessary in today’s world. This article is older, and the transition property and its sub-properties are supported by all major browsers. I believe it has since been deprecated (please correct me if I’m wrong!).

Simple enough, right? The real problem for me was overlooking specificity. I was originally looking for CSS transition or hover type effects, and used something that I had found (the original website escapes me). After a bit of frustration I realized that there was one crucial mistake with my code, and I’m hoping that I can help at least one other person who may be tripped up with this.

This was the difference:


.post-image {
  opacity: 1; 	
  transition: opacity 3s;
	
}
/* img element throws it all off */
.post-image img:hover {
	
  opacity: .7;
  transition: opacity 1s;
	
	
}

After removing the img element everything was fine. If I had to take the stab at the why, while .post-image:hover already has a higher level of specificity than .post-image, specifying the img element on top of the .post-image class throws off the relationship between the two states (mouse on and mouse off).

While writing this, I had the idea of testing whether or not I could “restore” equality, because in essence I realized that the misbehaving code refers to two different elements. The bad code is actually referring to the descendant (img) of post-image. When “balancing things out” with the following code everything seems to work:

.post-image img {
	
	opacity: 1; 
	transition: opacity 3s;
	
}
.post-image img:hover{
	
	opacity:.7;
	transition: opacity 1s;
	
}

They are now both referring to the descendant img element of post-image, and they are affecting opposite events of the same element. I hope this could help someone work things out between CSS and WordPress. Please feel free to comment if you notice any mistakes or have something to add.

Leave a Comment