Skip to content

Instantly share code, notes, and snippets.

@whizark
Last active August 29, 2015 14:14
Embed
What would you like to do?
CSS/Sass: Robust/Scalable Layered CSS Architecture #sass #css
<div class="app">
<!--
An element should know only its own child elements,
child elements should not know the parent element.
(at least, in HTML)
Therefore, well-structured element has ONLY 1-2 class(es).
-->
<div class="app--note note">
<ul class="note--list list">
<li class="list--li li">Item</li>
</ul>
</div>
</div>
<!-- Anti pattern -->
<div class="app">
<div class="app--note">
<!-- .app knows too many things. -->
<ul class="app--note--list">
<!-- .app--note knows too many things. -->
<li class="app--note--list--li">Item</li>
</ul>
</div>
</div>
<!--
Note: `--` in HTML comment is invalid.
This is just an example.
-->
// ----
// Sass (v3.4.9)
// Compass (v1.0.1)
// ----
// CSS/Sass: Robust/Scalable Layered CSS Architecture
//
// http://twitter.com/whizark
//
// Other ideas
// https://github.com/whizark/xass#ideas
/* =============================================
1. Element Layer
2. Object Layer (IS-A)
3. Component Layer (HAS-A)
4. Application Layer
============================================ */
// CSS is an inheritance-oriented language,
// so there are some issues also in this example.
//
// Using Mixin, Delegation with pre/post-processor such as Sass,
// it would be more better.
/* ===============================================
1. Element Layer
Styles for SINGLE element with Type selector
=============================================== */
// Element type (li)
li { /* defines generic li styles */ }
// Element type (ul)
ul { /* defines generic ul styles */ }
/* ================================================
2. Object Layer (IS-A)
Styles for SINGLE element with Class selector
================================================ */
// .li is li element.
.li { /* overrides li styles */}
// .list-item is li element.
.list { /* overrides ul styles */ }
// These are similar with property/method chaining.
// e.g. (pseudo-code)
// var li = new Li(); // element: .li
// li.style = { /* styles */ }; // styles : .li
//
// var list = new Ul(); // element: .list
// list.style = { /* styles */ }; // styles : .li
// other objects ...
// ANTI PATTERN:
// Do not use BEM-like syntax for a variant (`element--modifier`):
// .li--featured { /* variant styles of .li */ }
//
// Defines new name for a variant of object:
// .featured-li { /* variant styles of .li */ }
/* ====================================================
3. Component Layer (HAS-A)
Styles for Aggregation/Composition of elements.
Styles for Aggregation/Composition of components.
EVERYTHING CAN BE REPRESENTED AS COMPONENT.
==================================================== */
// Note:
// I use `--` as a class name separator to represent child element
// and `--` just measn *has* .
// This is similar with BEM's Element syntax (`block__element`).
// .list has .li
.list { /* overrides .list styles */ }
.list--li { /* overrides .li styles */ }
// These are similar with property/method chaining.
// e.g. (pseudo-code)
// list.li = li; // element: .list--li
// list.style = { /* styles */ }; // styles : .list
// list.li.style = { /* styles */ }; // styles : .list--li
// Nesting compoenent;
// Defines new class name for only its own child elements.
.note { /* defines .note styles */ }
.note--list { /* overrides .list styles */ }
.note--list .list--li { /* overrides .list--li styles */ }
// These are similar with property/method chaining.
// e.g. (pseudo-code)
// var note = new Note(); // element: .note
//
// note.list = list; // element: .note--list
// note.style = { /* styles */ }; // styles : .note
// note.list.style = { /* styles */ }; // styles : .note--list
// note.list.li.style = { /* styles */ }; // styles : .note--list .list--li
/* ========================================================
4. Application Layer
Context-specific style, Project-specific style etc.
======================================================== */
// Application-level element/context.
// THIS IS ALSO A COMPONENT.
.app { /* defines .app styles */ }
.app--note .note--list .list--li {
/* overrides .list--li styles */
}
// These are similar with property/method chaining.
// e.g. (pseudo-code)
// var app = new App(); // element: .app
//
// note.note = note; // element: .app--note
//
// styles: .spp-note .note--list .list--li
// app.note.list.li.style = { /* styles */ };
/* =============================================
1. Element Layer
2. Object Layer (IS-A)
3. Component Layer (HAS-A)
4. Application Layer
============================================ */
/* ===============================================
1. Element Layer
Styles for SINGLE element with Type selector
=============================================== */
li {
/* defines generic li styles */
}
ul {
/* defines generic ul styles */
}
/* ================================================
2. Object Layer (IS-A)
Styles for SINGLE element with Class selector
================================================ */
.li {
/* overrides li styles */
}
.list {
/* overrides ul styles */
}
/* ====================================================
3. Component Layer (HAS-A)
Styles for Aggregation/Composition of elements.
Styles for Aggregation/Composition of components.
EVERYTHING CAN BE REPRESENTED AS COMPONENT.
==================================================== */
.list {
/* overrides .list styles */
}
.list--li {
/* overrides .li styles */
}
.note {
/* defines .note styles */
}
.note--list {
/* overrides .list styles */
}
.note--list .list--li {
/* overrides .list--li styles */
}
/* ========================================================
4. Application Layer
Context-specific style, Project-specific style etc.
======================================================== */
.app {
/* defines .app styles */
}
.app--note .note--list .list--li {
/* overrides .list--li styles */
}
<div class="app">
<!--
An element should know only its own child elements,
child elements should not know the parent element.
(at least, in HTML)
Therefore, well-structured element has ONLY 1-2 class(es).
-->
<div class="app--note note">
<ul class="note--list list">
<li class="list--li li">Item</li>
</ul>
</div>
</div>
<!-- Anti pattern -->
<div class="app">
<div class="app--note">
<!-- .app knows too many things. -->
<ul class="app--note--list">
<!-- .app--note knows too many things. -->
<li class="app--note--list--li">Item</li>
</ul>
</div>
</div>
<!--
Note: `--` in HTML comment is invalid.
This is just an example.
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment