Sobreposição transparente preta no foco da imagem apenas com CSS?

101

Estou tentando adicionar uma sobreposição preta transparente a uma imagem sempre que o mouse está passando sobre a imagem apenas com CSS. Isso é possível? Eu tentei isso:

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

Mas não consigo fazer o div aparecer.

<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
fonte
você pretendia colocar: passe o mouse sobre a div da imagem, não a div de sobreposição?
andi
1
Apenas uma observação: por que você está colocando um Z-index tão alto na sobreposição? Os índices Z não são globais; não há necessidade de 'hackear' um valor alto ou baixo para fazê-los funcionar.
Jimmy Breck-McKye
1
Isso é o que finalmente me ajudou a resolver esse problema: jsfiddle.net/4Dfpm Não é necessário sobrepor div. A imagem fica menos opaca ao passar o mouse, a div abaixo deve ter um fundo preto, voila.
Kai Noack

Respostas:

211

Eu sugiro usar um pseudoelemento no lugar do elemento de sobreposição. Como os pseudoelementos não podem ser adicionados a imgelementos incluídos , você ainda precisaria envolver o imgelemento.

EXEMPLO AO VIVO AQUI - EXEMPLO COM TEXTO

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

Quanto ao CSS, defina dimensões opcionais no .imageelemento e posicione-o relativamente. Se você está visando uma imagem responsiva, apenas omita as dimensões e ainda funcionará (exemplo) . É apenas importante notar que as dimensões devem estar no elemento pai em oposição ao imgpróprio elemento, ver .

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

Dê ao imgelemento filho uma largura 100%igual a do pai e adicione vertical-align:toppara corrigir os problemas de alinhamento da linha de base padrão.

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

Quanto ao pseudoelemento, defina um valor de conteúdo e posicione-o absolutamente em relação ao .imageelemento. Uma largura / altura de 100%garantirá que funcione com imgdimensões variadas . Se você deseja fazer a transição do elemento, defina uma opacidade de 0e adicione as propriedades / valores de transição.

.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;
}

Use uma opacidade de 1ao passar o mouse sobre o pseudoelemento para facilitar a transição:

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

RESULTADO FINAL AQUI


Se você deseja adicionar texto ao passar o mouse:

Para uma abordagem mais simples, basta adicionar o texto como o contentvalor do pseudoelemento :

EXEMPLO AQUI

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

    /* Other styling.. */
}

Isso deve funcionar na maioria dos casos; no entanto, se você tiver mais de um imgelemento, pode não querer que o mesmo texto apareça ao passar o mouse. Você poderia, portanto, definir o texto em um data-*atributo e, portanto, ter um texto exclusivo para cada imgelemento.

EXEMPLO AQUI

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

Com um contentvalor de attr(data-content), o pseudoelemento adiciona o texto .imagedo data-contentatributo do elemento :

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

Você pode adicionar algum estilo e fazer algo assim:

EXEMPLO AQUI

No exemplo acima, o :afterpseudo elemento serve como a sobreposição preta, enquanto o :beforepseudo elemento é a legenda / texto. Como os elementos são independentes uns dos outros, você pode usar estilos separados para um posicionamento mais otimizado.

.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
fonte
1
Obrigado Josh. Eu gosto mais dessa versão. O que você faria se quisesse exibir algum texto branco em cima dessa escuridão transparente? Você adicionaria outro div e aplicaria opacidade a ele separadamente?
RobVious de
Sim, apenas pairando, na verdade.
RobVious de
1
obrigado, esta é uma solução melhor do que a que eu tentei antes
wingskush
Como posso definir a legenda para o centro da imagem? top:30%funciona, veja meu violino , mas para um layout responsivo, seria bom configurá-lo exatamente no centro. BTW: Obrigado por este agradável anúncio.
p2ou
3
@poor Aqui está uma abordagem responsiva (exemplo atualizado) .. ele usa top: 50%/ transform: translateY(-50%)para centralização vertical. É uma das abordagens mencionadas nesta outra resposta if mine - stackoverflow.com/questions/5703552/…
Josh Crozier
44

Filtro CSS3

Embora esse recurso seja implementado apenas no webkit e não seja compatível com o navegador , vale a pena dar uma olhada em:

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

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

JSFiddle Demo

Referências

Tópicos semelhantes em SO

Hashem Qolami
fonte
1
Desde o lançamento do FF35, o FF também oferece suporte a filtros: jsfiddle.net/Zf5am/1766 .
Jacob van Lingen
cara!! solução incrível !!
Alvaro João
11

Você estava perto. Isso vai funcionar:

.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; }

Você precisava colocar a :hoverimagem, e fazer a .overlaycapa da imagem inteira adicionando right:0;e bottom:0.

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

david
fonte
Eu também sugeriria o uso de animações CSS3 para uma transição um pouco mais suave para navegadores compatíveis (os usuários do IE terão que sofrer).
Jimmy Breck-McKye
7

Esta é uma boa maneira de usar: depois do div da imagem, em vez do div de sobreposição extra: 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);}
e eu
fonte
2

.overlaynão tem altura ou largura e nenhum conteúdo, e você não pode passar o mouse sobre ela display:none.

Em vez disso, dei ao div o mesmo tamanho e posição que .imagee alterei o RGBAvalor ao pairar.

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
fonte
1

Você pode fazer isso brincando com a opacidade da imagem e definindo a cor de fundo da imagem como preto. Ao tornar a imagem transparente, ela parecerá mais escura.

<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 }

Você pode precisar definir a opacidade específica do navegador também para fazer isso funcionar em outros navegadores também.

Sumurai8
fonte
0

Eu daria uma altura mínima e uma largura mínima para o div de sobreposição do tamanho da imagem e mudaria a cor de fundo ao passar o mouse

.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
fonte
0

Veja o que fiz aqui: http://jsfiddle.net/dyarbrough93/c8wEC/

Primeiro, você nunca define as dimensões da sobreposição, o que significa que ela não estava aparecendo em primeiro lugar. Em segundo lugar, recomendo apenas alterar o Z-index da sobreposição ao passar o mouse sobre a imagem. Altere a opacidade / cor da sobreposição para atender às suas necessidades.

.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
fonte