1

I have a DIV and an A tag inside it, like this:

<DIV CLASS="product"><A HREF="...">blah</A></DIV>

I want to change the "A" text color when the user mouse-over the DIV, so my CSS is:

.product a { color:blue; }
.product:hover a { color:red; }

As CSS, works. But I'm creating a "template configurator" and I want to show a preview to the user, changing the colors dynamically using jQuery, something like this:

$('.product a').css('color','green');
$('.product:hover a').css('color','yellow');

Nothing happens... On Chrome's inspector I can see the definition as "accepted". But if I try to read...

16:03:16.250 $('.product:hover a').css('color')
16:03:16.255 undefined

Any idea why and how to fix?


Update

Example

  • Normal: "A" is the green text. Mouse over the 1 pixel border to trigger div:hover (mouse not over "A").
  • Now: "A" text is red. Move out, outside the DIV.
  • Now: backs to the original green text.

I want to change dynamically the red color to yellow, for example, using jQuery.

Arvy
  • 1,072
  • 2
  • 16
  • 29
  • I'm not clear where the green comes into it? If you show a preview on hovering the product, then the link is going to turn yellow... – FluffyKitten Sep 16 '20 at 20:06
  • In the image is like `.product a { color:green; }` and `.product:hover a { color:red; }` and I want to change dynamically the red color to yellow, but `$('.product:hover a').css('color','yellow');` does not work, nothing happens. In the final situation I want to have green as normal and yellow when hover the div. – Arvy Sep 16 '20 at 20:18
  • OK, from your description, it sounded like the change only happened on hovering the *link* which is why changing the blue to green didn't make sense :) I've added an answer below before you commented so I didn't see your edits (the question is much clearer now) - however the answer still applies.and might even be more suitable than I first thought! – FluffyKitten Sep 16 '20 at 20:21
  • Yes, you see... I'm a long time jQuery user, but this is driving me crazy. – Arvy Sep 16 '20 at 20:30
  • Does this answer your question? [How to define the css :hover state in a jQuery selector?](https://stackoverflow.com/questions/21051440/how-to-define-the-css-hover-state-in-a-jquery-selector) or https://stackoverflow.com/questions/5986464/change-div-background-on-rollover-with-jquery – WOUNDEDStevenJones Sep 16 '20 at 20:53
  • 1
    @WOUNDEDStevenJones unfortunately that doesn't work in the OP's situation because it permanently changes the colour (which you can see in some of the answers below) - they just want to apply a temporary colours, so they'd have to save the old values on mouseover and reapply them on mouseout. – FluffyKitten Sep 16 '20 at 21:03
  • "they'd have to save the old values on mouseover and reapply them on mouseout" there's no reason they couldn't do that though, right? Correct, this isn't an exact duplicate of the other 2 linked questions. But there are enough similarities with using jQuery to change the style of `div:hover a` using mouse events that I think the "mark as duplicate" still stands. Especially considering they eventually want to pull this value dynamically (i.e. not from predefined classes). Until an answer below proves me wrong and my flag can be removed. :) – WOUNDEDStevenJones Sep 16 '20 at 21:08
  • The question you said is not the same thing. Background color works, change A hover color does not. The main point is: why `$('.product:hover a').css('color','yellow')` does not work? – Arvy Sep 16 '20 at 21:13
  • 1
    if you're looking for an explanation to that question, it's because when you use `.css()` it sets the `style` property on the selected _element_ https://api.jquery.com/css/#css2, and there is no element `.product:hover` because that's a _hovered state_ of a `.product` element. For more control over this sort of mouse event, the linked answers appear to offer solutions. – WOUNDEDStevenJones Sep 16 '20 at 21:17
  • @WOUNDEDStevenJones That's a good point and give some idea. I really can see this on Chrome's inspector. So, how to change the class itself, not the element style? This can solve the problem. – Arvy Sep 16 '20 at 21:22
  • @WOUNDEDStevenJones in normal circumstances then yes saving the variable would be viable, (and I even mentioned it on one of the previous revisions of my answer) but it sounds more and more like the purpose is to show a whole new theme on hover which would include saving and restoring many variables which is quite unwieldy if there are better or cleaner options. – FluffyKitten Sep 16 '20 at 22:02
  • On reviewing the edits on this question, it has constantly evolved from the original question - the temporary colour change wasn't clear in the original and dynamically changing colours are the most recent addition. I've gone through 3 or 4 answers now to keep up! This is against SO guidelines so the question needs to be fixed at a point where the answers still apply to the question, and the OP can ask a new question with additional requirements. I've restored a previous version where the answers/dupes at least address the question. – FluffyKitten Sep 17 '20 at 00:00

4 Answers4

1

If you don't want to permanently change the colour on hover, then you could keep it simple and just apply a class on hover, and use it to specify the CSS for your preview.

UPDATE: jQuery-only Solutions Based on your latest comments and edit, you cannot add classes to the CSS. So lets do it using nothing but jQuery!

1. Add CSS styles with jQuery (keeps the flexibility of CSS classes)

The example below still uses the power and flexibility of css classes but without the need to change the HTML or CSS:

  • Creates new CSS rules directly in jQuery - this lets you easily set up the alternative styles in CSS for the preview class, e.g.:
$("<style>.preview .product:hover a{color:yellow;}</style>").appendTo("head");
  • adds the preview class to the container on mouseover and removes it on mouseout

$("<style> \
.preview .product a { color:green; } \
.preview .product:hover a { color:yellow; } \
</style>").appendTo("head");

$("#container").mouseover(function() {
  $("#container").addClass('preview');
}).mouseout(function() {
  $("#container").removeClass('preview');
});
.product a { color:blue; }
.product:hover a { color:red; }
/* for demo only */
#container { padding: 10px;  background: #f5f5f5;}
#container div {  padding: 10px; margin:20px;  border: 1px solid grey; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <div class="product">
    <a href="...">hover colour changes when div is hovered</A>
  </div>
</div>

2. Save the default colours and restore on mouseout

As I mentioned previously, another option is to use variables to save the original colours, replace them with the temporary colours on mouseover and restore the original values on mouseout. As I also mentioned, this means storing variables for all the styles that will be changed and can get unwieldy and difficult to maintain if you have many.

However I've expanded on this below with an example in case it is something you want to try.

// decalre variables to save the default colours
var origColor = $('.product a').css('color');
var origColorHover;  // we can't set this until the link is hovered

$(".product").mouseover(function() {
    // save hover colour
    if (origColorHover == "")  origColorHover = $(this).css('color');    
    // set the temporary hover colours
    $('.product a').css('color','green');
    $('.product a:hover').css('color','yellow');
}).mouseout(function() {
    // reset the original colour after hovering
    $('.product a').css('color', origColor);
    $('.product a:hover').css('color', origColorHover);
});
.product a { color:blue; }
.product a:hover { color:red; }
/* for demo only */
#container { padding: 10px;  background: #f5f5f5;}
#container div {  padding: 10px; margin:20px;  border: 1px solid grey; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <div class="product">
    <a href="...">hover colour changes when link is hovered</A>
  </div>
</div>

PREVIOUS EXAMPLES (might be helpful to other users with similar questions):

3. Use CSS classes for the alternative colours and apply the class on hover

The example below uses CSS classes to set up the alternate styling for the elements, and used jQuery to add the class to a container on mouseover e.g.:

$(".product").mouseover(function() {
  $("#container").addClass('preview');
}).mouseout(function() {
  $("#container").removeClass('preview');
});
.product a { color:blue; }
.product:hover a { color:red; }

.preview .product a { color:green; }
.preview .product:hover a { color:yellow; }

/* for demo only */
#container div { padding: 10px; margin: 10px; background: lightgrey;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <DIV CLASS="product">
    <A HREF="...">hover colour changes when div is hovered</A>
  </DIV>
</div>

Its difficult to say without knowing how your project works, but in general terms this sounds like a more maintainable and adaptable way to apply different template colours anyway?

You can set up a whole different stylesheet for the .preview and if you wish, and simply applying that class can change multiple styles at once. e.g. the example below applies a new set of styles to all elements, or if you only want to show it on a per-div basis, you apply the class to the div instead.

$("#container").mouseover(function() {
    $(this).addClass('preview');
}).mouseout(function() {
    $(this).removeClass('preview');
});
.product a { color:blue; }
.product:hover a { color:red; }
.product2 a { color:green; }
.product2 a:hover { color:yellow; }

.preview { text-align: center;}
.preview .product a { color:green; }
.preview .product:hover a { color:orange; }
.preview .product2 a { color:purple; font-weight: bold; }
.preview .product2 a:hover { color:yellow; }

/* for demo only */
#container { padding: 10px;  background: #f5f5f5;}

#container div {  padding: 10px; margin:10px;  border: 1px solid grey; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <DIV CLASS="product">
    <A HREF="...">hover colour changes when container is hovered</A>
  </DIV>
  <DIV CLASS="product2">
    <A HREF="...">hover colour changes when link is hovered</A>
  </DIV>
</div>
FluffyKitten
  • 13,824
  • 10
  • 39
  • 52
  • Yes, this is more near what I need but, in my project, user can choose the color in a color wheel. See the image in the original message (updated now). So I cannot add/delete classes, but this gives me a new idea, create classes dynamically... I'll try but I don't think this will work. – Arvy Sep 16 '20 at 20:27
  • @Arvy if you have specific requirements (like not being able to change the HTML) then you really should include them in the question - we can only give you an answer based on the information you give us :) This is why there has been confusion over the answers already. So when you say you cannot add/delete classes, do you mean in the HTML or in the CSS? – FluffyKitten Sep 16 '20 at 20:29
  • Yes, my goal is only change, using jQuery, the "A" hover color dynamically when user mouses over the DIV itself. I understand you... I'm not english native (what complicates a bit for me to explain a not usual requirement) hehe See the new image to understand my project. "Mouse T" is "color when mouse is over Text" ("A"). – Arvy Sep 16 '20 at 20:35
  • I mean: I want to Live Preview everything to the user. So, after change the "Mouse T" color, the user can mouse over the DIV and see the new color on "A" text. – Arvy Sep 16 '20 at 20:37
  • @Arvy I've updated my answer with a full jQuery-only answer using the power of classes but without needing to change the CSS! – FluffyKitten Sep 16 '20 at 20:46
  • Great, I'll try this idea! I'll update soon with my results! – Arvy Sep 16 '20 at 20:53
  • Sure, I'll try soon! I did a fast view, looks interesting, another approach. – Arvy Sep 16 '20 at 21:01
  • Well, I don't know if I did something wrong but I cannot run the code. I understand your idea about inject the class, but this will impact my code... even the topic cited by @WOUNDEDStevenJones does not solve exactly the problem, it gives some extra ideas. I'll need some time to test, but it's 19:00 in Brazil and it's time to rest. Tomorrow I'll study more. For now, thanks again for your help! – Arvy Sep 16 '20 at 21:39
  • @Arvy your question changed again, that's why it won't work :) Your original question didn't ask for colours that could be dynamically changed. This changes the question requirements again, and that isn't allowed on SO, because it can make the answers invalid so they're not useful to future users any more. What you *can* do is accept or upvote any useful answers that helped so far with your *original* question and then ask a new question about how to adapt what you have now to work as you wish. Just make sure to include *all* requirements this time, it does change the answers you need! – FluffyKitten Sep 16 '20 at 23:55
  • Hmmm I didn't understand. The original text has the text "changing the colors dynamically using jQuery". The subject is the same, I just looking for a way to "run" the code as initially I said that is not working: `$('.product:hover a').css('color','yellow')` – Arvy Sep 17 '20 at 00:09
  • 1
    @Arvy Yes, but how "dynamic" wasn't specified - changing it in JS is dynamic, changing it using variable values that change at run-time is a whole different level! That needs a different answer than *how to change the hover colour in jQuery* - which is the what the answers here are answering :) Maybe we all misunderstood, but the main thing is: if the question and answers don't match up, this isn't helpful to other users (and that's what SO is all about). We can't change all the answers, so the best option is to ask a new question about setting it based on user input. But we will still help! – FluffyKitten Sep 17 '20 at 00:23
  • 1
    @Arvy You should still post here - now we understand the problem (it just took a while to get there), so we can help you by editing the question to explain it if it needs more help. This was a difficult question to explain for anyone - even English speakers :) I really think we can help now though. Please don't be put off asking other questions here either in future, it just might take a bit of time to get right for the non-trivial ones, but you should be fine most of the time :) We're here to help ! – FluffyKitten Sep 17 '20 at 00:34
  • 1
    After going to sleep thinking about the problem, I tried to think differently and found a solution that works. I will share it here to help other people, but I ask you to edit whatever is necessary to make it as clear as possible. Thanks so much for all your help @FluffyKitten! – Arvy Sep 17 '20 at 13:15
  • 1
    @Arvy Glad you found a solution! I'll take a look later to see if the wording needs any tweaks :) Maybe you could add where this code is added though, just so it is clear for other users - it looks like they are added in CSS but I didn't think you could change that, so is this done through jQuery? – FluffyKitten Sep 17 '20 at 23:51
  • I had to change the CSS to create variables. I had no choice. So, now I use jQuery to change a CSS variable, so I don't need to mess with the object itself. – Arvy Sep 18 '20 at 12:06
  • @Arvy Did you try my option 2? That is a pure jQuery solution that doesn't need you to change the CSS at all - which is what you were looking for! :) – FluffyKitten Sep 19 '20 at 15:35
