0

So i've got a button on an image that i want to change the colour of when a user hovers over the image.

The css for the button itself

.prev{
    cursor: pointer;
    position: absolute;
    top: 50%;
    width: auto;
    padding: 16px;
    margin-top: -50px;
    color: white;
    font-weight: bold;
    font-size: 20px;
    transition: 0.6s ease;
    border-radius: 0 3px 3px 0;
    user-select: none;
    -webkit-user-select: none;

This is the html

   <body>

<h2 style="text-align:center">Lightbox</h2>

<div class="row">
  <div class="column">
    <img src="img_nature.jpg" style="width:100%" onclick="openModal();currentSlide(1)" class="hover-shadow cursor">
  </div>
  <div class="column">
    <img src="img_fjords.jpg" style="width:100%" onclick="openModal();currentSlide(2)" class="hover-shadow cursor">
  </div>
  <div class="column">
    <img src="img_mountains.jpg" style="width:100%" onclick="openModal();currentSlide(3)" class="hover-shadow cursor">
  </div>
  <div class="column">
    <img src="img_lights.jpg" style="width:100%" onclick="openModal();currentSlide(4)" class="hover-shadow cursor">
  </div>
</div>

<div id="myModal" class="modal">
  <span class="close cursor" onclick="closeModal()">&times;</span>
  <div class="modal-content">

    <div class="mySlides">
      <div class="numbertext">1 / 4</div>
      <img src="img_nature_wide.jpg" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">2 / 4</div>
      <img src="img_fjords_wide.jpg" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">3 / 4</div>
      <img src="img_mountains_wide.jpg" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">4 / 4</div>
      <img src="img_lights_wide.jpg" style="width:100%">
    </div>

    <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
    <a class="next" onclick="plusSlides(1)">&#10095;</a>

    <div class="caption-container">
      <p id="caption"></p>
    </div>


    <div class="column">
      <img class="demo cursor" src="img_nature_wide.jpg" style="width:100%" onclick="currentSlide(1)" alt="Nature and sunrise">
    </div>
    <div class="column">
      <img class="demo cursor" src="img_fjords_wide.jpg" style="width:100%" onclick="currentSlide(2)" alt="Trolltunga, Norway">
    </div>
    <div class="column">
      <img class="demo cursor" src="img_mountains_wide.jpg" style="width:100%" onclick="currentSlide(3)" alt="Mountains and fjords">
    </div>
    <div class="column">
      <img class="demo cursor" src="img_lights_wide.jpg" style="width:100%" onclick="currentSlide(4)" alt="Northern Lights">
    </div>
  </div>
</div>

This is the css i'm trying to use. div.mySlides is the div that contains my images.

.prev {
    color:white;
}

div.mySlides:hover + .prev, .prev:hover {
    color:red;
}

The javascript i'm using

<script>
function openModal() {
  document.getElementById('myModal').style.display = "block";
}

function closeModal() {
  document.getElementById('myModal').style.display = "none";
}

var slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex += n);
}

function currentSlide(n) {
  showSlides(slideIndex = n);
}

function showSlides(n) {
  var i;
  var slides = document.getElementsByClassName("mySlides");
  var dots = document.getElementsByClassName("demo");
  var captionText = document.getElementById("caption");
  if (n > slides.length) {slideIndex = 1}
  if (n < 1) {slideIndex = slides.length}
  for (i = 0; i < slides.length; i++) {
      slides[i].style.display = "none";
  }
  for (i = 0; i < dots.length; i++) {
      dots[i].className = dots[i].className.replace(" active", "");
  }
  slides[slideIndex-1].style.display = "block";
  dots[slideIndex-1].className += " active";
  captionText.innerHTML = dots[slideIndex-1].alt;
}
</script>

