Superposition transparente noire sur le survol d'image avec seulement CSS?

101

J'essaie d'ajouter une superposition noire transparente à une image chaque fois que la souris survole l'image avec seulement CSS. Est-ce possible? J'ai essayé ceci:

http://jsfiddle.net/Zf5am/565/

Mais je ne peux pas faire venir la div.

<div class="image">
    <img src="http://www.newyorker.com/online/blogs/photobooth/NASAEarth-01.jpg" alt="" />
    <div class="overlay" />
</div> 

.image {
  position: relative;
  border: 1px solid black;
  width: 200px;
  height: 200px;
}
.image img {
  max-width: 100%;
  max-height: 100%;
}
.overlay {
  position: absolute;
  top: 0;
  left: 0;
  display: none;
  background-color: red;
  z-index: 200;
}
.overlay:hover {
  display: block;
}
RobVious
la source
vouliez-vous mettre: survolez l'image div, pas la superposition div?
andi
1
Juste une note: pourquoi mettez-vous un indice Z aussi élevé sur la superposition? Les index Z ne sont pas globaux; il n'est pas nécessaire de «pirater» une valeur élevée ou faible pour les faire fonctionner.
Jimmy Breck-McKye
1
C'est ce qui m'a finalement aidé à résoudre ce problème: jsfiddle.net/4Dfpm Aucune superposition de div nécessaire. L'image obtient moins d'opacité en survol, la div ci-dessous doit avoir un fond noir, voila.
Kai Noack

Réponses:

211

Je suggère d'utiliser un pseudo élément à la place de l'élément de superposition. Étant donné que les pseudo éléments ne peuvent pas être ajoutés sur des imgéléments inclus , vous devrez quand imgmême encapsuler l' élément.

EXEMPLE EN DIRECT ICI - EXEMPLE AVEC TEXTE

<div class="image">
    <img src="http://i.stack.imgur.com/Sjsbh.jpg" alt="" />
</div>

Comme pour le CSS, définissez des dimensions optionnelles sur l' .imageélément et positionnez-le de manière relative. Si vous visez une image responsive, omettez simplement les dimensions et cela fonctionnera toujours (exemple) . Il est juste intéressant de noter que les dimensions doivent être sur l'élément parent plutôt que sur l' imgélément lui-même, voir .

.image {
    position: relative;
    width: 400px;
    height: 400px;
}

Donnez à l' imgélément enfant une largeur de 100%du parent et ajoutez vertical-align:toppour résoudre les problèmes d'alignement de la ligne de base par défaut.

.image img {
    width: 100%;
    vertical-align: top;
}

Quant au pseudo élément, définissez une valeur de contenu et positionnez-le absolument par rapport à l' .imageélément. Une largeur / hauteur de 100%garantira que cela fonctionne avec des imgdimensions variables . Si vous souhaitez effectuer la transition de l'élément, définissez une opacité de 0et ajoutez les propriétés / valeurs de transition.

.image:after {
    content: '\A';
    position: absolute;
    width: 100%; height:100%;
    top:0; left:0;
    background:rgba(0,0,0,0.6);
    opacity: 0;
    transition: all 1s;
    -webkit-transition: all 1s;
}

Utilisez une opacité de 1lors du survol du pseudo élément afin de faciliter la transition:

.image:hover:after {
    opacity: 1;
}

FIN DU RÉSULTAT ICI


Si vous souhaitez ajouter du texte au survol:

Pour l'approche la plus simple, ajoutez simplement le texte comme valeur du pseudo élément content:

EXEMPLE ICI

.image:after {
    content: 'Here is some text..';
    color: #fff;

    /* Other styling.. */
}

Cela devrait fonctionner dans la plupart des cas; cependant, si vous avez plusieurs imgéléments, vous ne voudrez peut-être pas que le même texte apparaisse au survol. Vous pouvez donc placer le texte dans un data-*attribut et donc avoir un texte unique pour chaque imgélément.

EXEMPLE ICI

.image:after {
    content: attr(data-content);
    color: #fff;
}

Avec une contentvaleur de attr(data-content), le pseudo élément ajoute le texte de l' attribut de l' .imageélément data-content:

<div data-content="Text added on hover" class="image">
    <img src="http://i.stack.imgur.com/Sjsbh.jpg" alt="" />
</div>

Vous pouvez ajouter du style et faire quelque chose comme ceci:

EXEMPLE ICI

Dans l'exemple ci-dessus, le :afterpseudo élément sert de superposition noire, tandis que le :beforepseudo élément est la légende / le texte. Les éléments étant indépendants les uns des autres, vous pouvez utiliser un style distinct pour un positionnement plus optimal.

