Статьи

Как выжать максимум из МЕНЬШЕГО

Несколько недель назад во время больного дня я нашел то, на что собирался смотреть около года: МЕНЬШЕ . Если что-то стоит посмотреть на веб-технологии, я обещаю, что МЕНЬШЕ. В этой статье мы рассмотрим удивительную силу LESS и его способность упростить и улучшить процесс разработки. Мы расскажем о быстром прототипировании, создании облегченной грид-системы и использовании CSS3 с LESS.


В этом уроке я буду использовать реализацию PHP LESS от Leaf Corcoran. Эта реализация является лишь одним из многих, и принципы, обсуждаемые в этом руководстве, должны применяться к любой реализации LESS. Другие версии LESS включают в себя оригинальную версию Ruby и реализацию JavaScript .

Начните с загрузки последней версии LESS . После того, как вы извлечете файл, у вас должна появиться папка ‘lessphp’. Внутри вы найдете файл под названием «less.inc.php»: это тот, который мы хотим. Возьмите этот файл и поместите его в папку CSS вашего сайта.


LESS PHP работает путем анализа файлов .less и их преобразования в CSS, что могут понять браузеры. LESS PHP может выполнить эту задачу несколькими способами, но мы будем использовать простой метод класса PHP для разбора CSS; другие методы обсуждаются в документации LESS PHP. Хорошо, давайте напишем немного кода.

Создайте файл styles.php в папке CSS вашего сайта.

1
2
3
<?php
if (substr_count($_SERVER[‘HTTP_ACCEPT_ENCODING’], ‘gzip’)) ob_start(«ob_gzhandler»);
else ob_start();

Первая строка — это просто способ сжать окончательный файл «CSS», уменьшив его размер; это всегда хорошая практика. Вы также можете сделать это через файл .htaccess .

1
2
3
$files = array(
    ‘styles.less’
);

В этом коде мы устанавливаем пути к нашим файлам .less (мы добавим позже) и сохраняем эти пути в массиве. Одна вещь о LESS PHP в том, что анализ может занять некоторое время; это может занять до нескольких сотен миллисекунд, если у вас есть 20K + файла .less. Он также использует ресурсы сервера. Если вы собираетесь использовать версию PHP, кэширование обязательно. Давайте посмотрим, каким образом мы могли бы достичь этого.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
$time = mktime(0,0,0,21,5,1980);
$cache = ‘cache.css’;
 
foreach($files as $file) {
    $fileTime = filemtime($file);
 
    if($fileTime > $time) {
        $time = $fileTime;
    }
}
 
if(file_exists($cache)) {
    $cacheTime = filemtime($cache);
    if($cacheTime < $time) {
        $time = $cacheTime;
        $recache = true;
    } else {
        $recache = false;
    }
} else {
    $recache = true;
}

Этот код проверяет каждый из наших файлов .less и определяет время последнего изменения каждого из них. Затем это время сравнивается с измененным временем файла кэша, если оно существует. Если файл кэша еще не существует — или его нужно обновить — мы устанавливаем $recache в true. Продолжая …

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if(!$recache && isset($_SERVER[‘If-Modified-Since’]) && strtotime($_SERVER[‘If-Modified-Since’]) >= $time){
    header(«HTTP/1.0 304 Not Modified»);
} else {
    header(‘Content-type: text/css’);
    header(‘Last-Modified: ‘ . gmdate(«D, d MYH:i:s»,$time) . » GMT»);
 
    if($recache) {
        require ‘lessc.inc.php’;
        $lc = new lessc();
 
        $css = »;
 
        foreach($files as $file){
            $css .= file_get_contents($file);
        }
 
        $css = $lc->parse($css);
        file_put_contents($cache, $css);
        echo $css;
    } else {
        readfile($cache);
    }
}
?>

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

Если нам нужно создать файл кэша или обновить файл кэша, мы добавим файл LESS PHP. Мы требуем его, а не включать, потому что эта часть styles.php не будет работать без него. Затем мы перебираем файлы, присваивая их содержимое одной переменной $css которая анализируется LESS PHP, сохраняется на диск для будущих целей кэширования (для кэширования файла для всех необходим только один посетитель сайта) и анализируется LESS выводится как стандартный CSS. Если клиенту нужна версия файла (обновление или впервые), а кэшированный файл CSS обновлен, мы просто обслуживаем этот файл, что приводит к значительной экономии средств.


Прежде чем мы styles.less слишком далеко, нам нужно создать файл styles.less который мы styles.php в styles.php .

1
2
3
4
5
6
7
8
9
@h1BG: #1D5A50;
h1 {
    background: @h1BG;
    border-bottom: 1px solid @h1BG + #333;
    border-top: 1px solid @h1BG — #333;
    color: white;
    font-family: Helvetica, sans-serif;
    padding: 3px;
}

