Kiến trúc OOCSS / BEM / SMACSS


8

Tôi đã làm việc thông qua bài viết này để tổ chức mã mặt trước của mình. Nó tham khảo các bài viết về BEM / SMACSS, lần lượt tham khảo các bài viết khác.

Tôi thực sự đang cố gắng để hiểu các thực tiễn tốt nhất là gì ... Tôi có một vài ngày để đưa ra "tiêu chuẩn" này, và sau đó phải đốt cháy một dự án dòng thời gian có mức độ ưu tiên cao / khả năng hiển thị cao / giới hạn. Như vậy, tôi muốn đảm bảo rằng tôi bắt đầu với một nền tảng sẽ mở rộng như ứng dụng của tôi.

Đưa ra một thành phần có tên segment... Tôi đang tạo các trang sẽ có ~ 10 segmentsmỗi trang. Mỗi người segmentsẽ chia sẻ cùng một lớp cơ sở. Tuy nhiên, nhất định segmentssẽ có sửa đổi trên chúng (màu nền khác nhau). Hơn nữa, các phần tử trong mỗi khối (theo cách tiếp cận BEM) cũng sẽ có các sửa đổi. Để chứng minh, đây là một triển khai đơn giản (chỉ có một yếu tố duy nhất arrow, trong khi trang web đầy đủ của tôi sẽ có 4-5 yếu tố trong mỗi segment):

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow--orange {
    @extend .segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--white {
    @extend .segment__arrow;
    background-image: url('/images/arrow_white.png');
}

Vì vậy, đây là cách tiếp cận đơn lớp:

<div class="segment__arrow--white"> ... </div>

Ngoài ra, tôi có thể đi theo cách tiếp cận đa lớp:

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow--orange {
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--white {
    background-image: url('/images/arrow_white.png');
}

Nơi đánh dấu của tôi sẽ là:

<div class="segment__arrow segment__arrow--white"> ... </div>

Thứ ba, tôi có thể làm:

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow.orange {
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow.white {
    background-image: url('/images/arrow_white.png');
}

Và sau đó lớp def của tôi sẽ là

<div class="segment__arrow orange"> ... </div>

Có lẽ thậm chí đặt tên màu cam với một cái gì đó như sa_orangeđể tránh các bộ chọn lỏng lẻo.

Kết quả cuối cùng mà tôi đang tìm kiếm là ít mã hơn / dễ bảo trì hơn (có thể loại trừ cách tiếp cận lớp đơn (tùy chọn 1), như được mô tả trong bài viết tuyệt vời này về kiến ​​trúc có thể mở rộng. Cách tiếp cận đa lớp (tùy chọn 2) dẫn đến rất nhiều chi tiết (đặc biệt là trong HTML của tôi), nhưng cực kỳ rõ ràng. Thứ ba sử dụng cách tiếp cận đa lớp, nhưng không sử dụng các công cụ sửa đổi được đặt tên (như .seribution__arrow), do đó ít dài dòng hơn (nhưng cũng ít rõ ràng hơn & cao hơn tiềm năng va chạm).

Có ai có kinh nghiệm trong thế giới thực với công cụ này có bất kỳ phản hồi nào về cách tốt nhất để tiếp cận điều này không?


Khớp nối các bộ sửa đổi từ các yếu tố đi ngược lại các nguyên tắc này, phải không? .orangekhông có ý nghĩa như một sửa đổi một mình. Tôi không thấy một vấn đề lớn trong việc sử dụng .segment__arrow--orangecùng với phương pháp đa kính của bạn. Tất nhiên trong các dự án lớn hơn, HTML của bạn có thể mất kiểm soát một chút (rất nhiều lớp).
kleinfreund

Đi nghỉ mát. Cảm ơn vì sự trả lời. Vâng, đó là lý do tại sao tôi đã quan tâm đến lựa chọn thứ ba. Bạn nói đúng, nó đi ngược lại các nguyên tắc này, nhưng như một quy mô dự án, tôi đang tưởng tượng một lớp = "phân đoạn _arrow phân đoạn bắt đầu nhận được một chút mã cho tôi ...
Scott Silvi

Thật. Không nên lái toàn bộ xe buýt BEM này quá xa. Không phải tất cả mọi thứ cần phải được BEMified.
kleinfreund

Câu trả lời:


8

Trong một thời gian dài, tôi đã sử dụng và đề xuất cách tiếp cận đa lớp rõ ràng (ví dụ thứ hai) vì nó là phổ biến nhất, có thể duy trì và kết hợp. Ở đây tôi sẽ cố gắng để hỗ trợ yêu cầu này.

Lớp đơn

Cách tiếp cận này có một vấn đề lớn khi có hai hoặc nhiều loại sửa đổi. Ví dụ: một nút. Với các sửa đổi nhỏ , lớn , lớn về kích thước và chính , thành công , thông tincảnh báo cho "màu". Ngoài các lớp 7 (= 3 + 4) thông thường, người ta cũng phải tạo tất cả 12 kết hợp:

.button--small--primary
.button--small--success
.button--small--info

Cho đến nay một chút bất tiện nhưng không phải là một thảm họa.

Một phiền toái khác - một vấn đề lớn hơn - là thứ tự chính xác "kích thước trước, màu thứ hai" phải được sử dụng và do đó được ghi nhớ (và được ghi lại rõ ràng).

Điều tồi tệ nhất là khi JavaScript có liên quan. Bạn muốn thay đổi "màu" của nút này nhưng vẫn giữ kích thước hiện tại? Phân tích thuộc tính lớp! Bạn muốn loại bỏ các sửa đổi thành công ? Phân tích thuộc tính lớp!

Đếm, ví dụ Bootstrap có 7 "màu", 4 kích cỡ và trạng thái hoạt động / tắt; trong đó các lớp 119 (= 13 + [7 * 4 + 7 * 2 + 4 * 2] + 7 * 4 * 2) phải được khai báo để duy trì cách tiếp cận lớp đơn! Đó là vấn đề lớn.

Nhiều lớp rõ ràng sẽ chỉ cần 13 lớp (một lớp cho mỗi sửa đổi). Thứ tự sẽ là tùy ý. Cuối cùng, việc thêm, xóa và thay đổi một cái trong khi bảo tồn những cái khác trong jQuery sẽ giống như:

$('#login-button').removeClass('button--primary').addClass('button--success');

Lối tắt đa lớp

Thứ nhất, như bạn đã đề cập, có khả năng xảy ra va chạm - một điều xấu.

Thứ hai, điều đó cũng có nghĩa là, nó .segment__arrow.orangecó tính đặc hiệu cao hơn và không thể được ghi đè bằng một bộ chọn lớp duy nhất. Điều này thường xảy ra khi một phần tử không chỉ là một nút lớn mà còn là một nút đăng nhập . Mã của nó sẽ trông như sau:

<a href="#" class="button large primary login__button">Log in</a>

Người ta có thể muốn có một phần đệm bên trái và bên phải lớn hơn trên nút đăng nhập nhưng vẫn giữ được chiều cao lớn . Điều này sẽ dẫn đến ngày càng nhiều bộ chọn cụ thể sẽ đưa chúng ta đến địa ngục đặc thù - một nơi OOCSS sẽ cứu chúng ta khỏi.

Rõ ràng điều này sẽ không xảy ra trong cách tiếp cận đa lớp rõ ràng .

Đa lớp

Vấn đề duy nhất (theo như tôi biết) về điều này là có một vài lớp đôi khi khá dài trong đánh dấu. Tôi thừa nhận điều này.

Hãy để tôi lưu ý rằng đây chỉ là vấn đề thị hiếu của nhà phát triển vì nó có ảnh hưởng không đáng kể (hoàn toàn không) đối với hiệu suất. Việc nén tiêu chuẩn sẽ đảm nhận việc này.

Điều đó đang được nói, sử dụng một IDE tốt sẽ giúp viết những điều này (vâng, tôi biết, nó vẫn sẽ trông hơi vô lý).

Một mặt, tôi sẽ nói, nhìn thấy các lớp dài như vậy buộc người ta phải suy nghĩ nhiều hơn về cấu trúc; ví dụ: liệu có tốt hơn không khi giới thiệu một thành phần mới (có thể tái sử dụng) thay vì lồng nó vào một thứ khác.


0

Tôi đang tranh luận với các đồng đội của mình về vấn đề Đơn / Đa lớp này ngay bây giờ

Dưới đây là một số quan điểm cá nhân của tôi dựa trên thực tiễn tốt nhất

Thực hành tốt nhất

  • html khai báo các phần tử
  • Điều khiển CSS kết xuất

Lớp đơn luôn tuân theo Thực tiễn tốt nhất

với các lợi ích duy trì thêm, với tên tốt nó có thể đạt được

  • thay đổi kiểu không yêu cầu cập nhật html * (xem bản demo)

  • kiểu khóa trong html (bạn sẽ có kiểu đúng hoặc không có gì)

Bản giới thiệu

@mixin segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}

.segment__arrow--type1 {
    @include segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--type2 {
    @include segment__arrow;
    background-image: url('/images/arrow_white.png');
}

@mixin bao gồm tốt hơn @extend

  1. có quyền kiểm soát thứ tự mã trong css cuối cùng
  2. kích thước nhỏ hơn trong phiên bản gzip

và giống như @extend, nó có thể được sử dụng lại và có thể thay thế nhiều lớp trong HTML

với @mixin, bạn sẽ có thêm sự linh hoạt

@mixin segment__arrow--type1 {
    @include segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
@mixin segment__arrow--type2 {
    @include segment__arrow;
    background-image: url('/images/arrow_white.png');
}
.segment__margic-arrow {
    @include screen(mobile) {
       @include segment__arrow--type1
    }
    @include screen(desktop) {
       @include segment__arrow--type2
    }
}

Để sử dụng javascript

quy tắc nhà nước của smacss

Hạn chế của lớp đơn

một và chỉ một:

kích thước tệp CSS lớn hơn, NHƯNG bạn luôn có thể dễ dàng tối ưu hóa CSS dựa trên các phần hoặc thành phần trang web trong trang

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.