At the moment the color will change only when a user hovers over the button location. I've tried changing the order about in the css only to find nothing works.

  • 2
    You need to show us more of the HTML, so that we can see the actual relation between div.mySlides and .prev ... I kinda doubt that they are actually siblings. (And if they are not, this is probably to be considered another duplicate of https://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector) – CBroe Jan 09 '18 at 18:56
  • Also, you should consider whether this is even a wise choice, UX-wise - if the button changes color when I hover anywhere over the image already, then I might be tempted to click on the image at whatever current mouse pointer position, and expect this to achieve the same thing, as clicking the button would - does it ...? – CBroe Jan 09 '18 at 19:01
  • I understand that. I was more just trying to work out how to display buttons only on hover but I was finding it difficult to see the changes due to the images i was using so i opted to try and work out how to color change first. –  Jan 09 '18 at 19:04
  • Ok, so they are siblings ... and this basically works already, only for just the last .mySlides element, because you selected only the immediately following .prev sibling, instead of _all_ further siblings that have the class, no matter how "far" after the hovered div they come - that's the `~`, _general sibling combinator_. https://jsfiddle.net/tpdm9nwa/ shows that it works in principle (without going through the bother of adding actual images or additional styling.) – CBroe Jan 09 '18 at 19:05
  • @CBroe Well now you might as well post an answer ;) – UncaughtTypeError Jan 09 '18 at 19:15
  • Thankyou for the help. It seems like it should work but for some reason, i'm still having the same issue. I think i possible need to put the hover on the image rather than the div but i don't know. Putting the hover on div.mySlides and then giving it an opacity value shows the correct result but not anything to do with the button. –  Jan 09 '18 at 19:18
  • With the given HTML structure, this should work (provided + is exchanged for ~) - unless you have other CSS that interferes maybe. Stuff like this is usually best to debug in the browser dev tools - select one of the div elements, trigger the hover mode (in Chrome dev tools f.e. via the "..." shown in front of the element when you hover over it in the elements panel), and then check which CSS rules get actually applied to what. – CBroe Jan 09 '18 at 19:25
  • Okay i'll take a look at that, thankyou. I've added the css for the button. –  Jan 09 '18 at 19:29
  • _"I think i possible need to put the hover on the image rather than the div"_ - nope, that brings us back to the potential duplicate I mentioned in the first comment - your current HTML structure doesn't allow for that, because those images and the .prev link are not siblings - you'd have to select from the image on "upwards" first, and that is not possible. – CBroe Jan 09 '18 at 19:29
  • Okay i've tried and the only thought i can offer is for some reason it only ever changes when i hover over the .prev button not the div. Yet i can hover over the div and show an opacity change. At a complete loss. –  Jan 09 '18 at 19:54
  • For us to be able to identify what's going wrong, you'd have to give us a [mcve] of the problem ... – CBroe Jan 09 '18 at 19:56

4 Answers4

1

So what you had basically works already, only for just the last .mySlides element, because you selected only the immediately following .prev sibling (using the adjacent sibling combinator +), instead of all further siblings that have the class, no matter how "far" after the hovered div they come - that's the ~, the general sibling combinator.

The following basic examle shows that it works in principle (without going through the bother of adding actual images or additional styling.)

.prev {
    color:blue;
}

div.mySlides { 
    margin:.5em 0;
    padding: .5em;
    border: 1px solid;
    cursor: pointer;
}

div.mySlides:hover ~ .prev, .prev:hover {
    color:red;
}
<div id="myModal" class="modal">
  <div class="modal-content">

    <div class="mySlides">
      <div class="numbertext">1 / 4</div>
    </div>

    <div class="mySlides">
      <div class="numbertext">2 / 4</div>
    </div>

    <div class="mySlides">
      <div class="numbertext">3 / 4</div>
    </div>

    <div class="mySlides">
      <div class="numbertext">4 / 4</div>
    </div>

    <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
    <a class="next" onclick="plusSlides(1)">&#10095;</a>
  </div>
CBroe
  • 82,033
  • 9
  • 81
  • 132
0

Try the code below

#a:hover ~ #b {
    color: #ccc
}
<div id="a">Div A</div>
<div>elements</div>
<div>elements</div>
<div>elements</div>
<div id="b">Div B</div>
izulito
  • 492
  • 3
  • 12
0

button{
  padding:30px;
  color:white;
  background-color: red;
}

img:hover + button{
  background-color: black;
}
<img src="https://www.google.ca/logos/doodles/2018/har-gobind-khoranas-96th-birthday-4731112378073088-s.png" width="200" />
<button>my button</button>
0

Change this

div.mySlides:hover + .prev, .prev:hover {
    color:red;
}

to this

div.mySlides:hover ~ .prev, .prev:hover {
    color:red;
}

See https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors vs.https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_selectors for more info.

fl0psy
  • 401
  • 4
  • 5