Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ensure CSS :hover is applied to dynamically added element

I have a script that adds full images dynamically over thumbnails when you hover over them. I've also given the full images a CSS :hover style to make them expand to a larger width (where normally they are constrained to the dimensions of the thumbnail). This works fine if the image loads quickly or is cached, but if the full image takes a long time to load and you don't move the mouse while it's loading, then once it does appear it will usually stay at the thumbnail width (the non-:hover style) until you move the mouse again. I get this behavior in all browsers that I've tried it in. I'm wondering if this is a bug, and if there's a way to fix or work around it.

It may be worth noting that I've also tried to do the same thing in Javascript with .on('mouseenter'), and encountered the same problem.

Due to the nature of the issue, it can be hard to reproduce, especially if you have a fast connection. I chose a largish photo from Wikipedia to demonstrate, but to make it work you might have to change it to something especially large or from a slow domain. Also note that you may have to clear the cache for successive retries.

If you still can't reproduce, you can add an artificial delay to the fullimage.load before the call to anchor.show().

HTML:

<img id="image" src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Cairo_International_Stadium.jpg/220px-Cairo_International_Stadium.jpg" />

CSS:

.kiyuras-image {
    position: absolute;
    top: 8px;
    left: 8px;
    max-width: 220px;
}

.kiyuras-image:hover {
    max-width: 400px;
}

JS:

$(function () {

    var fullimageurl = 'http://upload.wikimedia.org/wikipedia/commons/3/32/Cairo_International_Stadium.jpg';

    var fullimage = $('<img/>')
        .addClass('kiyuras-image')
        .load(function () {
            anchor.show();
        });

    var anchor = $('<a/>').hide().append(fullimage);

    $('body').prepend(anchor);

    $("#image").on('mouseenter', function () {
        fullimage.attr('src',fullimageurl);
        $(this).off('mouseenter');
    });

});

JS Bin

Updated JS Bin with 1.5-second delay added (Hopefully makes issue clearer)

Again: Reproducing the issue involves clearing your cache of the large image, and then hovering over the original image to initial the loading of large image, then not moving your mouse while it's loading. Intended behavior is for the large image to properly take on the :hover pseudo-class when it eventually loads. Issue I see when it takes longer than ~0.75 secs to load is that it does not take on :hover until you jiggle the mouse a little.

Edit: See my comments on @LucaFagioli's answer for further details of my use case.

Edit, the sequel: I thought I already did this, but I just tried to reproduce the issue in Firefox and I couldn't. Perhaps this is a Chrome bug?

like image 929
jonvuri Avatar asked Oct 29 '12 11:10

jonvuri


People also ask

Why Hover is not working on div?

You might have linked your stylesheet to your HTML file improperly. Some other CSS in the context of your project may be overriding the piece that you've given here. You might be running into browser compatibility issues with the :hover selector or something else in your code that is breaking the styling.

How do I enable hover in CSS?

The :hover CSS pseudo-class matches when the user interacts with an element with a pointing device, but does not necessarily activate it. It is generally triggered when the user hovers over an element with the cursor (mouse pointer).

Why hover property is not working in CSS?

Also, hover will not work if you use the wrong CSS format. Note that if you do not get the specificity right, the hover style will not work. Although you can use the ! important rule, there is no guarantee it will always work.

How do I make element visible only on hover?

To display div element using CSS on hover a tag: First, set the div element invisible i.e display:none;. By using the adjacent sibling selector and hover on a tag to display the div element.


2 Answers

Most browsers update their hover states only when the cursor moves over an element by at least one pixel. When the cursor enters the thumbnail's img it gets hover applied and runs your mouseenter handler. If you keep your cursor still until the full-sized image loads, your old img (the thumbnail) will keep the hover state and the new one won't get it.

To get it working in these browsers, move the hover pseudo-class to a common parent element in the CSS; for example, enclose both imgs in a span.

like image 131
pozs Avatar answered Oct 18 '22 22:10

pozs


If the selectors are correct, CSS will be applied to all elements, dynamic or otherwise. This includes all pseudo classes, and will change as attributes in the DOM change.

like image 41
Mild Fuzz Avatar answered Oct 18 '22 21:10

Mild Fuzz