Viết CSS chuyên nghiệp hơn với SCSS

130

I. SCSS là gì

Trước khi biết về SCSS thì mình sẽ kể cho bạn nghe về SASS trước. SASS là viết tắt của Syntactically Awesome Style Sheets (Cú pháp Style Sheets ảo diệu), là một CSS Preprocessor được thiết kế bởi Hampton Catlin và do Natalie Weizenbaum lập trình.

Mặc dù sau cùng SASS sẽ compile ra CSS, nhưng cú pháp của SASS lại không được gần gũi với CSS cho lắm.

.title
    color:red;
    font-style: italic;

Bạn thấy đó, cú pháp của SASS đã loại bỏ đi các dấu {}, thay vào đó là sử dụng các ký tự “thụt lề”.

Nhận thấy cú pháp trên không phù hợp, nên hai tác giả trên đã cho ra mắt phiên bản cải tiến mới, lấy tên là SCSS.

SCSS kế thừa toàn bộ cú pháp của CSS (nghĩa là vẫn sử dụng dấu {}) và mở rộng thêm nhiều cú pháp hay ho khác, giúp các developer code CSS bớt cực hơn.

Một số ưu điểm vượt trội của SCSS so với CSS:

  • Cho phép viết cú pháp lồng nhau
  • Có thể đặt biến và sử dụng biến
  • Có thể kế thừa
  • Hỗ trợ cú pháp mixin

II. Sử dụng Laravel Mix để viết SCSS

2.1 Giới thiệu về Laravel Mix

Laravel Mix là một npm package nằm trong hệ sinh thái của Laravel. Tuy được thiết kế tối ưu cho các dự án Laravel, nhưng bạn vẫn có thể sử dụng Laravel Mix một cách độc lập ở các dự án khác bình thường.

Là một phần của hệ sinh thái, Laravel Mix sinh ra để giải quyết việc build, complite các javascript, css pre-processor như SCSS, LESS, Stylus, PostCSS

2.2 Cài đặt Laravel Mix

Mình sẽ hướng dẫn các bạn cách sử dụng Laravel Mix một cách độc lập, không nhất thiết phải sử dụng Laravel Mix trong dự án Laravel nhé.

Bước 1: Kiểm tra môi trường NodeJS

Trước khi cài đặt Laravel Mix, hãy đảm bảo máy bạn đã cài sẵn nodejs và npm. Bạn có thể kiểm tra bằng cách chạy 2 command sau:

node -v # Đảm bảo máy bạn đã có nodejs
npm -v # Đảm bảo máy bạn đã cài npm

Nếu chưa có, thì bạn cũng có thể cài đặt dễ dàng tại đây

Bước 2: Khởi tạo dự án sử dụng Laravel Mix

Bạn chạy lần lượt các command sau để khởi tạo dự án sử dụng Laravel Mix:

mkdir learn-scss # Tạo thư mục mới tên là learn-scss
cd learn-scss # Di chuyển vào thư mục vừa tạo
mkdir src # Tạo thư mục tên src
touch src/app.scss # Tạo file app.scss để viết scss
npm init -y # Khởi tạo dự án nodejs
npm install laravel-mix --save-dev # Cài đặt gói Laravel Mix
npm install sass-loader sass [email protected] --save-dev --production=false # Cài đặt các gói để viết scss
npm install cross-env --save-dev # Laravel Mix bắt buộc cài theo gói này
cp node_modules/laravel-mix/setup/webpack.mix.js ./ # Publish file config của laravel mix để tiện làm việc

Đợi các command trên chạy xong bạn sẽ có một cấu trúc thư mục thế này:

  • node_modules/
  • src/
  • src/app.scss
  • package.json
  • webpack.mix.js

Giờ bạn mở file package.json, thêm vào các scripts sau

"scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "npm run development -- --watch",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
}

Tiếp tục mở file webpack.mix.js, xóa hết nội dung và thay thế bằng:

const mix = require('laravel-mix');

mix.sass('src/app.scss', 'dist') // đường dẫn tới file scss và thư mục chứa file css được compile từ scss

Hoặc bạn có thể clone repo này của mình về để sử dụng luôn: phambinh217/laravel-mix-stand-alone

Bước 3: Sử dụng Laravel Mix để compile SCSS ra CSS

Bạn mở src/app.scss thêm vào nội dung đầu tiên, sau đó lưu file lại

.hello {
    color: red;

    .world {
        font-size: 20px;
    }
}

