-1

trying to change opacity of all other siblings of an item (anchor tag which wraps an image) in a div when user hovers over 1 of the items in the div.

It partially works but when i hover over an item all siblings on bottom-right of hovered sibling change opacity but all siblings on top-left do not, not sure what i am doing wrong. See example below (where i am hovering over 2nd row 2nd column item) enter image description here What am I doing wrong? Thank you!

I've changed background color to red of the sibling items being changed to make it more clear.

Code:

<!DOCTYPE html>
<html>
    <head>
    <title>HTML CSS JS</title>
    <style>
        /* CSS styles */

    #imageTextGrid{
        padding-top: 80px;
        max-width:95vw;
        display:grid;
        
        grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
        gap:40px;
        
        /* slide in+opacity animation */
        /* opacity: 0; */
        position: relative;
        /* left: -80%; */
        margin: auto;
        animation: slide-in 1s forwards;
       
        transition: opacity 1s;
    }

    #imageTextGrid a:hover{
        opacity:0.2;
    }
    #imageTextGrid a:hover ~ a{
        opacity:0.5;
        background-color: red;
    }

    </style>
    </head>
    <body>
        <!-- Header -->
        <div  id="imageTextGrid" name="overview"  >
            <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a> <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
        </div>

</html>

Current result after changing code (GIF): Style is already applied to image when cursor is slightly to the right of image (not in image itself yet). It should only be applied when cursor is on image itself.

When Starting hovering effect (moving mouse onto image element), the styles are being applied when thumb (most leftside point of cursor) touches edge of image: enter image description here

When ending hovering effect (moving mouse off of image element), the styles are being removed/de-applied when pointy finger of cursor (highest point of cursor) touches edge of image: enter image description here

Why is a different point on the cursor being used when starting the hover state compared to when ending the hover state (to determine when an element is being hovered over)?

Current Code:

<!DOCTYPE html>
<html>
    <head>
    <title>HTML CSS JS</title>
    <style>
        /* CSS styles */

    #imageTextGrid{
        padding-top: 80px;
        max-width:95vw;
        display:grid;
        
        grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
        gap:40px;
        
        /* slide in+opacity animation */
        /* opacity: 0; */
        position: relative;
        /* left: -80%; */
        margin: auto;
        animation: slide-in 1s forwards;
       
        transition: opacity 1s;
    }

    #imageTextGrid.hovered img {
        opacity: 0.5;
        background-color: red;          
      }
      #imageTextGrid.hovered img:hover {
        opacity: 1;
      }

    </style>
    </head>
    <body>
        <!-- Header -->
        <div  id="imageTextGrid" name="overview"  >
            <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a> <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
            <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
        </div>

<script>

const links = document.querySelectorAll('.gridImg');
      const parent = document.querySelector('#imageTextGrid');
      
      for(const link of links) {
        link.addEventListener('mouseover', function() {
            parent.classList.add('hovered');
        });
        link.addEventListener('mouseout', function() {
            parent.classList.remove('hovered');
        })
      }
</script>

</html>
  • 1
    https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator: _"The general sibling combinator (~) separates two selectors and matches all iterations of the second element, that are **following the first element** (though not necessarily immediately), and are children of the same parent element."_ – CBroe Mar 01 '23 at 09:21

1 Answers1

1

You are unable to do this only with CSS, because there is no CSS rule to change styles of previous siblings (both + and ~ indicates next siblings only).

Here is this topic explained: Is there a "previous sibling" selector?

But you can achieve this with simple JS code:

