Как стать автором
Обновить

Использование градиента в качестве фона страницы

Время на прочтение 12 мин
Количество просмотров 10K
За время существования web 2.0 в сети появились некоторые приемы так называемого web 2.0 дизайна, один из которых это градиент.
 
Создание подобного эффекта, если не брать в расчет элементы с фиксированной высотой доставляет верстальщику не мало сложностей. Ключевым моментом реализации является оптимизация графики, но с другой стороны слишком "пережатый" файл теряет качество, что особенно заметно при использовании такого элемента с нефиксированной высотой. А что делать если эффект градиента необходимо использовать в фоне страницы ?

 
Задача: рассмотреть два способа использования градиента в качестве фона страницы.
 
Я хотел бы рассмотреть реализацию не просто градиентного фона, а фона с какими-либо графическими элементами, плавно меняющими свой цвет от начала страницы до ее конца.
 
Этот фон рисовал не дизайнер студии, так что никаких претензий =)
Это фон страницы.
 
 
 
 
 
 
 
 
 
   
Итак, общее представление реализации это разбиение всего фона на несколько слоев
 

 
Первый слой, это паттерн, с названием нашей прекрасной студии.
Второй слой это сам градиент.
Третий это тело документа.
На рисунке упущен еще один слой, это слой с контентом сайта, он является самым верхним слоем, но нас не интересует.
 
 
 
 
    
Когда есть общее представление реализации, можно перейти к деталям.
 
Первый шаг, это подготовка графики для первого слоя. Просто сохраните его в photoshop'e в формате png-24, после чего оптимизируйте изображение с помощью сервиса punypng. В моем случае исходный файл сжался на 47%. Теперь скажу немного о ие6, дело в том что если использовать для него оптимизированный файл, то полупрозрачные пикселы в картинке обрежутся, оставив "битые" края надписи. Сторонние скрипты не дали мне нужный результат, поэтому я подготовил отдельную картинку без альфа-канала. Для второго примера реализации она не понадобится.
 
Этот шаг общий, следующий это создание градиента, реализация с этого момента имеет два варианта.
 

Вариант 1


Заключается в использовании растровой графики для реализации второго слоя. В этом примере я подготовил файл png8 размером 1х100 пикселей с нужным градиентом ( от  оранжевого  к  салатовому  ). Размер файла составил 465 байт.
После того как графика подготовленна необходимо собрать все в тестовую страничку.
 
<!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" lang="ru">
 <head> 
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> 
  
  <style type="text/css"> 
   * { margin: 0; padding: 0; } 
   html { height: 100%; } 
   body { height: 100%; color: #fff; } 
   .all, .content { position: relative; z-index: 1; } 
   .gradient { position: absolute; top: 0; left: 0; z-index: 0 } 
   .filter { position: absolute; z-index: 0; width: 100%; height: 100%; background: transparent url(artsofte.png) repeat scroll top left; } 
  </style> 

  <!--[if IE 6]> 
   <style type="text/css">  
    .filter { background: transparent url(artsofte2.png) repeat scroll top left; }  
    .gradient, .filter { height: expression( parseFloat(this.parentNode.offsetHeight)); } 
   </style> 
  <![endif]--> 
  
  <title></title>
 </head>
 <body> 
  <div class="all"> 
   <img class="gradient" src="background.png" width="100%" height="100%" alt="" /> 
   <div class="filter"></div> 
   <div class="content">  
    
    <!-- все что угодно --> 
  
   </div> 
  </div> 
 </body>
</html>


* This source code was highlighted with Source Code Highlighter.
Код прост, главный слой растягивается от кол-ва элементов в нем, а высота градиента и фильтра принимают значение в 100% высоты главного блока
— в итоге получилось 4 файла без вынесения стилей в отдельный файл.
К сожалению не получилось сверстать без хаков для ие 6, буду благодарен если кто-то из читающих, заинтересовавшись, выразит свой интерес в предложении более простого способа.
Пока же из предложенного мной решения видно что задача это не простая.
Хотел бы еще вспомнить один из фильтров для ИЕ, позволяющий залить слой градиентом средствами DirectX. 
Пример:
 
filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, enabled='true', startColorStr='#00458E', endColorStr='#DA251D')

