Кроссбраузерный box-shadow

CSS*
Здравствуйте, дорогие читатели. Сегодня хочу с вами поделиться чрезвычайно простым способом кроссбраузерной реализации css-свойства box-shadow. Способ настолько простой и очевидный, что я был чрезвычайно удивлен тем, что не смог найти на просторах интернета аналогичного решения (хотя я более чем уверен, что не являюсь первооткрывателем).



Итак для начала css для нормальных браузеров.
Copy Source | Copy HTML
  1. div {
  2.     background: green; /* обязательно для ie */
  3.     -webkit-box-shadow: 0px 0px 15px #222;
  4.     -moz-box-shadow: 0px 0px 15px #222;
  5.     box-shadow: 0px 0px 15px #222;
  6. }

Суть реализации свойства box-shadow для ie сводится к четырёхкратному применению фильтра shadow с разными значениями direction. Таким образом тень начинает обрамлять весь контур контейнера.
Copy Source | Copy HTML
  1. <!--[if IE]>
  2. <style type="text/css">
  3.     div {
  4.         filter:
  5.         progid:DXImageTransform.Microsoft.Shadow(color='#042b47', Direction=45, Strength=6)
  6.         progid:DXImageTransform.Microsoft.Shadow(color='#042b47', Direction=135, Strength=6)
  7.         progid:DXImageTransform.Microsoft.Shadow(color='#042b47', Direction=225, Strength=6)
  8.         progid:DXImageTransform.Microsoft.Shadow(color='#042b47', Direction=315, Strength=6);
  9.         position: relative;
  10.         top: -12px;
  11.         left: -12px;
  12.         zoom: 1;
  13.     }
  14. </style>
  15. <![endif]-->

Несколько нюансов, на которые стоит обратить внимание:
  • Тень, при использовании фильтра получается темнее, поэтому, чтобы добиться идентичности, нужно поиграться с параметрами color и strength
  • IE увеличивает размеры блока на ширину тени, а так как для каждой стороны у нас по сути две тени, то и увеличение размеров становится двоекратным. Т.е. в конце нам нужно относительно сместить блок влево и вверх по формуле left = top = -(strength*2)
  • IE6 и IE7 требуют hasLayout, поэтому для них ставим zoom: 1 (или ширину, высоту и другие свойства, которые присваивают hasLayout)
  • Для блока обязательно нужно задавать фон, иначе фильтр будет применяться к дочерним элементам

Минусы:
  • Фильтры — это всегда лишние тормоза
  • IE выключает сглаживание текста внутри блока с фильтрами
  • Тень в IE по форме отличается от тени в других браузерах (более квадратная)
  • Внутри таким образом оформленного блока перестаёт работать alphaImageLoader (возможно и другие фильтры тоже — не проверял)

Итоговый пример.

На этом всё. Спасибо за внимание.
+33
28 мая 2010, 12:52
136

комментарии (41)

+1
locky_yotun #
Темноватый вы фон выбрали, тень почти не видно. У меня, кстати, ни в 7-м, ни в 8-м IE её нет.
+3
smashercosmo #
Ой, не тот файл залил. Сейчас исправлю.
+2
smashercosmo #
Исправил
НЛО прилетело и опубликовало эту надпись здесь
0
smashercosmo #
Обновил статью с учётом твоих комментариев
0
Sabiko #
IE выключает сглаживание текста внутри блока с фильтрами
Ещё он не хочет нормально применять некоторые другие свои фильтры. И восьмёрка ломает спрайты — у неё background-position перестает работать. И начинаются хитрые косяки с отступами (в текстовых инпутах особенно прелестно). Если между блоком с тенью и внутренними с текстом-фильтрами-спрайтами есть хотя бы одна обёртка, то всё это лечится через position:relative на неё.