.image:after, .image:before {
    position: absolute;
    opacity: 0;
    transition: all 0.5s;
    -webkit-transition: all 0.5s;
}
.image:after {
    content: '\A';
    width: 100%; height:100%;
    top: 0; left:0;
    background:rgba(0,0,0,0.6);
}
.image:before {
    content: attr(data-content);
    width: 100%;
    color: #fff;
    z-index: 1;
    bottom: 0;
    padding: 4px 10px;
    text-align: center;
    background: #f00;
    box-sizing: border-box;
    -moz-box-sizing:border-box;
}
.image:hover:after, .image:hover:before {
    opacity: 1;
}
Josh Crozier
la source
1
Merci Josh. J'aime mieux cette version. Que feriez-vous si vous vouliez afficher du texte blanc en plus de cette noirceur transparente? Souhaitez-vous ajouter un autre div et appliquer l'opacité séparément?
RobVious
Ouais, seulement en vol stationnaire en fait.
RobVious
1
merci c'est une meilleure solution que celle que j'avais essayée auparavant
wingskush
Comment puis-je placer la légende au centre de l'image? top:30%fonctionne, voyez mon violon , mais pour une mise en page réactive, ce serait bien de le placer au centre exact. BTW: Merci pour cette belle annswer.
p2 ou
3
@poor Voici une approche responsive (exemple mis à jour) .. elle utilise top: 50%/ transform: translateY(-50%)pour le centrage vertical. C'est l'une des approches mentionnées dans cette autre réponse si la mienne - stackoverflow.com/questions/5703552/…
Josh Crozier
44

Filtre CSS3

Bien que cette fonctionnalité ne soit implémentée que dans le kit Web , et qu'elle ne soit pas compatible avec le navigateur , cela vaut la peine de jeter un coup d'œil à:

.image img {
    max-width: 100%;
    max-height: 100%;
    -webkit-transition: .2s all;
}

.image img:hover {
    -webkit-filter: brightness(50%);
}

Démo JSFiddle

Références

Sujets similaires sur SO

Hashem Qolami
la source
1
Depuis la sortie de FF35, FF prend également en charge les filtres: jsfiddle.net/Zf5am/1766 .
Jacob van Lingen
mec!! solution géniale !!
Alvaro Joao
11

Vous étiez proche. Cela fonctionnera:

.image { position: relative; border: 1px solid black; width: 200px; height: 200px; }
.image img { max-width: 100%; max-height: 100%; }
.overlay { position: absolute; top: 0; left: 0; right:0; bottom:0; display: none; background-color: rgba(0,0,0,0.5); }
.image:hover .overlay { display: block; }

Vous deviez mettre l' :hoverimage sur et faire de la .overlaycouverture l'image entière en ajoutant right:0;et bottom:0.

jsfiddle: http://jsfiddle.net/Zf5am/569/

David
la source
Je suggérerais également d'utiliser des animations CSS3 pour une transition un peu plus fluide pour les navigateurs compatibles (les utilisateurs d'IE devront simplement souffrir).
Jimmy Breck-McKye
7

Voici un bon moyen d'utiliser: après sur l'image div, au lieu du div superposition supplémentaire: http://jsfiddle.net/Zf5am/576/

<div class="image">
    <img src="http://www.newyorker.com/online/blogs/photobooth/NASAEarth-01.jpg" alt="" />
</div>

.image {position:relative; border:1px solid black; width:200px; height:200px;}
.image img {max-width:100%; max-height:100%;}
.image:hover:after {content:""; position:absolute; top:0; left:0; bottom:0; right:0; background-color: rgba(0,0,0,0.3);}
et moi
la source
2

.overlayn'avait pas de hauteur ou de largeur et aucun contenu, et vous ne pouvez pas survoler display:none.

J'ai plutôt donné au div la même taille et la même position que .imageet change la RGBAvaleur au survol.

http://jsfiddle.net/Zf5am/566/

.image { position: absolute; border: 1px solid black; width: 200px; height: 200px; z-index:1;}
.image img { max-width: 100%; max-height: 100%; }
.overlay { position: absolute; top: 0; left: 0; background:rgba(255,0,0,0); z-index: 200; width:200px; height:200px; }
.overlay:hover { background:rgba(255,0,0,.7); }
Andrew Clody
la source
1

Voyez ce que j'ai fait ici: http://jsfiddle.net/dyarbrough93/c8wEC/

Tout d'abord, vous ne définissez jamais les dimensions de la superposition, ce qui signifie qu'elle ne s'affiche pas en premier lieu. Deuxièmement, je recommande de simplement changer le z-index de la superposition lorsque vous survolez l'image. Modifiez l'opacité / la couleur de la superposition en fonction de vos besoins.

.image { position: relative; width: 200px; height: 200px;}
.image img { max-width: 100%; max-height: 100%; }
.overlay { position: absolute; top: 0; left: 0; background-color: gray; z-index: -10; width: 200px; height: 200px; opacity: 0.5}
.image:hover .overlay { z-index: 10}
Davis Yarbrough
la source
1

Vous pouvez accomplir cela en jouant avec l'opacité de l'image et en définissant la couleur d'arrière-plan de l'image sur le noir. En rendant l'image transparente, elle apparaîtra plus sombre.

<div class="image">
    <img src="http://www.newyorker.com/online/blogs/photobooth/NASAEarth-01.jpg" alt="" />
</div> 

CSS:

.image { position: relative; border: 1px solid black; width: 200px; height: 200px; background: black; }
.image img { max-width: 100%; max-height: 100%; }
.image img:hover { opacity: .5 }

Vous devrez peut-être également définir l'opacité spécifique au navigateur pour que cela fonctionne également dans d'autres navigateurs.

Sumurai8
la source
0

Je donnerais une hauteur min et une largeur min à votre div superposition de la taille de l'image, et changerais la couleur d'arrière-plan en survol

.overlay { position: absolute; top: 0; left: 0;  z-index: 200; min-height:200px; min-width:200px; background-color: none;}
.overlay:hover { background-color: red;}
Jako
la source