* This source code was highlighted with Source Code Highlighter.

рассматривать валидность данного свойства конечно не приходится, так как мы уже не можем говорить о 100% валидации при использовании expression для ие, а вот о быстродействии сказать стоит, т.к. фильтр всегда требует большее количество ресурсов.  Использование фильтра в моем примере увеличила используемую память на 4 мб. А изменение размера окна браузера загружало  ЦП на 10% больше чем с картинкой.
 
Примечания
В ходе реализации я столкнулся с многоими неприятными моментами, о которых я расскажу попорядку.
— первое с чем я столкнулся это "торможение" браузера, это происходит из-за растягивания картинки с градиентом, т.к. браузер сглаживает растянутую картинку размером 1х100. Если увеличить размер картинки, то можно заметить прирост скорости, но "тормоза" все равно будут.
— второе это поведение ие6, пришлось рисовать отдельную картинку, и использовать css exspression.
— Еще один неприятный на мой взгляд момент, это возможность выделения заднего фона страницы.
— Самое критичное в этой реализации градиента это порядок загрузки изображений, ведь если градиент загрузится быстрее, то пользователь увидит на мгновение только градиент, эффект очень неприятный, градиенты могут быть очень яркими и постоянное "моргание" страницы создает впечатление глючного сайта. Правда если речь идет об использовании только градиента, то можно предположить что такой проблемы не возникнет.
Не смотря на то, что конечная цель была достигнута, подобный эффект потребовал относительно больших затрат, не стоит забывать  что это только пустая страница, только с одним эффектом, оправданны ли подобные затраты думаю зависит от конкретного случая, в целом все получилось.
 

Вариант 2


Итак, наткнувшись на подводные камни реализации градиентного фона с помощью картинки и слоя, я хотел бы обратить ваше внимание на то, что сам недавно начал использовать в проектах – векторная графика.
Я остановлюсь на двух языках для описания векторной графики, это SVG (Scalable Vector Graphics ) и VML (Vector Markup Language), хочу сразу оговорить что язык VML разработан фирмой Microsoft в разработке VML принимали участие несколько фирм: Microsoft, Macromedia, Autodesk, Hewlett-Packard, Visio Corporation., его поддерживают IE начиная с версии 5. SVG не поддерживается в IE без дополнительного плагина от Adobe, но для реализации плагин нам не понадобится.
 
Подключение векторной графики для ИЕ
Для того чтобы браузер определил как передавать данные VML-процессору, необходимо определить пространство имен и параметры отображения графики, пространство имен для ие6-7 определяется с помощью подключения следующей строки в секцию head.
 
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />

* This source code was highlighted with Source Code Highlighter.

Эта информация сообщает браузеру что необходимо использовать пространство имен "urn:schemas-microsoft-com:vml" анализируя элементы xml с префиксом v: для их дальнейшей передачи и обработки vml-процессору.
Для подключения пространства имен в ие8 необходимо дописать эту строку
 
<?import namespace="v" implementation="#default#VML" ?>

* This source code was highlighted with Source Code Highlighter.

Далее описываем параметры отображения, просто добавив строку в css, у меня получился отдельный файл vml.css в котором необходимо описать все используемые vml примитивы, в своем примере я ограничился только этой строкой
 