Для тех, кто не знаком с LESS, в этом коде мы установили переменную @h1BG и присвоили ей темно-зеленый цвет. В правиле h1 мы использовали его три раза: как только мы использовали стандартное свойство, и два других раза мы сказали LESS, что хотим, чтобы границы были немного светлее / темнее фона. Меньше PHP выполнил для нас математику шестнадцатеричных значений.

Теперь давайте создадим базовый HTML-документ, чтобы использовать эту новую таблицу стилей.

01
02
03
04
05
06
07
08
09
10
11
<!doctype html>
<html lang=»en»>
    <head>
        <meta charset=»utf-8″>
        <title>My Less Demo</title>
        <link type=»text/css» rel=»stylesheet» href=»css/styles.php»>
    </head>
    <body>
        <h1>Sample Page Header</h1>
    </body>
</html>

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

Пример тега h1 с зеленым фоном.

Если вы загляните в исходный styles.php в своем браузере, вы должны увидеть следующее:

1
2
3
4
5
6
7
8
h1 {
  background:#1d5a50;
  border-bottom:1px solid #508d83;
  border-top:1px solid #00271d;
  color:white;
  font-family:Helvetica, sans-serif;
  padding:3px;
}

Обратите внимание, что переменная не только правильно применяется, но и объявление переменной не появляется в конечном коде. Как примечание: LESS PHP сокращает ваш CSS, но не уменьшает его.

Давайте пойдем дальше и посмотрим, что еще может сделать LESS. Сделайте следующие дополнения в вашем styles.less и HTML (и пока мы это делаем, измените @h1BG на @color4 ):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@pageWidth: 1000px;
@color1: #F0F0F0;
@color2: #201A16;
@color3: #3B3128;
@color4: #1D5A50;
 
#wrap {
    background: @color1;
    border: 2px solid @color2;
    margin: 0 auto;
    overflow: hidden;
    width: @pageWidth;
}
 
h1 {
    background: @color4;
    border-bottom: 1px solid @color4 + #333;
    border-top: 1px solid @color4 — #333;
    color: white;
    font-family: Helvetica, sans-serif;
    padding: 3px;
}
 
h2 {
    color: #A1915F;
}
 
#content, #skyscraper {
    float: left;
}
 
#content {
    border-right: 1px solid @color1 — #111;
    width: @pageWidth * .75;
 
    h2 {
        background: @color2;
    }
 
    p {
        background: #FFF;
    }
}
 
#skyscraper {
    width: @pageWidth * .25;
 
    h2 {
        background: @color3;
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
<body>
    <div id=»wrap»>
        <h1>Sample Page Header</h1>
        <div id=»content»>
            <h2>My Content</h2>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
        <div id=»skyscraper»>
            <h2>Be the first to advertise!</h2>
        </div>
    </div>
</body>

Во-первых, те из вас, кто не знаком с LESS, могут быть смущены правилами в рамках концепции правил, или вложенными правилами. Это означает, что вам больше не нужно вводить #content h2 {...}, #content a {...} . Это также позволяет лучше структурировать ваш CSS, чтобы вы могли четко видеть цепочку наследования CSS.

Для тех, кто занимается программированием, вы заметили несколько проблем. Граница 1px на #content приводит к тому, что наш раздел объявлений опускается ниже. Это та же самая проблема, с которой вы столкнулись бы, если бы определили ширину как 75% и 25%. Как многие из вас знают, отступы, границы и отступы могут нанести ущерб с помощью плавающих, основанных на процентах макетов. Итак, давайте исправим некоторые из них; было бы неплохо, если бы контент не был так сгруппирован. Внесите следующие изменения в styles.less :

1
2
3
4
5
6
7
@contentRightBorder: 1px;
@contentLRPadding: 15px;
 
#content {
    border-right: @contentRightBorder solid @color1 — #111;
    padding: 0 @contentLRPadding 5px @contentLRPadding;
    width: (@pageWidth * .75) — @contentRightBorder — (2 * @contentLRPadding);
проблема с плавающей точкой до и после

Как вы уже можете сказать, я не дизайнер (хотя цветовая схема не плохая *) *. Однако, если бы я был, я бы хотел, чтобы заголовки на сайте имели схожие характеристики. Давайте сделаем это МЕНЬШЕ. Добавьте следующее в styles.less :

1
2
3
4
5
6
7
8
.header(@headingBackground: @color4; @headingFontColor: #FFF;) {
    background: @headingBackground;
    border-bottom: 1px solid @color4 + #333;
    border-top: 1px solid @color4 — #333;
    color: @headingFontColor;
    font-family: Helvetica, sans-serif;
    padding: 3px;
}

Это называется миксин ; думать об этом как о функции CSS. Мы можем применить это к нашим заголовкам. Сделайте следующие изменения:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
h1 {
    .header();
}
 
#content {
    h2 {
        .header(@color2; #A1915F;);
    }
}
 
#skyscraper {
    h2 {
        .header(@color3; #A1915F);
    }
}

Давайте рассмотрим только вывод CSS заголовка, чтобы узнать, сможем ли мы узнать что-нибудь о LESS.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.header {
  background:#1d5a50;
  border-bottom:1px solid #508d83;
  border-top:1px solid #00271d;
  color:#ffffff;
  font-family:Helvetica, sans-serif;
  padding:3px;
}
h1 {
  background:#1d5a50;
  border-bottom:1px solid #508d83;
  border-top:1px solid #00271d;
  color:#ffffff;
  font-family:Helvetica, sans-serif;
  padding:3px;
}
#content h2 {
  background:#201a16;
  border-bottom:1px solid #508d83;
  border-top:1px solid #00271d;
  color:#a1915f;
  font-family:Helvetica, sans-serif;
  padding:3px;
}
#skyscraper h2 {
  background:#3b3128;
  border-bottom:1px solid #508d83;
  border-top:1px solid #00271d;
  color:#a1915f;
  font-family:Helvetica, sans-serif;
  padding:3px;
}

