CSS: The Good Parts
MIT License
The so-called
"nico-style"
brought to markdown. Because Style Guide.
This style guide is a jab at solving collisions between CSS class names, and issues that ultimately lead to confusion, having to use !important
rules, copying and pasting style declarations, and similarly awful aspects of CSS development.
These suggestions aren't set in stone, they aim to provide a baseline you can use in order to write more consistent codebases. To maximize effectiveness, share the styleguide among your co-workers and attempt to enforce it. Don't become obsessed about code style, as it'd be fruitless and counterproductive. Try and find the sweet spot that makes everyone in the team comfortable developing for your codebase, while not feeling frustrated that their code always fails automated style checking because they added a single space where they weren't supposed to. It's a thin line, but since it's a very personal line I'll leave it to you to do the drawing.
Astonishingly, this style guide won't do anything for you that you're not able to figure out for yourself. That means you won't see the benefits unless you try and follow most of the conventions laid out next.
Use together with bevacqua/js for great good!
Feel free to fork this style guide, or better yet, send Pull Requests this way!
id
attributeComponents should always be assigned a unique namespace prefix.
Consider the following example, where we assigned ddl
to a drop down list component. Take note of the class names.
.ddl-container {
// ...
}
.ddl-item-list {
// ...
}
.ddl-item {
// ...
}
.item-list {
// ...
}
.dropdown-item-list {
// ...
}
.xyz-item-list {
// ...
}
Classes that are meant to be shared among a large set of elements, or provide reusable styles, should be grouped under a universal namespace, such as uv
.
.uv-clearfix {
// ...
}
.clearfix {
// ...
}
See Selectors and Nesting for information in regard to how styles should be overridden
Class names must follow a few rules.
.ddl-item {
// ...
}
.ddl-selected {
// ...
}
.ddl-item-selected {
// ...
}
.ddlItem {
// ...
}
.ddl-item-container-text {
// ...
}
.ddl-foo-bar-baz {
// ...
}
Attributes make decent selectors from time to time. Some ground rules apply.
[href] {
// ...
}
a[href] {
// ...
}
[href^='http'] {
// ...
}
id
attributeWhile the id
attribute might be fine in HTML and JavaScript, it should be avoided entirely inside stylesheets. Few reasons.
.ur-name {
// ...
}
#ur-name {
// ...
}
Just assign a class name to the element.
Tag names in selectors follow a few rules.
a.foo
)
button {
padding: 5px;
margin-right: 3px;
}
.ddl-button {
background-color: #f00;
}
.ddl-container button {
background-color: #f00;
}
Styles shouldn't need to be nested more than three (four at worst) levels deep. This includes pseudo-selectors. If you find yourself going further, think about re-organizing your rules (either the specificity needed, or the layout of the nesting).
.sg-title-icon:before {
// ...
}
.dg-container .sg-title {
font-size: 1.1em; // larger segment title inside dialogs
}
.dg-container .sg-container .sg-title {
font-size: 1.1em;
}
.dg-container .sg-title span:before {
// ...
}
If a component needs to be different within another component, these rules apply.
Suppose you have a User List component .ul-*
and a User Card component .uc-*
.
<div class='ul-container'>
<div class='uc-container'>
<span class='uc-name ul-card-name'>John Doe</span>
</div>
</div>
.ul-card-name {
// ...
}
<div class='ul-container'>
<div class='uc-container'>
<span class='uc-name'>John Doe</span>
</div>
</div>
.ul-container .uc-name {
// ...
}
<div class='ul-container'>
<div class='uc-container'>
<span class='uc-name uc-name-in-ul'>John Doe</span>
</div>
</div>
.uc-name-in-ul {
// ...
}
Ideally, you should keep your stylesheets separated in different files. Either of the approaches below is fine. The former is prefered.
all.{styl,less,scss}
file and have it @import
every other fileA few rules apply.
Presentation-Specific styles are those that only alter the visual design of the element, but don't change its dimensions or position in a meaningful way. The examples below are presentation-specific.
color
, font-weight
, or font-variant
font-size
is not considered a meaningful dimension changepadding
may fit this category (loosely), but only if box-sizing: border-box;
is in effectmax-width
and max-height
may fit either category, but it's generally reasonable to consider them presentation-specificLayout-Specific Styles are those that change the dimensions or positioning of DOM elements. These are mostly layout-specific.
margin
or padding
width
, and height
position
z-index
, definitelyWhere possible, it's suggested to explicitly split styles into these two categories. The explicit differentiation could be made in a few different ways.
.foo {
position: fixed;
top: 8px;
right: 8px;
padding: 2px;
font-weight: bold;
background-color: #333;
color: #f00;
}
.foo {
position: fixed;
top: 8px;
right: 8px;
padding: 2px;
font-weight: bold;
background-color: #333;
color: #f00;
}
.foo {
position: fixed;
top: 8px;
right: 8px;
padding: 2px;
}
.foo {
font-weight: bold;
background-color: #333;
color: #f00;
}
.foo {
font-weight: bold;
background-color: #333;
color: #f00;
position: fixed;
top: 8px;
right: 8px;
padding: 2px;
}
.foo {
right: 8px;
color: #f00;
padding: 2px;
top: 8px;
background-color: #333;
font-weight: bold;
position: fixed;
}
These rules apply to your CSS property values
0
, do not specify units!important
rule should be aggressively avoided.
!important
ruledisplay: none !important;
typez-index
levels in variables in a single file. Avoids confusion about what level should be given to an element, and arbitrarily-high 999
-style values#000
unless there's an explicit need for an rgba
declarationline-height
is preferred because it does not inherit a percentage value of its parent element, but instead is based on a multiplier of the font-size
..btn {
color: #222;
}
.btn-error {
color: #f00;
}
.btn-red {
color: #f00 !important;
}
.btn {
color: #222;
}
If you are reading this, I salute you. You're almost as boring as I am. I'm more boring because I actually wrote the damn thing. It's not a contest, though.
A few rules apply to media queries.
.co-field {
width: 120px;
}
@media only screen and (min-width: 768px) {
.co-field {
width: 400px;
color: #f00;
}
}
.co-field {
width: 400px;
color: #f00;
}
@media only screen and (max-width: 768px) {
.co-field {
width: 120px;
color: initial;
}
}
You should shy away from all of these. A few rules apply.
normalize.css
if you wantSome rules apply to stylesheet, regardless of language.
.foo {
color: #f00;
}
.foo,
.bar,
.baz {
color: #f00;
}
.foo {
color: #f00;
}
.foo, .bar, .baz {
color: #f00;
}
.foo {
color: red;
}
These rules apply to every language except Stylus.
:
in property declarations{
in rule declarations.foo {
color: #f00;
}
.foo{
color: #f00;
}
.foo {
color:#f00;
}
.foo {
color: #f00
}
Rules applicable to most pre-processor languages.
//
statements.foo { .bar {} }
vs .foo .bar {}
.foo
and .foo .bar
need styling&{selector}
to concatenate selectorsz-index
levels in a single file, using variables// foo
.bar {
// ...
.baz {
///...
}
}
/* foo */
.bar {
// ...
}
.bar .baz {
// ...
}
Rules specific to Stylus.
{}
in rule declarations:
and ;
in property declarationsnib
// foo
.foo
color #f00
.foo
color #f00
.bar
padding 2px
/* foo */
.foo {
color: #f00;
}
.foo {
color: #f00;
}
.foo .bar {
padding: 2px;
}
MIT
Fork away!