v\:vmlframe { behavior:url(#default#VML); display: block; width: 100%; min-height: 100%; position: absolute; }

* This source code was highlighted with Source Code Highlighter.

 
для ие6
 
v\:vmlframe { height: 100%; }

* This source code was highlighted with Source Code Highlighter.

 
В ИЕ vml является стандартной надстройкой. Для того что бы весь вышеприведенный код отрабатывал только в ие, воспользуемся conditional comments.
Для того что бы не возникало конфликтов с SVG, добавте в css строку скрывающую все элементы относящиеся к ней.
.svg { display: none; }

* This source code was highlighted with Source Code Highlighter.

 
Рисование
На элементах vml останавливаться подробно не буду, всю необходимую информацию можно взять в спецификации. Приведенный код ниже необходимо сохранить в vectors.vml
 
<xml xmlns:v="urn:schemas-microsoft-com:vml">

 <!-- элемент group объединяет примитивы -->
 <v:group id="bg" style="width: 100%; height: 100%">

  <!-- квадрат с градиентным фоном -->
  <v:rect style="position: absolute; width: 100%; height: 100%;">
   <v:fill type="gradient" angle="0" color="#D0E805" color2="#E88A05"></v:fill>
  </v:rect>

  <!-- квадрат с узором -->
  <v:rect style="position: absolute; width: 100%; height: 100%;">
   <v:fill type="tile" src="artsofte.png"></v:fill>
  </v:rect>

 </v:group>
  
</xml>

* This source code was highlighted with Source Code Highlighter.

На заметку: VML показался мне удобным языком, так как все векторные рисунки можно хранить в одном файле, и при необходимости указывать, используя уникальный идентификатор, какой из рисунков следует отобразить.
Теперь когда рисунок готов необходимо его подключить, это можно сделать с помощью елемента v:vmlframe, его назначение думаю все поняли по его названию, внедрять его на страницу будем также используя условные комментарии. Такое подключение может показаться удобным, но к сожалению только в этом случае, забегая вперед скажу что в следующей статье такой способ подключения не подойдет.
 
<!--[if IE]><v:vmlframe clip="true" src="vct/background.vml#bg" class="vml"><![endif]-->

<div class="content">

</div>

<!--[if IE]></v:vmlframe><![endif]-->

* This source code was highlighted with Source Code Highlighter.
Такая вложенность позволяет не использовать css expression для ие6, это экономит производительность браузера.
 
Подключение векторной графики для Mozilla, Opera, Safari, Chrome, Arora, Avant..
Подключение SVG намного проще, для этого необходимо подключить внешний файл с описанием графики с помощю элемента object :
<object class="svg" type="image/svg+xml" data="background.svg" width="100%" height="100%"></object>

* This source code was highlighted with Source Code Highlighter.

с указанным MIME-типом.
В ходе тестирования этого примера в разных браузерах, наткнулся на особенность в Сафари. Если при загрузке страницы окно было например размера 800х600, то при изменении размеров окна скажем на 1024х768, размер фона останется прежним, поэтому пришлось искать решение для Сафари, и оно нашлось достаточно быстро.
Т.к. SVG элементами можно управлять средствами JavaScript, то небольшой скрипт для Сафари вполне мог изменять размеры фона при изменении размера окна. Для того что бы скрипт работал только в этом браузере необходимо проверить поддержку объекта window свойства devicePixelRatio.
Ниже приведен весь код файла background.svg :
 
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<svg version = "1.1"
  baseProfile="full"
  xmlns = "http://www.w3.org/2000/svg"
  xmlns:xlink = "http://www.w3.org/1999/xlink"
  xmlns:ev = "http://www.w3.org/2001/xml-events"
  height="100%" width="100%">
 
  <script type="text/ecmascript"><![CDATA[
  function resize() {
   document.getElementById('rect').setAttribute("width", "100%");
   document.getElementById('rect').setAttribute("height", "100%");
   document.getElementById('rect2').setAttribute("width", "100%");
   document.getElementById('rect2').setAttribute("height", "100%");
  }
  if(window.devicePixelRatio) { window.onresize = resize }
  ]]></script>
 
  <defs>
 
  <linearGradient id="OrangeToGreen" x1="0%" y1="0%" x2="0%" y2="100%">
   <stop offset="0%" style="stop-color: #E88A05"></stop>
   <stop offset="100%" style="stop-color: #D0E805"></stop>
  </linearGradient>
  
  <pattern id="artsofte" patternUnits="userSpaceOnUse" x="0" y="0" width="200" height="200">
   <image x="0" y="0" width="200" height="200" xlink:href="artsofte.png" />
  </pattern>
  
  </defs>
 
  <rect id="rect" rx="0" ry="0" x="0" y="0" width="100%" height="100%" fill="url(#OrangeToGreen)" style="fill-opacity: 1; stroke: #E4E4E4; stroke-width: 1;"/>
  <rect id="rect2" rx="0" ry="0" x="0" y="0" width="100%" height="100%" fill="url(#artsofte)" style="fill-opacity: 1; stroke: #E4E4E4; stroke-width: 1;"/>
</svg>


* This source code was highlighted with Source Code Highlighter.

 SVG был основан на языке VML, поэтому между ними есть некоторое сходство, хочу отметить что все свойства объектов описываются не в самих объектах в отличии от языка VML, а в специальной секции <defs>, а последующее их использование осуществляется через их идентификатор.
После описания векторных рисунков, можно разметить тестовую страничку
 
<!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" lang="ru">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

  <title>Пример неоднородного фона страницы</title>

  <style type="text/css">
    *    { margin: 0; padding: 0; }
    html   { height: 100%; }
    body   { position: relative; background-color: #7E0A0A; color: #808080; min-height: 100%; _height: 100% }
    body:after { display: block; content: "."; clear: both; font-size: 0; } /* клиринг */
    .content { position: relative; /* минимальная ширина например */ }
    .svg   { position: absolute; z-index: -1; }
  </style>

  <!--[if IE]>
   <xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
   <?import namespace="v" implementation="#default#VML" ?>
   <style type="text/css">
    /*<!CDATA[[*/
     v\:vmlframe { behavior:url(#default#VML); display: block; width: 100%; min-height: 100%; _height: 100%; position: absolute; }
     .svg { display: none; }
    /*]]>*/
   </style>
  <![endif]-->

</head>
<body>

  <object class="svg" type="image/svg+xml" data="background.svg" width="100%" height="100%"></object>
  <!--[if IE]><v:vmlframe clip="true" src="vectors.vml#bg" class="vml"><![endif]-->
   <div class="content">

    <!-- все что угодно -->

   </div>
  <!--[if IE]></v:vmlframe><![endif]-->

</body>
</html>


* This source code was highlighted with Source Code Highlighter.

Итак, в итоге 4 файла без вынесения css стилей в отдельный файл.
Плюсы и минусы:
— Минус есть в IE, заключается в возможности выделить фон полностью.
— Большой размер файлов, т.к. графика описывается в формате XML. Формат SVG существует в сжатом виде, но, к сожалению, вопрос для меня остался пока что открытым. Правда в этом варианте размер файлов и так не большой.
- Использование скрипта для Safari.
+ Такой метод легко переносить на другой проэкт, так же легко изменить сам градиент, все это можно сделать не используя графический редактор.
+ Не будет происходить "морганий" страницы, в отличии от первого варианта, т.к. SVG файл не отображается пока не будет полностью прочтен. В каких-то вариантах это можно отнести к минусам.
+ Нет необходимости подготавливать для ие6 картинку без альфа-канала, т.к. VML понимает прозрачность, плюс избавились от css expressions.
+ Данный вариант полностью валиден
+ Использование трех элементов на странице ( в первом 4 )
… думаю и плюсов и минусов еще может добавится.
 

В заключении


Думаю разница в результатах видна без каких либо комментариев. Проделана достаточно большая работа, но все же я не осветил некоторые стороны использования SVG и VML. Например, при использовании VML, Internet Explorer блокирует страницу, кого-то это смущает. Не полностью раскрыта тема производительности браузеров в зависимости от первого и второго вариантов.  Конечно, проблемные места в реализации есть в обоих случаях, но, на мой взгляд, использование второго варианта оправдало себя в большей степени.
Интересно увидеть комментарии на тему не только каких либо доработок, но и по поводу значимости подобного эффекта в дизайне.
Готовые примеры в скором времени выложу выложил (раз) (два) на сервер
 
Теги:
Хабы:
+64
Комментарии 55
Комментарии Комментарии 55

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн