CSS Style Guide
DO NOT FEAR REFACTORING. If you think of a way to write your CSS (or any code, really) in a more simple, elegant way, do it. It’ll be worth the yak-shaving.
1. CSS Attribute Order
display
width
height
margin
padding
position
top
right
bottom
left
z-index
float
clear
overflow
When writing properties, use this order. It starts with the box model and other important properties, and then everything else can be written alphabetically.
If an element has a lot of complex transitions / animations going along with it, break that out separate, just so it's easier to see what's going on. Same thing for different color blocks. It's better for organization, so just use your best judgement.
1.1 Put @ at the top
For better organization, put @include
and @extend
before other style declarations. It also makes it easier to override the included or extended styles this way.
At-Rule Placement
%tcell {
display: table-cell;
vertical-align: middle;
}
@mixin pseudo-triangle {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
border: solid transparent;
}
.linkster {
@extend %tcell;
@include pseudo-triangle;
position: static;
vertical-align: top;
}
2. Media Queries
When writing media queries, leave a comment for where exactly the media query applies, just so it's clear. Indent code inside the block, and leave a space on top and on bottom.
Media Query Formatting
/*——————————————————————————————————————————————————————————
/ Details: Tablet & Up
/—————————————————————————————————————————————————————————*/
@media #{$medium-up} {
ul {
@include columns(3 3em)
padding-left: 0;
border-left: 0;
list-style-type: square;
li {
padding-left: 1em;
text-indent: -1em;
list-style-position: inside;
}
}
}
Try to keep media query blocks to the standard breakpoints, and group them under medium-sized parent elements: for example, body.page
is probably too broad, whereas .btn.yellow
is too narrow. Aim for “just right,” also known as the Goldilocks Principle.
You should begin with the smallest breakpoint and work your way up. The current default breakpoints in Foundation are:
Foundation Breakpoints
$small-breakpoint: em-calc(640) !default;
$medium-breakpoint: em-calc(1024) !default;
$large-breakpoint: em-calc(1440) !default;
$xlarge-breakpoint: em-calc(1920) !default;
3. Nesting Elements
When nesting elements, begin with pseudo elements, then compound CSS classes, then nested elements inside the parent.
Element Nesting
.parent {
width: 50%;
float: left;
&:before, &:after {
content: "";
}
&:first-child {
color: red;
}
.child-element {
display: none;
}
&:hover {
color: blue;
.child-element {
display: block;
}
}
&.open {
height: 100%;
.child-element {
color: red;
}
}
}
3.1 Elements Order Explained
- Scenario pseudo-classes (:first-child, :last-child, etc)
- Relational pseudo-classes (:before and :after)
- Children (if they need to be nested).
- State pseudo-classes (:hover, :active, etc)
Because you may change something about the :first-child
, :before
, or child elements on hover, and it's easier to see what the change is if the original CSS is above.
Nest only if you need to
REMEMBER: Group child elements together, either nested or unnested.
To determine whether a child element needs to be nested, consider:
- If the class is unique enough (nav.main, .logo, etc.) to stand on its own, don’t nest it.
- If the class is too generic (.image, .text, .left, .right), or is likely to be reused (.title), then nest it.
If you’re unsure what to do, start off by not nesting the element. If you run into problems with it, then consider whether you need to nest it, or whether you can solve it another way.
HTML
<div class="parent">
<div class="generic-child-element">
…
</div>
<div class="unique-child-element">
<h3 class="title">This Block's Title</h3>
</div>
<div class="another-child-element">
Some text…
</div>
</div>
SCSS
.parent {
width: 50%;
float: left;
&:before, &:after {
content: "";
}
&:first-child {
color: red;
}
&:hover {
color: blue;
.generic-child-element {
display: inline-block;
}
.unique-child-element {
display: block;
}
}
&.open {
height: 100%;
.unique-child-element {
color: red;
}
.another-child-element {
color: green;
}
}
}
.parent .generic-child-element {
display:none;
}
.unique-child-element {
display: none;
//[lots of CSS lines…]
}
.another-child-element {
//[lots of CSS lines…]
}
The .generic-child-element here is styled outside of the .parent styles. Even though it needs the specificity, it's better to group .generic-child-element with the other child elements.
BEM Clases / CSS nesting doesn't have to match HTML nesting
CSS nesting does not have to match HTML nesting. Also, try to use BEM naming conventions when you're styling a module, so that you can keep styles scoped to the module and easy to override at the same time. For example:
HTML
<div class="module">
<div class="module-image">
<img src="a-cool-cucumber.gif" />
</div>
<div class="module-text">
<h3 class="module-title">This Block's Title</h3>
</div>
</div>
the proper way to nest the CSS in this case would be:
SCSS
div.module {
&-image {
margin: .5em;
}
img {
border: none;
}
&-text {
padding: .25em;
}
&-title {
font-size: 1.5em;
}
}
Write in order of the DOM tree
Finally, write in order of the DOM tree: that is, write the CSS in the same order as the HTML. This will keep things better organized and keep your code more maintainable.
4. File Names
- All partial SCSS files begin with an underscore, e.g., _header.scss, so that they won't be accidentally compiled in Codekit.
- Generally, mirror the CSS file after the theme file: header.php and _header.scss
- Use one SCSS file per post type: archive-practice-area.php and content-practice-area.php would both be styled in _practice-areas.scss
- Use _atoms.scss for small, reusable modules.
5. SASS Variables
Variables make our code more efficient, but please name and document them properly. If a variable could apply anywhere in the site, stick it in settings.scss. Otherwise, limit its scope to the beginning of the module that it pertains to.
6. Document Everything
Ninja code, while impressive, is not maintainable. When you write ninja code, you make other developers first decipher your code before they can modify your code.
So if you’re doing some crazy thing with lists and loops and what all else, that block better be plastered with comments.