Расставляем префиксы и сжимаем CSS автоматически

Существует множество способов сжать файл CSS или автоматически генерировать префиксы браузеров для CSS3. Обычно для решения такой задачи требуется дополнительная утилита, которая может быть достаточно неудобной в использовании. В данном уроке мы рассмотрим, как такая задача может быть решена с помощью PHP.

Разберем три вопроса:

  • Генерирование свойств CSS3 с префиксами браузеров, чтобы не заниматься ими вручную.
  • Соединение CSS файлов и исключение комментариев и избыточных пробелов, чтобы уменьшить количество запросов к серверу и сократить время загрузки страницы.
  • Выполнение выше указанных процессов при запросе страницы.

Приведем пример, который показывает, насколько прост в использовании результат нашего урока.

В CSS файле вместо префиксов используется подчеркивание:

_border-radius: 10px;

Код скрипта сгенерирует полный список свойств с префиксами:

-o-border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;

А в HTML коде ссылка для импорта стилей записывается следующим образом:

<link rel="stylesheet" href="css/css.php?f=css_file1|css_file2|css_file3">

Одним тегом link загружается сразу три CSS файла. Скрипт css.php читает перечисленные файлы (css_file1.css, css_file2.css, and css_file3.css), комбинирует их и возвращает один единый файл.

Теперь посмотрим, как устроен скрипт.

 

Пишем код

Создаем файл css.php со следующим кодом:

<?php
$files = explode("|", $_GET["f"]);

$contents = "";
foreach ($files as $file) {
    $contents .= file_get_contents($file . ".css");
}

preg_match_all('/_[a-zA-Z\-]+:\s.+;|[a-zA-Z\-]+:\s_[a-zA-Z].+;/',
    $contents, $matches, PREG_PATTERN_ORDER);

$prefixes = array("-o-", "-moz-", "-webkit-", "");
foreach ($matches[0] as $property) {
    $result = "";
    foreach ($prefixes as $prefix) {
        $result .= str_replace("_", $prefix, $property);
    }
    $contents = str_replace($property, $result, $contents);
}

$contents = preg_replace('/(\/\*).*?(\*\/)/s', '', $contents);
$contents = preg_replace(array('/\s+([^\w\'\"]+)\s+/', '/([^\w\'\"])\s+/'), '\\1', $contents);

header("Content-Type: text/css");
header("Expires: " . gmdate('D, d M Y H:i:s \G\M\T', time() + 3600));
echo $contents;

Скрипт сначала получает список CSS файлов для обработки в виде строки из параметра URL (доступного в PHP как $_GET["f"]). Каждый файл отделен вертикальной чертой. Функция explode() разделяет строку по символу вертикальной черты и возвращает массив имен файлов.

Функция file_get_contents() получает содержание каждого файла, одного за другим, и мы добавляем его в переменную $contents.

После того как содержание CSS файлов было получено, начинается поиск свойств, которые начинаются с подчеркивания, которое заменяется на префикс браузера. Функция preg_match_all() находит в тексте все части, которые соответствуют регулярному выражению, и помещает их как массив в $matches[0].

Рисунок описывает шаблон для регулярного выражения:

Шаблон для         регульярного выражения

Массив $prefixes содержит префиксы браузеров.  Вы может добавить или удалить то, что нужно. Каждое свойство в $matches[0] wбудет трансформировано в набор свойств CSS3 с префиксами браузеров. Код обрабатывает каждое свойство и создает буфер результата, заменяя подчеркивание в свойстве на очередной префикс, а затем заменяя оригинальное свойство содержанием буфера.

После добавления префиксов браузеров и возвращения свойств в $contents, скрипт вырезает любые комментарии в содержании для уменьшения размера. Рисунок ниже описывает соответствующее регулярное выражение.

Выделяем         комментарии

Затем другое регулярное выражение используется для удаления ненужных пробелов и переходов на новую строку.

Удаление пробелов         и переходов на новую строку

Свойства, которые соответствуют регулярному выражению будут сильно сжиматься:

Сжамание         свойства

