PIE для скрытых или динамических элементов
Появление скрипта CSS3 PIE значительно упростило реализацию так полюбившихся дизайнерам скругленных углов и различного рода теней. Ведь теперь IE6-8 тоже могут вести себя так, как будто они понимают целый ряд CSS3-свойств.
И пускай это только эмуляция, за которой скрывается достаточно сложное (и, порой, капризное) действо с участием VML-объекта, для простого верстальщика важно, что сделать, например, скругление можно в несколько строк CSS.
Но, конечно, в реальной жизни все так радужно не бывает. Помимо прочих трудностей (перечень которых можно почитать в списке по ссылке, приведенной выше), есть еще одна серьезная проблема.
Проблема PIE и скрытых элементов
Пускай у нас есть какой-то элемент и всплывающая подсказка к нему. Причем подсказку попробуем красиво оформить — добавим скругление и теньку.
<div id="pic"> <img src="pic/pic.png" width="69" height="69" alt="тут нарисована морковь"> <div class="hint">Морковка</div> </div>
Добавляем стили:
#pic { color: #fff; position: relative; /* относительно этого блока позицонируем подсказку */ float: left; } .hint { /* оформляем подсказку */ background: #880E00; padding: 5px 15px 6px 15px; position: absolute; top: 20px; left: 70px; /* Наводим красоту: */ -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; -webkit-box-shadow: 0 0 10px #969696; -moz-box-shadow: 0 0 10px #969696; box-shadow: 0 0 10px #969696; behavior: url(js/pie.htc); /* это правило лучше вынести в отдельный ie6-8 CSS */ }
На этом этапе все будет просто замечательно (если ты, конечно, не забудешь подключить скрипт PIE). Даже IE6 отобразит закругленную подсказку с тенькой.
А теперь давай добавим динамики. Самый простой вариант — мгновенное отображение подсказки. Использую свой любимый jQuery:
jQuery(document).ready(function(){ jQuery("#pic").hover( function () { jQuery(".hint").css("display","block"); }, function () { jQuery(".hint").css("display","none"); } ); });
Ну и, конечно, изначально подсказка должна быть не видна. Добавляем правило:
.hint { display: none; }
Вот собственно и все. Приплыли. PIE больше работать не будет. Да-да, в IE6-8 подсказка будет обычным прямоугольником:
Проблема на лицо. Если блок изначально скрыт (display: none) или вообще отсутствует в коде (вставляется позже, динамически), PIE для него не сработает.
Решение
Конечно, можно попытаться обмануть скрипт и вместо скрытия блока просто вынести его куда-нибудь за пределы какого-нибудь родителя с overflow: hidden. Однако такой трюк для динамически генерируемого блока не пройдет.
В качестве универсального решения предлагается подключать нужным блокам PIE «на лету».
Для этого определим специальные функции:
var ie = jQuery.browser.msie, ieV = jQuery.browser.version, ie6 = ie&&(ieV == 6), ltie7 = ie&&(ieV <= 7), ltie8 = ie&&(ieV <= 8); function setPie(selectors){jQuery(selectors).css("behavior", "url(js/pie.htc)")}; function unsetPie(selectors){jQuery(selectors).css("behavior", "none")}; function resetPie(selectors){ unsetPie(selectors); setPie(selectors); };
Теперь в нужный момент PIE можно установить (или сбросить, во избежание глюков):
jQuery("#pic").hover( function () { jQuery(".hint").css("display","block"); ltie8 ? resetPie(".hint") : false; } ...
Демо-пример — PIE в скрытом блоке.
Проверено в:
- IE 6-8
- Firefox 3.6+
- Opera 11
- Safari
- Chrome
Примечание для самых внимательных
В коде демо-примера есть малопонятная на первый взгляд строка:
p { behavior: url(js/pie.htc); }
Что это и как оно туда попало?
Дело в том, что при первом вызове функции resetPie произойдет загрузка pie.htc, а это почти 34Кб. Время загрузки может оказаться очень даже заметным — самый первый раз, при наведении на рисунок в IE6-8, подсказка сначала появится без CSS3-наворотов, которые «догонят» ее несколько позже.
В больших проектах этой неприятности несложно избежать. Если какой-либо статичный элемент уже использует PIE, то библиотека, конечно, уже будет загружена и глюка не произойдет. На простенькой страничке демо-примера мне пришлось искусственно загрузить PIE, подцепив его на «левый» элемент — абзац. Этот трюк чем-то сродни предварительной загрузке изображений.
Вывод
Теперь PIE можно смело применять для оформления скрытых или динамически генерирующихся блоков.