13. I asked them. And they said
it’s all about …
The whole ‘Cascading’ thing
The ‘Specificity’ thing
(see also: ‘the Cascading thing’)
Selector Chaos
(mostly re: Specificity & Cascading)
Layout
(old-school Layouts, that is…)
20. First Principles
be DRY - ‘Don’t Repeat Yourself’
be Maintainable - write for updates &
debugging
be Predictable - Don’t keep hacking what’s
broken (unless you have to)
Don’t ‘Optimize’ Prematurely
21. Strategic Rules For CSS
Name All The Things™
Stop Hoarding Classes
& Rationing Letters
Be a Lover, not a Fighter
Automate or Die
28. Love Display: Inline-Block
Supported Since IE8 !!!
Does what you expect
vertical-align: a feature, not a bug :-)
text-align: gets you left, right, or
center
29. Love Display: Inline-Block
(The whitespace thing *is* a bug.
Easy, transparent fix: zero-sized
fonts on the container.
Use @mixin !)
30. Display: Inline-Block (Coda)
Those deceptively-reasonable .clearfix
classes that don’t need extra HTML?
They need :after …
… which requires CSS 2.1 …
… which has display: inline-block
31. Bonus Confusing Layout Idol
To Consider Burning
Ems
(Browser scaling works great)
(In practice, people use a range of
assistive technologies, and very
rarely rely on custom stylesheets.)
36. “In God, we trust.
All others:
bring evidence.”
37. OK… Maintainability… How?
1. AUTOMATE (OR DIE)
2. “NAME ALL THE THINGS”… CLEARLY
3. USE ELEMENT SELECTORS ONLY FOR RESETS
4. STOP OVER-NESTING… OR MAYBE NESTING
*AT ALL*
5. AVOID UNNECESSARY COMPLEXITY
38. Maintainability… How?
1. AUTOMATE (OR DIE)
2. “NAME ALL THE THINGS”… CLEARLY
3. USE ELEMENT SELECTORS ONLY FOR RESETS
4. STOP OVER-NESTING… OR MAYBE NESTING
*AT ALL*
5. AVOID UNNECESSARY COMPLEXITY
39. AUTOMATION
Enough with the FUD. It’s easier than you think.
Just use a (pre-)compiler. Always. (See Yeoman for help.)
A new age is upon us.
There is literally not enough time in this session to detail
all the ways in which a compiler will make your CSS
better.
But here’s a few: you’ve heard about ‘variables’ and
‘mixins’, but not *why* you need them:
40. AUTOMATION Examples:
Human-Readable Colors
Stop working directly with color codes! Use human-readable
references like $brand-primary-highlight
or $ugly-greenish-blue.
Lighten, Darken, Opacify, Transparentize, using a single
original reference color. Make a whole chart w/:
color: $myRed
$redTwo: darken($myRed, 10%)
$redThree: darken($myRed, 20%)…
‘Theme’ a design with just a few variables, and @import
44. MOAR AUTOMATION
Browser prefixes suck. Use either @mixin’s… or Grunt!
Easy theming: take theme-specific variables & @mixin’s,
then @import your default rules, and voilà!
45. Maintainability… How?
1. AUTOMATE (OR DIE)
2. “NAME ALL THE THINGS”… CLEARLY
3. USE ELEMENT SELECTORS ONLY FOR RESETS
4. STOP OVER-NESTING… OR MAYBE NESTING
*AT ALL*
5. AVOID UNNECESSARY COMPLEXITY
46. Who was it who told us that this:
#nav-list li a {
… stuff…
}
… was a good idea? Instead of this:
.nav-list-link {
… same stuff …
}
… or better… this:
.main-header__nav-list__link {
… same stuff …
}
47. Stop Rationing Classes!
It’s as if we were afraid that classes were radioactive:
too many, too close together, and they’d go super-critical
Or as if they were contaminating our pristine HTML
We also like to feel clever. (Be afraid of that instinct.)
Classes are as efficient as it gets, speed-wise.
48. Use Clear, Descriptive Classes
It shouldn’t be necessary to hunt for things. Class names
should tell us where to expect to find things.
Sometimes, the hardest thing about using good names is
just inventing ones that make sense.
Use any system you like (BEM, OOCS, Suit), which is both
highly descriptive, and which helps you design good class
names.
(Remember they’re helpful patterns, not religious faiths.)
49. A Note on Namespacing
As a way of collecting a ‘module’ of related content or
functionality, namespacing is super-cool.
But it quickly goes fractal with automation.
Consider whether using detailed, descriptive class
names gets you what you were probably really after:
the avoidance of collisions.
(See the section on over-nesting.)
50. Maintainability… How?
1. AUTOMATE (OR DIE)
2. “NAME ALL THE THINGS”… CLEARLY
3. USE ELEMENT SELECTORS ONLY FOR RESETS
4. STOP OVER-NESTING… OR MAYBE NESTING
*AT ALL*
5. AVOID UNNECESSARY COMPLEXITY
51. About That Whole
‘Cascade’ Thing
No matter how much we explain it, the ‘back-end’ folks
will never understand why we would allow five different
user-created style declarations to apply to a single
element
They’re right: it’s not maintainable.
The “browser is designed that way” isn’t a good enough
reason.
We *can* do that, but we *shouldn’t*.
52. About That Whole
‘Cascade’ Thing
Element selectors are the number one reason we end up
fighting the cascade, and hoping that the Specificity
algorithm is on our side today.
You don’t need them.
One good use: resets and global styles, like:
a {
text-decoration: none;
color: red;
}
53. About That Whole
‘Cascade’ Thing
Use of !important is always a “code-smell”
Maybe use @extend or @include to create a narrower
class, rather than fight the existing one
“Be a lover, not a fighter”
54. Maintainability… How?
1. AUTOMATE (OR DIE)
2. “NAME ALL THE THINGS”… CLEARLY
3. USE ELEMENT SELECTORS ONLY FOR RESETS
4. STOP OVER-NESTING… OR MAYBE NESTING
*AT ALL*
5. AVOID UNNECESSARY COMPLEXITY
55. Descendant Selectors:
The Problems
General use of descendant selectors is anathema to real
specificity, and guarantees conflicts and overrides:
form label input
#login-form input .name-field
!
Descendant Selectors lock your content into a single
context, making them hard to re-use, or re-locate.
Plus, you can’t relocate other code into yours: ever try to
add a JQuery date-picker into code that’s styled with
descendant selectors?
56. Pre-Compilers Gone Wrong
body {
font-size: 12px;
#main-content: {
width: 400px;
height: 200px;
!
.left-nav {
width: 200px;
margin: 0 0 0 50px;
!
ul {
li {
display: block;
list-style-type: none;
… ∞ …
}}}}}
body #main .left-nav ul li …
5 selectors and counting,
where 1 would do it.
57. Descendant Selectors:
Performance
The most important thing you can know about selector
optimization is this: they’re evaluated right-to-left.
The most important piece of any selector is thus the last
piece, not the first. Which is pretty much the opposite of
what we usually do with descendant selectors:
#very-specific-id .semi-specific-class li a
The fact that we *can* nest and qualify selectors…
doesn’t mean that we *should*.
58. Nesting Without Stacking
A (pre-)compiler w/ BEM-like syntax gives us readability of
related styles, without descendant-selector headaches:
.main-content: {
&__left-nav {
&__item
}}}
compiles to:
.main-content {}
.main-content__left-nav {}
.main-content__left-nav__item {}
(If you don’t like those syntaxes, at least just use indentation
instead of nesting.)
59. Nesting & Stacking
Rule of thumb: nest selectors and stack classes when
you *have to*, not just when you *can*.
Rule of thumb: nest and stack your @mixin’s and
@extend’s, not your selectors.
@mixin body-text {
color: green;
font: {
size: 14px;
family: Arial;
} }
@mixin nav-list__item {
line-spacing: 1;
list-style-type: none;
display: inline-block;
vertical-align: top;
}
.header__nav-list__item {
@include body-text;
@include nav-list__item;
padding: 5px;
}
60. Nesting & Stacking
Relying on @mixin and @extend with descriptive
classes, rather than on stacked, generic classes means
that refactoring is easy, and overrides (if necessary)
happen where you can see them, and plan them: in your
code.
If it comes time to refactor for performance, your most-used
mixins can easily convert to standalone classes.
Going the other direction… not so much.
61. Stacking Classes: Pros & Cons
Stacking (<div class=“class1 class2”) is great if you can’t
re-write your classes (ie. Bootstrap, components)
Stacking is declarative, at least in your HTML
It’s not at all declarative back in the CSS, forcing us to use
the Dev Tools’ Style Inspector to see what happens
It puts you into ‘fighting’ mode: overriding the conflicts
For Optimization: use tactically, not strategically
62. Stacking Classes: Pros & Cons
A Thought: how many of the reasons why we stack our
classes are because we didn’t have pre-compilers back
when we started doing it?
63. Maintainability… How?
1. AUTOMATE (OR DIE)
2. “NAME ALL THE THINGS”… CLEARLY
3. USE ELEMENT SELECTORS ONLY FOR RESETS
4. STOP OVER-NESTING… OR MAYBE NESTING
*AT ALL*
5. AVOID UNNECESSARY COMPLEXITY
64. Don’t Fight Your Elements
Do you really know if <section>, <article>, etc. do
anything for you? (hint: they don’t) Use them only if
they’re helpful in some human-readable way.
Don’t feel guilty! The era of semantic *elements* for
machine-readability is largely over, in favor of semantic
*attributes*. See: WAI-ARIA, microformats
65. Don’t Fight Your Elements
Use the most flexible elements available; ones you can
rearrange and refactor without breaking them.
Just because some content is vaguely ‘tabular’ in nature
doesn’t mean you *have* to use a <table>. You can’t scroll
the <tbody>, and styling is painful. So, don’t do it.
Just because somebody once said that <ul> is more
‘semantic’ than <div> for navigation items doesn’t mean it’s
still worth fighting with it (particularly now that we have
<nav>) Does it *look like* a list? No? Then don’t.
66. Pseudo-Helpful
When you don’t control a template, and can’t assign
classes, pseudo-selectors are great. Otherwise, maybe not.
Expensive for what you get.
Are there other options? Can Javascript help? For example,
would using Angular’s $first and $last maybe work *at
least* as well as :first-child/:last-child?
(Remember: a new age is upon us.)
67. THANKS!
(Now go teach those ‘back-end’ folks some tricks.)
!
about.me/XML #xmlilley