How to hide an image if another image appears?

Sometimes both my main content region and my sidebar region contain an image near their top and this situation may cause a “graphical clash” that will interrupt some users to focus on the main content region.
That’s especially true if the image near the top of the sidebar is dark and the image near the top of the main content region is bright or very colorful.

To solve this problem I use JavaScript to check if the main content region contains a top image and if it does then I remove the sidebar top image.

if  (
    document.querySelector('#block-globalrs-content > div > article > div > div.text-content.clearfix.field.field--name-body.field--type-text-with-summary.field--label-hidden.field__item > img')
    ) {
    document.querySelector('.region--sidebar .block:first-of-type:has(img)').remove();
};

Is there a better way? With mere CSS perhaps?

Depending on structure you could much the same as you did in js using :has.

e.g. A simpler example.

2 Likes

Amazing :slight_smile:

Just a thought: I wish that CSS developers would allow to add if and then keywords sometimes, so instead this:

body:has(#block-globalrs-content > div > article > div > div.text-content.clearfix.field.field--name-body.field--type-text-with-summary.field--label-hidden.field__item > img) .region--sidebar .block:first-of-type:has(img) {
	display: none;
}

We could have done this:

IF 
body:has(#block-globalrs-content > div > article > div > div.text-content.clearfix.field.field--name-body.field--type-text-with-summary.field--label-hidden.field__item > img)
THEN
.region--sidebar .block:first-of-type:has(img) {
	display: none;
}
1 Like

I suppose it would have been more readable but essentially it’s the same.

I was wondering if you need to be so specific though. Is there not a shorter path to the images in question that isn’t ambiguous?

Maybe you already have a class on the image you could use as a target rather than the full path.

1 Like

There are no classes for these images. It may well be that I need to start giving some :slight_smile:

1 Like

Using CSS to address this issue would be challenging because CSS is not designed to make decisions based on content. It merely applies styles according to set rules. However, an alternative approach could be using the Intersection Observer API, a powerful JavaScript tool that allows you to configure a callback when an element enters or exits the viewport. This way, you can dynamically alter the appearance of your sidebar image based on whether the main content image is in view or not.

In case the Intersection Observer API is too complex for your needs, or if you require a solution that works on legacy browsers, you can stick with JavaScript but optimize your implementation. To reduce DOM traversal and make your code faster, consider caching your selectors like this:

var mainContentImage = document.querySelector('#block-globalrs-content > div > article > div > div.text-content.clearfix.field.field--name-body.field--type-text-with-summary.field--label-hidden.field__item > img');
var sidebarImage = document.querySelector('.region--sidebar .block:first-of-type:has(img)');

if (mainContentImage) {
    sidebarImage.remove();
}

This way, the browser only needs to traverse the DOM once for each selector, no matter how many times you refer to the elements in your code.

That’s not true anymore because that’s exactly what :has will do as shown in my answer. It allows a choice to be made based on the presence of some other element.

3 Likes