Définir l'opacité de l'image d'arrière-plan sans affecter les éléments enfants

214

Est-il possible de définir l'opacité d'une image d'arrière-plan sans affecter l'opacité des éléments enfants?

Exemple

Tous les liens dans le pied de page nécessitent une puce personnalisée (image d'arrière-plan) et l'opacité de la puce personnalisée doit être de 50%.

HTML

<div id="footer">
    <ul>
        <li><a href="#">Link 1</a></li>
        <li><a href="#">Link 2</a></li>
        <li><a href="#">Link 3</a></li>
        <li><a href="#">Link 4</a></li>
        <li><a href="#">Link 5</a></li>
    </ul>
</div>  

CSS

#footer ul li {
    background: url(/images/arrow.png) no-repeat 0 50%;
}  

Ce que j'ai essayé

J'ai essayé de définir l'opacité des éléments de la liste à 50%, mais l'opacité du texte du lien est également de 50% - et il ne semble pas y avoir de moyen de réinitialiser l'opacité des éléments enfants:

#footer ul li {
    background: url(/images/arrow.png) no-repeat 0 50%;
    /* will also set the opacity of the link text */        
    opacity: 0.5;
}

J'ai également essayé d'utiliser rgba, mais cela n'a aucun effet sur l'image d'arrière-plan:

#footer ul li {
    /* rgba doesn't apply to the background image */
    background: rgba(255, 255, 255, 0.5) url(/images/arrow.png) no-repeat 0 50%;
}
jmohr
la source

Réponses:

119

Vous pouvez utiliser CSS linear-gradient()avec rgba().

div {
  width: 300px;
  height: 200px;
  background: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)), url("https://i.imgur.com/xnh5x47.jpg");
}
span {
  background: black;
  color: white;
}
<div><span>Hello world.</span></div>

Autocollants
la source
C'est la meilleure solution!
Dzenis H.
93

Prenez votre image dans un éditeur d'image, réduisez l'opacité, enregistrez-la au format .png et utilisez-la à la place.

2ToneKenobi
la source
8
Hmm ... je viens de rétrograder, mais regardez cette réponse acceptée: stackoverflow.com/a/6502295/131809 a voté 10 fois, et à peu près identique.
Alex
9
C'est une bonne option, je ne sais pas pourquoi tant de votes négatifs. Si je pouvais voter contre cela deux fois, je le ferais. Un élément enfant d'un élément parent partiellement opaque va être partiellement opaque, et devrait l'être. Toutes les «solutions de contournement» sont des bogues qui devraient éventuellement être corrigés.
RobW
6
@mystrdat Vous téléchargez déjà l'image, ce n'est pas une demande supplémentaire.
brad
2
@mystrdat Mais il télécharge déjà l'image de la flèche. Vous n'avez pas fourni de solution sans image, c'était donc mon point. Il télécharge déjà l'image de la flèche, elle pourrait aussi bien venir que nécessaire, ce qui ne serait pas une demande supplémentaire. Je ne comprends pas d'où tu viens.
brad
1
@brad Je m'excuse, il s'avère que j'ai mal lu la question maintenant que j'ai vérifié à nouveau.
mystrdat
42

Cela fonctionnera avec tous les navigateurs

div {
 -khtml-opacity:.50; 
 -moz-opacity:.50; 
 -ms-filter:"alpha(opacity=50)";
  filter:alpha(opacity=50);
  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
  opacity:.50; 
}

Si vous ne souhaitez pas que la transparence affecte l'ensemble du conteneur et ses enfants, vérifiez cette solution de contournement. Vous devez avoir un enfant absolument positionné avec un parent relativement positionné.

Vérifiez la démo sur http://www.impressivewebs.com/css-opacity-that-doesnt-affect-child-elements/

