Skip to content

Latest commit

 

History

History
executable file
·
631 lines (465 loc) · 11.7 KB

README.md

File metadata and controls

executable file
·
631 lines (465 loc) · 11.7 KB

CSS

Saiku CSS code styleguide.

Table of Contents

  1. Preprocessor
  2. Best practices
  3. Colors
  4. Numbers and units
  5. Inline assets
  6. Pseudo elements
  7. Quotes
  8. Comments
  9. Naming conventions
  10. Namespaces
  11. Whitespace
  12. Code linting
  13. Resources

Preprocessor

  • 1.1 Stylus is our preprocessor of choice.

  • 1.2 Limit the use of its features to only variables and mixins.

Getting too crazy with Stylus can lead to both terrible code maintenance and output.

  • 1.3 @extend is allowed only when used with placeholders.

@extending classes can lead to terrible code output.

⬆ back to top

Best practices

  • 2.1 Avoid the use of !important at all costs. Exceptions to the rule:

    1. It's being used within a helper class;
    2. You can explain its use.
  • 2.2 Do not use ids.

They kill modularity and are not necessary for styling.

  • 2.3 Do not manually add vendor prefixes.

Our tooling should be able to handle this.

  • 2.4 Do not use vendor-specific font rendering techniques.

They are not consistent, break constrast and typography rules.

  • 2.5 Prefer background over background-color when possible.

Simply because it's a shorthand.

  • 2.6 Do not use pointer-events.

It's not reliable and it's not CSS's role.

  • 2.7 Avoid hard-coded magic numbers.

These are definitelly a code smell and make super hard to maintain.

// Bad
.selector {
  width: 73px; // WTF is 73px? Why?
  z-index: 99999; // Brute force here, not good at all
  margin-top: 128px; // Again, what the heck is this?
}

// Good (values actually make sense)
.selector {
  width: grid-columns(2);
  z-index: $depth-screen-foreground;
  margin-top: $selector-inner-padding;
}
  • 2.8 Avoid undoing styles.

These are code smells and almost always have room for improvement.

// Bad
h2 {
  font-size: 2em;
  margin-bottom: 0.5em;
  padding-bottom: 0.5em;
  border-bottom: 1px solid #ccc;
}

.no-border {

  // Brute force resets down here
  padding-bottom: 0;
  border-bottom: none;
}

// Good
h2 {
  font-size: 2em;
  margin-bottom: 0.5em;
}

.headline {
  padding-bottom: 0.5em;
  border-bottom: 1px solid #ccc;
}
  • 2.9 Prefer em over px.

This allows for a more flexible element sizing.

⬆ back to top

Colors

  • 3.1 Hexadecimal values should always be in lower case.

This approach improves code readability.

// Bad
.link {
  color: #EAEAE2;
}

// Good
.link {
  color: #eaeae2;
}
  • 3.2 Prefer shorthand notation.
// Bad
$color: #cccccc;

// Good
$color: #ccc;

// Bad
$color: #ff6600;

// Good
$color: #f60;
  • 3.3 Do not use CSS color names.

They're not consistently implemented on browsers.

// Bad
.error {
  background: red;
}

// Good
.error {
  background: #ff0066;
}

⬆ back to top

Numbers and units

  • 4.1 Avoid specifying units for zero values.
// Bad
.square {
  border: 0px;
}

// Good
.square {
  border: 0;
}
  • 4.2 Do not use floating decimals.

They do make code harder to read.

// Bad
.heading {
  margin-left: -.75px;
  padding: .25px;
  border: 2.px;
}

// Good
.heading {
  margin-left: -0.75px;
  padding: 0.25px;
  border: 2.0px;
}
  • 4.3 Use pt units to declare letter-spacing values.

We found it easier to match Photoshop visual specifications.

// Bad
.text {
  letter-spacing: -0.75px;
}

// Good
.text {
  letter-spacing: -0.75pt;
}
  • 4.4 Do not add units for line-height values.

Not doing so will break vertical rhythm.

// Bad
p {
  line-height: 1.5px;
}

// Good
p {

  // Equivalent to 150% of the font size
  line-height: 1.5;
}

⬆ back to top

Inline assets

  • 5.1 Inline assets are only allowed if they weight less than or equal to 1KB and are presented only once in the code.

⬆ back to top

Pseudo elements

  • 6.1 Use double collons :: to access pseudo elements.
// Bad
.button:after {
  background: #f60;
}

// Good
.button::before {
  outline: 1px solid;
}

⬆ back to top

Quotes

  • 7.1 Use single quotes ' for everything.

  • 7.2 Always wrap values with quotes.

Even though some are not mandatory, it will enforce consistency.

// Bad
@import helpers/clearfix;

input[type=radio] {
  opacity: 0.35;
}

.selector {
  background: url(path/to/image.png) no-repeat;
}

// Good
@import 'helpers/clearfix';

input[type='radio'] {
  opacity: 0.35;
}

.selector {
  background: url('path/to/image.png') no-repeat;
}