Вы можете получить много повторяющегося кода, если не будете осторожны.

Это главный недостаток LESS из того, что я вижу: вы можете получить много дублирующегося кода, если не будете осторожны. Обязательно подумайте, какой код вы вставляете — особенно в миксины. В выводе кода мы имеем класс .header который не используется, и несколько свойств, которые излишне дублируются. Помните, что когда вы работаете с LESS, вы работаете как с ним, так и с CSS, поэтому лучшие методы CSS все еще применяются. Лучший способ написать это было бы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
h1, h2, h3 {
    font-family: Helvetica, sans-serif;
    padding: 3px;
}
 
@header(@headingBackground: @color4; @headingFontColor: #FFF;) {
    background: @headingBackground;
    border-bottom: 1px solid @color4 + #333;
    border-top: 1px solid @color4 — #333;
    color: @headingFontColor;
}
 
h1 {
    @header();
}
 
#content {
    h2 {
        @header(@color2; #A1915F;);
    }
}
 
#skyscraper {
    h2 {
        @header(@color3; #A1915F);
    }
}

Если мы посмотрим на вывод кода сейчас, мы должны увидеть, что свойства, которые должны быть сгруппированы, есть. Уникальные свойства отображаются только в соответствующих правилах, и у нас нет ненужного правила .header , которое появляется в нашем CSS.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
h1, h2, h3 {
  font-family:Helvetica, sans-serif;
  padding:3px;
}
h1 {
  background:#1d5a50;
  border-bottom:1px solid #508d83;
  border-top:1px solid #00271d;
  color:#ffffff;
}
#content h2 {
  background:#201a16;
  border-bottom:1px solid #508d83;
  border-top:1px solid #00271d;
  color:#a1915f;
}
#skyscraper h2 {
  background:#3b3128;
  border-bottom:1px solid #508d83;
  border-top:1px solid #00271d;
  color:#a1915f;
}

Еще одна вещь, о которой следует быть осторожным, это излишнее вложение селекторов Если ваш CSS не должен быть настолько специфичным для работы, не вкладывайте его; это может быть отдельным правилом. LESS здесь, чтобы помочь вам написать CSS, а не раздуть вашу таблицу стилей. Не используйте его для переноса DOM в таблицу стилей; это достаточно плохо, где это. Вы не хотите в конечном итоге использовать такие правила, как #main .menu_items #center .menuTable table tr td.itemMoveDown a:hover {...} . Для ориентира взгляните на следующее:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#wrapper {
    background: blue;
 
    #content {
        color: pink;
 
        .about {
            float: left;
 
            p {
                span {
                    font-weight: bold;
 
                    a {
                        font-family: Aurabesh, sans-serif;
                    }
                }
 
                a {
                    font-family: Verdana, sans-serif;
                }
            }
        }
    }
}
 
/* (among other rules) results in: */
 
#wrapper #content .about p span a {
    font-family: Aurabesh, sans-serif;
}
 
/* (depending on the DOM), better could be: */
 
#wrapper {
    background: blue;
}
 
#content {
    color: pink;
}
 
