Установите непрозрачность фонового изображения, не затрагивая дочерние элементы

214

Можно ли установить непрозрачность фонового изображения, не влияя на непрозрачность дочерних элементов?

пример

Все ссылки в нижнем колонтитуле должны иметь собственную маркировку (фоновое изображение), а непрозрачность пользовательской маркировки должна составлять 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%;
}  

Что я пробовал

Я попытался установить непрозрачность элементов списка на 50%, но затем непрозрачность текста ссылки также составляет 50% - и, похоже, нет способа сбросить непрозрачность дочерних элементов:

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

Я также попытался использовать rgba, но это не влияет на фоновое изображение:

#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
источник
Связанный stackoverflow.com/q/806000/759452
Адриен Бе

Ответы:

119

Вы можете использовать CSS linear-gradient()с 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>

Наклейки
источник
Это лучшее решение!
Дзенис Х.
93

Перенесите изображение в редактор изображений, уменьшите прозрачность, сохраните его в формате .png и используйте вместо этого.

2ToneKenobi
источник
8
Хм ... я просто проголосовал против, но посмотрите на этот принятый ответ: stackoverflow.com/a/6502295/131809 проголосовал 10 раз, и в значительной степени идентичен.
Алекс
9
Это хороший вариант, не знаю, почему так много отрицательных голосов. Если бы я мог поднять это дважды, я бы сделал это. Дочерний элемент частично непрозрачного родительского элемента будет частично непрозрачным, и должен быть. Все «обходные пути» - это ошибки, которые в конечном итоге должны быть исправлены.
RobW
6
@mystrdat Вы уже загружаете изображение, это не дополнительный запрос.
Брэд
2
@mystrdat Но он уже загружает изображение стрелки. Вы не предоставили решения, не связанного с изображением, так что это была моя точка зрения. Он уже загружает изображение стрелки, оно может также появиться по мере необходимости, что не будет дополнительным запросом. Я не понимаю, откуда ты.
Брэд,
1
@brad Я прошу прощения, оказалось, что я неправильно прочитал вопрос теперь, когда я проверил еще раз.
Mystrdat
42

Это будет работать с каждым браузером

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

Если вы не хотите, чтобы прозрачность влияла на весь контейнер и его дочерние элементы, проверьте этот обходной путь. Вы должны иметь абсолютно позиционированного ребенка с относительно позиционированным родителем.

Проверьте демо на http://www.impressivewebs.com/css-opacity-that-doesnt-affect-child-elements/

Хусейн
источник
Я думаю, вам нужно изменить "кавычки в приведенном выше коде на", чтобы он работал при прямой вставке копии.
nsantorello
6
Является ли этот ответ лучшим решением, которое люди нашли для решения проблемы: «Как заставить дочерний элемент не наследовать значение непрозрачности CSS родительского элемента»? Мне нужно, чтобы ребенок действительно был ребенком ... и в документообороте ... а также не хотел вводить javascript / flash для этого; предпочитаю чистый CSS.
Говинда
У меня есть 50% непрозрачных родительских <li>, содержащих дочерние изображения, которые я хочу, чтобы 100% непрозрачные. Установка <li> в position:relative;и img в position:absolute;НЕ позволяет мне переопределить унаследованную непрозрачность в img, и я не могу использовать абсолютное позиционирование для самих <li> (это беспорядок ;-). В Javascript я пытался imgs[i].style.opacity = '1';, но это также не работает, чтобы переопределить унаследованную непрозрачность. Если я правильно понимаю, я также не могу использовать rgba, потому что мне нужно влиять на сами imgs, а не только на цвет фона. У кого-нибудь есть рекомендации для меня?
Говинда
26
Весь этот ответ не имеет смысла. Данный код, в дополнение к тому, что именно тот, кто спрашивает , не хочет делать, потому что он не работает , не соответствует описанию или ссылке. Мне очень трудно понять, почему так много людей проголосовало за это.
BoltClock
Если бы вопрос был «Как установить прозрачность 50% для элемента», это был бы хороший ответ.
19
29

Если вы используете изображение в качестве маркера, вы можете рассмотреть псевдоэлемент: before.

#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;
}
Мистер гривер
источник
3
Фильтр - только решение IE
Хуссейн
1
Я думаю, что это, вероятно, лучшее решение. Это чистое решение CSS. Также возможно взломать поддержку IE7 с помощью *zoom: expression( … );(см . Псевдоэлементы css и до того, как взломать псевдоэлементы css для IE 7 ), но IE7, наконец, становится пассивным.
Тридцать
14

Вы можете поместить изображение в div: after или div: before и установить непрозрачность для этого «виртуального div»

div:after {
  background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/owl1.jpg);
  opacity: 0.25;
}

находится здесь http://css-tricks.com/snippets/css/transparent-background-images/

Зид Хамди
источник
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 с непрозрачностью 0,99 (меньше 1) создает контекст z-index, поэтому вы можете не беспокоиться о глобальных значениях z-index. (Попробуйте удалить его и посмотрите, что произойдет в следующей демонстрации, где родительский упаковщик имеет положительный z-индекс.)
Если у вашего элемента уже есть z-индекс, то вам этот хак не нужен.

