SCSS — немного практики, часть I

    image

    Статей про SASS(SCSS), Less на хабрахабре уже полно, но на мой взгляд не хватает такой, в которой было бы немного реальной практики. Я постараюсь восполнить этот пробел. Около года назад одна из SASS-статей меня "зацепила", и с тех пор я полюбил эту технологию настолько, что ручной набор обычного CSS кода представляется мне лишней тратой времени. Сия статья посвящается тем верстальщикам (или web-программистам), которые про SCSS ещё не слышали, или же ещё не пробовали в деле. Более опытным товарищам, полагаю, в ней ловить нечего.

    Что такое SCSS


    SCSS — "диалект" языка SASS. А что такое SASS? SASS это язык похожий на HAML (весьма лаконичный шаблонизатор), но предназначенный для упрощения создания CSS-кода. Проще говоря, SASS это такой язык, код которого специальной ruby-программой транслируется в обычный CSS код. Синтаксис этого языка очень гибок, он учитывает множество мелочей, которые так желанны в CSS. Более того, в нём есть даже логика (@if, each), математика (можно складывать как числа, строки, так и цвета). Возможно, некоторые возможности SCSS покажутся вам избыточными, но, на мой взгляд, лишними они не будут, останутся "про запас".

    Отличие SCSS от SASS заключается в том, что SCSS больше похож на обычный CSS код. Пример SASS-кода:

    $blue: #3bbfce
    $margin: 16px
    
    .content-navigation
      border-color: $blue
      color: darken($blue, 9%)
    
    .border
      padding: $margin / 2
      margin: $margin / 2
      border-color: $blue

    И тоже самое на SCSS:

    $blue: #3bbfce;
    $margin: 16px;
    
    .content-navigation {
      border-color: $blue;
      color: darken($blue, 9%);
    }
    
    .border {
      padding: $margin / 2;
      margin: $margin / 2;
      border-color: $blue;
    }

    Я выбрал SCSS в виду того, что он проще для восприятия коллегам с ним ещё не знакомым. Ещё стоило бы отметить что обычный CSS код вполне вписывается в SCSS синтаксис.

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


    Для начала нужно установить ruby. После чего нужно установить sass-gem ( gem install sass в консоли ). Если всё прошло гладко, то теперь вам доступна консольная программа sass. О всех нюансах её использования вы можете прочесть здесь ― sass --help. Я расскажу лишь о двух базовых возможностях:

    --watch


    Если запустить sass с ключом --watch, то программа будет следить за указанными вами файлами. В случае их изменения, она автоматически пересоберёт все необходимые css-файлы (не все вообще, а только связанные с изменёнными).

    Предположим, что у вас есть следующая структура проекта:

    -- css
    ---- scss
    ------ style.scss
    ---- style.css

    Необходимо чтобы sass отслеживал все изменения в css/scss/* и результат сохранял в css/*.css. В таком случае запускаем sass так ― sass --watch css/scss:css/.. Т.е. sass --watch [что]:[куда].

    --update


    Если вам нужно единожды обновить css-файлы, то в место --watch применяем --update. Никакой слежки проводится не будет, так же как и проверок на необходимость обновления.

    Стоит отметить, что в отличии от Less, SASS не умеет компилировать свой код прямо в браузере. На мой взгляд, такой подход (компиляция на сервере или ПК-верстальщика) является единственно верным.

    Практика


    Итак, мы подошли к самому главному. Начнём с @import.

    @import


    Изначально, до использования SCSS, весь CSS код движка, с которым мне по долгу службы приходится работать, находился в 1-ом огромном style.css файле. Моя IDE (Netbeans (кстати, вот плагин для подсветки синтаксиса)) работала с ним с существенными тормозами. Разбивать же его на множество файлов поменьше, и, при необходимости, склеивать их в 1 ― никто не хотел. SCSS решает этот вопрос автоматически.

    Стоит отметить 1 нюанс. Если скормить sass не конкретный файл-источник, а директорию, то css файлы не будут генерироваться для файлов начинающихся с _. Т.е. наличие файла style.scss приведёт к созданию style.css, а наличие файла _some.scss ― нет.

    Итак, для того, чтобы включить содержимое файла _template.scss или template.scss пишем

    @import "template"; // шаблоны

    В конечном счёте, вместо 1-го большого style.css файла у меня получилось более сотни мелких scss-файлов. С первого взгляда может показаться, что такое количество слишком велико и приведёт к страшным мукам. Однако, нужный мне файл я нахожу сразу исходя из удобной структуры каталогов. К тому же, я полагаю, что благодаря кешированию такая "схема" более производительна.

    @вложенность


    Одна из самых желанных "фич" для CSS ― вложенность селекторов. Пример:

    #some {
      border: 1px solid red;
      .some { background: white; }
    }
    
    /* => */
    
    #some { border: 1px solid red; }
    #some .some { background: white; }

    Ещё пример:

    input {
      border: 1px solid gray;
      background: white;
    
      &[type=text] { color: black; }
      &.some_class { display: none; }
    }
    
    /* => */
    
    input { border: 1px solid gray; background: white; }
    input[type=text] { color: black; }
    input.some_class { display: none; }

    Символ & равносилен родительскому селектору. Допустим тег <body> у нас имеет класс ie_7, в случае если в качестве обозревателя у нас Internet Explorer 7. Следующий код позволяет избавиться от всех "хаков" и спец.комментариев:

    $IE_7: 'body.ie_7';
    //...
    .some {
      display: inline-block;
      #{$IE_7} & { zoom: 1; display: inline; }
    }
    
    /* => */
    
    .some { display: inline-block; }
    body.ie_7 .some { zoom: 1; display: inline; }

    $variables


    Переменные ― удобная штука. Определяются они так:

    $some: red;

    Переменные ― не константы, их можно менять по ходу кода :) Одна из первых моих мыслей вылилась в _const.scss файл, который заключает в себе все базовые цвета, размеры шрифтов и пр.

    $link: #15157d;
    $link_bottom: $link;
    $input_font_size: 13px;
    $content_bg: #F1F1F1;
    $input_color: #4E4D4D;
    $input_color_placeholder: #959595;
    $text_color: black;
    ...

    Предполагается, что цвет ссылок на сайте ― $link.

    a { color: $link; }
    span.link {
      color: $link;
      text-decoration: underline; 
    }

    Если в дальнейшем выяснится, что цвет ссылок изменился ― достаточно поменять 1 переменную (в случае CSS нужно было бы пройтись авто-заменой по файлам, возможно даже выборочно). Предположим, что, внезапно, выясняется, что в некотором модуле contacts, цвет ссылок другой. Есть, как минимум, два пути решения.

    Первый:

    $contacts_link: orange;
    // код модуля с использованием $contacts_link вместо $link

    Второй

    $__link: $link;
    $link: orange;
    // код модуля
    $link: $__link;

    Переменные у нас не типизированные, поэтому с равным успехом могут содержать строки, числа и цвета.

    @математика


    Разделим математику на 2 категории ― цвета и числа. Начнём с чисел. Простой пример:

    .block {
      $block_width: 500px;
      padding: 5px;
      border: 1px solid black;
      width: $block_width - ( 5px * 2 ) - ( 1px * 2 );
    }

    При желании можно и padding с border-ом задавать переменными. Всё зависит от сложности вёрстки.

    Ещё пример:

    .block {
      $count: 10;
      $margin_left: 5px;
      $all_width: 1000px;
    
      width: $all_width;
      .sub_element {
         width: ( $all_width / $count ) - $margin_left;
         margin: 0 0 0 $margin_left;
      }
    }

    Хочу отметить, что подобного рода манипуляции применяются очень часто. Без них я как без ног.

    А теперь цвета. Цвета можно складывать, перемножать:

    .some {
      $color: #010203; 
      color: $color;
      border-color: $color - #010101;
      &:hover { color: #010203 * 2; }
    }
    
    /* => */
    
    .some { color: #010203; border-color: #000102; }
    .some:hover { color: #020406; }

    Довольно удобная штука, когда лень подбирать цвета. Также доступны такие функции как opacify и transparentize (более подробно).

    @строки


    SASS умеет складывать строки, а также поддерживает конструкцию #{}

    $image_dir: 'images/web/';
    $page: 12;
    
    .some 
    { 
      background-image: url( $image_dir + 'pen.gif' ); 
      &:before { content: "Страница #{ $page }!"; }
    }
    
    /* => */
    
    .some { background-image: url("images/web/pen.gif"); }
    .some:before { content: "Страница 12!"; }

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

    Статья


    В виду того, что статья получилась довольно объёмной, я решил разбить её на 2 части. В следующей статье я рассмотрю (синтаксис и область применения):

    • @mixin ― пользовательские функции
    • @if ― условия
    • @each ― циклы
    • Несколько дизайнов для одного сайта
    • По желанию читателей

    Ссылки


    Метки:
    Поделиться публикацией
    Похожие публикации
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 24
    • +1
      А почему не Stulys, как самый продвинутый на сегодня. Практически без ограничений.
      • +1
        Я в первые наткнулся на него совсем недавно. Если не сложно, опишите вкратце в чём его преимущества перед SASS?
        • +3
          Почему Stulys более продвинутый? Sass/SCSS очень расширяемые и мощны. У них даже есть свои библиотеки. Например, Compass, который может и спрайты автоматически генерировать и картинки inline-вставлять.
          • +1
            думаю что не лучше как минимум потому что не наследует синтаксис css и вызывает тем самым раздражение
          • 0
            border-radius()
            -webkit-border-radius arguments
            -moz-border-radius arguments
            border-radius arguments

            body
            font 12px Helvetica, Arial, sans-serif

            a.button
            border-radius 5px


            Кода меньше. Более продвинутый список встроенных функций
            • +3
              Насчёт кода — тут лучше сравнивать с SASS, в нём кода тоже минимум. Касательно функций, насколько я знаю sass + compass весьма продвинут. Сам правда пока компасом не пользовался.
              • +1
                Это просто синтаксический сахар. Например, бета-сборки Sass/SCSS уже поддерживаю блоки в примесях. Например:
                @unclude for-mobile {
                  width: 100px;
                }
                
              • +2
                Зря не написали в качестве преимущества про Compass compass-style.org/.
                • 0
                  У меня опыта в нём нету ) Посему и не написал, очень смутно представляю его возможности. Но мне кажется хабре не хватает статьи про него… :)
                • 0
                  А мне наоборот SASS больше нравится, чем SCSS. Во-первых, не нужно ставить скобки и точки с запятой, как следствие пишем меньше кода. Во-вторых, нет кучи закрывающих скобок при большой вложенности.
                  • 0
                    Особенно если использовать вместе с HAML и CoffeeScript, получается красивая связка.
                  • +1
                    а как вы дебажите css? ведь после генерации css из scss нумерация строк изменяется.
                    P.S. сам не верстальщик, но верстальщик на работе негодует
                    • 0
                      source map
                    • 0
                      Для firebug есть аддон firesass. Но с ним у меня firebug страшно тормозит, ввиду чего я дебажу при помощи поиска по файлам\файлу в IDE. В принципе, как таковой, проблемы я не вижу, ибо редко сталкиваюсь с debug-ом CSS. Обычно я точно знаю в каком файле та или иная строчка уже по селектору. А сама строчка находится через ctrl + f. Возможно, есть способы поудобнее )
                      • +1
                        Если юзать compass, то он вставляет в выходной файл комментарии вида /* line 63, ../sass/_header.sass */, над каждым селектором. По моему опыту «дебажить css» с компасом очень редко бывает нужно. Правильная разбивка на модули, использование переменных и custom mixins, дает компактный код, который легко поддерживать.
                        • 0
                          Если не юзать, тоже вставляет. Это опция команды sass
                          -l, --line-numbers Emit comments in the generated CSS indicating the corresponding source line.

                        • 0
                          я использую это — github.com/nex3/firesass
                        • 0
                          Раньше пользовался SCSS как встроенным в Rails по дефолту, но потом перешел на Less. Одна из причин — использовать твиттеровский Bootstrap, а другая — более удобный синтаксис примесей, которые мне довольно часто пригождаются.

                          Вот как это сделано в SASS/SCSS:

                          @mixin rounded-corners($radius: 5px) {
                            border-radius: $radius;
                            -webkit-border-radius: $radius;
                            -moz-border-radius: $radius;
                          }
                          
                          #header {
                            @include rounded-corners;
                          }
                          #footer {
                            @include rounded-corners(10px);
                          }


                          и в LESS:

                          .rounded-corners (@radius: 5px) {
                            border-radius: @radius;
                            -webkit-border-radius: @radius;
                            -moz-border-radius: @radius;
                          }
                          
                          #header {
                            .rounded-corners;
                          }
                          #footer {
                            .rounded-corners(10px);
                          }


                          Лично мне второй вариант кажется намного приятнее.
                          • 0
                            На мой взгляд разница косметическая. А вот отсутствие @if, @each и прочих вкусностей… Хотя вроде бы кто-то недавно утверждал что они вскоре должны появиться.
                          • +1
                            А еще очень рекомендую Slim вместо Haml =).
                            • 0
                              За Slim спасибо, сам использую Jade (nodeJS), но мне его не хватает. Погляжу на «слим».

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