Posso definir uma opacidade apenas para a imagem de fundo de um div?

87

Digamos que tenho

<div class="myDiv">Hi there</div>

Quero colocar um background-imagee dar um opacityde 0.5- mas quero que o texto que escrevi tenha opacidade total ( 1).

Se eu escrever o CSS assim

.myDiv { opacity:0.5 }

tudo ficará em baixa opacidade - e eu não quero isso.

Portanto, minha pergunta é - Como posso obter uma imagem de plano de fundo de baixa opacidade com texto totalmente opaco?

Alon
fonte
stackoverflow.com/questions/6624457/… Observe que eu tenho um comentário lá (sob a resposta de Phil) mostrando uma maneira de fazer isso com opacidade css, se essa for a forma preferida. ( jsfiddle.net/4tTNZ )
Joonas
Essa resposta é muito mais sucinta e acredito que seja exatamente a mesma.
JohnAllen de

Respostas:

102

Não, isso não pode ser feito desde opacity afeta todo o elemento, incluindo seu conteúdo, e não há como alterar esse comportamento. Você pode contornar isso com os dois métodos a seguir.

Div secundário

Adicione outro divelemento ao contêiner para manter o plano de fundo. Este é o método mais compatível com vários navegadores e funcionará até mesmo no IE6.

HTML

<div class="myDiv">
    <div class="bg"></div>
    Hi there
</div>

CSS

.myDiv {
    position: relative;
    z-index: 1;
}

.myDiv .bg {
    position: absolute;
    z-index: -1;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: url(test.jpg) center center;
    opacity: .4;
    width: 100%;
    height: 100%;
}

Veja o caso de teste no jsFiddle

: before e :: before pseudo-elemento

Outro truque é usar os pseudo-elementos CSS 2.1 :beforeou CSS 3 ::before. :beforeO pseudo-elemento é compatível com o IE a partir da versão 8, enquanto o ::beforepseudo-elemento não tem suporte. Esperamos que isso seja corrigido na versão 10.

HTML

<div class="myDiv">
    Hi there
</div>

CSS

.myDiv {
    position: relative;
    z-index: 1;
}

.myDiv:before {
    content: "";
    position: absolute;
    z-index: -1;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: url(test.jpg) center center;
    opacity: .4;
}

Notas Adicionais

Devido ao comportamento de z-indexvocê terá que definir um índice z para o contêiner, bem como um índicez-index para a imagem de fundo.

Casos de teste

Veja o caso de teste no jsFiddle:

Mekwall
fonte
2
Sou superparanóico quando se trata de usar valores negativos com Z-index ... mas não posso contestar os resultados. No entanto, eu adicionaria width: 100%; height: 100%;ao .bgpara que o ie6 possa espalhar o bg dentro do div pai. jsfiddle.net/sbGb4/2
Joonas
Achei que houvesse um truque do CSS3 para ele que estava faltando - mas isso também é ótimo!
Alon
@Lollero bom ponto! z-indexé uma dor, mas isso deve ser relativamente seguro, desde que você dê aos pais um índice positivo.
mekwall
@Alon se você verificar aquele comentário que escrevi em sua postagem de pergunta. Eu tenho um link lá para outra questão que tem várias outras opções incluindo rgba que é a opção css3. Aqui está um truque muito bom para os mais velhos, ou seja, css-tricks.com/2151-rgba-browser-support
Joonas
@Alon Eu adicionei outro método usando o ::beforepseudo-elemento. Era esse que você estava procurando?
mekwall
155

Então, aqui está uma outra maneira:

background-image: linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0.5)), url("your_image.png");
GrmXque
fonte
3
@jj_: Porque na época o suporte para linear-gradient. A resposta aceita que escrevi tem mais de 4 anos;)
mekwall
3
Talvez você possa adicionar um comentário ou uma pequena atualização para sua dúvida, informando que esta é a nova boa forma de fazê-lo. Vejo você em 4 anos para uma nova atualização;)
jj_
@jj_: Na verdade, essa solução não torna a imagem transparente. Ele apenas adiciona uma camada branca com 50% de transparência em cima dela. Portanto, não é uma resposta válida para a pergunta.
mekwall
7
Acho que podemos concordar que atinge o objetivo da pergunta, então sim, é uma resposta válida para a pergunta.
David Clarke
sim .. esta resposta é basicamente a mais simples que existe .. senão o posicionamento com absoluto torna-se uma bagunça lá fora
Harkirat Saluja
4

