メインコンテンツまでスキップ

SCSS

SCSS Nâng Cao

1. Mixin và Include

Trong ngữ cảnh CSS, mixin được hiểu là một chỉ thị được sử dụng để nhóm các quy tắc CSS cùng nhau. Điều này tương tự như Placeholder, nhưng không hoàn toàn giống nhau. Với mixin, bạn có thể truyền tham số trong khi Placeholder không thể.
Mixin được bao gồm vào ngữ cảnh hiện tại bằng cách sử dụng @include, có cú pháp @include <name> hoặc @include <name>(<arguments...>), trong đó <name> là tên của mixin.

/*Scss*/
@mixin reset-list{
margin: 0;
padding: 0;
list-style: none;
}
@mixin horizontal-list{
@include reset-list;

li{
display: inline-block;
margin:{
left: -2px;
right: 2em;
}
}
}
nav ul{
@include horizontal-list;
}

/*Css*/
.nav ul{
margin: 0;
padding: 0;
list-style: none;
}
.nav ul li{
display: inline-block;
margin-left: -2px;
margin-right: 2em;
}

Mixins cho phép bạn định nghĩa các kiểu dáng có thể tái sử dụng trong toàn bộ bảng điều khiển của bạn. Chúng giúp tránh việc sử dụng các lớp không ngữ nghĩa như .float-left và cho phép phân phối các bộ kiểu dáng trong các thư viện. (Điều này sẽ thường được sử dụng cho các phong cách được sử dụng nhiều lần trong dự án)

Ví dụ:

/*No Parameters*/
/*scss*/
@mixin menu{
#menu{
a{
background: #333;
text-decoration: none;
}
li{
height: 30px;
line-height: 30px;
}
}
}
--------------------------
@include menu;
/*css*/
#menu a{
background: #333;
text-decoration: none;
}
#menu li{
height: 30px;
line-height: 30px;
}

/*Use variable*/
/*scss*/
$color-blue: blue;
@mixin menu{
background: $color-blue;
}
.header{
@include menu;
}
/*css*/
.header{
background: blue;
}

/*The default value of parameter*/
/*scss*/
@mixin nav($background, $color: white){
background: $background;
color: $color;
}
.nav{
@include nav(red);
border: solid 1px;
}
/*css*/
.nav{
background: red;
color: white;
border: solid 1px;
}

/*Pass parameter with variable names*/
/*scss*/
@mixin nav($background, $color){
background: $background;
color: $color;
}
.nav{
@include nav($color : blue, $background: red);
border: solid 1px;
}
/*css*/
.nav{
background: red;
color: blue;
border: solid 1px;
}

/*@content*/
/*scss*/
@mixin nav($border){
border: $border;
@content;
}
.nav{
@include nav(solid 1px red 1231){
padding: 20px;
};
}
/*css*/
.nav{
border: solid 1px red 1231;
padding: 20px;
}

2. Function

Function không xa lạ trong lĩnh vực lập trình, và trong SASS nó là một khái niệm khá mới và tất nhiên rất hữu ích trong xây dựng CSS.

Function trong SASS tương tự như "@mixin", tuy nhiên, nếu phân tích cẩn thận, "@mixin" tương đương với thủ tục (Function không có giá trị trả về) và Funtion là hàm có giá trị trả về.

Function được định nghĩa bằng cách sử dụng at-rule "@function", có cú pháp @function <name>(<arguments...>) { ... }.

Tên của một Function có thể là bất kỳ từ khóa nào trong SASS. Nó chỉ có thể chứa các câu lệnh chung và at-rule @return để chỉ định giá trị sử dụng làm kết quả của cuộc gọi Funtion. Funtion được gọi bằng cú pháp Funtion thông thường của CSS.

/*scss*/
@function pow($base, $exponent){
$result: 1;
@for $_ from 1 through
$exponent{
$result: $result * $base;
}
@return $result;
}
.sidebar{
float: left;
margin-left: pow(4,3) * 1px;
}

@function sum($numbers...){
$sum: 0;
@each $number in $numbers{
$sum: $sum * $number;
}
@return $sum;
}
.micro{
width: sum(50px, 30px, 100px);
}

/*css*/
#sidebar{
float: left;
margin-left: 64px;
}
#micro{
width: 180px;
}

Các hàm cho phép bạn xác định các thao tác phức tạp trên các giá trị SassScript mà bạn có thể sử dụng lại trong toàn bộ biểu định kiểu của mình.
Chúng giúp dễ dàng tóm tắt các công thức và hành vi phổ biến theo cách dễ đọc.

Thêm ví dụ:

/*scss*/
@function width_wrapper($value){
@return ($value + 20px);
}
.wrapper{
width: width_wrapper(80px);
}

/*css*/
.wrapper{
width: 100px;
}

3. IF AND ELSE

If

