Sass Variable Naming

As of Version 4, Kickstart uses Amadeus conventions for naming variables.

This helps to establish consistency and predictability with the naming of variables.

Layout styles

Before you start adding components to your page, it's best to decide if you want a fixed, fluid, or fixed-fluid layout.

Fixed layout

A fixed layout simply limits the width of the layout to a certain amount.

For a fixed wrapper, create a fluid wrapper around your content with $fluid; true. Now you just need to limit that fluidity with a max-width property.

For a fixed wrapper, use the .wrapper.wrapper-fixed classes.

The default max-width is about 768px, however, you can define your own by adding a max-width property.

<div class="wrapper">
  <h1>Hello world</h1>
</div>

.wrapper{
  @include wrapper($fluid: true);
  max-width: 700px;
}

<div class="wrapper wrapper-fixed">
  <h1>Hello world</h1>
</div>

.wrapper.wrapper-fixed {
  max-width: 700px; // if 768px is not sufficient
}

Fluid layout

A fluid layout allows the width of the content to match the width of the viewport

For a fluid wrapper use the mixin wrapper($fluid: true)

To have elements break out of a wrapper (called "bleeding"), just end the wrapper before the bleed content and open it back up afterwards.

.wrapper {
  @include wrapper($fluid: true);
}

<div class="wrapper wrapper-fluid">
  ...
</div>

Fluid-fixed layout

This layout is the default behavior for a wrapper in Kickstart and combines the best of both worlds.

Instead of constantly resizing to the size of the viewport, a new fixed width is used at each breakpoint.

Create a wrapper around your content and use the mixin wrapper()and use the .wrapper class.

<div class="wrapper">
  <h1>Hello world</h1>
</div>

.wrapper{
  @include wrapper();
}

<div class="wrapper">
  <h1>Hello world</h1>
</div>

HTML styles

Several styles are applied at the HTML level for convenience throughout the DOM.

A default font-size of 16-18px (varies depending on the theme) is set. This should really be the only place where px are used to define font-size. Elsewhere, the rem unit is used, which is relative to the font-size in the HTML document.

On supporting browsers, this font-size will scale with the width of the screen. See Typography for more information on responsive text.

Naming conventions

Kickstart is not a fan of BEM for several reasons that won't be mentioned here.

However, a miniscule part of the philosophy behind it is used in Kickstart naming conventions. As an alternative to distinguishing "Blocks, elements, and modifiers" Kickstart simply distinguishes "Components and modifiers."

Components

Components can be HTML elements that are standalone--they cannot or typically do not have other components nested within them.

<button class="button">Send</button>

Other components can have elements nested within them, but no distinction is made in the naming convention.

<div class="navbar">
  <ul>
    <li>
      <a href="#">Home</a>
    </li>
    <li>
      <a class="button" href="#">Home</a>
    </li>
  </ul>
</div>

Component names try to remain simple, however sometimes a space character is needed. The underscore (_) character is reserved for this.

<div class="tooltip_trigger">
  <span class="tooltip"></span>
</div>

Modifiers

Elements with alternate states and schemes have modifiers

For example, here is a default button and a yellow button

<button class="button">...</button>
<button class="button button-yellow">...</button>

Why the repetition? Why not just .button .yellow? This is to specify that yellow is a modifier on the button.

You may want to define your button as a non-kickstart component "foo" as well

<button class="button foo button-yellow">...</button>

Maybe foo is a component that styles the outline of the button, which we want to be blue.

With this convention, it's clear where the modifier should be applied.

<button class="button foo button-yellow foo-blue">...</button>

Using decoupled modifiers

One of the problems you may run into when using the mixins across multiple classes, is getting individual properties to stay separate.

Consider the following css:

.button { 
  @include button(); 
}
.button.button-blue {
  @include button($background-color: map-get($colors, blue));
}
.button.button-large {
  @include button($size: 1.3);
}

If I create a big, blue button, this button will probably not show up blue. Why? Look at the third rule in the css, by including button() we also included the default styling for a button, which is not blue.

<button class="button button-blue button-large">Send</button>

For this reason, most mixins include decoupled sub-mixins to target individual properties.

.button { 
  @include button; 
}
.button.button-blue {
  @include button-color(map-get($colors, blue));
}
.button.button-large {
  @include button-size(1.3)
}

In the above examples, button-size() and button-color are the exact same mixins called from button(). They are simply written outside of the mixin for this exact purpose.

Colors

Rainbow colors

To use a color variable, refer to the $color Sass map and retrieve one of red, orange, yellow, green, blue, or violet.

Read more about Sass maps

.button
  color: map-get($colors, red)

Grayscale

Grayscale variables live in three separate maps, $white, $gray, and $black. Shades of each are called using -, -er, and -est patterns as such:

