[recovery mode] Курс по Sass на Code School и мировозрение после него на примере (смотрим на .less, .scss и .sass)

В сентябре я прошел курс на Code School по Sass, называется Assembling Sass и вел его Nick Walsh, гуру в css и sass. Курс полностью бесплатный. Пройдя его я задумался на чем бы себя испробовать. Мой друг недавно написал на Less «Punches» — имея background и foreground и налажением сверху CSS мы получяем следущий эффект «дырок». (Если интересно запустить этот код могу дать ссылку на github).


image

Less код примера:
.punch(@punch-size: 100px, @punch-left: 0px, @punch-top: 0px, @punch-background: none, @punch-grid: false, @punch-z-index: 0) {
  @punch-sizeIn: @punch-size*0.86;
  @punch-shadowOffset: @punch-size/20;
  @punch-shadowSize: @punch-size/20;
  @punch-bgShadowOffset: @punch-size/10;
  @punch-bgShadowSize: @punch-size/5;
  
  left: @punch-left;
  top: @punch-top;
  
  box-shadow: inset 0px @punch-shadowOffset @punch-shadowSize rgba(0,0,0,0.5);
  
  z-index: @punch-z-index;
  
  .punch-shadow;
  
  .punch-white {
    box-shadow: inset 0px -@punch-shadowOffset @punch-shadowSize rgba(255,255,255,0.3);
    
    .punch-shadow;
    
    .punch-in {
      position: absolute;
      top: (@punch-size - @punch-sizeIn)/2;
      left: (@punch-size - @punch-sizeIn)/2;
      
      width: @punch-sizeIn;
      height: @punch-sizeIn;
      
      z-index: @punch-z-index + 1;
      
      border-radius: @punch-sizeIn/2;
      
      background: @punch-background;
      .punch-grid(@punch-grid);
      
      box-shadow: inset 0px @punch-bgShadowOffset @punch-bgShadowSize rgba(0,0,0,0.8);
      
      .punch-content {
        overflow: hidden;
        border-radius: @punch-sizeIn/2;
        max-height: @punch-sizeIn;
        max-width: @punch-sizeIn;
      }
    }
  }
  
  .punch-shadow {
    position: absolute;
    
    width: @punch-size;
    height: @punch-size;
    
    border-radius: @punch-size/2;
  }
  
  .punch-grid (@punch-grid) {
    background-position: 0 0;
  }
  
  /* You can fix the background to the top/left corner of your page */
  /* This should create a cool effect if you have a grid of little punches (about 30px) */
  .punch-grid (@punch-grid) when (@punch-grid = true) {
    background-position: -@punch-left -@punch-top;
  }
}


Код же на Sass у меня получился следущий (здесь представилен .scss, про .sass поговорим позже):
@mixin punch($punch-size: 100px, $punch-left: 0px, $punch-top: 0px, $punch-background: none, $punch-grid: false, $punch-z-index: 0) {
  /* Stuff you may want to change */
  
  $punch-sizeIn: $punch-size * 0.86;
  $punch-shadowOffset: $punch-size / 20;
  $punch-shadowSize: $punch-size / 20;
  $punch-bgShadowOffset: $punch-size / 10;
  $punch-bgShadowSize: $punch-size / 5;
  
  left: $punch-left;
  top: $punch-top;

  box-shadow: inset 0px $punch-shadowOffset $punch-shadowSize rgba(0,0,0,0.5);

  z-index: $punch-z-index;

  @include punch-shadow($punch-size);
  
  .punch-white {

    box-shadow: inset 0px (-$punch-shadowOffset) $punch-shadowSize rgba(255,255,255,0.3);

    @include punch-shadow($punch-size);
    
    .punch-in {
      position: absolute;
      top: ($punch-size - $punch-sizeIn) / 2;
      left: ($punch-size - $punch-sizeIn) / 2;
      
      width: $punch-sizeIn;
      height: $punch-sizeIn;
      
      z-index: $punch-z-index + 1;
      
      border-radius: $punch-sizeIn / 2;
      
      background: $punch-background;

      /* You can fix the background to the top/left corner of your page */
      /* This should create a cool effect if you have a grid of little punches (about 30px) */
     
      @if $punch-grid{
          background-position: (-$punch-left) (-$punch-top);
        }
      @else{
          background-position: 0 0;
        }
      
      box-shadow: inset 0px $punch-bgShadowOffset $punch-bgShadowSize rgba(0,0,0,0.8);
      
      .punch-content {
        overflow: hidden;
        border-radius: $punch-sizeIn / 2;
        max-height: $punch-sizeIn;
        max-width: $punch-sizeIn;
      }
    }
  }
  
  .punch-shadow {
    @include punch-shadow($punch-size);
  }
}

@mixin punch-shadow($punch-size){
    
    position: absolute;
    
    width: $punch-size;
    height: $punch-size;
    
    border-radius: $punch-size / 2;
}



С первой же строчки можно заметить разнецу — в Less мы можем работать напрямую с css классом и отдавать ему аргументы:

.punch(@punch-size: 100px, @punch-left: 0px, @punch-top: 0px, @punch-background: none, @punch-grid: false, @punch-z-index: 0) 

что не возможно в Sass

@mixin punch($punch-size: 100px, $punch-left: 0px, $punch-top: 0px, $punch-background: none, $punch-grid: false, $punch-z-index: 0)

где надо идти через фунцию

@mixin methodName($arguments...)


Приведу пример на том же проекте чем это плохо/хорошо. Чтобы вызвать

@mixin($arguments...) 
нам надо идти через

@include methodName($arguments...)
в то время как Less все проще