Chạy command sau để mỗi khi file app.scss có sự thay đổi thì Laravel Mix sẽ compile ra một phiên bản CSS mới

npm run watch

Trong một số trường hợp Laravel Mix không lắng nghe được sự thay đổi từ file app.scss, bạn có thể thay thế command trên bằng command sau

npm run watch-poll

Nếu thành công bạn sẽ thấy Laravel Mix compile ra một file css tại dist/app.css. Thử mở file dist/app.css để xem nội dung bên trong thế nào.

Bạn thấy gì không, nội dung trong file dist/app.css chính là được compile ra từ file src/app.scss đó. Điều này cũng đồng nghĩa rằng bạn đã cài đặt thành công Laravel Mix để viết SCSS. Giờ chỉ việc tìm hiểu thêm về quy tắc của SCSS nữa thôi.

III. Một số quy tắc phổ biến của SCSS

3.1 Quy tắc lồng nhau

SCSS cho phép bạn viết cú pháp lồng nhau, bạn có thể xem một vài ví dụ sau để hiểu.

SCSS

.hello {
    color: red;

    .world {
        color: red;
    }
}

SCSS

.hello {
    color: red;

    &.world {
        color: blue;
    }
}

SCSS

.hello {
    color: red;

    >.world {
        color: blue;
    }
}

SCSS

.hello {
    color: red;

    &:after {
        display: block;
        content: " ";
        clear: both;
    }
}

Compiled CSS

.hello {
    color: red;
}

.hello .world {
    color: red;
}

Compiled CSS

.hello {
  color: red;
}

.hello.world {
  color: blue;
}

Compiled CSS

.hello {
  color: red;
}

.hello > .world {
  color: blue;
}

Compiled CSS

.hello {
  color: red;
}

.hello:after {
  display: block;
  content: " ";
  clear: both;
}

Các ví dụ trên mình mới chỉ lồng 2 cấp, nhưng bạn có thể lồng n cấp tùy ý nhé.

3.2 Sử dụng biến

Một điều rất hay trong SCSS là nó cho phép bạn có thể sử dụng biến như trong các ngôn ngữ lập trình. Biến trong SCSS được viết theo cú pháp:

$ten_bien: <giá trị>;

Bạn có thể sử dụng biến trong các thuộc tính của SCSS như trong ví dụ sau:

SCSS

$primary: blue;
$padding: 10px;

.btn-primary {
    background: $primary;
    padding: $padding;
}

.text-primary {
    color: $primary;
}

Compiled CSS

.btn-primary {
  background: blue;
  padding: 10px;
}

.text-primary {
  color: blue;
}

Biến trong SCSS rất hữu dụng trong trường hợp CSS của bạn có những giá trị hay thay đổi và thường xuyên bị lặp đi lặp lại như màu sắc, khoảng cách giữa các phần tử, độ cong của viền (border-radius), đổ bóng (box-shadow),..

Biến trong CSS chỉ có thể lưu được 1 giá trị, và không lưu được thuộc tính. Trong trường hợp bạn muốn lưu được cả giá trị và thuộc tính thì có thể tham khảo tiếp quy tắc Mixin dưới đây

3.3 Quy tắc Mixin

Mixin gần giống như biến, nhưng mạnh mẽ hơn ở chỗ Mixin có thể chứa nhiều cặp thuộc tính – giá trị. Đặc biệt Mixin còn có cơ chế truyền tham số, tương tự như chúng ta truyền tham số vào function của một ngôn ngữ lập trình vậy.

Mixin trong SCSS được định nghĩa theo cú pháp:

// Mixin không sử dụng tham số
@mixin ten_mixin {
    //
}

// Mixin kèm theo tham số
@mixin ten_mixin ($thamSo1, $thamSo2) {
    //
}

Để sử dụng Mixin, chúng ta dùng cú pháp:

// Sử dụng mixin không có tham số
.selector {
    @include ten_mixin;
}

// Sử dụng mixin kèm theo tham số
.selector {
    @include ten_mixin($bien1, $bien2);
}

Ví dụ: Mình rất thường xuyên phải sử dụng tổ hợp mấy thuộc tính content: " "; display: block; clear: both; để chống vỡ khung khi sử dụng float css. Để tránh phải lặp đi lặp lại nhiều, thì mình hay tạo ra một mixin có tên là clear_both để tiện sử dụng.

SCSS

@mixin clear_both {
    content: " ";
    display: block;
    clear: both;
}

.row {
    padding-left: 10px;
    padding-right: 10px;
    
    &amp;:after {
        @include clear_both;
    }
}