.about {
    float: left;
 
    span {
        font-weight: bold;
 
        a {
            font-family: Aurabesh, sans-serif;
        }
 
    a {
        font-family: Verdana, sans-serif;
    }
}

Не используйте меньше, чтобы перенести DOM в вашу таблицу стилей, там достаточно плохо.

Выше, если на вашем сайте #content всегда находится внутри #wrapper , вам не нужно указывать #contents внутри #wrapper и так далее. С тех пор, если ваш документ имеет td s, которые не находятся внутри строк или таблиц, у вас есть другие проблемы. Еще раз, перед тем, как вкладывать деньги, убедитесь, что это экономит ваше время и является необходимым. Как правило, никогда не гнездитесь внутри body или вашего основного div.

Хорошо, вернемся к нашему примеру. Итак, вы только что показали сайт клиенту. Он был слишком широк для его смартфона, поэтому он хотел бы, чтобы его сайт был шириной 800px . О, и он хочет, чтобы его цвета были голубым и темно-синим, а зеленый должен быть оранжевым. Предполагая, что он хочет сохранить те же пропорции, сколько строк мы должны изменить для нового макета и темы? Всего четыре:

1
2
3
4
@pageWidth: 800px;
@color2: #9CDCF8;
@color3: #0E0E7A;
@color4: #F89500;

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

  • Синтаксис LESS похож на CSS.
  • Меньше можно сделать математику на цветах и ​​единицах измерения.
  • Переменные LESS могут использоваться в нескольких местах в вашем CSS.
  • LESS может дублировать код, поэтому придерживайтесь того же мнения, что и в CSS.
  • LESS делает настройку CSS всего сайта тривиальной.

Я не знаю, сколько из вас работали с некоторыми из популярных систем сеток CSS, поэтому позвольте мне представить вам несколько проблем.

01
02
03
04
05
06
07
08
09
10
11
12
<div id=»wrap» class=»w16″>
    <div id=»content» class=»w12″>
        <h2 class=»g12″>My Content</h2>
        <p class=»g4″>Sample text</p>
        <p class=»g4″>More sample text</p>
        <p class=»g4″>And some more sample text</p>
    </div>
    <div id=»skyscraper» class=»w4″>
        <h2 class=»g4″>Still waiting for some ads!</h2>
        <p class=»g4″>Space is available</p>
    </div>
</div>

Эта гипербола кода имеет смысл: фреймворки могут вызывать грубый код. Наша разметка разработала серьезный случай «classitis», не говоря уже о том, что ни один из классов не является семантическим. CSS не намного лучше:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
g1, g2, g3 … {
    display: inline;
    float: left;
    margin: 0 10px;
}
wrap2, wrap3 … {
    margin: 0;
}
g1 { width: XXpx;
g2 { width: XXpx;
wrap2 { width: XXpx;
wrap3 { width: XXpx;
wrap12 g2, wrap12 g3 … {
    width: XXpx;
}
alpha, omega, push, pull…

В итоге получаются десятки на десятки строк … минимизированные. Большинство систем сетки также страдают от проблемы, с которой мы сталкивались ранее. Что если я хочу добавить границу к элементу или какой-нибудь отступ? До сих пор, если вы работали в одной из этих систем, вы должны были либо добавить дополнительный div внутри вашего «div сетки», который имел границу и отступ, либо вам пришлось перезаписать правило сетки, говоря #content { width: 699px; } #content { width: 699px; } потому что у него есть граница и некоторые отступы. Мы также сталкиваемся с довольно серьезной проблемой, если клиент изменяет ширину сайта, так как этот CSS был адаптирован к определенной ширине контента и количеству столбцов.

Готовы построить семантическую, гибкую сеточную систему … в четырнадцати строках кода? Используя только те знания, которые мы уже изучили? Представляем grid.less :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
@unit: @pageWidth / 24;
@gm: 10px;
@g(@u: 20; @margin: @gm; @marginTop: 0; @marginBottom: 0;) {
    @gpadding: @gpadding + 0;
    @gborder: @gborder + 0;
    display: inline;
    float: left;
    margin: @marginTop @margin @marginBottom @margin;
    width: (@u * @unit) — ((@margin * 2) + @gpadding + @gborder);
}
@shift(@pu: -20){
    left: @pu * @unit;
    position: relative;
}
@newRow {
    clear: left;
}

Итак, это было семнадцать строк, но я не хочу считать закрывающие скобки. Давайте пройдемся по коду. Сначала мы определяем переменную LESS, которая называется unit . Каждая единица составляет 1/24 ширины страницы. Не стесняйтесь выбирать любой номер, который вам удобен. Я выбрал 24, потому что и его, и его половину (12) можно разделить на 2, 3 и 4. Вскоре мы обнаружим, что не имеет значения, какое число вы здесь grid.less , grid.less может обрабатывать все, что вы выбрасываете на него. Однако следует отметить одну вещь: браузеры Webkit хотели бы, чтобы вы выбирали количество столбцов, кратное ширине вашего сайта, иначе они могут потерять один или два пикселя, если вы поместите несколько маленьких элементов сетки в линию. Chrome и Safari не любят макеты, основанные на процентах, если процент заканчивается частичными пикселями. Firefox и IE (на удивление) не заботятся: они обрабатывают разницу, добавляя дополнительные пиксели по всем элементам, пиксель здесь и пиксель там.

Во второй строке @gm обозначает поле сетки; на следующем @g обозначает единицу сетки. Оба они короткие, чтобы их было легче набирать при применении, но короткие имена совсем не уменьшат размер вашего файла, потому что переменные LESS и @ -префиксированные миксины не выводят в конечный файл CSS при разборе файлов LESS , Вам больше не нужно рекламировать свою сеточную систему в вашем CSS, поскольку сетка волшебным образом исчезает. Спасибо, МЕНЬШЕ!

Вернуться к коду. В @g mixin первым параметром является то, какой единицей является элемент: 2, 4.8, 6, 12 и т. Д. Подождите … 4.8? Конечно; Вы хотели, чтобы на странице было пять ящиков одинакового размера, не так ли? 24/5.

Второй параметр — это поле по умолчанию между нашими элементами страницы; он принимает значение, определенное @gm . Хотите их поближе? @gm: 5px В дальнейшем? @gm: 10px или @gm: 12px . Меньше можно сделать это.

Посмотрев на код еще раз, вы можете заметить, что нам не хватает обертывающего элемента, который есть в большинстве систем сетки. Или мы? Примените @g(12; 0;) к правилу. Выполнено.

У нас также есть возможность передать margin-top и margin-bottom в нашу сеточную функцию в качестве третьего и четвертого параметров. Это хорошо по двум причинам. Во-первых, это позволяет нам использовать сокращенный код поля; и, во-вторых, нам нужно управлять маржинальными операциями только в одном месте, смешанном вызове.

Внутри миксина мы делаем небольшую хитрость. В LESS PHP @gpadding и @gborder , которые используются для расчета ширины, всегда равны 0, если они не определены в правиле CSS / LESS до того, как мы применим @g mixin. В других версиях LESS вам может потребоваться создать другой сброс, например, передать его в качестве параметра в миксин.

@shift используется главным образом для помощи в целях SEO. Как правило, эффективная практика заключается в том, чтобы разместить основное содержание как можно раньше в документе, чтобы поисковые системы могли придать ему вес. Иногда дизайны, которые нам дают, указывают на то, что другой контент — например, боковая панель или реклама — на первом месте. Со shift мы можем поддерживать хорошую разметку и при этом достигать желаемого дизайна. @shift может принимать как положительные, так и отрицательные единицы. @newRow — просто удобное напоминание; это на самом деле не нужно, так как вы можете легко напечатать clear: left наедине. Если вы это сделаете, мы вернемся к тем 14 линиям, на которые я надеялся ранее.

Хватит разговоров, пришло время посмотреть пример, чтобы мы могли обернуть голову вокруг всего этого. Давайте начнем код заново. В styles.php теперь у нас будет на 3 файла меньше: settings.less , grid.less и styles.less . Settings.less получит переменные нашей цветовой схемы, код заголовка и ширину сайта. Не забудьте стереть styles.less чтобы мы могли поработать с новой разметкой. Давайте также сделаем movie5.html .

Ваш файловый массив в styles.php должен выглядеть следующим образом:

1
2
3
4
5
$files = array(
    ‘settings.less’,
    ‘grid.less’,
    ‘styles.less’
);

Разметка для movies5.html:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<div id=»page»>
    <h1>My Movies</h1>
    <ul id=»site-navigation»>
        <li><a href=»#»>Movie 1</a></li>
        <li><a href=»#»>Movie 2</a></li>
        <li><a href=»#»>Movie 3</a></li>
        <li><a href=»#»>Movie 4</a></li>
        <li class=»selected»><a href=»#»>Movie 5</a></li>
        <li><a href=»#»>Movie 6</a></li>
    </ul>
    <div id=»movie»>
        <h2 id=»movie-title»>Movie 5</h2>
        <div id=»dvd-cover»>
            <img alt=»movie poster»>
        </div>
        <p id=»short-description»>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        <div id=»characters»>
            <div class=»character»>
                <h3>Farmer</h3>
                <img alt=»feeling cold»>
                <p>About this character…</p>
            </div>
            <div class=»character»>
                <h3>Gunslinger</h3>
                <img alt=»nice tent»>
                <p>About this character…</p>
            </div>
            <div class=»character»>
                <h3>Princess</h3>
                <img alt=»fiery temper»>
                <p>About this character…</p>
            </div>
            <div class=»character»>
                <h3>Sorcerer</h3>
                <img alt=»out of breath»>
                <p>About this character…</p>
            </div>
            <div class=»character»>
                <h3>Frog</h3>
                <img alt=»swamp country»>
                <p>About this character…</p>
            </div>
            <div class=»character»>
                <h3>Trusty Dog</h3>
                <img alt=»walking carpet»>
                <p>About this character…</p>
            </div>
        </div>
    </div>
    <div id=»main-ad» class=»ad»>Ad space available</div>
    <div id=»secondary-ad» class=»ad»>Advertise here</div>
</div>

Наша новая styles.less стилей для styles.less :

001
002
003
004
005
006
007
008
009
010
011
012
013
014
+015
016
+017
018
019
020
021
022
023
024
025
026
027
028
029
+030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
+055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
#page {
    background: @color1;
    border: 1px solid @color3;
    overflow: hidden;
    margin: 0 auto;
    padding: @gm 0;
    width: @pageWidth;
}
 
h1 {
    @gpadding: 6;
    @g(6);
    @header();
}
 
#site-navigation {
    padding: 0;
 
    @g(18; 0;);
 
    li {
        background: @color2;
        padding: @gm / 2;
        @gpadding: @gm;
        @g(3; @gm; @gm;);
 
        &.selected {
            background: @color4;
        }
    }
    a {
        color: #FFF;
        text-decoration: none;
    }
}
 
@midBlockHeight: 468px;
 
#movie {
    @shift(3);
    @g(18; 0; @gm;);
    @newRow;
    min-height: @midBlockHeight;
 
    h2 {
        @gpadding: 6;
        @g(18; @gm; 0; @gm;);
        @header();
    }
}
 
#short-description {
    background: @color1 + #111;
    padding: @gm / 2;
    @gpadding: @gm;
    @g(12);
}
 
#dvd-cover {
    background: @color2;
    padding: @gm;
    @gpadding: @gm * 2;
    @g(6);
 
    img {
        background: #FFF;
        display: block;
        height: 100px;
        width: 100%;
    }
}
 