0

This is a working example of changing color and previewing.

$(document).ready(function () {
  $('#container .product a').hover(function () {
    if (isPreviewActive()) {
      $(this).css('color', $('#hover').val());
    }
  }, function () {
    if (isPreviewActive()) {
      $(this).css('color', $('#color').val());
    }
  });

  $('#checkbox').change(function () {
    if (this.checked) {
      $('.product a').css('color', $('#color').val());
    } else {
      $('.product a').css('color', '');
    }
  });
});

function isPreviewActive() {
  return $('#checkbox')[0].checked;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="container">
  <div class="product"><a href=="#">blah</a></div>
</div>

<p>
  <label>Color:</label>
  <input id="color" type="text" value="red"></input>
  <label>Hover:</label>
  <input id="hover" type="text" value="yellow"></input>
</p>
Enable Preview? <input type="checkbox" id="checkbox"></input>
francisco neto
  • 797
  • 1
  • 5
  • 13
  • No, you're changing the text color. This works. As I said, I want to change the hover color. If you change your code from $('.product a') to $('.product:hover a') does not work. – Arvy Sep 16 '20 at 19:28
  • 1
    You are right. I've updated the code, and now it works. – francisco neto Sep 17 '20 at 12:27
  • Hmmm, works but not exactly for what I need. If you add `padding:10px` to `.product` when you mouse over it (div) won't change the "A" color. What I need is mouse over the container and change the hover color of "A". But I found a solution, see my new comment. – Arvy Sep 17 '20 at 13:12
0

If you want to set the hover color using jquery, you need to use the hover method on the given object

$(".product a").hover(
    function() {
        $(this).css("color", "yellow");
    },
    function() {
        $(this).css("color", "green");
    }
);

CodePen

Dan Mullin
  • 4,285
  • 2
  • 18
  • 34
  • Apparently it doesn't like the lambda. I edited it to a working version. – Dan Mullin Sep 16 '20 at 19:39
  • This change permanently the "A" color when hover over it (A, not DIV). What I need is change the "A" text color only when the mouse is over the DIV (not the link), and return back to the original color when blur. – Arvy Sep 16 '20 at 19:45
  • I get you. I just made another update to account for that. The hover function accepts two functions. One sets the hover color and one sets the unhovered color. – Dan Mullin Sep 16 '20 at 19:48
  • Hmmm not yet, this change the hover color but permanently. I'll update the original question with an image to be more clear. – Arvy Sep 16 '20 at 20:03
0

I found a solution that changes colors without having to touch the objects themselves. The solution only changes colors in variables. It only considers modern browsers with CSS3 that supports "var" function.

First, I defined 2 colors in variables:

:root {
   --normal-color: green;
   --hover-color: red;
}

and set the classes as:

.product a { color: var(--normal-color); }
.product:hover a { color: var(--hover-color); }

now all I need to do is dynamically change the variables:

$(':root').css('--normal-color','blue');
$(':root').css('--hover-color','yellow');

so, the new link color is blue and when I mouse over the container (.product), the link will be yellow.

Arvy
  • 1,072
  • 2
  • 16
  • 29