Skip to content

Instantly share code, notes, and snippets.

@Skateside
Last active July 6, 2016 18:45
Show Gist options
  • Save Skateside/3957429 to your computer and use it in GitHub Desktop.
Save Skateside/3957429 to your computer and use it in GitHub Desktop.
Having read up on SMACSS, I put together a basic starting point for all my style sheets. This is that starting point.
/* # Base rules
This style sheet attempts to show how CSS selectors can be limited to no more
than a single class (although there are exceptions). Keeping to such a
restriction helps contain the styling to a module and allows for easier
sub-classes of modules. It also enables the surgical classes (below) to work.
## Universal rules
Every element is affected by these classes.
1. This rule allows the parent element to define a `border-color` and have the
children copy that colour, as opposed to defaulting to `currentcolor`. This
is particularly handy with tables.
*/
* {
border-color: inherit; /* 1 */
margin: 0;
padding: 0;
}
*,
*::before,
*::after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/* ## Basic fonts
All fonts inherit from the `body` tag, so we have some basic font family, size
and line-height applied.
The `html` element has `text-size-adjust` set to `100%` to prevent iOS text size
adjust after orientation change, without disabling user zoom.
Taken from [Normalize.css](http://necolas.github.io/normalize.css/).
*/
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 1em; /* 16px */
line-height: 1.25;
}
/*
All text nodes (including headings, paragraphs and lists) have a top and bottom
margin, relative to the size of the text at the time.
*/
h1,
h2,
h3,
h4,
h5,
h6,
p,
dl,
ol,
ul {
font-weight: normal;
font-size: 1em;
margin: 10px 0;
}
/*
Prevent `sub` and `sup` affecting `line-height` in all browsers. Taken from
[Normalize.css](http://necolas.github.io/normalize.css/).
<p>Normal text<br>
and line-height.</p>
<p>H<sub>2</sub>0<br>
x<sup>2</sup></p>
*/
sub,
sup {
font-size: 0.75em;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/*
Remove most spacing between table cells. Taken from [Normalize.css](http://necolas.github.io/normalize.css/)
<table>
<thead>
<tr>
<th>One</th>
<td>Two</td>
</tr>
</thead>
<tbody>
<tr>
<th>Three</th>
<td>Four</td>
</tr>
</tbody>
</table>
*/
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}
/* # Utility classes
Utility classes are frequently used styling patterns. They are the only classes
in this style sheet that are allowed to know anything about the child elements
(although this should be limited to the immediate children).
## Self-contained floats.
Although there are other layout abilities in modern CSS, it is often handy to
simply float elements. The `u-floated` class will allow for that while also
forcing the parent to wrap the children.
<div class="u-floated">
<div>All elements are floated.</div>
<article>This includes articles ...</article>
<span>... and inline elements like a span</span>
</div>
*/
.u-floated::before,
.u-floated::after {
content: "";
display: table;
}
.u-floated::after {
clear: both;
}
.u-floated > * {
float: left;
}
/* ## Bulletless lists
A list is a very useful structure for collating elements. Sometimes it's
beneficial to not display the bullet points. The `u-bulletless` class will
remove the bullet points from either an ordered or unordered list.
<ul class="u-bulletless">
<li>This list</li>
<li>has no</li>
<li>bullet points</li>
</ul>
*/
.u-bulletless {
list-style-type: none;
margin: 0;
padding: 0;
}
/* ## Equidistant children
Every now and again, it's useful to have children equally spaced apart.
Currently there is no single CSS property to do this.
It should be noted that this technique often fails slightly if the children are
different widths; setting a `min-width` on the children in that situation can be
useful.
[Credit to Chris Coyer and James Meyer](http://css-tricks.com/equidistant-objects-with-css/#comment-1250696)
<div class="u-equidistant">
<span>Span</span>
<div>Div</div>
<i>I</i>
</div>
*/
.u-equidistant {
text-align: justify;
}
.u-equidistant::after {
content: "";
display: inline-block;
width: 100%;
}
.u-equidistant > * {
display: inline-block;
}
/* ## Reduces margins
Often a box will be created to contain text but the text elements' natural
margin will cause the whitespace between the box top and the text top to be more
than anticipated. The `u-reduce` class removes the top margin from the first
element and the bottom margin from the last one, keeping the box's whitespace
being defined by the box.
<div class="u-reduce" style="border: 1px solid red; padding: 10px;">
<p>alpha</p>
<p>bravo</p>
<p>charlie</p>
</div>
*/
.u-reduce > :first-child {
margin-top: 0;
}
.u-reduce > :last-child {
margin-bottom: 0;
}
/* # Text rules
Frequently, specific text styling should be applied but the text element itself
may change during the page's lifetime. Separating the text rules into their own
classes allows the HTML structure to be changed without changing the styling.
## Headlines
Rather than traditional style frameworks that rely on the heading elements
(`<h1>` to `<h6>`) this one has `h-` classes. This allows the styles to be
applied to any element - very handy when a client's SEO company asks us to swap
the `<h1>` and `<h2>` elements.
<h1 class="h-headline">Headline</h1>
<h2 class="h-subheadline">Sub headline</h2>
<h3 class="h-byline">By line</h3>
<h4 class="h-standout">Stand-out</h4>
<h5 class="h-attention">Attention</h5>
<h6 class="h-minor">Minor</h6>
As mentioned, the element gaining the class is not important. The above example
could easily look like this:
<h2 class="h-headline">Headline (but an h2)</h2>
<p class="h-subheadline">Sub headline (but a p)</p>
<p><strong class="h-byline">By line (but a strong)</strong></p>
<p><span class="h-standout">Stand-out (but a span)</strong></p>
<div class="h-attention">Attention (but a div)</div>
<h1 class="h-minor">Minor (but an h1)</h1>
*/
.h-headline,
.h-subheadline,
.h-byline,
.h-standout,
.h-attention,
.h-minor {
font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
}
.h-headline { font-size: 2em; } /* 32px */
.h-subheadline { font-size: 1.6667em; } /* 26.6672px (approx) */
.h-byline { font-size: 1.5em; } /* 24px */
.h-standout { font-size: 1.3333em; } /* 21.3328px (approx) */
.h-attention { font-size: 1.1667em; } /* 18.6672px (approx) */
.h-minor { font-size: 1em; } /* 16px */
/* # Modules
Code from here on describes modules.
The modules here are mainly for demonstration purposes and are not necessarily
designed for production use (although they are tested).
## Form Layout
Requres the `u-floated` class. Designed to position labels next to the inputs
but still allow either side to expand as necessary.
<dl class="u-floated">
<dt class="form_title"><label for="input1">Input 1</label></dt>
<dd class="form_desc"><input type="text" name="input1" id="input1"></dd>
<dt class="form_title">
<label for="input2">Input 2</label>
<small>Useful notes about the input</small>
</dt>
<dd class="form_desc"><input type="text" name="input2" id="input2"></dd>
<dt class="form_title"><label for="input3">Input 3</label></dt>
<dd class="form_desc">
<textarea rows="3" cols="10" name="input3" id="input3"></textarea>
</dd>
<dt class="form_title"><label for="input4">Input 4</label></dt>
<dd class="form_desc"><input type="text" name="input4" id="input4"></dd>
</dl>
*/
.form_title,
.form_desc {
min-height: 1.25em; /* Same as body line-height */
margin-top: 5px;
}
.form_title {
clear: both;
width: 45%;
}
.form_desc {
float: right;
margin-left: 0;
width: 50%;
}
/* ## Tame tables
This module demonstrates how to set classes on table elements to keep the
single-class-maximum requirement and aid further styling. The module does not
require that all table elements exist, it will function correctly without a
`caption` element, for example.
<table class="table">
<caption class="table_caption">Just testing</caption>
<thead class="table_head">
<tr class="table_hrow">
<th class="table_hcell">Heading</th>
<th class="table_hcell">Heading</th>
</tr>
<tr class="table_hrow">
<th class="table_hcell">Heading</th>
<th class="table_hcell">Heading</th>
</tr>
</thead>
<tbody class="table_body">
<tr class="table_row">
<td class="table_cell">Content</td>
<td class="table_cell">Content</td>
</tr>
<tr class="table_row">
<td class="table_cell">Content</td>
<td class="table_cell">Content</td>
</tr>
<tr class="table_row">
<td class="table_cell">Content</td>
<td class="table_cell">Content</td>
</tr>
</tbody>
</table>
*/
.table {
border-color: #999;
table-layout: fixed;
}
.table_caption {
caption-side: bottom;
font-size: 0.8em;
}
.table_head {
border-style: solid;
border-width: 0 0 2px;
}
.table_row:nth-child(odd) {
background-color: #DDD;
}
.table_hcell,
.table_cell {
border-style: solid;
border-width: 1px;
padding: 5px 10px;
}
.table_hcell {
font-weight: bold;
}
/* ## Items
This module exists mainly to show how `:nth-child()`, `:first-child`,
`:last-child` etc. is not needed to create space between list items. This keeps
CSS selectors to the single-class-maximum requirement. The `u-floated` and
`u-bulletless` classes will help style this module.
The convention of this class is for the class to be the plural whereas the items
are the singular, rather than using the underscore to denote a sub-element.
<ul class="u-floated u-bulletless items">
<li class="item">alpha</li>
<li class="item">bravo</li>
<li class="item">charlie</li>
</ul>
*/
.items {
margin-left: -10px;
margin-right: -10px;
}
.item {
margin-left: 10px;
margin-right: 10px;
width: 200px; /* Random width, not required. */
}
/* ## Box
The box is a generic container for elements. Important things to note in this
module are the "lip" classes. In this convention, a lip overlaps the box's
padding, allowing a `border-bottom` to touch the box's side borders, for
example.
<div class="box">
<h1 class="box_lip box_border">Heading</h1>
<p>Content</p>
</div>
*/
.box {
border: 1px solid #CCC;
padding: 10px;
}
.box_lip {
margin-left: -10px;
margin-right: -10px;
padding-left: 10px;
padding-right: 10px;
}
.box_border { /* Just for demonstration, not required */
border-bottom-style: solid;
border-bottom-width: 1px;
padding-bottom: 10px;
}
/* ## Flip-flops
This demonstration module shows how to make text/image combinations alternate
positions. This is one of the few situations where a `:nth-child()` selector is
required.
<article class="flip">
<div class="flip_image">(image)</div>
<div class="flip_text">this text should be on the right</div>
</article>
<article class="flip">
<div class="flip_image">(image)</div>
<div class="flip_text">this text should be on the left</div>
</article>
*/
.flip {
border: 1px solid red;
display: flex;
flex-direction: row;
height: 200px;
justify-content: space-between;
width: 450px;
}
.flip:nth-child(even) {
flex-direction: row-reverse;
}
.flip_image,
.flip_text {
height: 100%;
width: 200px;
}
.flip_image {
background-image: linear-gradient(to bottom, #F5F5F5 0%, #E1E1E1 100%);
}
.flip_text {
border: 1px dotted #CCC;
}
/* # Surgical classes
These are classes that fix minor problems in a consistent way. The classes are
prefixed with "x" (surgery, cutting, Ctrl + X). Each of the classes have
easy-to-remember short names:
- `x-db` = Display Block
- `x-dn` = Display None
- `x-fw` = Full Width
- `x-tal` = Text-Align Left
- `x-tac` = Text-Align Center
- `x-tar` = Text-Align Right
This idea of these classes is not to build modules from them, but often a minor
change is needed and it is easier to use one of these surgical classes than
creating a sub-module or module part just to add that minor change.
Also worth noting is that this is not an exhaustive list. Many more
possibilities exist.
*/
.x-db { display: block; }
.x-dn { display: none; }
.x-fw { width: 100%; }
.x-tal { text-align: left; }
.x-tac { text-align: center; }
.x-tar { text-align: right; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment