Окт
Кроссбраузерность для internet explorer
Тени элементов и текста, скругление углов блоков, линейные и радиальные градиенты давно стали использоваться в дизайне веб страниц. Все эти элементы в разные времена создавались разными технологиями. С приходом css 3 всё намного упростилось. Но старые браузеры, такие как ИЕ 8 не поддерживают многие css 3 свойства. В данном посте я опишу методы которые я использую для достижения кроссбраузерности в Ie.
Expressions для ИЕ
В контексте данной статьи о кроссбраузерности ie затрону за одно и Expressions. Хоть это и актуально для ie7 (а он почти ушёл со сцены) но вдруг кому пригодится. Итак, с чем же мы имеем дело. Expressions - это конструкция в css файле, которую понимает только IE. С помощью этой конструкции мы можем писать в css файле полноценный javascript код.
.box { width: 100px; height: 100px; zoom: expression(javascript код); }
Такой вот не сложный синтаксис. Часто встречается использование в выражениях волшебного слова "this" (ссылаются на данный объект), но на практике оказалось, что использовать это не обязательно. В основном, с помощью экспрешенов выводят, вычисляют, задают css-свойства элементов. Перед тем как попробовать написать expressions, давайте вспомним основные методы работы с css стилями в javascript под ИЕ 7.
- style- дает доступ к стилю элемента. Свойство читается и переписывается. Пример: element.style.height='50px'
- currentStyle (IE)- отдаёт вычисленное (computed) значение, которое получено после исполнения всех правил CSS. Работает только в IEgetComputedStyle
- runtimeStyle (IE) - позволяет читать и переопределять значение стиля
Используя данные методы, напишем несколько expressions.
Изменяем блочную модель для ИЕ
В браузерах отличных от ИЕ 7 ширина дива будет вычисляться с учётом границы слева (граница будет входить в ширину). В ИЕ ширина блока и границы будут складываться. Чтобы этого не происходило, мы написали экспрешен, который вычисляет ширину блока в ИЕ с вычитанием из его ширины толщину границы.
.myDiv{ border-left: 1px solid #fff; border-bottom: 1px solid #fff; -moz-box-sizing: border-box; box-sizing: border-box;/*отменяем блочную модель*/ zoom:expression( runtimeStyle.zoom = '1', runtimeStyle.width=parentNode.clientWidth-parseInt(currentStyle.borderLeftWidth)+'px' ); }
Эмуляция after и before и контента в них
Задает + и - как элементы after и before
.box{ zoom:expression( runtimeStyle.zoom = 1, insertAdjacentHTML('afterBegin','+'), insertAdjacentHTML('beforeEnd', '-') ); }
Создаём элемент small, и делаем для него первого "ребёнка" и назначаем ему класс before, создаём последнего "ребёнка", и назначаем ему класс after.
.plus { *zoom: expression( this.runtimeStyle.zoom="1", this.insertBefore( document.createElement("small"), this.firstChild ).className="before", this.appendChild( document.createElement("small") ).className="after" ); }
Задаём значения для элементов after и before
.plus .before{ *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '+'); } .plus .after{ *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '-'); }
Min-width и max-width
.class { min-width : 500px ; width : expression ( document.body.clientWidth < 500? "500px" : "auto" ); }
Давайте для начала создадим тестовый стенд.
<div class="block"> <div class="gradient">Фильтр Shadow</div> <!--[if lt IE 9]><div class="shadow"></div><![endif]--> </div>
Забегу вперёд, мы будем применять разные фильтры для браузера IE. У меня не получилось применить несколько фильтров к одному блоку. Работала либо тень либо градиент. Поэтому я решил создать отдельный блок для тени и подключать его через условный комментарий только для ИЕ. Ну теперь можно начинать. А начнём мы с градиента.
Градиент для ИЕ
Для включения градиента в ИЕ будем использовать его фильтр:
filter: progid:DXImageTransform.Microsoft.gradient
(GradientType=0, startColorstr=#097FBA, endColorstr=#F5F9FB);
- startColorstr=#097FBA, endColorstr=#F5F9FB - начальный и конечный цвет градиента
- GradientType=0 - направление градиента (1-горизонтальный, 0-вертикальный)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <style type="text/css"> .block { position: relative; margin: 30px 0 50px 90px; width: 200px; height: 200px; float: left; } .gradient { position: absolute; width: 200px; height: 200px; background-color: #F5F9FB; z-index: 1; text-align: center; line-height: 70px; font-size: 20px; color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-weight: bold; /*для старых браузеров*/ -webkit-box-shadow: 5px 5px 10px 1px rgba(0,0,0, 0.5); -moz-box-shadow: 5px 5px 10px 1px rgba(0,0,0, 0.5); box-shadow: 5px 5px 10px 1px rgba(0,0,0, 0.5); /*для всех других браузеров*/ background: linear-gradient(to top, #F5F9FB, #097FBA); /*градиент для ие 6 7 8*/ filter: progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#097FBA, endColorstr=#F5F9FB); } .shadow { width: 200px; height: 200px; } </style> </head> <body> <div class="block"> <div class="gradient">Фильтр Shadow</div> <!--[if lt IE 9]><div class="shadow"></div><![endif]--> </div> </body>
Теперь градиент будет отображаться и в ИЕ 7-8. Перейдём к теням.
Тени для ИЕ
У эксплорера есть несколько фильтров для создания теней. Эти фильтры мы будем применять к блоку с классом "shadow". И так первый фильтр:
Фильтр Shadow
ms-filter:"progid:DXImageTransform.Microsoft.Shadow(color=#868383, direction=135, strength=8)";
filter:progid:DXImageTransform.Microsoft.Shadow(color=#868383, direction=135, strength=8);
- color - цвет тени
- direction - определяет направление тени в градусах с шагом 45 градусов
0 - вверх
45 - вверх и вправо
90 - вправо
135 - вниз и вправо
180 - вниз
225 - вниз и влево
270 - влево
315 - вверх и влево
- strength - определяет величину области тени в пикселях в заданном направлении 1-255
.shadow{ width: 200px; height: 200px; ms-filter:"progid:DXImageTransform.Microsoft.Shadow (color=#868383, direction=135, strength=8)"; filter:progid:DXImageTransform.Microsoft.Shadow (color=#868383, direction=135, strength=8); }
Фильтр Drop Shadow
-ms-filter:"progid:DXImageTransform.Microsoft.DropShadow
(color=#50000000, offX=8px, offY=8px)";
filter:progid:DXImageTransform.Microsoft.DropShadow
(color=#50000000, offX=8px, offY=8px);
Для прозрачных пикселей
-ms-filter:"progid:DXImageTransform.Microsoft.DropShadow
(color=#8000ff00, offX=8px, offY=8px positive=false)";
filter:progid:DXImageTransform.Microsoft.DropShadow
(color=green, offX=8px, offY=8px, positive=false);
- color - цвет тени например #8000ff00 первые две цифры это альфа канал (прозрачность) 00-полностью прозрачный FF - полностью не прозрачный. Остальные цифры цвет RGB в шестнадцатеричной системе.
-offX - смещение тени в пикселях по оси x (положительное значение вправо отрицательное влево)
-offY - смещение тени в пикселях по оси y (положительное значение вправо отрицательное влево) positive -флаг, определяющий для каких пикселей элемента создаётся тень прозрачных или нет. По умолчанию true не прозрачные пиксели.
Фильтр Blur
-ms-filter:"progid:DXImageTransform.Microsoft.Blur(pixelRadius=10)";
filter:progid:DXImageTransform.Microsoft.Blur(pixelRadius=10);
Полупрозрачная тень с радиусом размытия 5 px
-ms-filter:"progid:DXImageTransform.Microsoft.Blur(makeShadow=true, pixelRadius=5, shadowOpacity=0.5)";
filter:progid:DXImageTransform.Microsoft.Blur(makeShadow=true, pixelRadius=5, shadowOpacity=0.5);
-makeShadow - элемент отображается тенью
-pixelRadius определяет - радиус размытия
-shadowOpacity - прозрачность тени
Как отображаются тени, созданные разными фильтрами мы можем увидеть в demo примере. На мой взгляд самый оптимальный фильтр это blur c opacity. К недостаткам создания теней в ИЕ через его фильтры можно отнести несемантичность html разметки. Приходится создавать отдельный контейнер для тени. Можно конечно использовать псевдоэлементы after и befor, но у ИЕ 7 сложности с их пониманием. К ещё одному минусу можно отнести невозможность скруглить углы у контейнеров с тенью без javascript. И вот мы переходим к вопросу о круглых уголках.
Скругление углов в ИЕ
У браузеров, отличных от ИЕ закругление углов задаётся свойством border-radius. ИЕ это свойство не понимает и не имеет фильтров для его эмуляции. Для задания скруглений в ИЕ можно использовать два варианта. Первый это canvas, а второй использование javascript библиотек. Начнём с использования canvas.
Canvas
Canvas поддерживаются у нас в html 5, а IE 7-8 html 5 не поддерживают. Для того что бы научить ИЕ понимать canvas нам нужно будет подключить js библиотеку Explorer Canvas. Скачать её можно здесь . О возможностях почитать в моём посте о js библиотеках для IE. И так подключаем библиотеку.
<!--[if IE]><script type="text/javascript" src="/excanvas.js"></script><![endif]-->
Теперь создаём рабочий холст в html разметке
<div class="block"> <div class="txt">Canvas and explorercanvas<br> (нет тени в IE) </div> <canvas id=c width="210" height="210"> </canvas> </div>
Теперь вставляем между тегами <head> такой вот код
<script type="text/javascript"> function viewCanvas(){ var canvas = document.getElementById('c'); ctx = canvas.getContext('2d'); var gradient = ctx.createLinearGradient(0, 0, 0, canvas.height); gradient.addColorStop(0, '#097FBA'); gradient.addColorStop(1, '#F5F9FB'); ctx.fillStyle = gradient; ctx.beginPath(); ctx.arc(15, 185, 15, Math.PI, Math.PI*0.5, true); ctx.arc(185, 185, 15, Math.PI*0.5, 0, true); ctx.arc(185, 15, 15, 0, Math.PI*1.5, true); ctx.arc(15, 15, 15, Math.PI*1.5, Math.PI, true); ctx.shadowOffsetX = 5; ctx.shadowOffsetY = 5; ctx.shadowBlur = 10; ctx.shadowColor = "rgba(0, 0, 0, 0.5)"; ctx.fill(); } window.onload = viewCanvas; </script>
Не буду описывать синтаксис canvas, результаты вы можете увидеть в demo. Мы скруглили углы у блока. Минусы данного метода на мой взгляд в том, что приходится создавать отдельный блок canvas. Так же у меня не получилось отобразить в IE при помощи библиотеки Explorer Canvas тени блока и текста.
Библиотека css3 PIE - progressive internet explorer
На мой взгляд применение данной библиотеки самый оптимальный вариант достижения кроссбраузерности для ИЕ. Скачать библиотеку pie можно здесь . О возможностях и подключении css3 PIE читаем в моём посте. Подключить библиотеку можно разными способами. Я выбрал подключение с помощью javascript. Так же нам нужно будет подключить библиотеку jquery.
<script type="text/javascript" src="/jquery.js" ></script> <script type="text/javascript" src="/PIE.js" ></script>
Применяем нашу библиотеку к блоку с css классом ".gradientPIE"
<script type="text/javascript"> $(function() { if (window.PIE) { $('.gradientPIE').each(function() { PIE.attach(this); }); } }); </script>
Css свойства блока будут выглядеть так:
.gradientPIE{ position: absolute; width: 200px; height: 200px; background-color: #097FBA; z-index: 1; text-align: center; line-height: 70px; font-size: 20px; color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-weight: bold; -webkit-border-radius: 10px; -moz-border-radius: 10px; -ms-border-radius: 10px; -o-border-radius: 10px; border-radius: 10px; -webkit-box-shadow: 5px 5px 10px 1px rgba(0,0,0, 0.5); -moz-box-shadow: 5px 5px 10px 1px rgba(0,0,0, 0.5); box-shadow: 5px 5px 10px 1px rgba(0,0,0, 0.5); background: linear-gradient(to top, #097FBA, #F5F9FB); background: -webkit-linear-gradient(top, #097FBA, #F5F9FB); background: -moz-linear-gradient(top, #097FBA, #F5F9FB); background: -o-linear-gradient(top, #097FBA, #F5F9FB); background: -ms-linear-gradient(top, #097FBA, #F5F9FB); /*градиент для PIE*/ -pie-background: linear-gradient(#097FBA, #F5F9FB); }
Скрипту нужно было только объяснить свойство градиент записью -pie-background. С помощью css3 PIE мы объяснили ИЕ что блока есть градиент, тень и скругленные углы.
Тени для текста в ИЕ
Теперь мы подошли к последнему пункту нашего поста, это создание теней для текста. Первый вариант создания тени для текста в ИЕ это использование его фильтра DropShadow. Второй вариант опять же использование javascript библиотек. Создадим в блоке textShd заголовок h3 с текстом DropShadow параграф р с текстом JsShadow. К заголовку h3 будем применять фильтр ИЕ, а к параграф js скрипт.
<div class="block"> <div class="textShd"> <h1>C тенью на:</h1><h3>DropShadow</h3><p>JsShadow</p> </div> </div>
DropShadow
Применяем фильтр ИЕ к h3 заголовку.
.textShd h3{ color: #fff; text-shadow: 4px 4px 5px #000; font-family: serif; font-size: 30px; margin: 0; padding: 0; filter:progid:DXImageTransform.Microsoft.DropShadow (color="#666666", offX=4,offY=4,positive="true"); zoom: 1; }
Мы получили тень для текста в ИЕ, но здесь есть один нюанс. Тень получается угловатая с неровными краями. Особенно это заметно на крупных шрифтах при большом смещении тени. Это является недостатком данного метода.
Библиотека Textshadow
<script type="text/javascript"> src="/jquery.textshadow.js"</script>
Применяем к параграфу с текстом "JsShadow"
<script type="text/javascript"> $(document).ready(function(){ $(".textShd p").textShadow(); }) </script>
.textShd p{ color: #fff; font-family: serif; font-size: 30px; margin: 0; padding: 0; text-shadow: 4px 4px 3px #000; }
При применении js библиотеки тени выглядят лучше
И так подведём итог. Моё мнение такое. Быстрее и проще обучить ИЕ скруглению углов, градиенту и теням, это использовать js библиотеки css3 PIE и textshadow. Мы добились кроссбраузерности для ie, но скорей бы старые ишаки ушли со сцены.