Sass căn bản

Chắc hẳn đây không phải là lần đầu tiên bạn nghe cái tên Sass. Vậy Sass là gì và tại sao những ông lớn framework lại sử dụng nó? Nói đơn giản, Sass là một ngôn ngữ giúp mở rộng CSS với những tính năng vượt trội mà bản thân CSS không thể cung cấp. Vì những lợi ích này, hầu hết các trang web, ứng dụng và framework nổi tiếng đều sử dụng Sass.

Trước khi dùng Sass, ta phải chắc rằng máy đã cài Ruby vì trình biên dịch của Sass được viết bằng Ruby. Tiếp đó, bạn hãy vào trang web chính thức của Sass và tải về tập tin cài đặt. Sau khi cài đặt xong, ta chạy chương trình và gõ vào sass --version để kiểm tra. Lúc này, Sass sẽ hiện ra số phiên bản đang dùng.

Quy trình làm việc với Sass

Quy trình làm việc với Sass cũng khá đơn giản. Đầu tiên, ta dùng Sass để định kiểu. Sau đó, trình biên dịch của Sass sẽ dịch toàn bộ tập tin .scss (định dạng của Sass) sang CSS.

Bây giờ, ta bắt đầu viết Sass. Bạn mở Sublime Text, sau đó gõ vào một rule CSS, ví dụ như:

1
2
3
body {
    margin: 0;
}

Sau đó, ta lưu lại với tên style.scss (hoặc tên khác nếu bạn muốn). Tiếp theo, trong cửa sổ dòng lệnh, ta chuyển sang thư mục đang chứa tập tin Sass vừa lưu rồi gõ lệnh sau:

sass style.scss

Lúc này, Sass sẽ tạo ra một tập tin mới tên style.css chứa kết quả biên dịch từ style.scss. Ta có thể mở tập tin này lên để xem nội dung CSS bên trong. Toàn bộ những bước trên đây chính là quy trình làm việc với Sass. Đầu tiên ta viết Sass, sau đó dùng trình biên dịch để tạo ra tập tin CSS.

Nếu cảm thấy mệt mỏi với việc cứ gõ lệnh để biên dịch mỗi khi lưu tập tin Sass, bạn có thể dùng lệnh sau để Sass biên dịch tự động:

sass --watch .

Với lệnh này, Sass sẽ luôn theo dõi thư mục để xem có tập tin nào thay đổi không. Nếu có, nó sẽ tự động biên dịch thành CSS.

Quy tắc lồng

Chắc bạn đã gặp trường hợp viết đi viết lại nhiều lần selector cho một rule CSS nào đó. Và nếu bạn có máu lười như tôi, điều này không thể chịu đựng được. Nhưng giờ đây, ta đã có Sass và nó sẽ giúp ta vượt qua bể khổ với tính năng Quy tắc lồng.

Như tên gọi của nó, quy tắc lồng cho phép viết các quy tắc CSS lồng vào nhau. Khi biên dịch, Sass sẽ cho ra tập tin CSS với đầy đủ các selector theo đúng chuẩn. Nếu như bạn vẫn chưa hiểu tôi nói gì thì hãy xem một ví dụ đơn giản sau đây.

Giả sử ta có một tập tin HTML như sau:

1
2
3
4
<div class="content">
    <h2>Tiêu đề</h2>
    <p>Lorem Ipsum...</p>
</div>

Thông thường khi viết CSS cho tập tin HTML này, ta thường làm như sau:

1
2
3
4
5
6
7
.content h2 {
    font-size: 2em;
}

.content p {
    font-size: 1.2em;
}

Như ta thấy, selector .content được viết lại nhiều lần. Điều này hoàn toàn không nên bởi vì nó vi phạm quy tắc DRY (Don’t Repeat Yourself), một điều cấm kị khi viết code.

Do đó, Sass đem đến một giải pháp hoàn hảo. Giờ đây ta có thể viết .content một lần duy nhất và để trình biên dịch Sass lo toàn bộ những thứ còn lại. Trong tập tin .scss, ta gõ:

1
2
3
4
5
6
7
8
.content {
    h2 {
        font-size: 2em;    
    }
    p {
        font-size: 1.2em;
    }
}

Lưu tập tin này lại và cho Sass biên dịch. Cuối cùng ta nhận được tập tin CSS với đoạn code hoàn toàn giống lúc đầu. Vậy là từ giờ trở đi, những công việc lặp đi lặp lại nhàm chán ta hãy để cho Sass xử lý, còn ta thì dành thời gian để viết những đoạn code thú vị hơn.

