Blogブログ

Scroll

FLOCSS là gì? Cách đặt tên và cấu trúc thư mục theo FLOCSS

suffix_ngothikimthoa

Xin chào, mình là T đến từ team WEB!

Công ty mình hiện tại đang quản lý CSS theo tiêu chuẩn của FLOCSS. Do đó, mình đã tìm hiểu và muốn chia sẻ những gì mình đã tìm hiểu đến với mọi người. Hy vọng bài viết của mình sẽ giúp ích được cho các bạn trên con đường tổ chức code hiệu quả hơn nhé!


FLOCSS là gì?

FLOCSS là từ viết tắt của "Foundation Layout Object CSS", là sự kết hợp ưu điểm của OOCSS, BEM, SMACSS và SuitCSS. FLOCSS cũng nhận ảnh hưởng lớn từ cấu tạo layer của MCSS.


Cấu trúc thư mục

FLOCSS được cấu tạo bởi 3 layer: Foundation, Layout, Object và các layer con của Object.

FLOCSS

Foundation

Thư mục quản lý default style cho toàn trang web

reset.scss

Định nghĩa css dùng để reset style mặc định của browser
Ví dụ:
box-sizing: border-box;
margin: 0;

base.scss

Định nghĩa style nền tảng cơ bản cho thiết kế
  • Định nghĩa style cơ bản bên trong thẻ
  • Thêm reset không được định nghĩa ở reset.scss
  • Thêm size, font family cơ bản cho chữ

mixin.scss

Quản lý mixin được sử dụng cho toàn bộ trang web

variable.scss

Quản lý biến được sử dụng cho toàn bộ trang web


Layout

Quản lý style liên quan đến layout, cấu tạo nên các trang, như header, main, container, footer...
  • Chỉ định nghĩa layout như vị trí
  • Không định nghĩa style cho các thẻ con
  • Thiết kế bên trong layout sẽ được định nghĩa tại Project
Ví dụ về l-header, p-header:
// ページ全体からみたレイアウトに対するスタイル
.l-header {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 100;
	width: 100%;
}
// ヘッダーというパーツのスタイル
.p-header {
	display: flex;
	&__logo {
		width: 100px;
		height: 50px;
		...
	}
	...
}

l-wrapper.scss

Nằm ngay bên dưới thẻ body, bao quanh header, main, footer

l-header.scss

Định nghĩa style vị trí của header

(l-nav.scss)

Tuỳ vào cấu trúc màn hình mà nav trở thành .p-nav nằm bên trong .l-header, hoặc trở thành Layout nếu nằm trong phần khung .l- dễ làm việc hơn

l-main.scss

Định nghĩa style chung khu vực content của main
  • Ví dụ như canh lề hay làm cho cân đối phần fixed của header
  • Chỉ định nghĩa phần lề chung trên dưới trái phải

l-container.scss

Chỉ định chiều rộng content bên trong khu vực main của trang web...

l-footer.scss

Đinh nghĩa style vị trí của footer

Object

Định nghĩa các part và block sử dụng lặp đi lặp lại ở nhiều nơi
  • Các part nhỏ sẽ được định nghĩa bên trong Component
  • Các block hay các khu vực lớn kết hợp từ các Component sẽ nằm trong Project

Component

Định nghĩa các module nhỏ với tư cách là pattern có thể tái sử dụng ở nhiều nơi
  • Không định nghĩa phần lề như margin. Sử dụng như part
  • Nên định nghĩa chức năng tối thiểu và cần tránh quy định các đặc điểm riêng về màu sắc, chiều rộng...
Ví dụ:
c-button.scss
c-label.scss
c-input.scss
...

Project

Quản lý các block và khu vực lớn được cấu tạo bởi các Component và các yếu tố khác
  • Sử dụng cả khi muốn chia nhỏ để quản lý cả các block không tái sử dụng
  • Khi muốn tập hợp các Component nhỏ sử dụng với tư cách là một Object
  • Khi quá lớn để định nghĩa là một Component
Ví dụ:
p-card.scss
p-first-view.scss
p-button-group.scss
...
Ví dụ về p-card.scss

Sự khác nhau giữa Component và Project

Component: các phần nhỏ
Project: tập hợp các Componet

Utility

Định nghĩa các class tiện ích để điều chỉnh một ít style khó hay không thích hợp để giải quyết bằng Modifier của Object Component hay Project
  • Tránh việc làm gia tăng các Object Component và Project một cách vô tận
  • Sử dụng trong trường hợp yếu tố quá nhỏ để định nghĩa làm Project, hay khi sử dụng bởi Component độc lập
  • Có vai trò định nghĩa khoảng cách với module liền kề như .u-mb10 { margin-bottom: 10px; } thay cho margin mà bản thân Object không được định nghĩa
  • Mang vai trò hỗ trợ
Ví dụ:
u-margin.scss
u-padding.scss
u-color.scss
u-text.scss
...

Quy tắc đặt tên

Sử dụng tiếp đầu ngữ (chữ cái đầu tiên) (prefix)


Đặt tiếp đầu ngữ bằng cách lấy ký tự đầu tiên của tên folder + dấu gạch ngang (-) để chỉ cần nhìn tên file cũng hiểu được, ví dụ: Layout thì là .l-, Component thì là .c- ... (Không kể trường hợp Foundation, do được dùng với mục đích reset và định nghĩa các giá trị nền tảng)
Ví dụ:
l-header.scss
l-footer.scss
c-button.scss
p-card.scss


Tên file = Tên class

Định nghĩa tên class là .l-header trong file l-header.scss


Không rút gọn tên file, tên class


Hạn chế rút gọn tên file, tên class để ai nhìn vào cũng có thể hiểu được

Áp dụng quy tắc đặt tên của MindBEMding