#characters {
    border-top: 1px solid @color1 — #222;
    @g(18; 0; @gm;);
}
 
.character {
    background: @color1 — #111;
    padding: 5px;
    @gpadding: 10px;
    @g(6; @gm; @gm;);
 
    h3 {
        margin: 0 0 5px;
        @header();
    }
 
    img {
        background: #FFF;
        display: block;
        float: left;
        margin-right: @gm;
        height: 50px;
        width: 50px;
    }
}
 
.ad {
    border: 1px solid @color2;
    height: @midBlockHeight;
    @gborder: 2;
    @g(3; @gm; @gm;);
}
 
#main-ad {
    @shift(-18);
}

Предполагая, что копирование и вставка сработали, вы должны получить что-то похожее на это:

пример сетки

Несколько замечаний по поводу предыдущего кода LESS. Если вы потратите @g времени на его изучение, вы несколько раз заметите, что я использовал @g mixin для управления вертикальной высотой, а также регулярную сеточную спецификацию количества столбцов, @g элементом. При определении верхнего и нижнего поля, если элемент не был элементом обтекания, я всегда передавал @gm в качестве второго параметра в mixin. Я сделал это вместо ввода значения @gm . Причина этого в том, что он оставляет только одно место, если мы решим, что хотим отрегулировать горизонтальный интервал между элементами сетки.

