Я не люблю CSS. Он простой и понятный. Это движущая сила Интернета, но он слишком ограниченный и им трудно управлять. Пришло время привести этот язык в порядок и сделать его более полезным, используя динамический CSS при помощи LESS.
Объясню свою позицию на примере. Почему бы вместо использования #FF9F94 для получения темно-персикового цвета просто не хранить значение этого цвета в переменной для её последующего использования? Что бы перекрасить сайт достаточно будет изменить значение переменной всего в одном месте и всё.
Другими словами: это будет очень изящно, если мы будем использовать немного программирования и логики в CSS, что бы сделать его более мощным инструментом. Хорошо, что это всё возможно с использованием LESS .
Затем создадим файл с расширением.less и привяжем его с помощью такого кода:
Удостоверьтесь, что вы прикрепили LESS файл перед JS.
Теперь LESS файл будет работать также как и обычный CSS.
@header-font: Georgia;
h1, h2, h3, h4 {
font-family: @header-font;
}
.large {
font-family:@header-font;
}
В примере выше мы объявляем переменную @header-font и записываем туда значение «Georgia». Теперь мы можем использовать эту переменную всегда, когда мы хотим установить шрифт Georgia. Если же мы решим, что Trebuchet MS лучше подходит для наших заголовков, то нам не нужно будет просматривать весь файл, мы просто изменим значение переменной.
Я нашел отличное применение переменным в определении цветов сайта. В старые добрые времена (которые были не так давно) я использовал что-то вроде этого:
/*
Colors for my Website
#ff9900 - Orange - used for links and highlighted items
#cccccc - Light Gray - used for borders
#333333 - Dark Black - Used for dark backgrounds and heading text color
#454545 - Mid Black - Used for general text color
*/
body {
background: #333333;
color: #454545;
}
a {
color:#ff9900;
}
h1, h2, h3, h4, h5, h6 {
color: #333333;
}
Нет ничего плохого в том, чтобы документировать ваши цвета также как здесь, это хорошая практика, проблема заключается в том, что документация не имеет ничего общего с функциональностью ваших стилей. Если вы решили изменить цвета после 2000 строки кода, а затем передумали на 3567 строчке, то будет чрезвычайно сложно исправить все цвета и документацию.
С LESS мы можем модифицировать и одновременно документировать наш рабочий процесс.
/* Colors for my Website */ @color-orange: #ff9900; @color-gray_light: #cccccc; @color-black_dark: #333333; @color-black_medium: #454545; body { background: @color-black_dark; color: @color-black_medium; } a { color:@color-orange; } h1, h2, h3, h4, h5, h6 { color: @color-black_dark; }
Область видимости переменных Область видимости переменных описывает места, где они доступны. Если вы определите переменную в самом начале LESS файла, то она будет доступна для любого кода написанного после.A {
@color: #ff9900;
color:@color;
}
button {
background: @color;
}
В этом примере LESS не будет сконвертирован из-за ошибки, не определена для использования внутри элемента button. Если переменная объявлена вне элемента и внутри другого элемента, то она будет доступна только локально.
@color: #222222;
a {
@color: #ffffff;
color:@color;
}
button {
background: @color;
}
Здесь ссылка будет окрашена в белый, а у кнопки будет черный фон.
@color-chirstmas_red: #941f1f;
@name-of-color: "color-chirstmas_red";
color: @@name-of-color;
Лично я почти не использую это, так как переменные в переменных почти бесполезны без замыканий, но я уверен, что найдутся умные примеры использования этого.
Button{
@unit: 3px;
border:@unit solid #ddd;
padding: @unit * 3;
margin: @unit * 2;
}
Код выше устанавливает переменную
в 3px. Затем мы устанавливаем это значение в ширину рамки, отступы в три раза больше этой ширины, а поля – в два.
Можно использовать операции умножения, деления, сложения и вычитания. Что бы создать блок с рамкой увеличивающей ширину сторон по часовой стрелке, можно использовать следующий код:
Box{ @base_unit: 1px; border: @base_unit @base_unit + 1 @base_unit + 2 @base_unit + 3 }
Управление цветом Моя любимая особе6нность LESS – управление цветом. Можно использовать операции для смешивания цветов и несколько специальных функций для работы с цветом.Цветовые операции Если вы хотите изменить значение цвета, то можете сделать это вычитанием или добавлением другого цвета. @color: #941f1f;
button {
background: #941f1f + #222222;
border: #941f1f - #111111;
}
Вышеприведённая операция с фоном увеличит каждое значение HEX на 2. Результатом будет “B64141″ - более светлый вариант оригинального цвета. Операция с рамкой уменьшит каждое значение HEX на 1 и выдаст более темный цвет: “830E0E”.
На практике есть немало случаев, когда мы начинаем с базового цвета и нуждаемся в слегка затемненном или осветленном его варианте.
@color-button: #d24444;
input.submit {
color:#fff;
background:@color-button;
border:1px solid @color-button - #222;
padding:5px 12px;
}
Этот код создает красную кнопку с немного затемненной рамкой. Это частая ситуация и определение лишь одного цвета – большая помощь.
@color: #faa51a;
.button {
background: -webkit-gradient(linear, left top, left bottom, from(@color + #151515), to(@color - #151515));
background: -moz-linear-gradient(top, @color + #151515, @color - #151515);
}
@color: #3d82d1;
.left_box {
background:lighten(@color, 20%);
}
.right_box {
background:darken(@color, 20%);
}
@color: #3d82d1;.left_box {
background: desaturate(@color, 18%);
}
.middle_box {
background: @color;
}
.right_box {
background: saturate(@color, 18%);
}
@color: #3d82d1;.left_box {
background: spin(@color, 25%);
}
.middle_box {
background: @color;
}
.right_box {
background: spin(@color, -25%);
}
@color = #167e8a;
hue(@color);
saturation(@color);
lightness(@color);
Это может показаться слишком мелочным – зачем нам нужна эта информация, когда мы можем просто ввести HEX значение? Если вы нормальный человек, то вы не сможете с ходу расшифровать HEX цвет. HEX значения отображают RGB спектр: первые два символа контролируют количество красного, следующие два - количество зеленого и последние два – количество синего.
Достаточно очевидно, что #ff0000 это красный, так как это RGB(255,0,0). Тона красного, никакого зеленого и синего. Тем не менее, если вы увидите #1f6b2d, то будет трудно декодировать, что это темно-зеленый. В HSL представлении hue (тон) управляет всем, вы могли бы просто назвать цвет, остальное просто задаст тон (это не совсем верно, но всё происходит именно так).
Имея это в виду, если вы нашли хороший пурпурный цвет как #e147d4, вы очень легко можете отыскать различные цвета с точно таким же оттенком. Скажем, вы хотите создать сливочную, более пастельную версию #e147d4, вот что можно сделать:
Новый цвет будет иметь тот же тон, но другие насыщенность и яркость. Результатом будет #c480bf, к которому гораздо труднее перейти от #e147d4 используя лишь HEX.
@color: #c480bd; .class { background-color: desaturate(spin(@color, 18), 12%);}
Вложенность Во время написания CSS мы пользуемся каскадностью стилей. Чтобы изменить поля у параграфа только внутри статьи можно использовать следующий код:Article.post p{
margin: 0 0 12px 0;
}
Нет ничего плохого в таком подходе, но если нам надо также изменить стиль ссылок, цитат, заголовков и т.д. только внутри статьи, нужно будет использовать префикс “article.post” для каждого элемента. Это делает написание кода более скучным и усложняет его чтение.
В LESS мы можем вложить эти правила, что даст нам более короткую и логичную версию наших стилей. Например:
Article.post {
p{
margin: 0 0 12px 0;
}
a {
color: red;
}
a:hover {
color: blue;
}
img {
float:left;
}
}
Отступы не обязательны, но они делают код более читабельным. Уровни вложенности не ограничены.
A { color:red; } p { margin:0px; } article { a { color: green; } p { color: #555; a { color:blue; } } }
Примеси (mixins) Примеси в LESS избавят вас от набора излишнего кода. Вам когда-нибудь приходилось создавать закругленную рамку в которой только верхние углы скругленны?Tab {
-webkit-border-top-left-radius: 6px;
-webkit-border-top-right-radius: 6px;
-moz-border-radius-topleft: 6px;
-moz-border-radius-topright: 6px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
И так каждый раз… С LESS все это можно изменить, создав примесь. Примеси – элементы многоразового использования, которые можно добавить к любому элементу как правило. И даже не нужно изучать новый синтаксис.
Rounded_top {
-webkit-border-top-left-radius: 6px;
-webkit-border-top-right-radius: 6px;
-moz-border-radius-topleft: 6px;
-moz-border-radius-topright: 6px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
.tab {
background: #333;
color:#fff;
.rounded_top;
}
.submit {
.rounded_top;
}
В вышеприведенном коде мы определили элемент.rounded_top для округления верхних углов. Когда мы добавляем его к любому другому элементу как примесь (смотрите.tab) мы по существу импортируем правила, которые мы создали для него. Благодаря такому синтаксису мы можем использовать любой элемент в качестве примеси.
Rounded_top {
-webkit-border-top-left-radius: 6px;
-webkit-border-top-right-radius: 6px;
-moz-border-radius-topleft: 6px;
-moz-border-radius-topright: 6px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
.tab {
background: #333;
color:#fff;
.rounded_top;
}
.submit {
.tab;
background: red;
}
Стили у элемента.submit - это скругленные углы наверху, белый цвет и красный фон (значение #333 переопределено).
Rounded_top(@radius) {
-webkit-border-top-left-radius: @radius;
-webkit-border-top-right-radius: @radius;
-moz-border-radius-topleft: @radius;
-moz-border-radius-topright: @radius;
border-top-left-radius: @radius;
border-top-right-radius: @radius;
}
.tab {
background: #333;
color:#fff;
.rounded_top(6px);
}
.submit {
.rounded_top(3px);
}
В вышеприведенном коде радиус у.tab равен 6px, а.submit элемент получит значение 3px.
Rounded_top(@radius:6px) {
-webkit-border-top-left-radius: @radius;
-webkit-border-top-right-radius: @radius;
-moz-border-radius-topleft: @radius;
-moz-border-radius-topright: @radius;
border-top-left-radius: @radius;
border-top-right-radius: @radius;
}
.tab {
background: #333;
color:#fff;
.rounded_top;
}
.submit {
.rounded_top(3px);
}
В этом примере.tab получит стандартное значение в 6px, а.submit – 3px.
Radius(@radius:6px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
.button(@radius:3px, @background: #e7ba64, @padding: 4px) {
.radius(@radius);
background:@background;
border: 1px solid @background - #222;
padding: @padding;
}
.read_more {
.button(0px);
}
В этом примере класс.read_more отформатирован с отступом 4px, фоновым цветом #e7ba64 и с border-radius рывным 0px.
Div {
border:1px solid #bbb;
}
Чтобы задать всем необходимым элементам серую границу, вы можете использовать такую функцию:
Gray_border(@width: 1px, @type: solid, @color: #bbb){
border:@arguments;
}
div {
.gray_border(2px, dashed);
}
@arguments это специальное ключевое слово, которое выводит все параметры один за другим в заданном порядке. Результатом вышеприведённого LESS кода будет:
Div { border:2px dashed #bbb; }
Параметрические примеси без параметров Также можно использовать параметрические примеси без параметров. Это используется тогда, когда вам не нужно выводить примесь в CSS, но вы хотите чтобы ее правила применялись к элементу в котором она используется.Alert {
background: red;
color: white;
padding:5px 12px;
}
.error_message {
.alert;
margin: 0 0 12px 0;
}
CSS вышеприведенного кода будет таким:
Alert {
background: red;
color: white;
padding:5px 12px;
}
.error_message {
background: red;
color: white;
padding:5px 12px;
margin: 0 0 12px 0;
}
Чтобы скрыть класс.alert нужно установить пустой параметр.
Alert() {
background: red;
color: white;
padding:5px 12px;
}
.error_message {
.alert;
margin: 0 0 12px 0;
}
Готовый CSS будет следующим:
Error_message {
background: red;
color: white;
padding:5px 12px;
margin: 0 0 12px 0;
}
В основном это используется для уменьшения размера CSS файла.
#my_framework {
p {
margin: 12px 0;
}
a {
color:blue;
text-decoration: none;
}
.submit {
background: red;
color: white;
padding:5px 12px;
}
}
Начиная работу над новым сайтом, основанным на вашем фреймворке, вы можете добавить связку #my_framework и использовать ее не засоряя пространство имён.
Submit_button {
#my_framework > .submit;
}
Также это отличный способ сделать возможным быструю смену и доработку тем. Если вы разрабатываете несколько тем для вашей компании, то для смены шаблонов на лету, вы можете поместить их все в один LESS файл, используя связки.
#fw_1 { p { margin: 12px 0; } a { color:blue; text-decoration: none; } .submit { background: red; color: white; padding:5px 12px; } } #fw_2 { p { margin: 8px 0; } a { color:red; text-decoration: underline; } .submit { background: blue; color: white; padding:8px 20px; } } .submit_button { #fw_2 > .submit; }
Строковая интерполяция Строковая интерполяция это еще одно причудливое слово, означающее, что эта произвольная строка может храниться в переменной, а затем использоваться в значении свойства. @url: "http://mycompany.com/assets/";background-image: url("@{url}/sprite.png");
Это может быть полезно при создании централизованного фреймворка.
Filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#666666", endColorstr="#444444");
Этот CSS не валиден, поэтому LESS не скомпилируется. В этом случае вы можете экранировать это значение, что позволит LESS пропустить его.
Button {
background: -webkit-gradient(linear, left top, left bottom, from(#666666), to(#444444));
background: -moz-linear-gradient(top, #666666, @color - #444444);
filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr="#666666", endColorstr="#444444")";}
Все что нужно сделать, это заключить секцию в кавычки и поставить тильду перед ней. Эта секция не пройдет через LESS процессор и не будет выкинута.
@import "reset.min.css";
@import "framework.less";
@import "widgets";
Первый импорт достаточно очевиден. Он импортирует CSS правила определённые в reset.min.css без обработки их LESS парсером.
Второй импорт вставит содержание framework.less и обработает его как любые другие LESS правила.
Третий импорт работает также как и второй. Если расширение не установлено, то препроцессор считает его LESS файлом.
/* This is my main LESS file. It governs how most of the site looks. /* body { padding:0px; // This resets the body padding }
Чего не хватает? Несмотря на то, что LESS восхитительный, всё же когда вы начнёте использовать его, обнаружатся некоторые недостатки, хотя они не очень беспокоят.Filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr="#faa51a", endColorstr="#f47a20")";
Этот код прекрасно работает, но цвета должны быть жёстко определены. Если строчка экранирована, то переменные не обрабатываются. Было бы неплохо иметь опцию, в которой переменные в экранированных строках обрабатывались до отправки в CSS файл.
Страница 4 из 4
Сжатие выходных данныхДля того чтобы сжать буфер вывода нужно передать функции ob_start() параметр - имя функции - компрессора, например ob_gzhandler .При этом будет выполнена проверка поддержки сжатия и если такая поддержка есть, то данные будут сжиматься:
// Здесь мы включили сжатие буфера: ob_start("ob_gzhandler"); echo "Contrary ... section"; ob_end_flush();
Результат обведён красным:
А вот результат без сжатия вывода:
Сжатие работает только применительно к HTML - коду , к картинкам и прочему это не относится. Учитывайте это. А ещё PHP позволяет сжимать только один буфер вывода , так как содержимое должно сжиматься всё и сразу. Имейте это ввиду, если вы используете стек буферов вывода.
Переписывание URLOutput_add_rewrite_var("name", "value")
Эта функция принимает два параметра, первый это имя переменной, а второй это значение этой переменной. Эта пара ключ-значение добавиться ко всем URL, формам и атрибутам SRC - элементов FRAME, в виде GET - переменных строки запроса. К формам добавятся скрытые поля с соответствующими значениями. В общем проще показать на примере:
"; echo "LINK"; ob_end_flush();
Выдаст такой HTML - код:
LINK
Заметьте атрибуты action тега form - остались не тронуты! Пример с тегами FRAME:
Ob_start(); output_add_rewrite_var("somevar", "someval"); echo " "; ob_end_flush();
Выдаст такой HTML - код:
Функцию output_add_rewrite_var() можно вызывать несколько раз с разными параметрами, в этом случае пары будут добавляться согласно формату кодирования данных: "application/x-www-form-urlencoded" разделяясь знаками амперсанда а в формы будут добавляться новые скрытые поля. Вот так будет выглядеть пример:
Ob_start(); output_add_rewrite_var("somevar", "someval"); output_add_rewrite_var("somevar1", "someval1"); output_add_rewrite_var("somevar2", "someval2"); echo " "; echo "LINK"; ob_end_flush();
Выдаст такой HTML - код:
LINK
А вот если в конце примера вызвать функцию output_reset_rewrite_vars() - то она отменит все изменения произведённые вызовами функций output_add_rewrite_var(...) т.е. все ссылки вернуться к исходному состоянию.
Ну, вот надеюсь я доступно объяснил что такое буферизация вывода в PHP и с чем её едят.
У меня есть большой объем данных для перемещения, используя два сценария PHP: один на стороне клиента, используя скрипт PHP командной строки и другие за Apache. Я отправляю данные на сервер и использую поток ввода : //, чтобы сохранить его на веб-сервере. Чтобы не доходить до пределов памяти, данные разделяются на куски 500 кБ для каждого запроса POST. Все это прекрасно работает.
Теперь, чтобы сохранить полосу пропускания и ускорить ее, я хочу сжать данные перед отправкой и распаковкой, когда они получены на другом конце. Я нашел 3 пары функций, которые могут выполнять эту работу, но я не могу решить, какой из них использовать:
ОБНОВЛЕНИЕ: Я только что прочитал zlib FAQ:
Формат (gzencode) был разработан, чтобы сохранить информацию о каталоге одного файла, например имя и дату последней модификации. С другой стороны, формат zlib (gzcompress) был разработан для приложений в памяти и коммуникационных каналах и имеет гораздо более компактный заголовок и трейлер и использует более быструю проверку целостности, чем gzip.
Все это можно использовать. Существуют тонкие различия между тремя:
Все три используют один и тот же алгоритм под капотом. gzencode() добавляет возможность включать исходное имя файла и другие данные об окружающей среде (это не используется при сжатии строки). gzencode() и gzcompress() добавляют контрольную сумму, поэтому можно проверить целостность архива, что может быть полезно для ненадежных методов передачи и хранения. Если все хранится локально и вам не нужны дополнительные метаданные, тогда gzdeflate() будет достаточно. Для переносимости я бы рекомендовал gzencode() (формат GZIP), который, вероятно, лучше поддерживается, чем gzcompress() (формат ZLIB) среди других инструментов.
Я не эксперт по PHP и не могу ответить на поставленный вопрос, но похоже, что здесь много угадываний, и предлагается нечеткая информация.
DEFLATE – это имя алгоритма сжатия, который используется ZLIB, GZIP и другими. Теоретически GZIP поддерживает альтернативные алгоритмы сжатия, но на практике их нет.
Не существует такого понятия, как «алгоритм GZIP». GZIP использует алгоритм DEFLATE и помещает данные кадрирования вокруг сжатых данных. С GZIP вы можете добавлять такие вещи, как имя файла, время файла, CRC, даже комментарий. Однако эти метаданные являются необязательными, и многие gzippers просто опускают его.
ZLIB аналогичен, за исключением другого, более ограниченного набора метаданных и определенного 2-байтового заголовка.
Это все в IETF RFC 1950 , 1951 и 1952 годах.
Сказать, что «алгоритм gzip сжимается лучше, чем DEFLATE» – это просто абсурд. Не существует алгоритма gzip. И алгоритм, используемый в формате GZIP, – DEFLATE .
Все методы по существу одинаковы, разница между ними в основном заключается в заголовках. лично я бы использовал gzencode, это приведет к выдаче вывода, равного вызову командной строки в утилиту gzip.
В жизни каждого мужчины наступает момент, когда трафик растёт и сервак умирает необходимо задуматься об оптимизации. В последнем дайджесте PHP (№ 40) была упомянута ссылкой статья «How GZIP Compression Works». Исходя из статистики , 56% веб-сайтов используют GZIP. Я надеюсь, эта статья раскроет перед читателем достоинства этой технологии.
В тексте возможны ошибки (делал вычитку несколько раз, но всё же вдруг), поэтому заранее прошу прощения и прошу сообщать мне обо всех проблемах через личные сообщения, если какая-то часть перевода покажется вам некорректной.
Даже в современном мире, со скоростным интернет соединением и неограниченными хранилищами информации, сжатие данных по-прежнему актуально, особенно для мобильных устройств и стран с медленным интернет-соединением. Этот пост описывает метод де-факто сжатия без потерь для сжатия текстовых данных на веб-сайтах: GZIP.
GZIP compression GZIP обеспечивает сжатие без потерь, иными словами, исходные данные можно полностью восстановить при распаковке. Он основан на алгоритме DEFLATE, который использует комбинацию алгоритма LZ77 и алгоритма Хаффмана.Алгоритм LZ77 Алгоритм LZ77 заменяет повторные вхождения данных на «ссылки». Т.е. если в имеющихся данных какая-то цепочка элементов встречается более одного раза, то все последующие её вхождения заменяются «ссылками» на её первый экземпляр. Алгоритм прекрасно рассмотрен horror_x и описан . Каждая такая ссылка имеет два значения: смещение и длина.Давайте рассмотрим пример:
Как вы могли заметить, слова «hosting» и «PHP» повторяются, поэтому во второй раз, когда подстрока найдена, она будет заменена ссылкой. Есть и другие совпадения, такие как «er», но т.к. это незначительно (в данном случае - «er» отсутствует в других словах) , остается оригинальный текст.
Кодирование Хаффмана Кодирование Хаффмана является методом кодирования с переменной длиной, которая назначает более короткие коды к более частым «символам». Проблема с переменной длиной кода, как правило в том, что нам нужен способ узнать, когда код закончился и начался новый, чтобы расшифровать его.Кодирование Хаффмана решает эту проблему, создав код префикса, где ни одно кодовое слово не является префиксом другого. Это может быть более понятно на примере:
>Original text: «ServerGrove»DEFLATE как алгоритм, который используется в GZIP сжатии, является комбинацией обоих этих алгоритмов.
Является ли GZIP лучшим метод сжатия? Ответ - нет. Есть другие методы, которые дают более высокие показатели сжатия, но существует несколько хороших причин использовать этот.Во-первых, даже при том что GZIP не самый лучший метод сжатия, он обеспечивает хороший компромисс между скоростью и степенью сжатия. Сжатие и распаковка у GZIP происходят быстро и степень сжатия на высоком уровне.
Во-вторых, нелегко внедрить новый глобальный метод сжатия данных, который смогут использовать все. Браузерам потребуется обновление, что на сегодняшний день гораздо проще за счёт автообновления. Как бы то ни было, браузеры - не единственная проблема. Chromium пытался добавить поддержку BZIP2, более лучшего метода основанного на преобразовании Барроуза-Уилера, но от него пришлось отказаться, т.к. некоторые промежуточные прокси-серверы искажали данные, т.к. не могли распознать заголовки bzip2 и пытались обработать gzip контент. Баг-репорт доступен .
Существует несколько известных багов в некоторых версиях браузеров, по этому рекомендуется* также добавить:
Кроме того, можно использовать предварительно сжатые файлы вместо того, чтобы сжимать их каждый раз. Это особенно удобно для файлов, которые не меняются при каждом запросе, например CSS и JavaScript, которые могут быть сжаты с использованием медленных алгоритмов. Для этого:
$originalFile = __DIR__ . "/jquery-1.11.0.min.js"; $gzipFile = __DIR__ . "/jquery-1.11.0.min.js.gz"; $originalData = file_get_contents($originalFile); $gzipData = gzencode($originalData, 9); file_put_contents($gzipFile, $gzipData); var_dump(filesize($originalFile)); // int(96380) var_dump(filesize($gzipFile)); // int(33305)
Вместо вывода (примечание переводчика) Не смотря на то, как чесались руки добавить в статью автора собственные пояснения алгоритмов, статистику и результаты тестов сравнения, перевод осуществлён практически без вмешательств со стороны переводчика. Перевод статьи осуществлён с разрешения автора и портала ServerGrove.