Compiled CSS

.row {
  padding-left: 10px;
  padding-right: 10px;
}

.row:after {
  content: " ";
  display: block;
  clear: both;
}

Một ví dụ khác: Web layout thì thường được chia ở dạng cột, về cơ bản cột nào cũng sẽ giống nhau về padding, margin, chỉ khác nhau về độ rộng. Mình sẽ tạo ra một mixin tên là col, với tham số là width để tiện sử dụng hơn.

SCSS

@mixin col ($width) {
    width: $width;
    float: left;
    padding-left: 10px;
    padding-right: 10px;
}

.col-6 {
    @include col(50%);
}

.col-12 {
    @include col(100%);
}

Compiled CSS

.col-6 {
  width: 50%;
  float: left;
  padding-left: 10px;
  padding-right: 10px;
}

.col-12 {
  width: 100%;
  float: left;
  padding-left: 10px;
  padding-right: 10px;
}

3.4 Quy tắc extend

Extend (kế thừa) là khái niệm thường tồn tại trong các ngôn ngữ lập trình hướng đối tượng, vậy mà giờ trong SCSS – một ngôn ngữ định dạng cũng đã xuất hiện.

Ví dụ: Giả sử mình có class .btn, giờ mình muốn một class .btn-default sẽ kế thừa toàn bộ thuộc tính của class .btn, thì mình sẽ viết như sau

SCSS

.btn {
    color: red;
    border: 1px solid #000;
}

.btn-default {
    @extend .btn;
}

Compiled CSS

.btn, .btn-default {
  color: red;
  border: 1px solid #000;
}

Extend trong SCSS cũng cho phép bạn ghi đè các thuộc tính. Vẫn là ví dụ trên, nhưng giờ ngoài việc class .btn-default kế thừa toàn bộ thuộc tính của class .btn thì còn ghi đè thuộc tính color thành blue, thì mình sẽ viết như sau:

SCSS

.btn {
    color: red;
    border: 1px solid #000;
}

.btn-default {
    @extend .btn;
    color: blue;
}

Compiled CSS

.btn, .btn-default {
  color: red;
  border: 1px solid #000;
}

.btn-default {
  color: blue;
}

3.5 Quy tắc vùng chọn

Quy tắc vùng chọn tương tự như quy tắc viết .class, #id vậy. Nhưng nếu bạn không gọi vùng chọn ra, thì nó sẽ không được compile thành css.

Vùng chọn trong SCSS được viết theo cú pháp

%ten_vung_chon {
    //
}

Ví dụ: Mình tạo ra một vùng chọn có tên là %btn, nhưng không gọi nó ở đâu cả

SCSS

%btn {
    color: blue;
    border: 1px solid #000;
}

Compiled CSS

// Không compile được gì
// do vùng chọn %btn
// không được sử dụng ở đâu cả

Giờ vẫn là vùng chọn %btn, nhưng sẽ được mình sử dụng ở đâu đó

SCSS

%btn {
    color: blue;
    border: 1px solid #000;
}

.btn-default {
    @extend %btn;
}

Compiled CSS

.btn-default {
  color: blue;
  border: 1px solid #000;
}

Trên là một số quy tắc, cú pháp phổ biến hay được sử dụng trong SCSS. Ngoài ra SCSS còn hỗ trợ nhiều cú pháp hay ho khác mà trong phạm vi bài viết này mình không thể đề cập được hết. Bạn có thể xem chi tiết tại bộ tài liệu chính thức của SCSS.

IV. Kết luận

Tới đây mình nghĩ bạn đã hiểu được 80% SCSS rồi đó, về cơ bản thì nó cũng chỉ có vậy. Thật sự trong các dự án mình cũng chỉ sử dụng tới biến, mixins, extend, còn ngoài ra chưa sử dụng thêm thành phần nào khác và vẫn cảm thấy đầy đủ.

Bạn cũng nên tập thói quen sử dụng SCSS thay vì sử dụng CSS bởi:

  • SCSS hỗ trợ 100% cú pháp của CSS, trong trường hợp bạn không thích dùng SCSS thì vẫn có thể viết CSS như thường
  • SCSS mạnh mẽ và có thể đóng gói được các thuộc tính
  • SCSS được sử dụng trong nhiều các CSS framework
  • SCSS có thể kết hợp đồng thời giữa việc compile và minify CSS

Chào tạm biệt, hẹn gặp lại bạn trong những bài viết lần sau.