Posted by: fxix on: Октябрь 23, 2008
1. Браузеры поддерживающие CSS3 opacity
Понимают CSS3 свойство opacity следующие браузеры: Mozilla 1.7b+, Firefox 0.9+, Safari 1.2+, Opera 9.
Для установки прозрачности через скрипт используем: object.style.opacity
2. Mozilla 1.6 и ниже, Firefox 0.8
Старые Mozilla и Firefox 0.8 используют своё название данного свойства: -moz-opacity
Для установки прозрачности через скрипт используем: object.style.MozOpacity
3. Safari 1.1, Konqueror 3.1
Данные товарищи, построенные на движке KHTML, используют для управления прозрачностью свойство: -khtml-opacity
Для установки прозрачности через скрипт используем: object.style.KhtmlOpacity
Однако, имейте ввиду, что данное свойство доступно лишь в данных версиях этих браузеров. Safari с версии 1.2 использует CSS3 opacity, но при этом Konqueror старше версии 3.1, перестав поддерживать -khtml-opacity, не ввел поддержку CSS3 opacity.
Данный браузер, начиная с версии 5.5 и включая последнюю на сегодняшний день версию Internet Explorer 7, реализует прозрачность через Alpha DirectX фильтр. Стоит отметить, что данный фильтр использует значение прозрачности в диапазоне от 0 до 100 (а не от 0.0 до 1.0). Так же отмечу, что фильтр можно применять лишь к элементу с установленным свойством height, или width, или position со значением absolute, или writingMode со значением tb-rl, или с contentEditable установленным в true.
Пример (устанавливаем прозрачность на половину):
.img1 { filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50); }/* синтаксис IE5.5+ (является предпочтительным) */
.img2 { filter: alpha(opacity=50); } /* синтаксис IE4 */
Для установки прозрачности через скрипт используем: object.style.filter = «progid:DXImageTransform.Microsoft.Alpha(строка параметров)». Для получения прозрачности аналогичной прозрачности W3C используем в качестве строки параметров значение «opacity=число от 0 до 100″.
4. CSS opacity симбиоз
Под симбиозом я подразумеваю объединение разных стилей для разных браузеров в одном CSS правиле для получения нужного эффекта, т.е. для реализации кросс-браузерности.
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50); /* IE 5.5+*/
-moz-opacity: 0.5; /* Mozilla 1.6 и ниже */
-khtml-opacity: 0.5; /* Konqueror 3.1, Safari 1.1 */
opacity: 0.5; /* CSS3 – Mozilla 1.7b +, Firefox 0.9 +, Safari 1.2+, Opera 9 */
По сути, нужными являются первое и последнее правила, для IE5.5+ и браузеров понимающих CSS3 opacity, а два правила по середине явно погоды не делают, но и не очень то и мешают (сами решайте, нужны ли они вам).
5. Javascript opacity симбиоз
Теперь попробуем установить прозрачность через скрипт с учетом особенностей разных браузеров описанных выше.
function setElementOpacity(sElemId, nOpacity)
{
var opacityProp = getOpacityProperty();
var elem = document.getElementById(sElemId);
if (!elem || !opacityProp) return; // Если не существует элемент с указанным id или браузер не поддерживает ни один из известных функции способов управления прозрачностью
if (opacityProp==»filter») // Internet Exploder 5.5+
{
nOpacity *= 100;
// Если уже установлена прозрачность, то меняем её через коллекцию filters, иначе добавляем прозрачность через style.filter
var oAlpha = elem.filters['DXImageTransform.Microsoft.alpha'] || elem.filters.alpha;
if (oAlpha) oAlpha.opacity = nOpacity;
else elem.style.filter += «progid:DXImageTransform.Microsoft.Alpha(opacity=»+nOpacity+»)»; // Для того чтобы не затереть другие фильтры используем «+=»
}
else // Другие браузеры
elem.style[opacityProp] = nOpacity;
}
function getOpacityProperty()
{
if (typeof document.body.style.opacity == ’string’) // CSS3 compliant (Moz 1.7+, Safari 1.2+, Opera 9)
return ‘opacity’;
else if (typeof document.body.style.MozOpacity == ’string’) // Mozilla 1.6 и младше, Firefox 0.8
return ‘MozOpacity’;
else if (typeof document.body.style.KhtmlOpacity == ’string’) // Konqueror 3.1, Safari 1.1
return ‘KhtmlOpacity’;
else if (document.body.filters && navigator.appVersion.match(/MSIE ([\d.]+);/)[1]>=5.5) // Internet Exploder 5.5+
return ‘filter’;
return false; //нет прозрачности
}
Функция принимает два аргумента: sElemId – id элемента, nOpacity – вещественное число от 0.0 до 1.0 задающее прозрачность в стиле CSS3 opacity.
Думаю, что стоит пояснить часть кода функции setElementOpacity относящуюся к IE.
var oAlpha = elem.filters['DXImageTransform.Microsoft.alpha'] || elem.filters.alpha;
if (oAlpha) oAlpha.opacity = nOpacity;
else elem.style.filter += «progid:DXImageTransform.Microsoft.Alpha(opacity=»+nOpacity+»)»;
Может возникнуть вопрос, а почему бы ни устанавливать прозрачность путем присваивания (=) свойству elem.style.filter = ‘…’;? Зачем используется «+=» для добавления в конец строки свойства filter? Ответ прост, для того чтобы не «затереть» другие фильтры. Но при этом, если добавить фильтр таким образом второй раз, то он не изменит ранее установленные значения этого фильтра, а будет просто добавлен в конец строки свойства, что не корректно. Поэтому, если фильтр уже установлен, то нужно им манипулировать через коллекцию примененных к элементу фильтров: elem.filters (но учтите, если фильтр ещё не был назначен элементу, то управлять им через данную коллекцию невозможно). Доступ к элементам коллекции возможен либо по имени фильтра, либо по индексу. Однако фильтр может быть задан в двух стилях, в коротком стиле IE4, или в стиле IE5.5+, что и учтено в коде.
6. Плавное изменение прозрачности элемента
Готовое решение. Используем библиотеку opacity.js
<html>
<head>
<!– Устанавливаем изначальную прозрачность картинок –>
<style type=»text/css»>
img {
filter:alpha(opacity=30);
-moz-opacity: 0.3;
-khtml-opacity: 0.3;
opacity: 0.3;
}
</style>
<!– Подключаем библиотеку –>
<script type=»text/javascript» src=»/js/opacity.js»></script>
<script type=»text/javascript»>
// Создаем правило изменения прозрачности: задаем имя правила, начальную и конечную прозрачность, а также необязательный параметр задержки влияющий на скорость смены прозрачности
fadeOpacity.addRule(‘oR1′, .3, 1, 30);
</script>
</head>
<body>
<img id=»fImg1″ onMouseOver=»fadeOpacity(this.id, ‘oR1′)» onmouseout=»fadeOpacity.back(this.id)» src=»/img/strawberry.jpg» width=»100″ height=»80″ />
<img id=»fImg2″ onMouseOver=»fadeOpacity(this.id, ‘oR1′)» onmouseout=»fadeOpacity.back(this.id)» src=»/img/tomato.jpg» width=»82″ height=»100″ />
<img id=»fImg3″ onMouseOver=»fadeOpacity(this.id, ‘oR1′)» onmouseout=»fadeOpacity.back(this.id)» src=»/img/sweet_cherry.jpg» width=»98″ height=»97″ />
</body>
</html>
Основные шаги:
1. Подключаем библиотеку функций;
2. Определяем правила;
3. Вызываем метод fadeOpacity() для перетекания цвета от начального к конечному, или fadeOpacity.back() для возврата к начальному цвету.
Разжевываем
Как подключать библиотеку, думаю, видно из примера выше. Теперь стоит пояснить определение правил. До того как вызывать методы плавного изменения прозрачности, нужно определить правила, по которым будет выполняться процесс: нужно определить начальную и конечную прозрачность, а также, при желании, указать параметр задержки, который влияет на скорость процесса смены прозрачности.
Правила определяются с помощью метода fadeOpacity.addRule
Синтаксис: fadeOpacity.addRule (sRuleName, nStartOpacity, nFinishOpacity, nDalay)
Аргументы:
* sRuleName – имя правила, задаётся произвольно;
* nStartOpacity и nFinishOpacity – начальная и конечная прозрачность, числа в диапазоне от 0.0 до 1.0 ;
* nDelay – задержка в миллисекундах (необязательный аргумент, по умолчанию равен 30).
Сам вызов фейдинга прозрачности делаем через методы fadeOpacity(sElemId, sRuleName), где sElemId это id элемента, а sRuleName имя правила. Для возврата прозрачности в исходное состояние используется метод fadeOpacity.back(sElemId).
:hover для простой смены прозрачности
Ещё отмечу, что для простой смены прозрачности (но не постепенного её изменения) в самый раз подходит псевдо-селектор :hover, который позволяет определить стили для элемента, в момент наведения на него мыши.
<style type=»text/css»>
a:hover img {
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);
-moz-opacity: 0.3;
-khtml-opacity: 0.3;
opacity: 0.3;
}
</style>
<a href=»javascript:void(0)»> <img src=»/images/articles/strawberry.jpg» width=»100″ height=»80″ /> </a>
Обратите внимание, что картинка размещена внутри элемента A. Дело в том, что Internet Explorer вплоть до версии 6, понимает псевдо-селектор :hover, только применительно к ссылкам, а не к любым элементам, как положено в CSS (в IE7 положение исправлено).
Прозрачность и зазубренный текст в IE
С выходом Windows XP появилось сглаживание экранных шрифтов методом ClearType, а вместе с ним и побочные эффекты в IE при использовании этого метода сглаживания. Касательно нашего случая, если применяется прозрачность к элементу с текстом при включенном методе сглаживания ClearType, то текст перестает нормально отображаться (полужирный текст – bold, например, двоится, могут так же появляться различные артефакты, например, в виде чёрточек, зазубренного текста). Для того чтобы исправить положение, для IE нужно задать фоновый цвет, CSS свойство background-color, элементу к которому применяется прозрачность. К счастью в IE7 баг устранен.
7. САМОЕ ХОРОШЕЕ РЕШЕНИЕ
Что-ж, внимательно все обдумав и взвесив все за и против я пришел к следующему мнению:
- мне не нужен “лишний” JavaScript или довесок ввиде компоненты;
- HTML код страниц должен быть максимально “нетронутым”, т.е. не содержать в себе ничего лишнего;
- на будущее, уход от поддержки IE6, и избавление от невалидных трюков, должен быть простым и безболезненным
В итоге родилось абсолютно неоригинальное, но сподручное, решение очень похожее на третий подход.
При вставке PNG изображения в разметку страницы обрамляем его тэгом <div> с каким-либо уникальным id
<div id=”png1″><img src=”sample.png” width=”100″ height=”100″ /></div>
Данный код “практически не содержит ничего лишнего” и корректно отработает картинку во всех нормальных браузерах, а наличие div c id позволит обработать картинку для IE6, но об этом позже.
С фоновым PNG для блоков еще проще – совсем ничего лишнего:
<div id=”bgpng1″ style=”width:100px;height:100px”></div>
Все, остаемся верными принципу максимальной “нетронутости”. Поле для работы готово, теперь займемся его обработкой через CSS, так как была договоренность: JavaScript не использовать.
Что-бы соблюсти третий пункт о простом уходе с невалидного CSS отделяем его от основного:
В основном оставляем только обработку фоновых PNG:
html>body #bgpng1 {
background: url(bgsample.png) no-repeat;
}
А в дополнительный, вот таким образом:
<!–[if lte IE 6]>
<style>@import ”pngfix.css”;</style>
<![endif]–>
выносим (что-бы в дальнейшем было легко от него отвязаться) все “шаманские заклинания” для IE6. Вот его содержимое pngfix.css:
#png1 {
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader (src=’sample.png’, sizingMethod=’scale’);
width:100px;height:100px;
}
#png1 img { display:none; }
#bgpng1 {
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader (src=’bgsample.png’, sizingMethod=’scale’);
}
А теперь, для лучшего укладывания в голове, пример целиком (картинки подставьте по Вашему желанию):
<!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”>
<head>
<meta content=”text/html; charset=UTF-8″ http-equiv=”Content-Type” />
<title>PNG in action!</title>
<!–[if lte IE 6]>
<style type=”text/css”>
@import url(”pngfix.css”);
</style>
<![endif]–>
<style type=”text/css”>
html>body #bgpng1 {
background: url(bgsample.png) no-repeat;
}
</style>
</head>
<body>
<div id=”png1″><img src=”sample.png” width=”100″ height=”100″ alt=”» /></div>
<div id=”bgpng1″ style=”width:100px;height:100px”></div>
</body>
</html>
Вот здесь живой пример. Между прочим Markup Validation Service говорит, что: This Page Is Valid XHTML 1.0 Transitional!, так что условные комментарии от Microsoft картину не портят, чего не скажешь о внешнем CSS.
Все это довольно коряво и не очень красиво, но думаю что с ростом доли IE7 среди браузеров, PNG будет постепенно занимать свою нишу, отбирая у GIF формата обжитые места где используется прозрачность. Задумываться о будущем необходимо уже сейчас, тем более когда существуют возможности его полноценного применения.
http://handynotes.ru/2007/10/png-ie6.html#p66
8. какая то другая прозрачность
filter: alpha(opacity:90);
KHTMLOpacity: 0.90;
MozOpacity: 0.90;
opacity: 0.90;