Также обратите внимание: всякий раз, когда вы определяете рамку или отступы, вам нужно установить @gborder или @gpadding в сумму соответствующих горизонтальных единиц. Обязательно помните, что правило типа padding: 5px; означает 10px от общего заполнения. Наконец, вы могли заметить & в коде. С LESS PHP это столяр и в результате li.selected . Я мог бы так же легко переместить .selected из правила li но все же внутри правила #site-navigation чтобы добиться того же эффекта (на самом деле в CSS это на 2 символа меньше).

Возможно, это не идеальная система сетки, но я определенно думаю, что это может быть немного больше работы. Он допускает семантическую разметку, избегает классицизма и может привести к значительно меньшему размеру CSS, поскольку вы выводите только тот код, который вам действительно нужен. Если у вас есть какие-либо предложения, пожалуйста, дайте мне знать, используя комментарии ниже.

Я был бы неблагодарен, если бы не выразил особой благодарности Кайлу Бломквисту, с которым я бросил несколько идей.

  • Миксины могут быть использованы для определения более сложных систем. Выясните проблему, которую можно решить с помощью математики, и создайте свой миксин, чтобы донести идею до браузера.

Что такое учебник в наши дни без CSS3? LESS может облегчить работу дизайнеров, поскольку им не нужно запоминать различия в синтаксисе браузеров. Создайте css3.less и добавьте его в styles.php . Начнем с чего-то простого, например, с хорошего линейного градиента.

1
2
3
4
5
6
7
8
9
@linearGradient(@color1: #000000; @color2: #FFFFFF;) {
    background: -moz-linear-gradient(@color1, @color2);
    background: -webkit-gradient(linear, left top, left bottom, from(@color1), to(@color2));
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=@color1, endColorstr=@color2);
    -ms-filter: «progid:DXImageTransform.Microsoft.gradient(startColorstr=@color1, endColorstr=@color2)»;
    -moz-background-clip: padding;
    -webkit-background-clip: padding-box;
    background-clip: padding-box;
}

Что ж, если вы не сделали этого много, вы скоро поймете, что правила CSS3 реализованы несколько иначе, когда речь идет о Firefox, Webkit или не совсем, когда дело доходит до IE 9. В результате это ограничивает МЕНЬШЕ … немного. Например, Firefox позволяет вам указывать градусы перемещения градиента, но Webkit ограничен top left bottom left определением типа. В IE есть только фильтр двух типов: вертикальный и горизонтальный. В результате, если мы хотим другое направление, мы должны сделать еще один МЕНЬШИЙ миксин.

