Css Preprocessors là gì ?

Khi tham gia các dự án về web, việc không thể thiếu đó là chúng ta phải viết css cho trang web đó. Nếu team của bạn không có một người chuyên cắt giao diện thì việc viết css là bắt buộc. Mình cũng thế, giai đoạn đầu số lượng code css còn ít, dễ control, dễ extend, tuy nhiên khi số lượng code trong file lên đến vài ngàn, thậm chí vài chục ngàn dòng thì đó là một nỗi ác mộng. Css Preprocessors sinh ra để giải quyết vấn đề đó. Trước kia, khi viết css chúng ta hay có khái niệm 'tĩnh', tuy nhiên Css Preprocessor ra đời, sẽ không còn 'tĩnh' nữa, mà lại rất động.

Css Preprocessors đúng như cái tên của nó - là phương pháp tiền xử lý CSS. Nó có nhiệm vụ logic hóa các đoạn code CSS để sao cho giống với ngôn ngữ lập trình. Nó cũng có biến, function, extends, import...Những tính năng hết sức tiện lợi và giúp chúng ta code CSS không còn nhàm chán nữa phải không nào.

Các loại Css Preprocessors hiện nay

Hiện nay trên thị trường có rất nhiều loại Css Preprocessors đang được sử dụng. Ta có thể kể đến như:

trong bài viết này, mình chỉ giới thiệu về SASS - một loại Css Proprecessors đang được sử dụng nhiều nhất hiện nay, còn về LESS đứng vị trí số 2. Tất nhiên, chúng ta sẽ ưu tiên vị trí số 1.

Sass - Css Preprocessors phổ biến nhất

Cài đặt

Để cài đặt sass, đơn giản nhất chúng ta sử dụng npm bằng lệnh

npm install -g sass 

Variables (biến)

Biến trong Sass sử dụng dấu $ ở đầu:
Ví dụ

$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
 color: $primary-color;
 font: 100% $font-stack;
}

Sau khi compile, output CSS sẽ như sau:

body {
 font: 100% Helvetica, sans-serif;
 color: #333;
}

Mixins

Mixins là gì nhỉ ? - Hiểu đơn giản có thể coi nó là function nhé. Khi làm việc với function chúng ta có 2 thao tác. 1 là khai báo function và nội dung xử lý bên trong function, 2 là gọi function đó.

Mixins ở đây cũng tương tự như vậy
Khai báo mixins không có parameter

@mixin mixin_name {
// SASS selectors...
}

Khai báo mixins có tham số

@mixin mixin_name(param1, param2...)
{
    // SASS selectors...
}

và để call function ta làm thế nào nhỉ ? Đơn giản lắm

@include mixin_name;

Ví dụ cụ thể hơn

@mixin border-radius($radius) {
 -webkit-border-radius: $radius;
 -moz-border-radius: $radius;
 border-radius: $radius;
 -ms-border-radius: $radius;
}

.box { @include border-radius(10px); }

vậy mixins cũng dễ hiểu phải không. Có mixins rồi, chúng ta chỉ cần viết 1 lần, call khắp nơi nhé.

Nested Rules (Xếp chồng)

Khi viết CSS chúng ta hay phải viết kiểu lồng nhau, mục đích của viết kiểu như vậy để thể hiện quan hệ cha, con, ông, cháu giữa các thẻ html. Mục đích của cái này cũng là để chúng ta có thể viết css kiểu lồng nhau như vậy. Tuy nhiên, thực tế khi chúng ta viết css mà lồng nhau tầng tầng lớp lớp như vậy không hề dễ đọc tí nào, mà ngược lại rất rối. Vì thế, chúng ta nên viết lồng nhau vừa phải thôi. Như vậy code sẽ dễ đọc, dễ maintainance hơn nhé.
Ví dụ cụ thể :

Khi viết css thường

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav li {
  display: inline-block;
}
nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}

Còn khi sang SASS Nested

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

rõ ràng là dễ đọc hơn, thể hiện rõ hơn quan hệ cha con giữ các thẻ ul, li, a với thẻ nav phải không.

Import và extend

Thực ra import cũng đơn giản như cái tên của nó vậy. Lấy nội dung ở chỗ A, nhập vào chỗ B, đại khái vậy đó. Có một vài chú ý ở đây

  • File import sẽ có dạng dấu gạch dưới ở trước tên file _name.scss.
  • Nội dung import chỉ chứa name mà không có dấu gạch _ và định dạng file .scss.

Ví dụ cụ thể cho dễ hiểu nhé.

CSS thông thường thì viết như vậy

.box {
    padding: 20px;
    line-height: 0;
}
.list {
    color: red;
}
.list li {
    font-size: 14px;
}

Khi sử dụng import trong Sass sẽ như vậy

_base.scss
.box {
    padding: 20px;
    line-height: 0;
}

style.scss
@import 'base';
.list {
    color: red;
    li {
        font-size: 14px;
    }
}

Nhìn vào đây, ta thấy nội dung của file _base.scss đã được import vào style.scss
Nếu muốn import nhiều file thì làm thế nào ? Cũng đơn giản lắm

@import 'reset','base';

Tiếp theo đến extends - tính năng này cũng hay ho không kém nhé.
Nó giúp một thành phần nào đó có thể thừa hưởng nội dung từ thành phần khác. Ví dụ cụ thể như này

.button_1 {
 border-radius:6px;
 border:1px solid #dcdcdc;
 display:inline-block;
 color:#777777;
 font-family:arial;
 font-size:15px;
}

.button_2 { @extend .button_1; }

vậy output CSS ra sẽ như này :

.button_1, .button_2 {
 border-radius: 6px;
 border: 1px solid #dcdcdc;
 display: inline-block;
 color: #777777;
 font-family: arial;
 font-size: 15px;
 font-weight: bold;
 padding: 6px 24px;
 text-decoration: none;
 text-shadow: 1px 1px 0px #ffffff; }

Vòng lặp

Cái này mới hay nè, viết CSS mà có thể loop như lập trình, sử dụng for, each, if, else, while như đúng rồi
Ví dụ cụ thể:

@each $name in 'save' 'cancel' 'help' {
    .icon-#{$name} {
        background-image: url('/images/#{$name}.png');
   

CSS output sẽ ra

.icon-save {
  background-image: url("/images/save.png");
}
.icon-cancel {
  background-image: url("/images/cancel.png");
}
.icon-help {
  background-image: url("/images/help.png");
}

ngắn gọn hơn nhiều, phải không nào ?

Function

Vừa ở trên, chúng ta có nói mixins giống như một function, cũng khai báo có tham số và không có tham số. Tuy nhiên, Sass vẫn hỗ trợ thêm function, nhưng hơn một chỗ nó có khả năng return về một giá trị

Ví dụ như thế này

@function make-greener($value) {
    @return $value + rgb(0,50,0);
}
p {
    background: make-greener(gray);
}

khi output ra CSS

/* compiled CSS */
p {
  background: #80b280;
}

Sử dụng webpack với Sass loader

Bài viết đã khá dài rồi, hẹn các bạn trong loạt bài viết tiếp theo nhé.