Результат в переменной $contents является готовым к отправке CSS файлом. Первый вызов функции header() информирует браузер о том, что передаваемую информацию надо воспринимать как CSS файл. Второй вызов функции header() указывает браузеру, что файл действует в течении часа, чтобы браузер поместил копию в свой кэш и не запрашивал файл повторно с сервера.

 

Использование скрипта

Приведем простой пример использования нашего скрипта. Поместим файл css.php в каталог css вашего проекта вместе с тремя CSS файлами.

Первый файл header.css:

 

#header {
  width: 800px;
  height: 100px;
  padding: 20px;

  _border-radius: 10px;
  _box-shadow: 0px 0px 10px #000000;
  background: _linear-gradient(#D30000, #3D0000);
}

The second file is center.css:

#center {
  width: 800px;
  height: 400px;
  padding: 20px;
  margin: 20px 0px;

  _border-radius: 10px;
  _box-shadow: 0px 0px 10px #000000;
  background: _linear-gradient(#8ED300, #213D00);
}

The third file is footer.css:

#footer {
  width: 800px;
  height: 100px;
  padding: 20px;

  _border-radius: 10px;
  _box-shadow: 0px 0px 10px #000000;
  background: _linear-gradient(#006ED3, #00203D);
}

Обратите внимание на то, как записаны свойства CSS3. Те из них, которые требуют наличия префиксов браузеров определяются только один раз с подчеркиванием перед именем.

Теперь создаем файл index.html, который использует данные стили.

<!doctype html>
<html lang="ru">
 <head>
  <meta charset="utf-8">
  <title>example</title>
  <link rel="stylesheet" href="css/css.php?f=header|center|footer">
 </head>
 <body>
  <div id="header">Заголовок</div>
  <div id="center">Центр</div>
  <div id="footer">Подвал</div>
 </body>
</html>

Обратите внимание на атрибут href в теге link. Каждый файл CSS отдлен вертикальной чертой.

 

Заключение

В данном уроке показаны некоторые базовые операции над CSS с помощью PHP. Скрипт основан на использовании регулярных выражений - мощного инструмента для манипуляции строками. Код получился очень простым, но достаточно эффективным.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: phpmaster.com/automatic-css3-prefixer-and-compressor/
Перевел: Сергей Фастунов
Урок создан: 28 Апреля 2012
Просмотров: 20682
Правила перепечатки


5 последних уроков рубрики "PHP"

  • Фильтрация данных с помощью zend-filter

    Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

    Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

  • Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

  • Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 30 Апреля 2012 06:52
    criminalist
    У меня не работает не загружает стили
  • 30 Апреля 2012 09:29
    user46577
    работает, но хотелось бы комбинацию prefixfree с этим, чтобы без подчеркивания определяло
  • 30 Апреля 2012 11:55
    mak326428
    Хм... Я вот так сделал....
    <?php
    header("Content-Type: text/css");
    header("Expires: " . gmdate('D, d M Y H:i:s \G\M\T', time() + 3600));
    $files = explode('|', $_GET['files']);
    $all = '';
    foreach ($files as $file)
    {	$nf = $file.'.css';	if (file_exists($nf)) {	$content = file_get_contents();	echo $content.'
    ';	}	else printf('/* File not found: %s */', $nf);
    }
    ?>
  • 30 Апреля 2012 14:54
    wicket
    Смешно же!)) ну зачем это? Раз уж захотелось динамики, то используйте LESS или же SASS.
    • 17 Июня 2012 18:36
      m_hamlet
      Если динамика нужна - согласен, сам использую LESS. Но если нужно подключить несколько десятков CSS/JavaScript файлов (последовательно, естественно), то лучше их объединить.
  • 1 Мая 2012 14:19
    LondoN
    Полная фмгня. Полнейшая. При таком подходе генерация страниц очень сильно увеличится. Бездарно используемые ресурсы, которые можно потратить на более благородные цели, например, обработку файлов или что-то еще. ИМХО.
    • 14 Августа 2012 00:29
      dronnis
      Моё имхо не думает так =)
  • 1 Мая 2012 21:50
    Иван Попов
    странно
  • 3 Октября 2012 00:25
    Webskill
    глупый совет... потеря времени на генерации безумная! при мощной нагрузки на проект гарантирован конкретный просед!
^ Наверх ^