CSS

Эффект отражения текста на CSS

Задача
Добавить эффект отражения текстовому элементу. Главное требование — гибкость, т.е. текст может меняться, эффект соответственно подстраиваться.



Решение-мечта

Упомяну сразу про CSS свойство, специально для этого предназначенное — -webkit-box-reflect. Пишем подобное правило:

.reflect {  
     -webkit-box-reflect: below 0 -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.5, transparent), to(white));  
 } 


и получаем нужный эффект. При чем данное свойство применимо как к тексту, так и к любым другим элементам, в включая изображения (<video> не пробовал). Не нужно беспокоится на каком фоне расположен элемент: отражение создается полупрозрачным. Единственный и серьезный минус данного решения — отсутствие кроссбраузерности: данное свойство поддерживают только webkit браузеры.

Решение-реальность

Чтобы добиться аналогичного результата кроссбраузерно, придется добавить атрибуты в HTML, воспользоваться псевдо элементами :after и :before, CSS правилами для трансформаций и градиентов:

 <h1 title="Xiper.net - пример CSS отражения" class="h1-css">Xiper.net - пример CSS отражения</h1>


 .h1-css {  
     color: #000066;  
     font-size: 24px;  
     margin-bottom: 30px;  
     position: relative; /* элемент к которому применяем эффект должен быть блочным и position: relative */ 
 }      

 .h1-css:after { /* получаем копию оригинального текста в перевернутом виде */ 
     content: attr(title); /* оказывается в CSS и так можно - извлечь значение атрибута */ 
     position: absolute; /* отражение позиционируется относительно родителя */ 
     left: 0;  
     top: 100%; /* можно управлять удаленностью отражения. 100% - отражение вплотную */ 
     width: 100%;  
     height: 100%;  
     -moz-transform: scaleY(-1); /* много правил для CSS переворота */ 
     -o-transform: scaleY(-1);  
     -webkit-transform: scaleY(-1);  
     -ms-transform: scaleY(-1);  
     transform: scaleY(-1);  
     z-index: 1; /* чтобы отражение можно было перекрыть */ 
 }  
 .h1-css:before { /* создаем эффект затухания */ 
     content: "";  
     display: block;  
     width: 100%;  
     height: 80%; /* подбирается в зависимости о того какой процент отражения должен быть виден */ 
     background:-moz-linear-gradient(top, rgba(255,255,255,0.7), rgba(255,255,255,1)); /* много правил для линейного градиента */ 
     background: -o-linear-gradient(top, rgba(255,255,255,0.7), rgba(255,255,255,1));  
     background: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,0.7)), to(rgba(255,255,255,1)));  
     position: absolute;  
     left: 0;  
     top: 110%; /* подбирается в зависимости от необходимого эффекта затухания */ 

     z-index: 2; / чтобы перекрыть перевернутый текст */  
 } 


Атрибут в HTML хоть и очень не хочется, но приходится добавлять, т.к. правило content не способно прочитать текст элемента.

А что же IE?

С IE есть целый ряд проблем даже если не считаться с IE6:

CSS переворот (transform) IE вплоть до 9-й версии не поддерживает. Но зато имеется CSS фильтр для переворота flipV. CSS градиенты тоже отсутствуют включая 9-ю версию, но зато есть фильтр Alpha. IE7 не поддерживает псевдо элементы. Правда это можно решить с помощью expression. в IE8-9 нельзя применить фильтры к пседоэлементам, т.к. последние применяются только к элементам, имеющие layout. IE8-9 не поддерживает expression. В итоге для IE7 можно написать CSS правила используя expression и фильтры которые тоже создадут эффект отражения. А вот IE8 и IE9, хотя браузеры и по новее, единственным преимуществом в данном случае перед IE7 оказалась поддержка псевдоэлементов. Ну и в данном случае с этой поддержи толку нет, т.к. нельзя к ним применить фильтры. И создать элементы в CSS тоже уже нельзя. Поэтому для них пришлось писать небольшой скрипт. Т.к. IE7 использует ту же технику, его тоже сюда включил. Меню — один из наиболее часто используемых компонентов сайта, для которого есть соблазн создать такой эффект. Поэтому его включил в этот пример:

 <!--[if lte IE 9]>  
 <style>  
 .h1-after,  
 .menu-css {  
     position:absolute;  
     left:0;  
     top:100%;  
     z-index: 1;  
     background: #fff;  
     -ms-filter: "flipV progid:DXImageTransform.Microsoft.Alpha(opacity=50, style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=70)"; /* для IE8-9 */ 
     filter: flipV progid:DXImageTransform.Microsoft.Alpha(opacity=50, style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=70); /* для IE7 */ 
 }  
 .h1-css:after,  
 .menu-css a:after {  
     display: none; /* для IE8-9 прячем контент псевдоэлемента */ 
 }  
 </style>  
 <script>  
 textReflect = function()  
 {  
     // отражение для заголовка  
     var el = document.getElementsByTagName("h1")[0];  
     el.insertAdjacentHTML("afterBegin", "<span class=&h1-after&>"+el.firstChild.nodeValue+"</span>");  
        
     // отражения для меню  
     var menu = document.getElementsByTagName("a"),  
         i,  
         lenMenu = menu.length;  
            
     for(i=0;i<lenMenu;i++) menu[i].insertAdjacentHTML("afterBegin", "<span class=&menu-after&>"+menu[i].firstChild.nodeValue+"</span>");  
        
 }  
     window.onload=textReflect;  
    
 </script>  
 <![endif]-->


Проверено в:

IE 6-8
Firefox 4
Opera 11
Safari 5
Chrome

Недостатки

дополнительный атрибут в HTML; раздутый CSS; не подходит для неоднородного фона; нет поддержки Opera 10 и IE6 (кому это нужно?); Javascript для IE.

Итого

Решение вышло отдаленно напоминающее боевой вариант. Хотя в некоторых случаях может пригодится. А в целом вариант больше теоретический, нежели практический.
Теги:
Эффект отражения текста
Добавлено: 23 Февраля 2015 07:40:17 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...