At-rule "@if" được viết dưới dạng @if <expression> { ... }, và nó kiểm soát xem khối mã của nó có được đánh giá hay không (bao gồm việc tạo ra bất kỳ kiểu dáng nào như CSS).
Biểu thức thường trả về giá trị true hoặc false - nếu biểu thức trả về true, khối mã sẽ được đánh giá, và nếu biểu thức trả về false, khối mã sẽ không được đánh giá.

Câu lệnh if else được sử dụng để kiểm tra xem một điều kiện có đúng hay không. Nếu điều kiện đúng, câu lệnh bên trong khối if sẽ được thực thi, và ngược lại nếu nó không đúng, câu lệnh bên trong khối else sẽ được thực thi.

/*scss*/
@mixin avatar($size, $circle: false){
width: $size;
height: $size;

@if $circle{
border-radius: $size / 2;
}
}
.square-av{
@include avatar(100px, $circle: false);
}
.circle-av{
@include avatar(100px, $circle: true);
}

/*css*/
.square-av{
width: 100px;
height: 100px;
}
.circle-av{
width: 100px;
height: 100px;
border-radius: 50px;
}

Else

Sau at-rule "@if", bạn có thể sử dụng tùy chọn at-rule @else, được viết dưới dạng @else { ... }. Khối mã của at-rule này sẽ được đánh giá nếu biểu thức của at-rule @if trả về false.

/*scss*/
$light-background: #f2ece4;
$light-text: #036;
$dark-background: #6b717f;
$dark-text: #d2e1dd;
@mixin
theme-colors($light-theme: true){
@if $light-theme{
background-color: $light-background;
color: $light-text;
} @else {
background-color: $dark-background;
color: $dark-text;
}
}
.banner{
@include theme-colors($light-theme: true);
body.dark & {
@include theme-colors($light-theme: false);
}
}

/*css*/
.banner{
background-color: #f2ece4;
color: #036;
}
body.dark .banner{
background-color: #6b717f;
color: #d2e1dd;
}

Else if

Bạn cũng có thể lựa chọn xem liệu khối mã của at-rule @else có được đánh giá hay không bằng cách sử dụng cú pháp @else if <expression> { ... }. Nếu làm như vậy, khối mã chỉ được đánh giá nếu biểu thức của at-rule @if trước đó trả về false và biểu thức của @else if trả về true.

Thực tế, bạn có thể xếp chồng bao nhiêu at-rule @else if sau at-rule @if tùy thích. Chỉ có khối mã đầu tiên trong chuỗi mà biểu thức của nó trả về true sẽ được đánh giá, và không có khối mã nào khác. Nếu có một at-rule @else đơn thuần ở cuối chuỗi, khối mã của nó sẽ được đánh giá nếu mọi khối mã khác đều không thỏa mãn.

ziuy
/*scss*/

@mixin triangle($size, $color, $direction){
height: 0;
width: 0;
border-color: transparent;
border-style: solid;
border-width: $size / 2;

@if $direction == up{
border-bottom-color: $color;
} @else if $direction == right{
border-left-color: $color;
} @else if $direction == down{
border-top-color: $color;
} @else if $direction == left{
border-right-color: $color;
} @else {
@error "Unknown direction #{$direction}.";
}
}
.next{
@include triangle(5px, black, right);
}

/*css*/
.next{
height: 0;
width: 0;
border-color: transparent;
border-style: solid;
border-width: 2.5px;
border-left-color: black;
}

4. EACH

Trong Sass chúng ta có at-rule @each có chức năng tương tự với vòng lặp foreach trong PHP. Tuy nhiên, trong Sass không có cấu trúc dữ liệu mảng như trong PHP, vì vậy at-rule @each trong Sass được sử dụng để lặp qua một kiểu dữ liệu tương tự danh sách mảng, chẳng hạn như danh sách dữ liệu định dạng.

At-rule @each giúp dễ dàng tạo ra các kiểu dữ liệu hoặc đánh giá mã cho mỗi phần tử trong một danh sách hoặc từng cặp trong một bản đồ. Nó rất hữu ích cho các kiểu dữ liệu lặp lại chỉ có một số biến thể giữa chúng. Thông thường, cú pháp của nó được viết là @each <variable> in <expression> { ... }, trong đó biểu thức trả về một danh sách. Khối mã sẽ được đánh giá cho từng phần tử của danh sách và gán cho biến có tên đã chỉ định.

/*scss*/

$sizes: 40px, 50px, 80px;
@each #size in $sizes{
.icon-#{$size}{
font-size: $size;
height: $size;
width: $size;
}
}

/*css*/
.icon-40px{
font-size: 40px;
height: 40px;
width: 40px;
}
.icon-50px{
font-size: 50px;
height: 50px;
width: 50px;
}
.icon-80px{
font-size: 80px;
height: 80px;
width: 80px;
}

/*scss*/

$icons: {"eye": "\f112", "start": "\f12e", "stop": "\f12f"};
@each @name, $glyph in $icons{
.icon-#{$name}:before{
display: inline-block;
font-family: "Icon Font";
content: $glyph
}
}

/*css*/
@charset "UTF-8";
.icon-eye:before{
display: inline-block;
font-family: "Icon Font";
content: "";
}
.icon-start:before{
display: inline-block;
font-family: "Icon Font";
content: "";
}
.icon-stop:before{
display: inline-block;
font-family: "Icon Font";
content: "";
}


/*scss*/

$class-name: col-xs-1 col-xs-2 col-xs-3;
@each @name in $class-name{
.#{$name}{
background: red;
}
}

$borders: "solid 2px" "solid 3px";
@each @border in $borders{
.h2{
border: #{$border};
}
}

/*css*/
.col-xs-1{
background: red;
}
.col-xs-2{
background: red;
}
.col-xs-3{
background: red;
}
.h2{
border: solid 2px;
}
.h2{
border: solid 3px;
}

5. FOR

Trong Sass, chúng ta có quy tắc @for cho phép tạo vòng lặp để tạo ra các kiểu CSS có cấu trúc tương tự như nhau nhưng khác nhau về giá trị. Quy tắc @for lặp qua một loạt các số và thực hiện một khối mã cho mỗi số trong khoảng đó.

Cú pháp của quy tắc @for có thể được viết là @for <variable> from <biểu thức bắt đầu> to <biểu thức kết thúc> { ... } hoặc @for <variable> from <biểu thức bắt đầu> through <biểu thức kết thúc> { ... }. Biểu thức đầu tiên đại diện cho giá trị bắt đầu và biểu thức thứ hai đại diện cho giá trị kết thúc của vòng lặp. Khối mã trong dấu ngoặc nhọn được thực thi cho mỗi giá trị trong khoảng được chỉ định. Giá trị hiện tại của vòng lặp được gán vào biến đã cho.


/*scss*/

$base-color: #036;
@for $i from 1 through 3{
ul:nth-child(3n + #{$i}){
background-color: lighten($base-color, $i * 5%);
}
}

/*css*/
ul:nth-child(3n + 1){
background-color: #004080;
}
ul:nth-child(3n + 2){
background-color: #004d99;
}
ul:nth-child(3n + 3){
background-color: #0059b3;
}

6. WHILE

Trong Sass, chúng ta cũng có quy tắc @while để tạo vòng lặp. Quy tắc @while được viết là @while <variable> { ... } và thực thi khối mã nếu biểu thức trả về giá trị true. Sau đó, nếu biểu thức vẫn trả về true, nó sẽ tiếp tục thực thi khối mã một lần nữa. Quá trình này tiếp tục cho đến khi biểu thức cuối cùng trả về false.

Với quy tắc @while, chúng ta có thể tạo ra vòng lặp với điều kiện chưa biết trước số lần lặp cụ thể. Quy tắc này rất hữu ích khi chúng ta muốn lặp lại một khối mã cho đến khi một điều kiện cụ thể không còn đúng nữa.

Tuy nhiên, như bạn đã đề cập, trong Sass, việc sử dụng vòng lặp while không phổ biến bằng vì CSS không cần nhiều vòng lặp. Trong CSS, chúng ta thường tập trung vào quản lý và tối ưu hóa các bộ chọn (selector) hơn là sử dụng vòng lặp.


/*scss*/
/* Divides `$value` by `$ratio` until it's below `$base`.*/
@function scale-below($value, $base, $ratio: 1.618){
@while $value > $base {
$value: $value / $ratio;
}
@return $value;
}

$normal-font-size: 16px;
sup{
font-size: scale-below(20px, 16px);
}

/*css*/
sup{
font-size: s12.36094px;
}

Preprocessing (Tiền xử lý)

Bạn cũng có thể theo dõi từng file hoặc thư mục riêng lẻ bằng flag --watch.
Watch flag trong Sass theo dõi các file nguồn của bạn để phát hiện thay đổi và biên dịch lại CSS mỗi khi bạn lưu file Sass. Nếu bạn muốn theo dõi (thay vì biên dịch thủ công) file input.scss của bạn, bạn chỉ cần thêm watch flag vào lệnh của bạn, như sau:

sass --watch input.scss output.css

Bạn có thể theo dõi và xuất ra thư mục bằng cách sử dụng đường dẫn thư mục làm đầu vào và đầu ra, và phân tách chúng bằng dấu hai chấm.
Trong ví dụ này:

sass --watch app/sass:public/stylesheets

Sass sẽ theo dõi tất cả các file trong thư mục app/sass để phát hiện thay đổi, và biên dịch CSS vào thư mục public/stylesheets.

Hình ảnh 1: Thư mục chứa các file [scss] thường là [asset]

scss1.png

Hình ảnh 2: Mở cửa sổ dòng lệnh bằng cách viết vào thanh địa chỉ (path bar).

scss2.png

Hình ảnh 3: Viết lệnh và đường dẫn để biên dịch từ scss sang css.

sass --watch scss:css

scss3.png