map-get($white, darker)

For the $gray map, you can retrieve the light, lighter, and lightest light subsets or the dark, darker, and darkest dark subsets.

map-get($gray, lightest)
map-get($gray, lighter)
map-get($gray, light)
map-get($gray, dark)
map-get($gray, darker)
map-get($gray, darkest)

The same is true for $white and $black. Intuitively, "light" versions of $white do not exist, nor do "dark" versions of $black

map-get($white, dark)
map-get($white, darker)
map-get($white, darkest)

map-get($gray, lightest)
map-get($gray, lighter)
map-get($gray, light)
map-get($gray, dark)
map-get($gray, darker)
map-get($gray, darkest)

map-get($black, lightest)
map-get($black, lighter)
map-get($black, light)

For regular white, gray, and black, simply use the css name.

This example represents a grayscale set all the way from white to black.

white

map-get($white, dark)
map-get($white, darker)
map-get($white, darkest)

map-get($gray, lightest)
map-get($gray, lighter)
map-get($gray, light)

gray

map-get($gray, dark)
map-get($gray, darker)
map-get($gray, darkest)

map-get($black, lightest)
map-get($black, lighter)
map-get($black, light)

black 

Semantic colors

Two semantic colors, $primary-color and $secondary-color are assigned to the colors/grayscale values above via the chosen theme. These are used throughout Kickstart to denote hierarchy in the interface.

Amadeus shortcuts

Kickstart natively supports Amadeus selector conventions for keeping selectors modular.

Here's an example of how that might look.

Notice we're using the + shortcut instead of @include here. This is optional and only available in Sass, not Scss. However, @include will work just fine as well.

If you're using the gulp framework, you'll be able to use the jade mixins as well. If not, you can still use the Sass mixins.

// Jade (Included with the optional gulp framework)

+page("store", "show")
  +b("products")
    h1 These are our products

    +c("product", "featured") Product 1
    +c("product") Product 2
    +c("product") Product 3
    +c("product") Product 4

// Sass

+page("store", "show")
  background: #EEEEEE

  +b("products")
    padding: $space

  +c("product")
    padding: $space/2
    font-size: 2rem

  +c("product", "featured")
    color: map-get($colors, green)

And here's how that would output.

<div data-controller="store" data-action="show">
  <div data-block="products">
    <div data-component="product" data-variant="featured">Product 1</div>
    <div data-component="product">Product 2</div>
    <div data-component="product">Product 3</div>
    <div data-component="product">Product 4</div>
  </div>
</div>

// Let's look at the output as SCSS for brevity.

[data-controller="store"][data-action="show"] {
  background: #EEEEEE;

  [data-block="products"] {
    padding: $space;
  }

  [data-component="product"] {
    padding: $space/2;
    font-size: 2rem;
  }

  [data-component="product" data-variant="featured"] {
    color: map-get($colors, green);
  }
}

Pages

The page() mixin takes either or both a controller and/or action in that order.

// Jade

+page("products", "show")
+page("products")
+page(null, "show")

// Sass

+page("products", "show")
  display: block

+page("products")
  display: block

+page(null, "show")
  display: block

And here is the output

<div data-controller="products" data-action="show"></div>
<div data-controller="products" data-action=""></div>
<div data-controller="" data-action="show"></div>

[data-controller="products][data-action="show"] { display: block; }
[data-controller="products] { display: block; }
[data-action="show"] { display: block; }

Blocks and Components

Blocks define large areas of an app that are in between a page and a component in significance and size. Typically, a block shouldn't exist unless there are components inside of it.

// Jade

+b("products")
  +c("product") Product 1
  +c("product") Product 2
  +c("product") Product 3

// Sass

+b("products")
  padding: $space

  +c("product")
    padding: $space/2

Here is the output

<div data-block="products">
  <div data-component="product">Product 1</div>
  <div data-component="product">Product 2</div>
  <div data-component="product">Product 3</div>
</div>

[data-block="products"] { padding: $space; }
[data-component="product"] { padding: $space/2; }

Variants

You can also add a variant attribute by passing in a second param

// Jade

+b("products")
  +c("product") Product 1
  +c("product", "featured") Product 2
  +c("product") Product 3

// Sass

+b("products")
  padding: $space

  +c("product")
    padding: $space/2

  +c("product", "featured")
    color: map-get($colors, green)

Here is the output:

<div data-block="products">
  <div data-component="product">Product 1</div>
  <div data-component="product" data-variant="featured">Product 2</div>
  <div data-component="product">Product 3</div>
</div>

[data-block="products"] { padding: $space; }
[data-component="product"] { padding: $space/2; }
[data-component="product"][data-variant="featured"] { color: map-get($colros, green); }