Quy tắc lồng nâng cao

Trong phần này ta sẽ tiếp tục với quy tắc lồng nhưng ở mức độ cao cấp hơn.

Để minh họa, ta hãy xem nội dung tập tin CSS sau:

1
2
3
4
5
6
7
a {
    color: red;
}

a:hover {
    color: green;
}

Sass cho phép sử dụng một ký hiệu đặc biệt & để ta không phải gõ lại thẻ anchor như trên. Ta hãy xem đoạn Sass sau:

1
2
3
4
5
6
a {
    color: red;
    &:hover {
        color: green;
    }
}

Sau khi được biên dịch, đoạn code này cho ra CSS tương tự như đoạn CSS ở trên, nhưng lần này, ta không phải gõ thẻ anchor nhiều lần.

Tiếp theo, ta hãy xem đoạn Sass sau đây:

1
2
3
4
5
6
7
8
#main {
    a {
        color: red;
        &:hover {
            color: green;
        }
    }
}

Sau khi biên dịch, tập tin CSS của ta sẽ trông như thế này:

1
2
3
4
#main a {
    color: red; }
    #main a:hover {
        color: green; }

Nếu tinh mắt, ta sẽ thấy trong tập tin CSS, Sass đã gợi ý cấu trúc lồng vào nhau bằng cách thụt đầu dòng ở những quy tắc con.

Biến

Nếu đã từng sử dụng qua một ngôn ngữ lập trình thì chắc bạn đã quá quen với khái niệm biến. Trong Sass, ta cũng có khái niệm này, đặc biệt là nó hoàn toàn giống với biến trong PHP: bắt đầu bằng dấu $ và theo sau là một chuỗi kí tự, ví dụ như $main-color. Tuy nhiên, một điều cần lưu ý đó là ta dùng dấu : thay cho dấu = khi gán giá trị cho biến, ví dụ: $main-color: #333.

Ta hãy xem qua một đoạn Sass ngắn sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
$main-color: #333;
$margin: 5px;

.main {
    color: $main-color;
    margin: $margin;
    padding: $margin * 5;
}

.nav {
    background-color: $main-color;
    margin: $margin;
}

Trong đoạn mã trên, kể từ khi khai báo biến, ta có thể dùng biến này thay cho giá trị mà nó đại diện. Điều này mang tới một ưu điểm nổi bật, đó là khi thay đổi giá trị của biến thì toàn bộ những chỗ mà nó xuất hiện cũng sẽ thay đổi giá trị theo.

Một điều thú vị nữa có thể nhận thấy trong đoạn mã trên đó là khả năng thực hiện phép tính ở dòng padding. Sass đủ thông minh để có thể hiểu được ý đồ của ta khi dùng phép nhân và cho ra kết quả cuối cùng sau biên dịch là padding: 25px.

Mixin

Bạn đừng để cái mixin này làm khó mình bởi vì nó chẳng có gì khó hiểu ngoại trừ cái tên. Thực ra nó giống như khái niệm hàm (function) bên PHP. Ta quăng cho nó vài câu lệnh rồi sau đó gọi cái tên hàm ở những nơi ta cần thực hiện những câu lệnh đó. Mixin cũng hoàn toàn tương tự như thế.

Ta hãy xem đoạn mã sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@mixin wtf {
    border: 1px solid red;
    margin: 5px;
    padding: 5px;
}

.main {
    @include wtf;
    background-color: green;
}

.nav {
    @include wtf;
    color: red;
}

Ta khai báo một mixin bằng @mixin và khi cần gọi nó thì ta dùng @include. Có lẽ không cần giải thích gì thêm nữa vì tôi biết chắc là bạn quá rành về khái niệm hàm trong PHP rồi.

Vẫn chưa hết, ta thậm chí có thể đính kèm thông số vào trong mixin như với function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@mixin wtf($number1, $number2) {
    border: 1px solid red;
    margin: $number1;
    padding: $number2;
}

.main {
    @include wtf(5px, 5px);
    background-color: green;
}

.nav {
    @include wtf(3px, 4px);
    color: red;
}

Mở rộng selector

