web-dev-qa-db-fra.com

css: éviter le survol de l'image lors du premier clignotement

J'ai une ancre qui change son image d'arrière-plan lorsqu'elle est survolée avec une classe class-btn qui contient un background-image.

En vol stationnaire, il a

a.class-btn:hover
{
    background-image('path/to/image-hovered.jpg');
}

Lorsque la page se charge la première fois et que vous survolez ce bouton la première fois, il clignote (il faut environ une demi-seconde pour télécharger l'image survolée). Comment éviter ce clignotement sans JavaScript (seuls les simples CSS et HTML sont autorisés)?

J'ai essayé de rechercher Stack Overflow pour la question similaire, mais sans succès.

Vient d'ajouter:

  • Dois-je "précharger" l'image survolée? Comment?
  • Dois-je jouer avec le z-index ou l'opacité?

Cela arrive avec tous les navigateurs et donc la solution devrait fonctionner pour tous les navigateurs.

59
Haradzieniec

Voici une technique de préchargement d'image CSS simple et efficace que j'ai utilisée plusieurs fois. Vous pouvez charger plusieurs images en plaçant du contenu: url () url () url () ... etc.

body:after{
 display:none;
 content: url(path/to/image-hovered.jpg) url(path/to/another-image-hovered.jpg);
}
73
Kristian Svensson

Le moyen le plus simple d'éviter cela est d'utiliser des sprites d'image. Pour un bon aperçu, consultez cet article CSS Tricks .

De cette façon, non seulement vous résolvez le problème de scintillement que vous voyez, mais vous réduisez également le nombre de requêtes HTTP. Votre CSS ressemblera à quelque chose comme:

a.class-btn { background: url('path/to/image.jpg') 0 0 no-repeat; }
a.class-btn:hover { background-position: 0 -40px; }

Les détails dépendront de vos images. Vous pouvez également utiliser un générateur de sprites en ligne pour faciliter le processus.

59
CherryFlavourPez

Une astuce simple que j'utilise est de doubler l'image d'arrière-plan d'origine en veillant à mettre l'image en vol stationnaire en premier

.next {
  background: url(../images/next-hover.png) center center no-repeat;
  background: url(../images/next.png) center center no-repeat;
    &:hover{
      background: url(../images/next-hover.png) center center no-repeat;
    }
 }

Pas de performance et très simple

Ou si vous n'utilisez pas encore SCSS:

.next {
  background: url(../images/next-hover.png) center center no-repeat;
  background: url(../images/next.png) center center no-repeat;        
 }
 .next:hover{
  background: url(../images/next-hover.png) center center no-repeat;
 }
15
Callam

Si tu fais ça:

#the-button {
background-image: url('images/img.gif');
}
#the-button:before {
  content: url('images/animated-img.gif');
  width:0;
  height:0;
  visibility:hidden;
}

#the-button:hover {
  background-image: url('images/animated-img.gif');
}

Ça va vraiment aider!

Vois ici:

http://particle-in-a-box.com/blog-post/pre-load-hover-images-css-only

P.S - pas mon travail mais une solution que j'ai trouvée :)

8
Benjamin Dordoigne

Il s'agit d'une solution non CSS: si les images survolées sont dans un répertoire et ont une convention de dénomination commune, par exemple contiennent une sous-chaîne '-on.', Il est possible de sélectionner les noms de fichiers et de les placer dans le HTML en tant que séries de:

<img src='...' style='display: none' />
2
Martin Staufcik

@ La méthode de Kristian pour appliquer le contenu caché: url () après que le corps ne semble pas fonctionner dans Firefox 48.0 (OS X).

Cependant, la modification de "display: none;" à quelque chose comme:

body:after {
 position: absolute; overflow: hidden; left: -50000px;
 content: url(/path/to/picture-1.jpg) url(/path/to/picture-2.jpg);
}

... a fait l'affaire pour moi. Peut-être que Firefox ne chargera pas les images cachées, ou peut-être que cela est lié au rendu (?).

1
hdscp

Cette technique fonctionne bien pour moi et garantit non seulement que l'image survolée est préchargée, mais qu'elle est également prête et attend d'être affichée. (La plupart des autres solutions reposent sur le basculement de l'image d'arrière-plan en survol, ce qui semble juste prendre un peu de temps au navigateur pour comprendre, quelle que soit la taille de l'image préchargée.)

Créez: avant et: après les pseudo-éléments sur le conteneur avec les deux images, mais masquez celui que vous voulez voir en survol. Ensuite, en survol, changez la visibilité.

Tant qu'ils partagent la même taille et les mêmes règles de positionnement, vous devriez voir un échange soigné.

.image-container {
    &:before { display: block; background-image: url(uncovered.png); }
    &:after { display: none; background-image: url(uncovered.png); }
}
.image-container:hover {
    &:before { display: none; }
    &:after { display: block; }
}
0
Colin James Firth

L'astuce "doubler l'image d'arrière-plan d'origine" n'a pas fonctionné pour moi, j'ai donc utilisé une autre astuce css:

.next {
    background: url(../images/next.png) center center no-repeat;        
}
.next:hover {
    background: url(../images/next-hover.png) center center no-repeat;
}
.next:after {
    content: url(../images/next-hover.png);
    display: none;
}
0
Nailgun

S'ils ont les mêmes dimensions, une possibilité est de dessiner les deux images directement l'une sur l'autre, avec le CSS :hover classe pour l'image du haut ayant display: none;

De cette façon, les deux images seront préchargées, mais le survol rendra la seconde visible.

0
asc99c

Vous pouvez précharger les images

function preloadImages(srcs, imgs, callback) {
var img;
var remaining = srcs.length;
for (var i = 0; i < srcs.length; i++) {
    img = new Image();
    img.onload = function() {
        --remaining;
        if (remaining <= 0) {
            callback();
        }
    };
    img.src = srcs[i];
    imgs.Push(img);
}
}
// then to call it, you would use this
var imageSrcs = ["src1", "src2", "src3", "src4"];
var images = [];
preloadImages(imageSrcs, images, myFunction);
0