Last active
March 19, 2022 01:18
-
-
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…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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%); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.