Giờ đây chắc bạn cũng đã có chút kinh nghiệm trong việc dùng Sass. Nói thật thì những khái niệm trong Sass đều vay mượn từ ngôn ngữ lập trình PHP. Và một lần nữa, Sass lại vay mượn tính năng kế thừa trong PHP.

Hãy xem đoạn mã sau:

1
2
3
4
5
6
7
8
9
.entry {
    background: red;
    border: 1px solid green;
    width: 100%;
}

.content {
    @extend .entry;
}

Nếu như bạn là trùm lập trình hướng đối tượng PHP, thì đoạn mã trên quá dễ đối với bạn. Ở đây, class content sẽ kế thừa từ class entry và do đó sở hữu những quy tắc của class entry.

Các hàm xử lý màu sắc

Thông thường, trong CSS, ta chỉ có thể khai báo màu dưới dạng hex, RGB hoặc các từ khóa định sẵn (red, green, blue). Nhưng trong Sass, ta còn làm được nhiều hơn thế. Để dễ hiểu, ta hãy xem một ví dụ sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$main-background: complement(blue);
$link-color: mix(yellow, pink);

.header {
    background: lighten(red, 5%);
}

.main {
    background: $main-background;
}

a {
    color: $link-color;
}

.footer {
    background: darken(green, 5%);
}

Sass cung cấp hàng loạt hàm xử lý màu giúp ta không bị giới hạn bởi số hex hay RGB. Bạn cũng có thể đoán được chức năng của từng hàm bằng cách nhìn vào tên của nó. Hàm lighten để làm tăng độ sáng, còn hàm darken làm nó tối hơn. Hàm mix dùng để trộn 2 màu lại với nhau để tạo ra một màu mới. Sass còn có khá nhiều hàm xử lý màu mà bạn có thể tự tham khảo trong documentation.

Import tập tin

Trong CSS, ta có thể tách các rule thành nhiều tập tin CSS riêng biệt. Khi đó, ta dùng lệnh @import để chèn nội dung tập tin bên ngoài vào nơi cần sử dụng. Trong Sass, ta cũng có thể thực hiện chức năng tương tự.

Hãy tạo một tập tin mới đặt tên là _bien.scss có nội dung như sau:

1
2
$main-background: complement(blue);
$link-color: mix(yellow, pink);

Sau đó, bạn sẽ import tập tin _bien.scss vào trong tập tin Sass hiện hành bằng lệnh @import:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@import _bien.scss;

.header {
    background: lighten(red, 5%);
}

.main {
    background: $main-background;
}

a {
    color: $link-color;
}

.footer {
    background: darken(green, 5%);
}

Sau khi biên dịch, kết quả vẫn y như cũ. Nhưng lần này, ta đã tách thành 2 tập tin.

Một điều mà tôi muốn bạn lưu ý, đó là tên tập tin _bien.scss có một dấu _ ở đằng trước. Khi trình biên dịch Sass nhìn thấy dấu này, nó sẽ bỏ qua mà không biên dịch ra CSS. Cho nên khi nhìn vào thư mục, bạn sẽ không hề thấy tập tin nào tên _bien.css.

Thêm một điều lưu ý nữa đó là thứ tự import rất quan trọng, bởi vì CSS áp dụng kiểu theo phương pháp ghi đè (cascade), nghĩa là những rule khai báo sau sẽ đè lên rule khai báo trước. Do đó, hãy cẩn thận khi bạn có nhiều tập tin import cùng lúc.

Hàm

Trong phần trước, ta đã được làm quen với một vài hàm xử lý màu của Sass. Trong phần này, ta sẽ học cách tự khai báo một hàm cho riêng mình.

Khái niệm hàm thì chắc không có gì mới với bạn, cho nên cái mà tôi sẽ đề cập ở đây chính là cú pháp và sự khác nhau của nó với mixin. Ở hàm, bạn bắt buộc phải có giá trị trả về bằng cách gọi @return, còn mixin thì không.

Hãy xem một ví dụ để minh họa cho hàm:

1
2
3
4
5
6
7
@function getColor($color1, $color2) {
    @return mix($color1, $color2);
}

.main {
    background: getColor(red, blue);
}

Ở đây, hàm getColor sẽ trả về giá trị trộn 2 màu mà bạn nhập vào. Với mixin, ta phải gọi bằng @include, với hàm thì chỉ cần gọi tên hàm và cho vào các tham số nếu có. Một lần nữa, những ý tưởng này hoàn toàn giống bên PHP, nó chỉ khác nhau ở cú pháp. Nếu bạn rành PHP thì những thứ thế này không thành vấn đề với bạn.