Hussein
la source
Je pense que vous devez changer les "guillemets dans le code ci-dessus" pour que cela fonctionne lorsqu'il est copié-collé directement.
nsantorello
6
cette réponse est-elle toujours la meilleure solution que les gens ont trouvée au problème de: "comment faire en sorte qu'un élément enfant n'hérite pas de la valeur d'opacité CSS de l'élément parent"? J'ai besoin que l'enfant soit vraiment un enfant .. et dans le flux de documents ... et je ne veux pas non plus apporter de javascript / flash pour cela; préférez le CSS pur.
govinda
J'ai un parent <li> à 50% opaque contenant des images enfant que je veux 100% opaques. Définir <li> sur position:relative;et img sur position:absolute;ne me permet PAS de remplacer l'opacité héritée sur img, et je ne peux pas utiliser le positionnement absolu pour les <li> eux-mêmes (c'est un gâchis ;-). En Javascript, j'ai essayé imgs[i].style.opacity = '1';, mais cela ne fonctionne pas non plus pour remplacer l'opacité héritée. Si je comprends bien, je ne peux pas non plus utiliser rgba car j'ai besoin d'affecter les images elles-mêmes, pas seulement une couleur d'arrière-plan. Quelqu'un a une recommandation pour moi?
govinda
26
Cette réponse n'a aucun sens. Le code donné, en plus d'être précisément ce que le demandeur ne veut pas faire parce qu'il ne fonctionne pas , ne correspond pas à la description ou au lien. J'ai beaucoup de mal à comprendre pourquoi tant de gens l'ont voté.
BoltClock
Si la question était «Comment définir une transparence de 50% sur un élément», ce serait une bonne réponse.
lharby
29

Si vous utilisez l'image comme une puce, vous pouvez envisager le pseudo-élément: avant.

#footer ul li {
}

#footer ul li:before {
    content: url(/images/arrow.png);
    filter:alpha(opacity=50);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
    opacity:.50;
}
Mr Griever
la source
3
Le filtre n'est qu'une solution IE
Hussein
1
Je pense que c'est probablement la meilleure solution. Il s'agit d'une pure solution CSS. Il est également possible de pirater la prise en charge d'IE7 en utilisant *zoom: expression( … );(voir : après et: avant que les pseudo-éléments de CSS ne piratent pour IE 7 ), mais IE7 est enfin en train de devenir dépassé.
Thirdender
9
#footer ul li {
  position: relative;
  opacity: 0.99;
}

#footer ul li::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  z-index: -1;
  background: url(/images/arrow.png) no-repeat 0 50%;
  opacity: 0.5;
}

Hack avec opacité .99 (moins de 1) crée un contexte d'index z afin que vous ne puissiez pas vous soucier des valeurs globales d'index z. (Essayez de le supprimer et voyez ce qui se passe dans la prochaine démo où le wrapper parent a un z-index positif.)
Si votre élément a déjà un z-index, alors vous n'avez pas besoin de ce hack.

Démo de cette technique .

utilisateur
la source
Savez-vous pourquoi nous devons définir une valeur d'opacité inférieure à 1? Est-ce une solution multi-navigateur?
zVictor
1
@zVictor oui, il s'agit d'un comportement normalisé w3c. Voir Comprendre le z-index CSS: le contexte d'empilement .
utilisateur
4

Malheureusement, au moment d'écrire cette réponse, il n'y a aucun moyen direct de le faire. Tu dois:

  1. utilisez une image semi-transparente pour le fond (beaucoup plus facile).
  2. ajoutez un élément supplémentaire (comme div) à côté des enfants dont vous voulez l'opaque, ajoutez-y un arrière-plan et après l'avoir rendu semi-transparent, placez-le derrière les enfants mentionnés.
Reyraa
la source
4

Une autre option est l' approche CSS Tricks consistant à insérer un pseudo-élément de la taille exacte de l'élément d'origine juste derrière pour simuler l'effet d'arrière-plan opaque que nous recherchons. Parfois, vous devrez définir une hauteur pour le pseudo-élément.

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;   
}
kaleazy
la source
3

La propriété "filter", a besoin d'un entier pour le pourcentage d'opacité au lieu du double, afin de fonctionner pour IE7 / 8.

filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);

PS: je poste cela comme une réponse, car SO, a besoin d'au moins 6 caractères modifiés pour une modification.

lyubeto
la source
2

Pour vraiment affiner les choses, je recommande de placer les sélections appropriées dans les wrappers de ciblage du navigateur. C'est la seule chose qui a fonctionné pour moi quand je n'ai pas réussi à faire fonctionner IE7 et IE8 "avec les autres" (car je travaille actuellement pour une société de logiciels qui continue de les soutenir).

/* color or background image for all browsers, of course */            
#myBackground {
    background-color:#666; 
}
/* target chrome & safari without disrupting IE7-8 */
@media screen and (-webkit-min-device-pixel-ratio:0) {
    #myBackground {
        -khtml-opacity:.50; 
        opacity:.50;
    }
}
/* target firefox without disrupting IE */
@-moz-document url-prefix() {
    #myBackground {
        -moz-opacity:.50;
        opacity:0.5;
    }
}
/* and IE last so it doesn't blow up */
#myBackground {
    opacity:.50;
    filter:alpha(opacity=50);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
}

