Puis-je définir une opacité uniquement sur l'image d'arrière-plan d'un div?

87

Disons que j'ai

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

Je veux mettre un background-imageet lui donner un opacityde 0.5- mais je veux que le texte que j'ai écrit ait une opacité totale ( 1).

Si j'écrivais le CSS comme ça

.myDiv { opacity:0.5 }

tout sera en faible opacité - et je ne veux pas de ça.

Ma question est donc la suivante: comment puis-je obtenir une image d'arrière-plan à faible opacité avec un texte en pleine opacité?

Alon
la source
stackoverflow.com/questions/6624457/... Notez que j'ai un commentaire ici (sous la réponse de Phil) montrant un moyen de le faire avec l'opacité css, si c'est la méthode préférée. ( jsfiddle.net/4tTNZ )
Joonas
Cette réponse est beaucoup plus succincte et je pense qu'elle est exactement la même.
JohnAllen

Réponses:

102

Non, cela ne peut pas être fait depuis opacity affecte tout l'élément, y compris son contenu, et il n'y a aucun moyen de modifier ce comportement. Vous pouvez contourner ce problème avec les deux méthodes suivantes.

Div secondaire

Ajoutez un autre divélément au conteneur pour contenir l'arrière-plan. C'est la méthode la plus conviviale pour tous les navigateurs et fonctionnera même sur 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%;
}

Voir le cas de test sur jsFiddle

: avant et :: avant pseudo-élément

Une autre astuce consiste à utiliser les pseudo-éléments CSS 2.1 :beforeou CSS 3 ::before. :beforeLe pseudo-élément est pris en charge dans IE à partir de la version 8, tandis que le ::beforepseudo-élément n'est pas du tout pris en charge. Nous espérons que cela sera corrigé dans la version 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;
}

Notes complémentaires

En raison de votre comportement, z-indexvous devrez définir un z-index pour le conteneur ainsi qu'un négatifz-index pour l'image d'arrière-plan.

Cas de test

Voir le cas de test sur jsFiddle:

mekwall
la source
2
Je suis super paranoïaque quand il s'agit d'utiliser des valeurs négatives avec z-index .. mais, je ne peux pas contester les résultats. Cependant, j'ajouterais width: 100%; height: 100%;au .bgafin que ie6 puisse diffuser le bg à l'intérieur du div parent. jsfiddle.net/sbGb4/2
Joonas
Je pensais qu'il y avait une astuce css3 qui me manquait - mais c'est super aussi!
Alon
@Lollero bon point! z-indexest une douleur, mais cela devrait être relativement sûr tant que vous donnez au parent un indice positif.
mekwall
@Alon si vous vérifiez ce commentaire que j'ai écrit sous votre question. J'ai un lien vers une autre question qui a plusieurs autres options, y compris rgba qui est l'option css3. Heres assez bon truc pour les plus âgés ie .. css-tricks.com/2151-rgba-browser-support
Joonas
@Alon J'ai ajouté une autre méthode utilisant le ::beforepseudo-élément. Est-ce celui que vous recherchiez?
mekwall
155

Voici donc un autre moyen:

background-image: linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0.5)), url("your_image.png");
GrmXque
la source
3
@jj_: Parce qu'à l'époque, le support pour linear-gradient. La réponse acceptée que j'ai écrite a plus de 4 ans;)
mekwall
3
Vous pourriez peut-être ajouter un commentaire ou une petite mise à jour à votre question, en vous informant que c'est maintenant la nouvelle bonne façon de le faire. Rendez-vous dans 4 ans pour une nouvelle mise à jour;)
jj_
@jj_: En fait, cette solution ne rend pas l'image transparente. Il ajoute uniquement une couche blanche avec une transparence de 50% par-dessus. Par conséquent, ce n'est pas une réponse valable à la question.
mekwall le
7
Je pense que nous pouvons convenir que cela répond à l'intention de la question, alors oui, c'est une réponse valable à la question.
David Clarke
ouais .. cette réponse est à peu près la plus simple là-bas .. sinon le positionnement avec absolu devient désordre là
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
la source
0

Cela peut être fait en utilisant la classe div différente pour le texte Hi There ...

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

Vous pouvez maintenant appliquer les styles au

marque. sinon pour la classe bg. Je suis sûr que ça marche bien

Supraja Machavaram
la source
0

J'ai implémenté la solution de Marcus Ekwall mais pu supprimer quelques éléments pour la rendre plus simple et cela fonctionne toujours. Peut-être la version 2017 de 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
la source
1
Cela fait la même chose que le "div secondaire" dans ma réponse, la seule différence étant que vous avez omis le z-index (il est possible que cela se comporte différemment aujourd'hui et peut également dépendre du navigateur). Mais faire confiance au navigateur pour qu'il se comporte comme prévu est généralement une mauvaise idée.
mekwall
0

Bonjour à tous, j'ai fait ça et ça a bien fonctionné

	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
la source
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>

y compris 4 ensembles de nombres le rendrait rgba, pas cmyk, mais dans les deux cas fonctionnerait (rgba = 00000088, cmyk = 0%, 0%, 0%, 50%)

villageois1
la source
-1

Aucune des solutions n'a fonctionné pour moi. Si tout le reste échoue, récupérez l'image dans Photoshop et appliquez un effet. 5 minutes contre tant de temps là-dessus ...

user2060451
la source