1
2
3
4
5
6
7
8
9
@linearGradientH(@color1: #000000; @color2: #FFFFFF;) {
    background: -moz-linear-gradient(0deg,@color1, @color2);
    background: -webkit-gradient(linear, left top, right top, from(@color1), to(@color2));
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=@color1, endColorstr=@color2, GradientType=1);
    -ms-filter: «progid:DXImageTransform.Microsoft.gradient(startColorstr=@color1, endColorstr=@color2, GradientType=1)»;
    -moz-background-clip: padding;
    -webkit-background-clip: padding-box;
    background-clip: padding-box;
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
@backgroundClip {
    -moz-background-clip: padding;
    -webkit-background-clip: padding-box;
    background-clip: padding-box;
}
 
@linearGradient(@color1: #000000; @color2: #FFFFFF;) {
    background: -moz-linear-gradient(@color1, @color2);
    background: -webkit-gradient(linear, left top, left bottom, from(@color1), to(@color2));
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=@color1, endColorstr=@color2);
    -ms-filter: «progid:DXImageTransform.Microsoft.gradient(startColorstr=@color1, endColorstr=@color2)»;
    @backgroundClip;
}

Все еще не очень хорошо, и теперь у нас есть два правила, но градиенты должны работать. Так что еще мы можем сделать с фильтрами, чтобы IE тоже мог играть ? Тени? Хотя мы можем попытаться сделать несколько вещей, используя другие фильтры, предоставленные Microsoft, такие как размытие и тень, большинство попыток не очень хорошо соответствуют реализациям CSS3 в современных браузерах. Честно говоря, большинство попыток выглядят довольно ужасно или требуют дополнительной разметки. Градиенты, безусловно, самые красивые. Есть также некоторые вещи, которые не могут быть сделаны с фильтрами, такими как закругленные углы. Я не знаю о вас, но я хотел бы использовать больше свойств, чем просто градиенты.

К счастью, я нашел хороший проект под названием CSS3 Pie . Этот инструмент Progressive IE Enhancement использует поведения, которые, как надеялась Microsoft, будут использовать фрагменты JavaScript многократного использования для достижения многих эффектов CSS3. Если вы хотите пойти по пути фильтра (поскольку PIE использует JavaScript), дайте нам знать, если вы справляетесь лучше, чем я, используя раздел комментариев ниже.

Начнем с загрузки последней версии PIE с сайта. Нам нужен файл PIE.htc ; поместите его в свой каталог CSS. CSS3 PIE позволяет нам использовать линейные градиенты, закругленные углы и тени от ящиков. Поскольку сейчас мы немного свободнее, давайте посмотрим, что мы можем придумать:

01
02
03
04
05
06
07
08
09
10
11
12
13
@linearGradient(@color1: #000000; @color2: #FFFFFF; @lgd: 90deg; @wkd1: left top; @wkd2: left bottom;) {
    background: -moz-linear-gradient(@lgd, @color1, @color2);
    background: -webkit-gradient(linear, @wkd1, @wkd2, from(@color1), to(@color2));
 
    *position: relative;
    *z-index: 1;
    *zoom: 1;
    -pie-background: linear-gradient(@lgd, @color2, @color1);
 
    -moz-background-clip: padding;
    -webkit-background-clip: padding-box;
    background-clip: padding-box;
}

В конце концов мы linearGradient один linearGradient . Обратите внимание, что PIE требует относительного положения и has-layout, потому что он рисует элемент VML за нашим исходным элементом html. Если у вас есть абсолютно позиционированные элементы, вам может потребоваться быть осторожным и переопределить это свойство для IE.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@borderRadius(@radius: 5px;) {
    -moz-border-radius: @radius;
    -webkit-border-radius: @radius;
    border-radius: @radius;
    *position: relative;
    *z-index: 1;
    *zoom: 1;
    behavior: url(PIE.htc);
}
 
@borderRadiusSpecific(@rtl: 0; @rtr: 0; @rbr: 0; @rbl: 0;) {
    -moz-border-radius-topleft: @rtl;
    -moz-border-radius-topright: @rtr;
    -moz-border-radius-bottomright: @rbr;
    -moz-border-radius-bottomleft: @rbl;
 
    -webkit-border-top-left-radius: @rtl;
    -webkit-border-top-right-radius: @rtr;
    -webkit-border-bottom-right-radius: @rbr;
    -webkit-border-bottom-left-radius: @rbl;
 
    border-top-left-radius: @rtl;
    border-top-right-radius: @rtr;
    border-bottom-right-radius: @rbr;
    border-bottom-left-radius: @rbl;
}

Радиус границы довольно прост; заметьте, однако, что если мы хотим округлить только часть элемента или иметь переменное округление, IE не сможет этого сделать, поскольку VML представляет собой скругленный прямоугольник с определенным радиусом.