Je peux avoir des redondances dans le code ci-dessus - si quelqu'un souhaite le nettoyer davantage, n'hésitez pas!

code-sushi
la source
3
Il n'est pas nécessaire de cibler chaque navigateur séparément, utilisez simplement les préfixes du navigateur dans un seul bloc de sélection. Avec les préfixes du navigateur, le navigateur n'utilisera que la propriété CSS appropriée. Au fur et à mesure que le temps passe et que la syntaxe de cette propriété devient standardisée, les fournisseurs de navigateurs abandonneront la prise en charge des préfixes et utiliseront la propriété CSS sans aucun préfixe (par exemple, Firefox a supprimé la prise -moz-border-radiusen charge de Firefox 13 et ne recherche que la border-radiuspropriété standard maintenant). IE7 et IE8 sont une histoire différente, mais c'est juste IE
:-p
Je voudrais savoir qui a voté contre et pourquoi, s'il vous plaît. Le vote est inutile sans retour d'information. J'aimerais pouvoir améliorer mes réponses. Si c'est simplement parce que les informations étaient obsolètes, veuillez vérifier la date. :) Merci.
code-sushi
@ code-sushi: Si le downvote s'est produit à peu près en même temps que votre commentaire, considérez qu'il pourrait provenir de quelqu'un d'autre qui se serait trouvé d'accord avec le commentaire du tiers (notez les upvotes sur le commentaire lui-même). Je n'ai pas voté sur votre réponse mais je suis d'accord - je voudrais ajouter que 1) KHTML ne verra jamais le -khtml-opacitycar il ne comprend pas la requête des médias, la rendant inutile 2) IE est plus stable que vous ne le pensez; il ne "explosera" pas simplement parce que vous ajoutez des préfixes non IE à une règle qui s'applique à IE. Le problème, au moment où vous l'avez affronté, devait venir d'ailleurs.
BoltClock
Ma réponse originale remonte à près de 2 ans et le vote négatif s'est produit récemment, comme cette année. J'étais juste curieux. Quant aux commentaires d'IE, ils concernaient 7 lorsque cela avait encore besoin de soutien; Je suis sûr que c'est OK maintenant dans la plupart des cas d'ignorer IE 7 ces jours-ci. Merci pour vos commentaires.
code-sushi
1

Si vous devez définir l'opacité uniquement sur la puce, pourquoi ne définissez-vous pas le canal alpha directement dans l'image? Au fait, je ne pense pas qu'il existe un moyen de définir l'opacité d'une image d'arrière-plan via css sans changer l'opacité de l'élément entier (et de ses enfants aussi).

Minkiele
la source
1

Pour ajouter à ce qui précède, vous pouvez utiliser le canal alpha avec les nouveaux attributs de couleur, par exemple. rgba (0,0,0,0) ok donc c'est noir mais avec une opacité nulle donc en tant que parent cela n'affectera pas l'enfant. Cela ne fonctionne que sur Chrome, FF, Safari et .... I thin O.

convertir vos couleurs hexadécimales en RGBA

face avant
la source
4
Cela ne fonctionnera pas avec le background-imagecomme demandé par l'OP.
Torsten Walter
1

J'ai trouvé un tutoriel assez bon et simple sur ce problème. Je pense que cela fonctionne très bien (et même s'il prend en charge IE, je dis simplement à mes clients d'utiliser d'autres navigateurs):

Transparence d'arrière-plan CSS sans affecter les éléments enfants, via RGBa et filtres

De là, vous pouvez ajouter un support de dégradé, etc.

Francisco
la source
Eh bien, cela ne fonctionnera pas directement. Vous auriez besoin de mettre un div en tant qu'élément parent avec la couleur de fond: (255,255,255,0,5) par exemple
Francisco
0
#footer ul li
     {
       position:relative;
       list-style:none;
     }
    #footer ul li:before
     {
       background-image: url(imagesFolder/bg_demo.png);
       background-repeat:no-repeat;
       content: "";
       top: 5px;
       left: -10px;
       bottom: 0;
       right: 0;
       position: absolute;
       z-index: -1;
       opacity: 0.5;
    }

Vous pouvez essayer ce code. Je pense que ça va marcher. Vous pouvez visiter la démo

Jakir Hossain
la source