Sử dụng quy tắc phân chia thành Block, Element, Modifier là syntax của BEM system.
Tuy nhiên, FLOCSS không sử dụng syntax nguyên bản của BEM mà về cơ bản, hoàn toàn lấy ý tưởng từ MindBEMding

Block

  • Tên Object
  • Đặt tên để ai nhìn vào cũng có thể hiểu
Ví dụ: card sử dụng ở trang about sẽ là .p-about-card

Modifier

Sự khác nhau về màu sắc, size của Object sẽ được đặt tên bằng cách nối tên màu, tên size bằng hai dấu gạch ngang (--), như .Block-Modifier
Không được đặt thành .Block--Modifier--Modifier
Ví dụ .Block--Modifier

Element

Nối các Element bên trong Object bằng hai dấu gạch ngang dưới (__), như .Block__Element


--Modifier nối tiếp __Element?

Nếu không quy định chi tiết quy tắc khi nào sử dụng Modifier cho Element sẽ dễ bị vỡ bố cục, khó hiểu khi người khác nhìn vào
Ví dụ:
Khi có sự khác nhau về màu sắc tổng thể Object thì sẽ đặt là .p-car--green .p-card--green__header...
Khi có sự khác nhau về việc canh phải hay canh giữa element bên trong Object thì sẽ đặt là .p-card__label--center hay .p-card__label--right...
Modifer giống nhau trong toàn thể Object
Modifier chỉ element bên trong Object
Có thể tạo nhiều Object pattern bằng việc phân chia như trên

Tên class được tham chiếu, vận hành từ JavaScript

Tên class được tham chiều từ JavaScript
  • Đặt tiếp đầu ngữ js- để chỉ rõ việc được tham chiếu từ JavaScript, ví dụ: js-button
  • Xử lý js-button bằng JavaScript
Tên class được vận hành từ JavaScript
  • Đặt tiếp đầu ngữ -is
  • Xử ký thao tác .is-click bằng JavaScript
  • Không định nghĩa style bên trong .is-click mà định nghĩa style bên trong .c-button.is-click
    (Tránh việc đụng với style bên trong .is-click đối với Object khác)

Chú ý việc cascading

Cascading có nghĩa là khi có nhiều khai báo đối với property bên trong element, sẽ quyết định mối quan hệ về mức độ ưu tiên của khai báo, và chỉ 1 khai báo sẽ trở nên có hiệu lực
  • Không được cascading sử dụng selector lấy Object khác làm parent
  • Điều đó có nghĩa là không được định nghĩa style của một Project bên trong một Project parent khác
Ví dụ về trường hợp không phù hợp:
// Component
.c-button {
	...
}
.c-dialog > .c-button {
/*c-dialogを親に持つc-buttonのみスタイルを指定しまっています → だめ*/
	...
}
// Project
.p-comments {
	...
}
.p-articles > .p-comments {
/*p-articlesを親に持つp-commentsのみスタイルを指定しまっています → だめ*/
	...
}

Lý do là,
Không phải chỉ tồn tại bên trong một module đặc định mà phải có thể tái sử dụng độc lập với tư cách là một module. Việc khai báo hỗn độn sẽ dẫn đến việc người khác không dự đoán được.
Có nghĩa là,
  • Part sử dụng cho nhiều mục đích (ví dụ như c-button...) sẽ trở nên chỉ có thể phát huy tác dụng ở trong Component khác
  • Việc tồn tại hỗn độn sẽ làm cho người khác rơi vào lúng túng không biết cái nào mới là style thật sự của c-button, c-button vậy mà khi ở trong element này thì lại khác, muốn sử dụng c-button này mà không thể...


Project có thể thay đổi Component

Trong trường hợp tập hợp các Component quản lý bằng Project với tư cách là Object, việc chỉnh sửa canh lề... khi đã được định nghĩa thì có thể tiến hành bằng cách viết song song __Element của Project với Component có parent là Project
Ví dụ trường hợp không phù hợp:
Khi viết như thế này thì khi muốn thay đổi lề của c-media__image không được viết như sau:
// c-media.scss
.c-media__image {
	float: left;
	margin-left: 10px;
}
// p-profile.scss
.p-profile > .c-media__image { // ここがだめ
	float: right;
	margin-left: 0;
	margin-right: 10px;
}

Lý do là vì nếu chỉ có c-media__image bên trong p-profile sẽ khó để hiểu
Do đó, hãy đảm bảo đặt tên class thành Element của p-profile và viết song song với c-media__image
Ví dụ phù hợp:
// c-media.scss
.c-media__image {
	float: left;
	margin-left: 10px;
}
// p-profile.scss
.p-profile__avatar {
	float: right;
	margin-left: 0;
	margin-right: 10px;
}

Nếu có thể giải quyết bằng việc tăng Modifier (pattern) của Component thì hãy giải quyết nó bằng cách đó
Tuy nhiên, giả định có từ 2 Modifier (pattern) trở lên

Extend trong SASS

Để tạo Modifier cho .c-button, cần phải thêm class Modifier vào một tag như ví dụ sau đây:
Tuy nhiên, bằng việc kế thừa .c-button bằng extend của SASS, có thể chỉ cần ghi class .c-button-blue
.c-button {
	...
}
.c-button--blue {
	@extend .c-button;
	background-color: blue;
}

Như vậy không cần phải ghi class c-button nữa
Tránh được việc tăng class

Nguồn:
https://qiita.com/super-mana-chan/items/644c6827be954c8db2c0
https://github.com/hiloki/flocss

  1. TOP
  2. お知らせ
  3. ブログ
  4. FLOCSS là gì? Cách đặt tên và cấu trúc thư mục theo FLOCSS

PAGE TOP