01
02
03
04
05
06
07
08
09
10
@boxShadow(@horizontalOffset: 5px; @verticalOffset: 5px; @blurRadius: 8px; @shadowColor: #555; @spreadRadius: 0px; @inset: 😉 {
    -moz-box-shadow: @inset @horizontalOffset @verticalOffset @blurRadius @spreadRadius @shadowColor;
    -webkit-box-shadow: @inset @horizontalOffset @verticalOffset @blurRadius @spreadRadius @shadowColor;
 
    box-shadow: @inset @horizontalOffset @verticalOffset @blurRadius @spreadRadius @shadowColor;
    *position: relative;
    *z-index: 1;
    *zoom: 1;
    behavior: url(PIE.htc);
}

Хотя я включил некоторые дополнительные свойства, такие как spreadRadius и spreadRadius , CSS3 PIE еще не поддерживает их. Так что, если IE важен для вас, пока держитесь.

01
02
03
04
05
06
07
08
09
10
11
@textShadow(@color: #555; @horizontalOffset: 2px; @verticalOffset: 2px; @blur: 3px;) {
    -moz-text-shadow: @color @horizontalOffset @verticalOffset @blur;
    -webkit-text-shadow: @color @horizontalOffset @verticalOffset @blur;
    /*
        filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=@horizontalOffset, OffY=verticalOffset, Color=’@color’, Positive=’true’);
        -ms-filter: «progid:DXImageTransform.Microsoft.dropshadow(OffX=@horizontalOffset, OffY=verticalOffset, Color=’@color’, Positive=’true’)»;
        *zoom: 1;
    */
 
    text-shadow: @color @horizontalOffset @verticalOffset @blur;
}

Хотя в IE есть фильтр теней, он не работает надежно. Тени текста, пусть даже и не очень заметные, не имеют большого значения, когда речь заходит о внешнем виде страницы, поэтому, если вы будете немного менее дружелюбны к браузерам, это не повредит слишком сильно.

Время для быстрого примера. Создайте styles.css3 и добавьте его в массив файлов в styles.php .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
#page {
    @boxShadow(0; 0; 20px; #777);
    @linearGradient(@color1 — #222; #FFF;);
    @borderRadius(10px;);
}
 
#dvd-cover {
    @boxShadow(3px; 3px; 6px; #555;);
    @borderRadius(15px;);
}
 
#site-navigation li {
    @borderRadius(5px;);
}
 
#short-description {
    @boxShadow(0; 0; 5px; #777);
    @linearGradient(#FFF; @color4; 45deg; left bottom; right top;);
}

Можете ли вы определить, что такое IE? К сожалению, есть подсказка, но это не CSS, так что я думаю, что все в порядке.

Firefox, IE 8 и Chrome с поддержкой css3

Хорошо, последнее свойство CSS3; давайте посмотрим, сможем ли мы сделать RGBA.

1
2
3
4
5
6
7
@rgba(@red: 0; @green: 0; @blue: 0; @alpha: .8; @iehex: «#99000000»;) {
    background:transparent;
    background: rgba(@red, @green, @blue, @alpha);
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=@iehex,endColorstr=@iehex);
    -ms-filter: «progid:DXImageTransform.Microsoft.gradient(startColorstr={@iehex},endColorstr={@iehex})»;
    zoom: 1;
}

Ну, это определенно не самая красивая функция, но она работает. Для классных браузеров просто передайте первые четыре свойства как обычно. Если бы LESS PHP мог делать операторы if , IE не потребовал бы каких-либо специальных параметров, но не такая удача. Длинный гекс состоит из двух частей. Первые две позиции устанавливают альфа, 00 для полной прозрачности, FF для отсутствия прозрачности. Последние шесть позиций для шестнадцатеричного эквивалента RGB. Возможно, вам придется немного подсчитать, но это работает (убедитесь, что длинный гекс в кавычках). Кроме того, в IE вы не можете иметь закругленные углы и RGBA, по крайней мере с этой реализацией. Если вы попробуете, RGBA будет иметь приоритет.


Несколько идей о том, куда вы можете пойти отсюда:

  • Сделайте так, чтобы ваша таблица стилей принимала несколько параметров $_GET и задавала ваши @color1 , @color2 … или даже ширину страницы.
  • В styles.php настроены некоторые цветовые схемы. Позволяет вам быстро менять темы, чтобы получить идеальную комбинацию для клиента.
  • Сделайте переключатель тем JavaScript, основанный на той же идее.
  • Возьмите переменные еще дальше, используя mixins. Есть меню? Подготовка к горизонтальной и вертикальной с использованием двух миксинов. Переключайтесь с помощью параметров.
  • Создавайте свои любимые приложения / фреймворки, такие как WordPress, Magento, Drupal, CakePHP и т. Д., Используя LESS. Это делает вещи намного проще, если сайт не ограничен одним приложением, а ваше приложение должно соответствовать чьей-то HTML-странице и существующей цветовой схеме.

Я играл с LESS всего несколько недель, и это те идеи, которые я придумала до сих пор. Какие у тебя? Пожалуйста, поделитесь ими с сообществом ниже.