Skip to content

Instantly share code, notes, and snippets.

@mdo
Last active March 19, 2022 01:18
Show Gist options
  • Save mdo/c0db745a0db31df70e08 to your computer and use it in GitHub Desktop.
Save mdo/c0db745a0db31df70e08 to your computer and use it in GitHub Desktop.
You can create the same set of components with HTML and (S)CSS in a handful of ways. Here's how the same set of buttons looks with base and modifier classes, as well as extends and placeholders. The goal is to measure the output—the total number of selectors and declarations. Personally, I consider fewest selectors to be more optimal (for you an…
// Original
//
// Markup:
//
// <button class="button">Button</button>
// <button class="button button-primary">Button</button>
// <button class="button button-danger">Button</button>
//
// Total selectors: 6
// Total declarations: 19
.button {
display: inline-block;
padding: .5rem 1rem;
font-size: 1rem;
color: #333;
background-color: #eee;
border: 1px solid darken(#eee, 10%);
&:hover {
cursor: pointer;
background-color: darken(#eee, 10%);
border-color: darken(#eee, 15%);
}
}
.button-primary {
color: #fff;
background-color: #0074d9;
border-color: darken(#0074d9, 10%);
&:hover {
background-color: darken(#0074d9, 10%);
border-color: darken(#0074d9, 15%);
}
}
.button-danger {
color: #fff;
background-color: #ff4136;
border-color: darken(#ff4136, 10%);
&:hover {
background-color: darken(#ff4136, 10%);
border-color: darken(#ff4136, 15%);
}
}
// Base class
//
// Markup:
//
// <button class="button button-default">Button</button>
// <button class="button button-primary">Button</button>
// <button class="button button-danger">Button</button>
//
// Total selectors: 8
// Total declarations: 20
.button {
display: inline-block;
padding: .5rem 1rem;
font-size: 1rem;
border: .1rem solid;
&:hover {
cursor: pointer;
}
}
.button-default {
color: #333;
background-color: #f5f5f5;
border-color: darken(#f5f5f5, 10%);
&:hover {
background-color: darken(#eee, 10%);
border-color: darken(#eee, 15%);
}
}
.button-primary {
color: #fff;
background-color: #0074d9;
border-color: darken(#0074d9, 10%);
&:hover {
background-color: darken(#0074d9, 10%);
border-color: darken(#0074d9, 15%);
}
}
.button-danger {
color: #fff;
background-color: #ff4136;
border-color: darken(#ff4136, 10%);
&:hover {
background-color: darken(#ff4136, 10%);
border-color: darken(#ff4136, 15%);
}
}
// Extend
//
// Markup:
//
// <button class="button-default">Button</button>
// <button class="button-primary">Button</button>
// <button class="button-danger">Button</button>
//
// Total selectors: 14
// Total declarations: 20
.button {
display: inline-block;
padding: .5rem 1rem;
font-size: 1rem;
border: .1rem solid;
&:hover {
cursor: pointer;
}
}
.button-default {
@extend .button;
color: #333;
background-color: #f5f5f5;
border-color: darken(#f5f5f5, 10%);
&:hover {
background-color: darken(#eee, 10%);
border-color: darken(#eee, 15%);
}
}
.button-primary {
@extend .button;
color: #fff;
background-color: #0074d9;
border-color: darken(#0074d9, 10%);
&:hover {
background-color: darken(#0074d9, 10%);
border-color: darken(#0074d9, 15%);
}
}
.button-danger {
@extend .button;
color: #fff;
background-color: #ff4136;
border-color: darken(#ff4136, 10%);
&:hover {
background-color: darken(#ff4136, 10%);
border-color: darken(#ff4136, 15%);
}
// }
// Extend w/ placeholder
//
// Markup:
//
// <button class="button-default">Button</button>
// <button class="button-primary">Button</button>
// <button class="button-danger">Button</button>
//
// Total selectors: 12
// Total declarations: 20
%button {
display: inline-block;
padding: .5rem 1rem;
font-size: 1rem;
border: .1rem solid;
&:hover {
cursor: pointer;
}
}
.button-default {
@extend %button;
color: #333;
background-color: #f5f5f5;
border-color: darken(#f5f5f5, 10%);
&:hover {
background-color: darken(#eee, 10%);
border-color: darken(#eee, 15%);
}
}
.button-primary {
@extend %button;
color: #fff;
background-color: #0074d9;
border-color: darken(#0074d9, 10%);
&:hover {
background-color: darken(#0074d9, 10%);
border-color: darken(#0074d9, 15%);
}
}
.button-danger {
@extend %button;
color: #fff;
background-color: #ff4136;
border-color: darken(#ff4136, 10%);
&:hover {
background-color: darken(#ff4136, 10%);
border-color: darken(#ff4136, 15%);
}
}
@mdo
Copy link
Author

mdo commented Feb 4, 2015

I'd recommend avoiding conflating relationships between components entirely. One class (or set of classes) should do one thing really well. That kind of cross pollination leads to often unexpected dependencies, lack of clarity around which component to use where, etc.

I see what you mean though, and that's what I want to point out—don't use @extend when it doesn't make sense to. In most cases, in so far as I've tried them, extends just lead to more trouble. I'd like to create some more tests to test that though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment