Sử dụng @include so với @extend trong Sass?


93

Trong Sass, tôi không thể phân biệt được sự khác biệt giữa việc sử dụng @includevới một mixin và sử dụng @extendvới một lớp giữ chỗ. Chúng không giống nhau sao?


2
bao gồm không cung cấp cho bạn mở rộng lớp cơ sở, nó chỉ thêm các tùy chọn. Chỉ khuyên bạn đọc sass-lang.com/docs/yardoc/…sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
CodeGroover

1
Ngoài ra, @CodeGroover, không phải là một bình luận hữu ích, có thể bạn đã hiểu sai câu hỏi. Đọc sách này cung cấp thông tin hữu ích hơn: gist.github.com/antsa/970172
temporary_user_name

4
Bất cứ khi nào bạn sử dụng một mixin không có tham số, một phần mở rộng sẽ hiệu quả hơn. Courtesy Chris
Abhijeet

Câu trả lời:


87

Phần mở rộng không cho phép tùy chỉnh, nhưng chúng tạo ra CSS rất hiệu quả.

%button
  background-color: lightgrey
  &:hover, &:active
    background-color: white

a
  @extend %button

button
  @extend %button

Kết quả:

a, button {
  background-color: lightgrey;
}
a:hover, button:hover, a:active, button:active {
  background-color: white;
}

Với mixin, bạn nhận được CSS trùng lặp, nhưng bạn có thể sử dụng các đối số để sửa đổi kết quả cho mỗi lần sử dụng.

=button($main-color: lightgrey, $active-color: white)
  background-color: $main-color
  border: 1px solid black
  border-radius: 0.2em

  &:hover, &:active
    background-color: $active-color

a
  +button

button
  +button(pink, red)

Kết quả trong:

a {
  background-color: lightgrey;
  border: 1px solid black;
  border-radius: 0.2em;
}
a:hover, a:active {
  background-color: white;
}

button {
  background-color: pink;
  border: 1px solid black;
  border-radius: 0.2em;
}
button:hover, button:active {
  background-color: red;
}

Vui lòng làm theo bộ ví dụ mã liên tiếp này để xem cách bạn có thể làm cho mã của mình sạch hơn và dễ bảo trì hơn bằng cách sử dụng các mã mở rộng và mixin một cách hiệu quả: http://thecodingdesigner.com/posts/balancing

Lưu ý rằng SASS rất tiếc không cho phép sử dụng các truy vấn phương tiện mở rộng bên trong (và ví dụ tương ứng từ liên kết trên là sai). Trong trường hợp bạn cần mở rộng dựa trên các truy vấn phương tiện, hãy sử dụng mixin:

=active
  display: block
  background-color: pink

%active
  +active

#main-menu
  @extend %active // Active by default

#secondary-menu
  @media (min-width: 20em)
    +active // Active only on wide screens

Kết quả:

#main-menu {
  display: block;
  background-color: pink;
}

@media (min-width: 20em) {
  #secondary-menu {
    display: block;
    background-color: pink;
  }
}

Việc trùng lặp là không thể tránh khỏi trong trường hợp này, nhưng bạn không nên quan tâm quá nhiều về nó vì tính năng nén gzip của máy chủ web sẽ đảm nhận việc đó.

PS Lưu ý rằng bạn có thể khai báo các lớp trình giữ chỗ trong các truy vấn phương tiện.

Cập nhật 2014-12-28 : Các tiện ích mở rộng tạo ra CSS nhỏ gọn hơn so với các mixin , nhưng lợi ích này bị giảm đi khi CSS được nén. Nếu máy chủ của bạn phục vụ CSS được nén (thực sự nên làm!), Thì việc mở rộng hầu như không mang lại lợi ích gì cho bạn. Vì vậy, bạn luôn có thể sử dụng mixin ! Thông tin thêm về điều này tại đây: http://www.sitepoint.com/sass-extend-nobody-told-you/


2
Tôi không nghĩ rằng điều đó không hoàn toàn chính xác ... bạn có thể tùy chỉnh @extendsbằng cách ghi đè phần mở rộng. Tất nhiên bạn không thể vượt qua trong các đối số, nhưng đó có phải là sự khác biệt duy nhất? Trong trường hợp đó, @extendchỉ là @mixinkhông có đối số? Tôi vẫn không thấy lợi thế hay sự khác biệt.
temporary_user_name

2
Dưới đây là một vài quirks khác ... stackoverflow.com/questions/30744625/...
Toni Leigh

Tôi sẽ cẩn thận giải thích khía cạnh "hầu như không mang lại lợi ích cho bạn" của đoạn cuối cùng, ở đó. Nén Gzip là một bộ mã hóa Huffman dựa trên từ điển, vì vậy nếu sự lặp lại xảy ra cách xa nhau, văn bản sẽ không có trong từ điển và tỷ lệ nén sẽ bị ảnh hưởng. Tôi vẫn luôn thích @extendở những nơi có thể, vì điều này sẽ tạo ra CSS nhỏ gọn hơn, mà vẫn sẽ nén khá tốt (xét cho cùng thì đó là văn bản ASCII).
amcgregor,