.class(@arguments[])


Less

/* Не надо писать file extension .less */
@import "punches";

/* Алюминнивый фон */
body {
  background-image: url("foreground.jpg");
}

#punch {
/*Вызываем функцию punch */
  .punch(300px, 30px, 50px, url("background.jpg"), true);
}


Sass

/* Путь к нашему файлу .scss (это надо делать так как у нас есть еще .sass про который поговорим ниже */
@import "punches.scss";

body {
  background-image: url("foreground.jpg");
}

#punch {
    @include punch(300px, 30px, 50px, url("images/background.jpg"), true);
}


Еще один момент — в Sass по сравнению с Less один @mixin() не может быть внутри другого. Пожтому мне пришлось вынести функцию (я не совсем прав говоря функция так как есть именно function() в Sass которая возвращает переменную, @mixin() это не делает, но про function() я говорить здесь не буду) punch-shadow за пределы первого @mixin punches().

Less

.punch(@punch-size: 100px){

/* Вызываем .punch-shadow функцию */
.punch-shadow;

.punch-shadow {
    position: absolute;
    width: @punch-size;
    height: @punch-size;
    border-radius: @punch-size/2;
  }
}


Sass

@mixin punch(){
  @include punch-shadow($punch-size);
}

@mixin punch-shadow($punch-size){
    
    position: absolute;
    width: $punch-size;
    height: $punch-size;
    border-radius: $punch-size / 2;
}


2) Следущим шагом замечаем что переменные обазначаются через "@" в Less, "$" в Sass. Мелочь, но все же. Еще один маленький момент который я заметил что в Sass если два числа/переменных стоят один за другим и второй имеет минус, Compass сделает вычитания поэтому надо закрываться скобками (этой проблемы нету в Less).

Less
background-position: -@punch-left -@punch-top;

Sass
background-position: (-$punch-left) (-$punch-top);


3) Речь пойдет про if else, for-loop и conditional statement. В Less oн отсутвует что привело моего друга к следущей записи

Less
.punch-grid (@punch-grid) {
    background-position: 0 0;
}
  .punch-grid (@punch-grid) when (@punch-grid = true) {
    background-position: -@punch-left -@punch-top;
  }


Я же смог это отыграть следущим оброзом.
Sass
@if $punch-grid{
          background-position: (-$punch-left) (-$punch-top);
        }
      @else{
          background-position: 0 0;
        }


Это известная проблема Less — у него так же отсутствует for-loop так что вот такое написать сложнее на Less (хочу заметить что в Sass for-loop и arrays начинаються с index-a 1, а не 0)

Sass

/* Первый тип for-loop */
$authors: nick me you her;
@each $author in $authors{
	.author-#{$author}{
		background: url(author-#{$author}.jpg);
	}

//В Sass можно использовать двойной backlass "//", тогда комментарий не будет скамрилирован в .css.
// Второй тип for-loop
@for $i from 1 through 3 {
		.item-#{$i} {
			top: $i * 30px; 
		}
	}

//И через while
@while $v1 < 7{

		.item-#{$v1}{
			top: $v1 * 2;
		}


4) Хотел бы еще сделать заметку на -#{} syntax — я не уверен если он есть в Less — он позволяет посылать параметры в части css кода как вы видим на

background: url(author-#{$author}.jpg);-#{$1} 
// или
.item-#{$v1}


И так код у меня вышел на 74 линии, у друга 69. Но тут появляеться самая интересная часть Sass — есть два способа написания — один это .scss и .sass. В Compass встроен метод «sass-convert» (раньше можно было с less в sass конвертировать но изза многих изменений в syntax обоих, это убрали. И так берем и идем в терминал, заходим в папку где у нас лежит наш punches.scss и пишем:

~$ sass-convert punches.scss punches.sass


Разница между .scss и .sass это в основном syntax (но есть и пару удобных вещей).

1)

@mixin methodName($arguments...)
теперь просто

=methodName($arguments...)

2)

@include methodName($arguments...)
теперь просто

+methodName($arguments...)

3) Главное отличие .sass — нету окончания '";" в конце строк.

Sass(.sass)

=punch($punch-size: 100px, $punch-left: 0px, $punch-top: 0px, $punch-background: none, $punch-grid: false, $punch-z-index: 0)
  /* Stuff you may want to change
  $punch-sizeIn: $punch-size * 0.86
  $punch-shadowOffset: $punch-size / 20
  $punch-shadowSize: $punch-size / 20
  $punch-bgShadowOffset: $punch-size / 10
  $punch-bgShadowSize: $punch-size / 5

  left: $punch-left
  top: $punch-top
  box-shadow: inset 0px $punch-shadowOffset $punch-shadowSize rgba(0, 0, 0, 0.5)
  z-index: $punch-z-index
  +punch-shadow($punch-size)

  .punch-white
    box-shadow: inset 0px -$punch-shadowOffset $punch-shadowSize rgba(255, 255, 255, 0.3)
    +punch-shadow($punch-size)
}


Так помогли ли это нам? Я выйграл этим 2 линии и 0.1 KB в размере байла по сравнению с LESS (с .scss я проигрывал на 0.1 KB).


Итог — будущее за LESS и Sass, меньше кода это всегда хорошо, но не надо забывать про читабельность — код пишеться все таки для людей. Удачи всем. Если есть вопросы или что-то не так пишите под кат.

P.S. Хотел бы добавить что пару недель назад вышла в свет второя часть Assembling Sass Part 2 — здесь именно фокус на .sass. Она так же бесплатна.


Читать дальше →

© Habrahabr.ru