<!DOCTYPE html>
<html>
  <head>
    <title>HTML CSS JS</title>
    <style>
      /* CSS styles */
      #imageTextGrid{
        padding-top: 80px;
        max-width:95vw;
        display:grid;
        grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
        gap:40px;
        /* slide in+opacity animation */
        /* opacity: 0; */
        position: relative;
        /* left: -80%; */
        margin: auto;
        animation: slide-in 1s forwards;
        transition: opacity 1s;
      }
      #imageTextGrid.hovered img {
        opacity: 0.5;
        background-color: red;          
      }
      #imageTextGrid.hovered img:hover {
        opacity: 0.2;
      }
    </style>
  </head>
  <body>
    <!-- Header -->
    <div id="imageTextGrid" name="overview"  >
      <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a> <a href="#" class="gridImg"><img class="popupHanne" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupIjsselmuiden" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
      <a href="#2" class="gridImg"><img class="popupApeldoorn" src="https://www.uri.edu/wordpress/wp-content/uploads/home/sites/7/500x500.png" /></a>
    </div>
    <script>
      const links = document.querySelectorAll('.gridImg img');
      const parent = document.querySelector('#imageTextGrid');
      
      for(const link of links) {
        link.addEventListener('mouseover', function() {
            parent.classList.add('hovered');
        });
        link.addEventListener('mouseout', function() {
            parent.classList.remove('hovered');
        })
      }
    </script>
  </body>
</html>
qiqqq
  • 631
  • 5
  • 10
  • Thank you @qiqqq for the clear answer. One more question if I may: If i want to change the css/js code such that the properties 'opacity' and 'background color' are being applied to the image elements inside the anchor tags (currently the properties are being applied to the anchor elements) And change the code such that the styles are only being applied when user hovers over image element (instead of anchor element). how can i do this? Thank you! – Maarten -Monica for president Mar 01 '23 at 13:47
  • To do this you need to change these two CSS rules to point `img` element instead of `a` element. I edited the above code. Is this what you mean? – qiqqq Mar 01 '23 at 14:03
  • I think this is what i mean but it doesnt seem to do what i intented. The 'issue' I was trying to solve with the original code is that the anchor element is slightly bigger than the image element, therfore when use hovers close to image (hovers over anchor element but not over image itself) the properties (opacity and bg-color) are already applied. I would like the properties to only be applied when user hover over the img itself. However, even with the edited code, when i put my cursor just to the right of an image (on anchor element but not on image element), the styles are applied.. – Maarten -Monica for president Mar 01 '23 at 14:11
  • I changed the element on which we detect mouseover to `img` instead of `a` in the code above. I think this is what you mean, right? – qiqqq Mar 01 '23 at 14:18
  • I thought indeed that what you suggested/changed to the code would solve the issue and that the styles would only be applied when cursor hovers over image element itself but for some reason that doesn't happen and the styles are already applied when cursor is slightly to the right of image (See edit of original answer on the bottom please with added (GIF) image to show the issue (styles being applied when cursor is not hovered directly over image element) and I've also adding the current code. Thank you again! – Maarten -Monica for president Mar 01 '23 at 23:01
  • actually i think the code is working as it should, however i find it a bit strange that it seems like when the cursor changes to the hand cursor (when hovering over image) the styles are being applied to the image element when the thumb (left most side of the cursor) reaches the edge of the image, and when removing the cursor from the image again the styles are removed from the element (goes back to initial state) when the pointing finger (top most point of cursor) goes past the edge of the image. – Maarten -Monica for president Mar 01 '23 at 23:09
  • I don't know why a different point seems to be used when placing mouse onto image element and removing cursor from image element to determine when element is being hovered over or not. I'll add another GIF image to the original post to show this – Maarten -Monica for president Mar 01 '23 at 23:10
  • Please see the GIF images and explanations added to the end of my original post – Maarten -Monica for president Mar 01 '23 at 23:19
  • Apparently this is normal behaviour for CSS's hover event: "When you start the hover event by moving the cursor onto the image, the mouseover event is triggered as soon as the cursor touches any part of the image, and the hovered class is added to the parent element. However, when you end the hover event by moving the cursor off the image, the mouseout event is triggered only when the cursor moves completely off the image, and the hovered class is removed from the parent element." – Maarten -Monica for president Mar 02 '23 at 00:03
  • 1
    @Maarten-Monicaforpresident I see one difference between your's current code and the code I edited in the answer. Change the JS part from `const links = document.querySelectorAll('.gridImg');` to `const links = document.querySelectorAll('.gridImg img');`. – qiqqq Mar 02 '23 at 10:50