css

div { 
    width: 200px;
    height: 200px;
    display: block;
    position: relative;
}

div::after {
    content: "";
    background: url(image.jpg); 
    opacity: 0.5;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    position: absolute;
    z-index: -1;
}

html

<div> put your div content</div>
Harsukh Makwana
fonte
0

Isso pode ser feito usando a classe div diferente para o texto Hi There ...

<div class="myDiv">
    <div class="bg">
   <p> Hi there</p>
</div>
</div>

Agora você pode aplicar os estilos ao

tag. caso contrário, para a classe BG. Tenho certeza de que funciona bem

Supraja Machavaram
fonte
0

Implementei a solução de Marcus Ekwall mas consegui remover algumas coisas para torná-la mais simples e ainda funcionar. Talvez a versão 2017 do html / css?

html:

<div id="content">
  <div id='bg'></div>
  <h2>What is Lorem Ipsum?</h2>
  <p><strong>Lorem Ipsum</strong> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen
    book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with
    desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>

css:

#content {
  text-align: left;
  width: 75%;
  margin: auto;
  position: relative;
}

#bg {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: url('https://static.pexels.com/photos/6644/sea-water-ocean-waves.jpg') center center;
  opacity: .4;
  width: 100%;
  height: 100%;
}

https://jsfiddle.net/abalter/3te9fjL5/

abalter
fonte
1
Isso faz o mesmo que o "div secundário" na minha resposta, com a única diferença sendo que você omitiu o índice z (é possível que isso se comporte de maneira diferente hoje e também pode depender do navegador). Mas confiar no navegador para se comportar conforme o esperado geralmente é uma má ideia.
mekwall
0

Olá a todos eu fiz isso e funcionou bem

	var canvas, ctx;

		function init() {
			canvas = document.getElementById('color');
			ctx = canvas.getContext('2d');

			ctx.save();
			ctx.fillStyle = '#bfbfbf'; //  #00843D   // 118846
			ctx.fillRect(0, 0, 490, 490);
			ctx.restore();
		}
section{
		height: 400px;
		background: url(https://images.pexels.com/photos/265087/pexels-photo-265087.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb);
		background-repeat: no-repeat;
		background-position: center;
		background-size: cover;
		position: relative;
	
}

canvas {
	width: 100%;
	height: 400px;
	opacity: 0.9;

}

#text {
	position: absolute;
	top: 10%;
	left: 0;
	width: 100%;
	text-align: center;
}


.middle{
	text-align: center;
	
}

section small{
	background-color: #262626;
	padding: 12px;
	color: whitesmoke;
  letter-spacing: 1.5px;

}

section i{
  color: white;
  background-color: grey;
}

section h1{
  opacity: 0.8;
}
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Metrics</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">  
</head>  
  
<body onload="init();">
<section>
<canvas id="color"></canvas>

<div class="w3-container middle" id="text">
<i class="material-icons w3-highway-blue" style="font-size:60px;">assessment</i>
<h1>Medimos las acciones de tus ventas y disenamos en la WEB tu Marca.</h1>
<small>Metrics &amp; WEB</small>
</div>
</section> 

adragom
fonte
0
<!DOCTYPE html>
<html>
<head></head>
<body>
<div style=" background-color: #00000088"> Hi there </div>
<!-- #00 would be r, 00 would be g, 00 would be b, 88 would be a. -->
</body>
</html>

incluir 4 conjuntos de números tornaria rgba, não cmyk, mas de qualquer forma funcionaria (rgba = 00000088, cmyk = 0%, 0%, 0%, 50%)

Villager1
fonte
-1

Nenhuma das soluções funcionou para mim. Se tudo mais falhar, leve a imagem para o Photoshop e aplique algum efeito. 5 minutos contra tanto tempo nisso ...

user2060451
fonte