Media Query

Media Query là thành phần không thể thiếu trong bất kỳ thiết kế responsive nào. Trong trường hợp bạn không biết nó là gì, tôi xin giải thích đơn giản cho bạn. Media Query là công cụ giúp tùy biến giao diện trang web tùy theo kích thước màn hình. Nói cách khác, với cùng một trang web, ta có thể thay đổi bố cục của trang dựa vào kích thước màn hình.

Điều này rất thuận lợi khi ngày nay có quá nhiều thiết bị được người dùng sử dụng để truy cập web. Thay vì thiết kế riêng từng trang cho từng thiết bị, với Media Query, ta có thể thay đổi các định kiểu của trang để nó hiển thị phù hợp nhất trên các thiết bị khác nhau.

Để dùng Media Query trong Sass, ta hãy xem qua đoạn code sau:

1
2
3
4
5
6
7
@media (max-width: 400px) {
    .main {
        .content {
            font-size: .5em;
        }
    }
}

Đặc biệt hơn, Sass cho phép ta sử dụng Media Query lồng trong một rule. Ví dụ:

1
2
3
4
5
6
7
8
9
.main {
    .content {
        font-size: 2em;

        @media (max-width: 400px) {
            font-size: .5em;
        }
    }
}

Thông thường, ta phải viết Media Query ở cuối tập tin CSS, nhưng với Sass ta có thể lồng vào trong rule mà ta muốn áp dụng nó. Với cách thức này, các định kiểu sẽ dễ quản lý hơn vì nó tập trung vào một chỗ thay vì rải rác khắp nơi như trong CSS.

Câu điều kiện

Trong lập trình, để rẽ nhánh dòng thực thi chương trình, ta dùng câu điều kiện if. Và trong Sass, ta cũng có thể thực hiện điều tương tự với @if. Hãy xem ví dụ sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
@mixin checkColor($color) {
    @if $color == red {
        background: yellow;
    } @else if $color == green {
        background: blue;
    } @else {
        background: black;
    }
}

.main {
    @include checkColor(red);
}

Đoạn mã trên khá quen thuộc nên tôi không giải thích gì nhiều. Điều duy nhất bạn cần nhớ là thêm dấu @ vào trước từ khóa ifelse.

Vòng lặp

Trước tiên, ta hãy xem qua đoạn mã sau:

1
2
3
4
5
6
7
8
9
10
11
@for $i from 1 through 10 {
    .box_#{$i} {
        margin: #{$i}px;
    }
}

@each $color in red, green, blue {
    .#{$color}_box {
        background-color: #{$color};
    }
}

Cũng như câu điều kiện, có lẽ tôi không cần phải giải thích gì nhiều. Tuy nhiên, có một chỗ mà tôi phải giải thích đó chính là kí hiệu #{$bien}. Nếu bạn đã từng dùng qua Ruby thì cái kí hiệu này khá quen thuộc. Kí hiệu này hoạt động như một placeholder có chức năng lần lượt thay thế các giá trị của biến $bien vào vị trí nó chiếm giữ.

Một điều nữa mà bạn cũng nên lưu ý là cú pháp các vòng lặp này khác so với cú pháp vòng lặp mà bạn đã biết trong ngôn ngữ lập trình. Ở vòng lặp @each, biến $color sẽ lần lượt là các màu trong danh sách mà tôi đã liệt kê (red, green, blue). Do đó, nó sẽ tự động thay thế các giá trị đó vào chỗ #{$color}. Tính năng này giúp ta có thể tạo ra các rule CSS một cách tự động. Trong vòng lặp @for, hãy nhớ nó dùng từ “through” chứ không phải từ “to”. Rất nhiều người nhớ lộn do quá quen với kiểu nói “from … to” trong tiếng Anh.

Lời kết

Giờ đây, tôi chắc rằng bạn đã trở nên nguy hiểm hơn xưa rất nhiều. Với những gì tôi trình bày ở trên, bạn đã có đủ những kiến thức cơ bản nhất về Sass để sử dụng cho những dự án trong tương lai. Tuy nhiên, những gì tôi trình bày chỉ là một phần rất nhỏ chức năng mà Sass có thể thực hiện, và tôi dành phần khám phá những tính năng cao cấp, thú vị của Sass lại cho bạn.