Тінь для зображення PNG у CSS


210

У мене є зображення PNG, яке має вільну форму (не квадратну).

Мені потрібно застосувати ефект тіні до цього зображення.

Стандартний підхід ...

-o-box-shadow:      12px 12px 29px #555;
-icab-box-shadow:   12px 12px 29px #555;
-khtml-box-shadow:  12px 12px 29px #555;
-moz-box-shadow:    12px 12px 29px #555;
-webkit-box-shadow: 12px 12px 29px #555;
box-shadow:         12px 12px 29px #555;

... відображає тіні для цього зображення, як би це квадрат. Отже, я бачу своє зображення і квадратну тінь, яка не відповідає формі об'єкта, відображеному на зображенні.

Чи є спосіб зробити це правильно?

Відповіді:


261

Трохи запізнюємось на вечірку, але так, цілком можливо створити «справжні» динамічні тіні для крапель навколо альфа-маскуваних PNG, використовуючи комбінацію фільтрів-тіней (для Webkit), SVG (для Firefox) та DX-фільтрів для IE.

.shadowed {
    -webkit-filter: drop-shadow(12px 12px 25px rgba(0,0,0,0.5));
    filter: url(#drop-shadow);
    -ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
    filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
}
<!-- HTML elements here -->

<svg height="0" xmlns="http://www.w3.org/2000/svg">
    <filter id="drop-shadow">
        <feGaussianBlur in="SourceAlpha" stdDeviation="4"/>
        <feOffset dx="12" dy="12" result="offsetblur"/>
        <feFlood flood-color="rgba(0,0,0,0.5)"/>
        <feComposite in2="offsetblur" operator="in"/>
        <feMerge>
            <feMergeNode/>
            <feMergeNode in="SourceGraphic"/>
        </feMerge>
    </filter>
</svg>

Деякі порівняння між справжньою тінню та коробкою-тінню та статтею про техніку, яку я щойно описав .

Я сподіваюся, що це допомагає!


1
Навіть пізніше на вечірку, але +1 для filterвласності CSS з перехресними формами ... Хоча я не думаю, що теги HTML SVG не потрібні, будь-який PNG з альфа-каналом зробить трюк
guillaume

2
Дадлі Сторі правильно. Без SVG тінь не з’являється у Firefox. @AntonAL міг би прийняти цю відповідь.
javsmo

5
DX-фільтри більше не працюють на IE ... Чи є якесь нове рішення для IE? msdn.microsoft.com/en-us/library/hh801215(v=vs.85).aspx
tb11

2
У наші дні Firefox підтримує, filter: drop-shadow(x y blur color); тому фокус SVG більше не повинен бути необхідним.
Raptor007

11
Чи ми не всі можемо погодитись, що IE слід було кидати у купу сміття років тому? Край трохи кращий, але свята корова M $ ви цілеспрямовано повернули розробку програмного забезпечення в темні віки за допомогою IE? Яка гидота
RyanNerd

216

Так, це можливо, використовуючи filter: dropShadow(x y blur? spread? color?)або в CSS, або inline:

img {
  width: 150px;
  -webkit-filter: drop-shadow(5px 5px 5px #222);
  filter: drop-shadow(5px 5px 5px #222);
}
<img src="https://cdn.freebiesupply.com/logos/large/2x/stackoverflow-com-logo-png-transparent.png">

<img src="https://cdn.freebiesupply.com/logos/large/2x/stackoverflow-com-logo-png-transparent.png" style="-webkit-filter: drop-shadow(5px 5px 5px #222); filter: drop-shadow(5px 5px 5px #222);">


8
Немає підтримки IE ... :(
CF

10
IE повинен отримати з часом: P
Брайант Джексон

6
-webkit-filter більше не потрібен
Бретт Дональд

11
2019: що IE? : P
evilReiko

36

Якщо у вас є> 100 зображень, для яких ви хочете мати тіні для краплі, я б запропонував використовувати програму ImageMagick командного рядка . За допомогою цього ви можете застосувати фігурні тіні до 100 зображень, просто ввівши одну команду! Наприклад:

for i in "*.png"; do convert $i '(' +clone -background black -shadow 80x3+3+3 ')' +swap -background none -layers merge +repage "shadow/$i"; done

Наведена вище команда (оболонка) приймає кожен .png файл у поточному каталозі, застосовує тінь випаду та зберігає результат у тіні / каталозі. Якщо вам не подобаються генеровані тіні, ви можете налаштувати параметри; для початку перегляньте документацію щодо тіней , а загальні інструкції з використання мають багато класних прикладів того, що можна зробити із зображеннями.

Якщо ви в майбутньому передумаєте про зовнішній вигляд тіней - це лише одна команда для створення нових зображень з різними параметрами :-)


22
Хоча це рішення, воно не відповідає на питання!
лео

6
Запитувач намагається, щоб браузер відобразив тінь, а не виконував сценарії на сервері, які можуть створювати тіні. Це корисна інформація, але не той самий проблемний простір.
SG1

Кілька нотаток, щоб зробити це спрацьованим: 1. Вам потрібно створити каталог тіней перед запуском цієї команди (наприклад, з mkdir shadow) 2. $iСлід зазначити (як у "$i"), або вона задихнеться, якщо в зображенні є пробіл у назви файлу:for i in *.png; do convert "$i" '(' +clone -background black -shadow 80x3+3+3 ')' +swap -background none -layers merge +repage shadow/"$i".png; done
Ендрю Машерет

2
3. Отримані файли будуть названі filename.png.png. Ось повністю працююча версія:for i in *.png; do convert "$i" '(' +clone -background black -shadow 80x3+3+3 ')' +swap -background none -layers merge +repage shadow/"$i"; done
Ендрю Машерет

@AndrewMacheret: Хороші моменти - хоча зауважте, це має бути ілюстрацією того, що можна зробити, а не повністю працюючою програмою! Я виправив подвійний суфікс .png та лапки; Що я відчуваю, що справа в каталозі просто
заважає

34
img {
  -webkit-filter: drop-shadow(5px 5px 5px #222222);
  filter: drop-shadow(5px 5px 5px #222222);
}

Це чудово працювало для мене. Одне зауважити, що в IE вам потрібен повний колір (# 222222) три символи не працюють.


29

Як Дадлі згадував у своїй відповіді це можливо завдяки випадаючому тіньовому фільтру CSS для веб-файлів, SVG для Firefox та DirectX-фільтрам для Internet Explorer 9-.

Ще один крок - вбудувати SVG, усуваючи зайвий запит:

.shadowed {
    -webkit-filter: drop-shadow(12px 12px 25px rgba(0,0,0,0.5));
    filter: url("data:image/svg+xml;utf8,<svg height='0' xmlns='http://www.w3.org/2000/svg'><filter id='drop-shadow'><feGaussianBlur in='SourceAlpha' stdDeviation='4'/><feOffset dx='12' dy='12' result='offsetblur'/><feFlood flood-color='rgba(0,0,0,0.5)'/><feComposite in2='offsetblur' operator='in'/><feMerge><feMergeNode/><feMergeNode in='SourceGraphic'/></feMerge></filter></svg>#drop-shadow");
    -ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
    filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
}

1
Він працює добре .. краще, ніж якщо я визначаю SVG всередині тегів HTML. (firefox)
Окі Ері Рінальді

18

Додайте межу з радіусом у вашому класі, якщо це блок. тому що за замовчуванням тінь застосовується на межі блоку, навіть якщо ваше зображення має закруглений кут.

border-radius: 4px;

змінити радіус кордону відповідно до кута зображення. Сподіваюся, що це допоможе.


12

Просто додайте це:

-webkit-filter: drop-shadow(5px 5px 5px #fff);
 filter: drop-shadow(5px 5px 5px #fff); 

приклад:

<img class="home-tab-item-img" src="img/search.png"> 

.home-tab-item-img{
    -webkit-filter: drop-shadow(5px 5px 5px #fff);
     filter: drop-shadow(5px 5px 5px #fff); 
}


3

Коли я розмістив це спочатку це було не можливо, так що це обхідний шлях. Тепер я просто пропоную використовувати інші відповіді.

Немає можливості точно накреслити зображення, але ви можете підробити це за допомогою діва за зображенням у центрі.

Якщо моя хитрість не працює, вам доведеться вирізати зображення і робити це для кожного маленького зображення. (чим більше зображень, тим точніше буде виглядати тінь), але для більшості зображень це добре виглядає лише одним зображенням.

що вам потрібно зробити, так це поставити обгортковий дів навколо свого зображення

<div id="imgWrap">
    <img id="img" scr="imgLocation">
</div>

потім ви помістите порожній роздільник всередині обгортки (це послужить тінню)

<div id="imgWrap">
    <div id="shadow"> </div>
    <img id="img" scr="imgLocation">
</div>

і тоді ви повинні змусити тінь з'являтися за імг за допомогою CSS:

#img {
    z-index: 1;
}

#shadow {
    z-index: 0; /*make this value negative if doesnt work*/
    box-shadow: 0 -130px 180px 150px rgba(255, 255, 0, 0.6);
    width: 0;
    height: 0;
}

тепер розташуйте imgWrap, щоб розташувати оригінальний img ... щоб центрирувати тінь img, ви можете возитися з першими двома значеннями box-тіні, роблячи їх негативними .... або ви можете позиціонувати img і тінь діви абсолютно прийняття верхнього та лівого значень img = 0 та значень тіньових розділів = половина ширини та висоти зображення відповідно.

Якщо це виглядає жахливо, виріжте ваш img up та спробуйте ще раз.

(Якщо ви не хочете, щоб тінь за img була лише на контуру, тоді вам потрібно зробити ваш img непрозорим і змусити його діяти так, ніби він прозорий, що не так складно. Ви можете прокоментувати, і я поясню пізніше)


коли я відповів, що це було неможливо, я здогадуюсь зараз. Майбутнє тут!
Xitcod13

2

У моєму випадку доводилося працювати на сучасних мобільних браузерах, із зображенням PNG різної форми та прозорості. Я створив тінь для краплі, використовуючи дублікат зображення. Це означає, що у мене є два imgелементи одного зображення, один над іншим (за допомогою position: absolute), а один позаду застосовує до нього такі правила:

.image-shadow {
  filter: blur(10px) brightness(-100);
  -webkit-filter: blur(10px) brightness(-100);
  opacity: .5;
}

Сюди входить фільтр яскравості, щоб затемнити нижнє зображення, і фільтр розмиття для відтворення тіні, що падає затьмареному ефекту, як правило, має. Потім непрозорість застосовується для пом'якшення.

Для цього можна застосувати крос-браузер за допомогою mozта msпрапорів.

Приклад: https://jsfiddle.net/5mLssm7o/



1

Це не можливо для css - зображення є квадратом, і таким чином тінь буде тінню квадрата. Найпростішим способом було б використовувати Photoshop / gimp або будь-який інший редактор зображень, щоб застосувати тінь, як основний малюнок.


Дякуємо за відповідь Але додавання зображення в редактор матиме проблеми в майбутньому, коли у мене буде> 100 зображень і я повинен трохи налаштувати тіні. Найкраще рішення моєї проблеми - це додати додаткове тіньове зображення під кожне зображення, про яке йдеться, за допомогою jQuery.
AntonAL

1

Трюк, який я часто використовую, коли мені просто потрібна "маленька" тінь (читайте: контур не повинен бути надточним), - це розміщення DIV з радіальною заливкою 100% - від чорного до 100% - прозорого під зображенням. CSS для DIV виглядає приблизно так:

.shadow320x320{    
        background: -moz-radial-gradient(center, ellipse cover, rgba(0,0,0,0.58) 0%, rgba(0,0,0,0.58) 1%, rgba(0,0,0,0) 43%, rgba(0,0,0,0) 100%); /* FF3.6+ */
        background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(0,0,0,0.58)), color-stop(1%,rgba(0,0,0,0.58)), color-stop(43%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */
        background: -webkit-radial-gradient(center, ellipse cover, rgba(0,0,0,0.58) 0%,rgba(0,0,0,0.58) 1%,rgba(0,0,0,0) 43%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */
        background: -o-radial-gradient(center, ellipse cover, rgba(0,0,0,0.58) 0%,rgba(0,0,0,0.58) 1%,rgba(0,0,0,0) 43%,rgba(0,0,0,0) 100%); /* Opera 12+ */
        background: -ms-radial-gradient(center, ellipse cover, rgba(0,0,0,0.58) 0%,rgba(0,0,0,0.58) 1%,rgba(0,0,0,0) 43%,rgba(0,0,0,0) 100%); /* IE10+ */
        background: radial-gradient(ellipse at center, rgba(0,0,0,0.58) 0%,rgba(0,0,0,0.58) 1%,rgba(0,0,0,0) 43%,rgba(0,0,0,0) 100%); /* W3C */
        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#94000000', endColorstr='#00000000',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
  }

Це створить круглу чорну зів’ялу "крапку" на DIV розміром 320x320. Якщо масштабувати висоту або ширину DIV, ви отримаєте відповідний овал. Дуже приємно створювати, наприклад, тіні під пляшки або інші форми, подібні циліндру.

Тут є абсолютно неймовірний, супер-відмінний інструмент для створення градієнтів CSS:

http://www.colorzilla.com/gradient-editor/

ps: Люб'язно натисніть на рекламу, коли ви користуєтесь нею. (І ні, я з цим не пов’язаний. Але ввічливість клацання має стати звичкою, особливо для інструменту, яким ви часто користуєтесь ... просто скажіть ... оскільки ми всі працюємо в мережі ... )


Я міг бачити, як це виглядає досить приємно, коли трохи
змінився

1
"Ввічливий клік оголошення"? Як серйозно, як зривати рекламодавців корисно для мережі? Багато хто з нас самі є рекламодавцями або платять ними, тому викликати плату за рекламодавців за рекламу товарів, які ви ніколи не збираєтесь купувати, - це дійсно неприємно робити. Якщо вас зацікавила реклама, натисніть її всіма силами, але не робіть цього!
alastair

О, зійди з моральної висоти, Аластер. Реальний світ виглядає дещо інакше. "Зривати рекламодавців"? Дійсно? ЛОЛ - Дай мені відпочити, чоловіче. Я займаюся рекламою та маркетингом майже 30 років. На розміщення дивного ввічливості клік не впливає ні на що, крім підтримки сайтів, які ви використовуєте БЕЗКОШТОВНО. Якщо ви переживаєте за інфляцію призів тощо, переживайте за все більш монополізуючі тенденції в галузі. Ось що спотворює рекламні призи, а не дивний клік ввічливості.
Rid Iculous

Це виглядає жахливо на FF та IE
barrypicker

1

Це неможливо зробити надійно у всіх браузерах. Microsoft більше не підтримує фільтри DX, як IE10 +, тому жодне з рішень тут не працює повноцінно:

https://msdn.microsoft.com/en-us/library/hh801215(v=vs.85).aspx

Єдине властивість, яке надійно працює у всіх веб-переглядачах box-shadow, і це просто ставить рамку на вашому елементі (наприклад, div), в результаті чого виходить квадратна межа:

тінь поля: горизонтальнаЗаглашення вертикальнаЗамкнення розмиттяРазрив відстаніЗахист кольорів ;

напр

box-shadow: -2px 6px 12px 6px #CCCED0;

Якщо у вас є зображення, яке є «квадратним», але з рівномірними закругленими кутами, тінь краплі працює border-radius, тому ви завжди зможете імітувати закруглені кути зображення у своєму діві.

Ось документація Microsoft для box-shadow:

https://msdn.microsoft.com/en-us/library/gg589484(v=vs.85).aspx


Я ціную пряму відповідь. Жоден із наведених вище прикладів не працює для мене.
barrypicker

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.