Вообще, если я ничего не путаю, это старая фишка, что-то такое было при эксплореровской модификации скроллбаров, кажется. Или в блоках с полупрозрачными пнг в шестёрке? Короче, и косяк, и лекарство стары, как сами иешные фильтры. жаль, что я про него забыла и в случае с тенью недавно пришлось придумывать эту очевидную вещь заново. битых полчаса, чёрт.
НЛО прилетело и опубликовало эту надпись здесь
0
banzalik #
Где-то я это видел…
+1
smashercosmo #
Это я тоже много раз видел. А вот тень, обрамляющую контейнер по всему контуру — ни разу.
0
banzalik #
Ваше открытие заключается в том, что оказывается, Microsoft.Shadow можно применить не только к 2 (нескольким) сторонам, но и к 4? :)
+3
smashercosmo #
В начале статьи я написал, что способ очень простой и очевидный. Но нигде я подобной реализации не нашёл. Если вы уже давно это применяете — вы молодец.
НЛО прилетело и опубликовало эту надпись здесь
0
smashercosmo #
Ну да на какие-то 11 месяцев опоздал :)
+4
homm #
У вас точно с кодом все в порядке?
	<!--[if IE]>
	<style type="text/css">
		filter: progid:DXImageTransform.Microsoft.Shadow(color='#042b47', Direction=45, Strength=6)
				progid:DXImageTransform.Microsoft.Shadow(color='#042b47', Direction=135, Strength=6)
				progid:DXImageTransform.Microsoft.Shadow(color='#042b47', Direction=225, Strength=6)
				progid:DXImageTransform.Microsoft.Shadow(color='#042b47', Direction=315, Strength=6);
		position: relative;
		top: -12px;
		left: -12px;
		zoom: 1;
	</style>
	<![endif]-->

Селектор для ИЕ не нужен, сразу свойства?
+5
smashercosmo #
Всё, всё… исправил
+1
waitekk #
а если таких блоков на странице будет, скажем, десяток? тормозить будет?
0
smashercosmo #
Я думаю, что будет! Хотя надо тестить конечно. AlphaImageLoader для png обычно многократно используется на странице. И ничего, вроде не сильно грузит страницу.
Я думаю, что этот способ хорошо применять, когда есть тень вокруг всего контента страницы. А для галереи с картинками не стоит.
0
tsmar #
будет конечно, это же IE

а по делу — все что имеет opacity отличный от 1 в IE добавляет тормозов
0
Isis #
Благодаря вам узнал о данном свойстве, спасибо =)
НЛО прилетело и опубликовало эту надпись здесь
0
smashercosmo #
Потому что в опере box-shadow поддерживается, начиная с версии 10.50
НЛО прилетело и опубликовало эту надпись здесь
0
simpel #
Решал задачу с тенью в IE. Итог — если применять фильтры на блоки больших размеров (центральная колонка с контентом сайта имеет тень) — ужасные тормоза. Применение фильтра к тонким блокам (10px в ширину) решает проблему тормозов но не полностью.
0
smashercosmo #
Фигово. Я как раз хотел этот способ использовать для тени вокруг всего контента сайта.
0
Olegbl4 #
> IE выключает сглаживание текста внутри блока с фильтрами
IE7 maybe
+1
zayceslav #
Напишите какой-нибудь текст в блок, чтоб посмотреть что значит «IE выключает сглаживание».
0
smashercosmo #
Обновил пример
+1
piumosso #
Вообще-то согласно концепции graceful degradation для ие не надо делать тени.
Как минимум из-за того. что это будет сильно сказываться на производительности
+1
mdss #
заказчики и дизайнеры в курсе?
0
Aux #
А почему не VML?
0
Andrewus #
Спасибо, интересное решение!
Я раньше пользовался решением Чикуёнка, но там «резиновость» блока лишь условная.
0
maxic #
Я бы не сказал что использование хака — это кроссбраузерный вариант.
Лучше в описании сразу указывать, что использовался хак,
НЛО прилетело и опубликовало эту надпись здесь
0
Glook #
«IE увеличивает размеры блока на ширину тени»
Я понимаю, что «ослика» теперь не пинает только ленивый, но Firefox и Opera тоже увеличивают ширину блока.
0
smashercosmo #
Это вы с чего взяли?
0
Glook #
ну…
на вашем же примере:
уберите отступы у body;
увеличьте ширину блока до 1000 пикселей;
переключите расширение вашего монитора на 1024 на 768;
… наблюдайте полосу прокрутки, которой, по идее, не должно быть.

увеличивайте размытие тени блока для усиления эффекта и доказательства моих слов
0
smashercosmo #
Хм… да, действительно, у body появляется прокрутка. Но насколько я понял, это единственный побочный эффект. Во всем остальном блок с тенью в FF и Opera ничем по поведению не отличается от других блоков. Просто в IE блок реально «смещается» на величину тени, так что приходится перемещать его обратно.
0
z0rg #
кроссбраузерный говорите? а опера доказывает обратное
opera 10.10
0
smashercosmo #
Ну да, и FF 2.0 доказывает обратное)) Опера поддерживает свойство box-shadow начиная с версии 10.50
0
mihdan #
Очевидный и простой способ заставляет кушать много ресурсов в ИЕ.
Лучшим решением будет использование VML в этом «браузере»
0
romn #
отнюдь не симпатичная тень в ie, к сожалению

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.