⬆ back to top

Comments

  • 8.1 Following is an example of a well documented component following our standards.
/* ==========================================================================
   Component name
   ========================================================================== */

// Component theming properties
$component-background-color: #f06;
$component-color: #fff;

// Set component's layout direction, which changes the way arrows are drawn
$component-direction: 'down';

/**
 * Some description about my component.
 * Always try to be very concise and straightforward.
 *
 * TODO: Split this component in two other components.
 */

.component {
  // ...
}

/* Sub component name
   ========================================================================== */

/**
 * Some description about my sub component.
 *
 * FIXME: Rendenring issue on IE8.
 */

.component__sub-component {
}

/**
 * Modifier: Description of component modifier.
 */

.component--modifier {
  // ...
}

/**
 * Function: Description of component function.
 */

component-function() {
  // ...
}

/**
 * Mixin: Description of component mixin.
 */

component-mixin() {
  // ...
}

⬆ back to top

Naming conventions

  • 9.1 Use hyphen-case to name classes, variables, functions, mixins and placeholders.
// Bad
.fooBar {
  border: none;
}

LoremIpsumDolor {
  text-align: center;
}

// Good
.foo-bar {
  outline: 1px solid red;
}


// Good
.lorem-ipsum-dolor {
  vertical-align: middle;
}
  • 9.2 Elements should have the base module name as a prefix and the name of the element, separated by double underscores __.

The advantage of elements is to not rely on the markup to apply a certain style.

.menu-item {
  // ...
}

// Bad
.menu-item.icon {
  // ...
}

// Good
.menu-item__icon {
  // ...
}

// Bad
.menu-item-list {
  // ...
}

// Good
.menu-item__list {
  // ...
}
  • 9.3 Modifiers should have the base module name as a prefix and the name of the modifier, separated by double hyphens --.

Modifiers are also complementary, therefore a master/base class should exist to provide the visual foundation.

.logo {
  background: url('./logo.png') no-repeat;
}

// Bad
.logoBig {
  transform: scale(1.5);
}

// Good
.logo--big {
  transform: scale(1.25);
}

// Bad
.logo-with-small-size {
  transform: scale(0.25);
}

// Good
.logo--small {
  transform: scale(0.5);
}
  • 9.4 States can be prefixed with is, has or should.
// Bad
.logo.logoHidden {
  opacity: 0;
}

// Good
.logo.is-hidden {
  opacity: 0;
}

// Bad
.logo.logo-disabled {
  border: 1px solid;
}

// Good
.logo.is-disabled {
  border: 1px solid fuchsia;
}

// Bad
.button-with-icon {
  // ...
}

// Good
.button.has-icon {
  // ...
}

⬆ back to top

Namespaces

Namespaces help us understand what role classes play.

Prefix Description Example
c For user interface components c-dropdown
ab For A/B testing stuff (usually removed and re-implemented once the test is done) ab-jira-ticket-42
u For utils u-clearfix
t For custom themes t-black-friday
_ For hacks (that should be removed as soon as possible) _fix-dropdown-ie8
is, has, should For component states is-disabled
v For vendor service hooks (such as Optimizely, Crazy Egg, etc) v-optimizely

⬆ back to top

Whitespace

  • 11.1 Add a space after selector definition.
// Bad
.selector{content: 'foo';}

// Good
.selector { content: 'foo'; }
  • 11.2 Add a space between a rule and its value.
// Bad
.button {
  color:#fff;
  background:#f06;
}

// Good
.button {
  color: #fff;
  background: #f06;
}
  • 11.3 Add inner spaces to inline selectors.
// Bad
.selector {content: 'foo';}

// Good
.selector { content: 'foo'; }
  • 11.4 If a selector has more than a single rule, break all the rules into new lines.

This will improve code readability.

// Bad
.section { cursor: pointer; text-align: center; }

// Good
.section { cursor: default; }

// Good
.section {
  text-align: left;
  vertical-align: middle;
}
  • 11.5 When targeting multiple selectors break each one in a new line.
// Bad
.footer, .header, .main {
  display: block;
}

// Good
.footer,
.header,
.main {
  margin: 0 auto;
}
  • 11.6 Keep multiple rules in more than one line for better readability.
// Bad
.box {
  box-shadow: 0 1px 1px #eee,
  inset 0 1px 0 #f00;
}

// Good
.box {
  box-shadow: 0 1px 1px #eee, 
              0 1px 0   #f00 inset;
  background: linear-gradient(
              #1e5799 0%,
              #2989d8 50%,
              #207cca 51%,
              #7db9e8 100%);
}
  • 11.7 Add a white space after each comma on multiple values.
// Bad
.selector {
  background: rgba(0,0,0,0.5);
}

// Good
.selector {
  background: rgba(255, 255, 255, 0.75);
}

⬆ back to top

Code linting

⬆ back to top

Resources

CSS naming methodologies

Blog posts

⬅ back to main    ⬆ back to top