Демонстрация этой техники .

пользователь
источник
Знаете ли вы, почему нам нужно установить значение непрозрачности меньше 1? Это кросс-браузерное решение?
zVictor
1
@zVictor Да, это стандартное поведение W3C. См. Понимание CSS z-index: Контекст стекирования .
пользователь
4

К сожалению, на момент написания этого ответа, прямого способа сделать это не существует. Тебе надо:

  1. использовать полупрозрачное изображение для фона (гораздо проще).
  2. добавьте дополнительный элемент (например, div) рядом с дочерними элементами, которые вы хотите сделать непрозрачными, добавьте к нему фон и, сделав его полупрозрачным, разместите его позади указанных дочерних элементов.
Reyraa
источник
4

Другой вариант - это CSS Tricks, который вставляет псевдоэлемент с точным размером исходного элемента прямо за ним, чтобы имитировать непрозрачный фоновый эффект, который мы ищем. Иногда вам нужно будет установить высоту для псевдоэлемента.

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
источник
3

Свойству «filter» требуется целое число в процентах непрозрачности вместо double, чтобы работать в IE7 / 8.

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

PS: я публикую это как ответ, так как для редактирования требуется как минимум 6 измененных символов.

lyubeto
источник
2

Чтобы по-настоящему настроить вещи, я рекомендую размещать соответствующие настройки в оболочках, ориентированных на браузер. Это было единственное, что сработало для меня, когда я не мог заставить IE7 и IE8 «хорошо играть с другими» (так как сейчас я работаю в софтверной компании, которая продолжает их поддерживать).

/* 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);
}

У меня может быть избыточность в приведенном выше коде - если кто-то хочет убрать его дальше, не стесняйтесь!

код-суши
источник
3
Нет необходимости настраивать таргетинг на каждый браузер отдельно, просто используйте префиксы браузера внутри одного блока выбора. С префиксами браузера браузер будет использовать только соответствующее свойство CSS. Со временем синтаксис этого свойства станет стандартизированным, поставщики браузеров откажутся от поддержки префиксов и будут использовать свойство CSS без префиксов (например, Firefox прекратил поддержку -moz-border-radiusFirefox 13 и border-radiusтеперь просто ищет стандартное свойство). IE7 и IE8 - это разные истории, но это всего лишь IE :-p
thirderder
Я хотел бы знать, кто проголосовал за это и почему, пожалуйста. Голосование бесполезно без информативной обратной связи. Я бы хотел улучшить свои ответы. Если это только потому, что информация устарела, пожалуйста, проверьте дату. :) Спасибо.
код суши
@ code-sushi: если понижение произошло примерно в то же время, что и ваш комментарий, учтите, что это могло быть от кого-то другого, кто согласился с комментарием третьего лица (обратите внимание на возражения на самом комментарии). Я не голосовал за ваш ответ, но я должен согласиться - я хотел бы добавить, что 1) KHTML никогда не увидит, -khtml-opacityпотому что он не понимает медиа-запрос, делая его бесполезным 2) IE более стабилен, чем вы думаете; он не «взорвется» только потому, что вы добавляете не-IE префиксы к правилу, которое применяется к IE. Проблема, в то время как вы столкнулись с этим, должна была прийти из других мест.
BoltClock
Мой первоначальный ответ был почти 2 года назад, и недавно, как и в этом году, произошло отрицательное голосование. Мне было просто любопытно. Что касается комментариев IE, они относились к 7, когда это все еще нуждалось в поддержке; Я почти уверен, что сейчас в большинстве случаев нормально игнорировать IE 7. Спасибо за ваш отзыв.
код суши
1

Если вам нужно установить непрозрачность только для маркера, почему бы вам не установить альфа-канал непосредственно в изображение? Кстати, я не думаю, что есть способ установить непрозрачность фонового изображения с помощью css без изменения непрозрачности всего элемента (и его дочерних элементов тоже).

Minkiele
источник
1

Просто чтобы добавить к вышесказанному ... вы можете использовать альфа-канал с новыми атрибутами цвета, например. rgba (0,0,0,0) хорошо, так что это черный, но с нулевой непрозрачностью, так что в качестве родителя это не повлияет на ребенка. Это работает только на Chrome, FF, Safari и .... Я худой O.

конвертировать ваши шестнадцатеричные цвета в RGBA

frontsideup
источник
4
Это не будет работать с background-imageзапросом OP.
Торстен Уолтер
1

Я нашел довольно хороший и простой учебник по этой проблеме. Я думаю, что он прекрасно работает (и хотя он поддерживает IE, я просто говорю своим клиентам использовать другие браузеры):

Прозрачность фона CSS, не затрагивая дочерние элементы, через RGBa и фильтры

Оттуда вы можете добавить поддержку градиента и т. Д.

Франциско
источник
Ну, это не сработает напрямую. Вам нужно было бы поместить div как видимый элемент с background-color: (255,255,255,0.5), например
Франциско
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;
    }

Вы можете попробовать этот код. Я думаю, что это будет работать. Вы можете посетить демо

Якир Хоссейн
источник