Sass in the Real World: book 1 of 4

Separation of content from container

The main culprit that violate this guideline are location dependent styles. A simple example of location dependent style is something like this:

.footer a {
  color: #ccc;
}

This example is applying a gray color to the anchor tag in the footer (or the anchor tags that are children of an element with the class of .footer). This will limit the usage of this style (although it should be noted that this style can be used outside of the footer, however this will make the style non-semantic and confusing). The correct approach is to allow the default style of the anchor tag be applied to it and create a style to override and apply the needed change.

a {
  color: blue;
}

.footer-link {
  color: #ccc;
}

Let's take a look at a more complicated (and more wrong) example:

#content #mainInfo p img.left {
  float: left;
  border: 0;
  padding: 2px;
  padding-right: 25px;
}

This style will only be applied to the <img> element with a class of .left that is nested in a <p> element which in turn is nested in an element with the id of #mainInfo and which in turn is nested in an element with an id of #content. If we want to apply the same style somewhere else we will have to re-created this style all over and apply it specifically to that element. So, how do we fix this? First thing is to examine what it is that we are trying to accomplish. What we are trying to accomplish is to float the <img> element to the left. The question is, do we only want to float an <img> element? Most likely the answer is no. We want to create a style that is robust enough to be applied to any element. As a result the first class we are going to create is this:

.float-left {
  float: left;
}

The style of setting no borders on the <img> element is something that maybe we want to set for all <img> elements and the exception would be to add border to the <img>. As a result, our CSS styles would be:

img {
  border: 0;
}

.float-left {
  float: left;
}

To attack the padding, we must consider padding for the element on the entire site. If we think that all <img> elements should have a padding of 2px then this is a style that should be applied at the <img> element level and then the exceptions should be overridden. The same logic applies to all other elements like <div>, <section>, <ul>, etc... So in this case, I would amend the code to something like this:

img {
  border: 0;
  padding: 2px;
}

.float-left {
  float: left;
}

This style also needs a padding on the right hand side of 20px. In order to apply this desired effect, we must consider the two options that we have. First option is the consider what we are creating this padding. In this situation, let's say that these images are thumbnails for an image gallery that we will be lining up in order for the user to view and click on them to view a larger view of the image. Therefore in this case, we will create a semantic class and apply the padding style to it.

.gallery-thumbnail {
  padding-right: 20px;
}

Our other option is to create a series of styles that will allow us to override individual paddings (and margins) not only in this situation but also in all others. The OOCSS Github site has the following padding and margin CSS code:

/**
 * Spacing classes
 * Should be used to modify the default
 * spacing between objects (not between nodes of the same
 * object)
 * Please use judiciously. You want to be
 * using defaults most of the time, these are
 * exceptions!
 * <type><location><size>
 */
/* spacing helpers
p,m = padding,margin
a,t,r,b,l,h,v = all,top,right,bottom,left,
horizontal,vertical
s,m,l,n = small(5px),medium(10px),large(20px),none(0px)
*/
.ptn,.pvn,.pan{padding-top:0px !important}
.pts,.pvs,.pas{padding-top:5px !important}
.ptm,.pvm,.pam{padding-top:10px !important}
.ptl,.pvl,.pal{padding-top:20px !important}
.prn,.phn,.pan{padding-right:0px !important}
.prs,.phs,.pas{padding-right:5px !important}
.prm,.phm,.pam{padding-right:10px !important}
.prl,.phl,.pal{padding-right:20px !important}
.pbn,.pvn,.pan{padding-bottom:0px !important}
.pbs,.pvs,.pas{padding-bottom:5px !important}
.pbm,.pvm,.pam{padding-bottom:10px !important}
.pbl,.pvl,.pal{padding-bottom:20px !important}
.pln,.phn,.pan{padding-left:0px !important}
.pls,.phs,.pas{padding-left:5px !important}
.plm,.phm,.pam{padding-left:10px !important}
.pll,.phl,.pal{padding-left:20px !important}
.mtn,.mvn,.man{margin-top:0px !important}
.mts,.mvs,.mas{margin-top:5px !important}
.mtm,.mvm,.mam{margin-top:10px !important}
.mtl,.mvl,.mal{margin-top:20px !important}
.mrn,.mhn,.man{margin-right:0px !important}
.mrs,.mhs,.mas{margin-right:5px !important}
.mrm,.mhm,.mam{margin-right:10px !important}
.mrl,.mhl,.mal{margin-right:20px !important}
.mbn,.mvn,.man{margin-bottom:0px !important}
.mbs,.mvs,.mas{margin-bottom:5px !important}
.mbm,.mvm,.mam{margin-bottom:10px !important}
.mbl,.mvl,.mal{margin-bottom:20px !important}
.mln,.mhn,.man{margin-left:0px !important}
.mls,.mhs,.mas{margin-left:5px !important}
.mlm,.mhm,.mam{margin-left:10px !important}
.mll,.mhl,.mal{margin-left:20px !important}
.mra,.mha{margin-right:auto !important}
.mla,.mha{margin-left:auto !important}

The above code can be placed in a separate CSS file and imported into any CSS file as desired. It is ideal that the styles that are applied to an element tell the story of all the styles being applied. So I don't see any issue with substituting the class .ptn with .padding-top-none or .pbl with .padding-bottom-large. So in order apply the desired original style to the <img> element, the HTML will look something like this:

<img src='path/to/the/image'
alt='appropriate text' class='float-left padding-right-large' />

Or to apply the .gallery-thumbnail, it will look something like this:

<img src='path/to/the/image'
alt='appropriate text' class='float-left gallery-thumbnail' />