@amcgregor, sự khác biệt là không đáng kể.
Andrey Mikhaylov - lolmaus,

@ AndreyMikhaylov-lolmaus Tôi đồng ý! Tôi hy vọng sự khác biệt về cơ bản là không thể đo lường qua dây, bất kể lựa chọn cho bất kỳ thứ gì lên đến megabyte hoặc lâu hơn của CSS được tạo, ngoài thực tế là kết quả cuối cùng không nén trong bộ nhớ sẽ nhỏ gọn hơn khi sử dụng @extend. Đây là một sự tối ưu hóa vi mô dường như dựa trên trực giác và cảm giác của ruột, chứ không phải là sự hiểu biết về cách thức hoạt động của sơ đồ nén liên quan. (Ngoài ra: nó bỏ qua các chi phí đáng kể theo yêu cầu gzip chuyển mã hóa; nén không phải là miễn phí;!)
amcgregor

18

Một cách tiếp cận tốt là sử dụng cả hai - tạo một mixin cho phép bạn tùy chỉnh nhiều và sau đó mở rộng cho các cấu hình phổ biến của mixin đó. Ví dụ (Cú pháp SCSS):

@mixin my-button($size: 15, $color: red) {
  @include inline-block;
  @include border-radius(5px);
  font-size: $size + px;
  background-color: $color;
}
%button {
  @include my-button;
}
%alt-button {
  @include my-button(15, green);
}
%big-button {
  @include my-button(25);
}

Điều này giúp bạn không phải gọi đi gọi lại my-button mixin. Điều đó cũng có nghĩa là bạn không phải nhớ các cài đặt cho các nút thông thường nhưng bạn vẫn có khả năng tạo một nút siêu độc đáo, một lần nếu bạn chọn.

Tôi lấy ví dụ này từ một bài blog tôi đã viết cách đây không lâu. Hi vọng điêu nay co ich.


12

Theo quan điểm của tôi, mở rộng là điều ác thuần túy và nên tránh. Đây là lý do tại sao:

đưa ra scss:

%mystyle {color: blue;}
.mystyle-class {@extend %mystyle}
//basically anything not understood by target browser (such as :last-child in IE8):
::-webkit-input-placeholder {@extend %mystyle}

Css sau sẽ được tạo:

.mystyle-class, ::-webkit-input-placeholder { //invalid in non-webkit browsers
  color: blue;
}

Khi một trình duyệt không hiểu một bộ chọn, nó sẽ làm mất hiệu lực của toàn bộ dòng bộ chọn. Điều này có nghĩa là lớp mystyle quý giá của bạn không còn màu xanh lam nữa (đối với nhiều trình duyệt). Ý nghĩa thực sự của điều này là gì? Nếu bất kỳ lúc nào bạn sử dụng tiện ích mở rộng mà trình duyệt có thể không hiểu bộ chọn thì mọi cách sử dụng tiện ích mở rộng khác sẽ bị vô hiệu. Hành vi này cũng cho phép cái ác làm tổ:

%mystyle {color: blue;}
@mixin mystyle-mixin {@extend %mystyle; height: 0;}
::-webkit-input-placeholder {@include mystyle-mixin} 
//you thought nesting in a mixin would make it safe?
.mystyle-class {@extend %mystyle;}

Kết quả:

::-webkit-input-placeholder, .mystyle-class { //invalid in non-webkit browsers
  color: blue;
}

::-webkit-input-placeholder {
  height: 0;
}

Tl; dr: @extend hoàn toàn ổn miễn là bạn không bao giờ sử dụng nó với bất kỳ bộ chọn cụ thể nào của trình duyệt. Nếu bạn làm như vậy, nó sẽ đột nhiên phá bỏ các phong cách bất cứ nơi nào bạn đã sử dụng nó. Thay vào đó, hãy thử dựa vào mixin!


4
Ghi chú thú vị
simhumileco

4

Sử dụng mixin nếu nó chấp nhận một tham số, nơi đầu ra đã biên dịch sẽ thay đổi tùy thuộc vào những gì bạn truyền vào nó.

@include opacity(0.1);

Sử dụng mở rộng (với trình giữ chỗ) cho bất kỳ khối kiểu tĩnh nào có thể lặp lại.

color: blue;
font-weight: bold;
font-size: 2em;

0

Tôi hoàn toàn đồng ý với câu trả lời trước của d4nyll. Có một văn bản về tùy chọn mở rộng và trong khi tôi nghiên cứu chủ đề này, tôi đã tìm thấy rất nhiều phàn nàn về mở rộng, vì vậy hãy ghi nhớ điều đó và nếu có khả năng sử dụng mixin thay vì mở rộng, chỉ cần bỏ qua mở rộng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.