Child pages
  • Bootstrap, Sass and Compass in PrestaShop 1.6

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Starting with version 1.6, PrestaShop theme API heavily relies on the Bootstrap framework (version 3), together with Sass and Compass. Simply put, if you want to build a 1.6-compatible theme, you must use these technologies.

Table of Contents

Bootstrap

About Bootstrap

Bootstrap is "a sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development." This tools makes it a lot simpler to build responsive web sites – meaning websites which adapt their design to the size of the screen, from mobile phone to giant TV.

A Bootstrap design is made of:

  • Conventions for structuring HTML code and naming CSS classes.
  • A base CSS files (using the LESS or Sass format) built from a file of variables.
  • A JavaScript for the the more usual functions.
Info

Bootstrap uses a whole new way of working on web project that will really benefit all your forthcoming project – even non-PrestaShop ones! We strongly advise to dive into it:

General technical information

Bootstrap uses some specific HTML elements which make it a requirement to use HTML5. Be careful to use the proper HTML5 doctype for all your template files!
Likewise, CSS3 is used for many CSS properties.

Code Block
<!DOCTYPE html>
<html lang="fr">
...
</html>

Bootstrap 3 is made to be mobile friendly from the start of your project: instead of adding optional mobile styles to your project, these styles are built into the core of the project, ensure that it displays well on all devices.
In order to ensure that your project renders well and that the touch zoom works as expected, you must add the viewport meta tag to your template's head element:

Code Block
<meta name="viewport" content="width=device-width, initial-scale=1.0">

Bootstrap makes it easy to build a responsive design, and you can use a little trick to make your images responsive too: use Bootstrap's img-responsive class on the image. That class will make your image use max-width: 100%; and height: auto; in order to adapt to the parent element.

Code Block
<img src="http://example.com/img/image.jpg" class="img-responsive" alt="Description of the image">

Fluid grid system

Bootstrap uses a 12-column grid system, which helps you build a fluid layout. You can use media queries to indicate breakpoints to the grid system, so that it can scale up or down its number of columns depending on the screen size. The default size is tailored for very small screen sizes (up to 480px width, for small phones), so no media query is required there. Bigger screen size are managed using the following queries:

Code Block
/* Small devices (tablets, 768px and up) */
@media (min-width: @screen-sm) { ... }

/* Medium devices (desktops, 992px and up) */
@media (min-width: @screen-md) { ... }

/* Large devices (large desktops, 1200px and up) */
@media (min-width: @screen-lg) { ... }

Bootstrap uses class prefixes to differentiate devices by their screen sizes:

  • .col-xs-...: extra small, for phones (< 768px)
  • .col-sm-...: small, for tablets (≥768 px)

  • .col-md-...: medium, for desktops (≥992 px)

  • .col-lg-...: large, for large desktops and TVs (≥1200 px)

For instance:

  • col-xs-3: 3 columns on phones.
  • col-md-4: 4 columns on desktops.

For each device, Bootstrap also provides CSS classes, allowing you to change the column's position:

  • col-size-push-col: move column to the left.

  • col-size-pull-col: move column to the right.

  • col-size-offset-col : position column according to other column.

For instance:

  • col-md-push-2: On desktops, move this column by two columns to the left.

Bootstrap & Sass: Using variables and mixins

Variables

You can configure Bootstrap by editiing the variables in the _variables.scss file. For instance:

Code Block
@grid-columns: 12;
@grid-gutter-width: 30px;
@grid-float-breakpoint: 768px;

Mixins

Info

A mixin lets you make groups of CSS declarations that you want to reuse throughout your site. For instance:

Code Block
@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
     -moz-border-radius: $radius;
      -ms-border-radius: $radius;
          border-radius: $radius;
}

.box { @include border-radius(10px); }

You can use use mixins to define new styles. For instance:

Code Block
.wrapper {
  .make-row();
}
.content-main {
  .make-lg-column(8);
}
.content-secondary {
  .make-lg-column(3);
  .make-lg-column-offset(1);
}

...for the following HTML code:

Code Block
<div class="wrapper">
  <div class="content-main">...</div>
  <div class="content-secondary">...</div>
</div>

Bootstrap classes

Bootstrap has many default CSS classes, and PrestaShop defines several more, to help you build a consistent design.

Helper classes

These classes are to be used when design an element that uses one of PrestaShop's Helper classes.

  • pull-left: For left float.

  • pull-right: For right float.

  • text-muted: For gray text.

  • clearfix: To prevent excessive size of floating blocks.

  • close: To create a close button (x).

  • caret: To indicate a dropdown effect.

  • center-block: To center an element.

  • show and hidden: To show/hide an element.

Responsive classes

These classes are useful to show/hide an element depending on the device.

  • visible-xs / hidden-xs

  • visible-sm / hidden-sm

  • visible-md / hidden-md

  • visible-lg / hidden-lg

  • visible-print / hidden-print

Navigation, tabs and menus

The main classes for these contexts are:

  • navbar and navbar-inner: Container class for the navigation bar.

  • navbar-fixed-top: To attach the navigation bar to the top of the page.

  • brand: For the site's title/store name.

  • nav, nav-tabs and nav-pills: For the navigation tabs.

  • btn and btn-navba: For the buttons.

  • nav-collapse, collapse, data-toggle, data-target: To automatically hide/show content.

  • icon-th-list: To display an icon (on small screens only: th).

Here is an example of a navigation bar with a menu on the right:

Code Block
<div class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container">
      <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
        <span class="icon-th-list"></span></a>
      <a href="#" class="brand">SiteTitle</a>
      <div class="nav-collapse collapse">
        <ul class="nav pull-right">
          <li class="active"><a href="#">Home</a></li>
          <li><a href="#">About Us</a></li>
          <li><a href="#">Contact Us</a></li>
        </ul>
      </div>
    </div>
  </div>
</div>

Here is an example of menu tab:

Code Block
<ul class="nav nav-tabs">
  <li class="active"><a href="#">Home</a></li>
  <li><a href="#">Profile</a></li>
  <li class="dropdown">
    <a href="#" data-toggle="dropdown" class="dropdown-toggle">Messages <b class="caret"></b></a>
    <ul class="dropdown-menu">
      <li><a href="#">Inbox</a></li>
      <li><a href="#">Drafts</a></li>
      <li class="divider"></li>
      <li><a class="disabled" href="#">Trash</a></li>
    </ul>
  </li>
</ul>

Tables

Main classes for tables:

  • table, table-responsive: To create a table and activate the scrolling on smaller screens.

  • table-striped: To add an alternating background in the rows.

  • table-bordered: To add a border.

  • table-hover: To add a background to the row when the mouse hovers it.

  • table-condensed: To divide the cellpadding in two (makes the table more compact).

  • success, warning, danger, etc.: To change the background color of a row or of a cell.

Sample usage::

Code Block
<table class="table table-condensed table-hover">
<thead>
  <tr>
    <th>First Name</th>
    <th>Last Name</th>
    <th>Email</th>
  </tr>
</thead>
<tbody>
  <tr class="warning">
    <td>John</td>
    <td>Carter</td>
    <td>[email protected]</td>
  </tr>
  <tr>
    <td>Peter</td>
    <td>Parker</td>
    <td>[email protected]</td>
  </tr>
  <tr>
    <td>John</td>
    <td>Rambo</td>
    <td>[email protected]</td>
    </tr>
  </tbody>
</table>

Panels

Main classes for this context:

  • panel, panel-body: To define a panel.

  • panel-default, panel-primary, panel-success, panel-info, panel-warning and panel-danger: To adapt the layout to the panel.

  • panel-heading and panel-title: To add a header and a title to the panel.

  • panel-footer: To add a footer to the panel.

Sample usage:

Code Block
<div class="panel panel-default">
  <div class="panel-heading">
    <h1 class="panel-title">Panel Title</h1>
  </div>
  <div class="panel-body">
      This is the content of the panel.
  </div>
  <div class="panel-footer clearfix">
    <div class="pull-right">
      <a href="#" class="btn btn-default">Go Back</a>
    </div>
  </div>
</div>

Images

  • img-rounded: To display an image with rounded borders.

  • img-circle: To display an image within a circle.

  • img-thumbnail: To handle thumbnails.

Sample usage:

Code Block
<div class="container">
  <div class="row">
    <div class="col-xs-6">
      <div class="thumbnail">
        <img src="avatar.jpg" alt="Sample Image">
        <div class="caption">
          <h3>label</h3><p>description...</p>
        </div>
      </div>
    </div>
    <div class="col-xs-6">
      <div class="thumbnail">
        <img src="avatar.jpg" alt="Sample Image">
          <div class="caption">
            <h3>label</h3><p>description...</p>
          </div>
      </div>
    </div>
  </div>
</div>

Lists

Main classes:

  • list-unstyled: List without list-style and now padding-left.

  • list-inline: Horizontal list.

  • breadcrumb: Horizontal list for navigation path.

  • dl-horizontal: List with two aligned elements.

  • list-group: Panel-list-like display.

Breadcrumb example:

Code Block
<ul class="breadcrumb">
  <li><a href="#">Home</a></li>
  <li><a href="#">Products</a></li>
  <li class="active">Accessories</li>
</ul>

Header and paragraph example:

Code Block
<div class="list-group">
  <a href="#" class="list-group-item">
    <h4 class="list-group-item-heading">What is HTML?</h4>
    <p class="list-group-item-text">HTML stands for HyperText Markup Language. 
      HTML is the main markup     language for describing the structure of Web pages.</p>
  </a>
  <a href="#" class="list-group-item active">
    <h4 class="list-group-item-heading">What is Twitter Bootstrap?</h4>
    <p class="list-group-item-text">Twitter Bootstrap is a powerful front-end framework for faster 
    and easier web development. It is a collection of HTML and CSS based design template.</p>
  </a>
  <a href="#" class="list-group-item">
    <h4 class="list-group-item-heading">What is CSS?</h4>
    <p class="list-group-item-text">CSS stands for Cascading Style Sheet. CSS allows you to specify 
    various style properties for a given HTML element such as colors, backgrounds, fonts etc.</p>
  </a>
</div>

Forms

Main classes:

  • form-inline and form-horizontal on the form element.

  • form-group on the div that groups the label and the textarea. Enables automatic adjustment of spacing.

  • form-control on the input, textarea and select elements– which by default have a width of 100%.

A container that has the form-group class always needs a label. To add a label and display it, you must use the sr-only class. For instance:

Code Block
<div class="form-group">
  <label class="sr-only" for="exampleInput">Email address, label not visible</label>
  <input type="email" class="form-control" id="exampleInput" placeholder="Enter email">
</div>

Classes that change the appearance of zones depending on content validation:

  • has-warning
  • has-error
  • has-success

Classes that enable the display of an icon in the textarea:

  • glyphicon et form-control-feedback

  • glyphicon-ok

  • glyphicon-warning-sign

  • glyphicon-remove

For instance:

Code Block
<div class="form-group has-warning">
  <label class="control-label" for="input1">Label with warning</label>
  <input type="text" class="form-control" id="input1">
  <span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>
</div>

Main classes:

  • btn: Base class for buttons

  • btn-default, btn-primary, btn-success, btn-info, btn-warning, btn-danger, btn-link: To change the button's appearance

  • btn-lg, btn-sm and btn-xs: To change the button's size.

  • btn-block: To change the size of the parent element.

  • active and disabled: to change the availability of a button.

Code Block
<span class="button ajax_add_to_cart_button btn btn-default disabled">
  <span>{l s='Add to cart'}</span>
</span>
<a itemprop="url" class="button lnk_view btn btn-default" 
    href="{$product.link|escape:'html':'UTF-8'}" title="{l s='View'}">
  <span>{l s='More'}</span>
</a>
<button type="submit" name="submitMessage" id="submitMessage" 
    class="button btn btn-default button-medium">
  <span>{l s='Send'}<i class="icon-chevron-right right"></i></span>
</button>

Sass

About Sass

Sass is the acronym for "Syntactically Awesome Style Sheets". It is a language that you can use to build your CSS files.
While remaining CSS3-compatible, it brings a lot of features that make it easier to create consistent CSS rules with less work, most notably less copy-pasting: nesting, variables, classes, control directives (if, for, each, while), etc.
To achieve this, Sass requires the use of a preprocessors: it turns your Sass files into CSS files that all browsers can read.

Sass has two syntaxes it can use:

  • SCSS syntax, or "Sassy CSS":
    • The newer syntax, and the one PrestaShop uses.
    • Files use the .scss extension.
    • Can use semicolons and parenthesis.
    • Extension of CSS3.
  • SASS syntax, or "indented syntax":
    • Older syntax, less used.
    • Files use the .sass extension.
    • Relies on tab indentation, just as in Python.
    • No semicolon, no parenthesis.
    • Properties must start with a newline.

You can see the difference between both syntaxes here:

Code Block
titleSCSS syntax
h1 {color: #000; background: #fff}
Code Block
titleSASS syntax
h1
  color: #000
  background: #fff

Installation

Sass (and Compass in the first place, see below) require the installation of the Ruby language on your machine.

Here are some installers:

  • Windows: Download http://rubyinstaller.org/ and launch it.
  • Mac OS X: Install Homebrew (http://brew.sh/), then type "brew install ruby".
  • Linux systems: In the command line, type "sudo apt-get install ruby1.9.1".

Once Ruby is installed on your machine, install Compass – which will in turn install Sass. Go to your Ruby command line and type "gem install compass".

Starting a project project

You are now ready to create your first project:

  1. Go to the /themes folder of your local installation of PrestaShop.
  2. Open a Ruby command line window for this folder, and type "compass create".
    Compass will automatically detect or create the config.rb configuration file that is necessary for the compilation of your project.

To make sure that .scss files are automatically compiled, you can type this Ruby command: "compass watch".

Not a command line fan?

If you would rather not spend your time in the command line, Scout is the cross-platform application for you: it is a self-contained Ruby environment that gives you easy access to Compass and Sass.

Download it here: http://mhs.github.io/scout-app/

After you have installed it, you must:

  1. Create your project at the root of your theme's folder.
  2. Indicate the folder of your .scss files (Input folder).
  3. Indicate the folder for your CSS files (Output folder).

Sass syntax

Comments

There are two ways to add a comment to a Sass file.

The first one enables you to add comments without having them used in the final CSS file:

Code Block
// This comment is not used in the CSS file.
a { color: green; }

The second one uses the regular CSS syntax, and enables you to add comments that WILL be used in the final CSS file:

Code Block
/* This comment is used in the CSS file. */
a { color: green; }

Nesting

Sass enables you to nest blocks in order to define rules that apply only within that selector:

Code Block
nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }
  li { display: inline-block; }
  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

Result:

Code Block
nav ul {margin: 0; padding: 0; list-style: none;}
nav li {display: inline-block;}
nav a {display: block;  padding: 6px 12px; text-decoration: none;}

Parent selector

Sass enables you to reference the parent selector in a nested block, using &:

Code Block
 a {
   font-weight: bold ;
   &:hover{
     color: red ;
   }
   li & {
     font-weight: normal; 
  }
 }

Result:

Code Block
a {font-weight: bold ;}
a:hover {color: red ;}
li a {font-weight: normal;}

Namespace properties

CSS can use namespace-like properties, such as font-family, font-size, etc.

You can use nesting to indicate properties within a given "namespace":

Code Block
p {
  font: {
    family: arial;
    size: 1.1em;
    weight: bold;
  }
}

Result:

Code Block
p {
  font-family: arial;
  font-size: 1.1em;
  font-weight: bold; 
}

CSS output formats

Sass allows 4 different kind of generated CSS.

Nested format:

Code Block
#main {
  color: #fff;
  background-color: #000; }
  #main p {
    width: 10em; }

Expanded format:

Code Block
#main {
  color: #fff;
  background-color: #000;
}
#main p {
  width: 10em;
}

Compact format:

Code Block
#main { color: #fff; background-color: #000; }
#main p { width: 10em; }

Compressed format:

Code Block
#main{color:#fff;background-color:#000}#main p{width:10em}

SassScript

Sass can make use of a scripting language called SassScript. It makes it possible to use variables, calculation and additional functions. It can be used for any property value.

Variables

Variables must be defined with the $ prefix:

Code Block
$blue: #3bbfce;
$margin: 16px;
.content-navigation {
  border-color: $blue;
  color: darken($blue, 9%);
}
.border {
  padding: $margin/2;
  margin: $margin/2;
  border-color: $blue;
}

You can change the value of a variable, or have it changed only if the variable does not exist yet or is empty by using !default.

For instance:

Code Block
$content: "Init Value";
$content: "Init if no value" !default;
$new_content: null;
$new_content: "Init new if no value" !default;
#main {
  content: $content;
  new-content: $new_content;
}

Result:

Code Block
#main {content: "Init Value";  new-content: "Init new if no value";}

SassScript supports 6 types of variables:

  • numbers (e.g. 1.2, 13, 10px)
  • strings of text, with and without quotes (e.g. "foo", 'bar', baz)
  • colors (e.g. blue, #04a3f9, rgba(255, 0, 0, 0.5))
  • booleans (e.g. true, false)
  • nulls (e.g. null)
  • lists of values, separated by spaces or commas (e.g. 1.5em 1em 0 2em, Helvetica, Arial, sans-serif)
  • maps from one value to another (e.g. (key1: value1, key2: value2))

When using a string value, you can use #{} to unquote quoted strings, making it easier to use in some cases, for instance as a mixin selector:

Code Block
@mixin warn-message($selector) {
  body.warn #{$selector}:before {
    content: "This is a warning !";
  }
}
@include warn-message(".header");

Result:

Code Block
body.warn .header:before {content: "This is a warning !";}

You can also use the quote() and unquote() functions:

Code Block
$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=#{$family}");

Result:

Code Block
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");

Operators

Your SCSS files can directly use calculations and comparators:

  • +, -, *, /, % and the <, >, <=, => number comparators.

  • + to concatenate two strings.

  • and, or, andnot for boolean variables.

  • == and != for all variable types.

Sass can use the / operator to separate two numerical values, but Sass can use it to divide numbers. For instance:

Code Block
p {
  font: 10px/8px;             // Plain CSS, no division
  $width: 1000px;
  width: $width/2;            // Uses a variable, does division
  width: round(1.5)/2;        // Uses a function, does division
  height: (500px/2);          // Uses parentheses, does division
  margin-left: 5px + 8px/2px; // Uses +, does division
}

...is compiled into:

Code Block
p {
  font: 10px/8px;
  width: 500px;
  height: 250px;
  margin-left: 9px; }

As usual, use parenthesis to handle priorities:

Code Block
p {
  cursor: e + -resize;
  font-family: sans- + "serif";
   margin: 3px + 4px auto;
   width: (1em + 2em) * 3;
}

Result:

Code Block
p {cursor: e-resize;  font-family: sans-serif;  margin: 7px auto;  width: 9em;}

You can also use several numerical functions:

  • percentage($value) - Converts a unitless number to a percentage.

  • round($value) - Rounds a number to the nearest whole number.

  • ceil($value) - Rounds a number up to the next whole number.

  • floor($value) - Rounds a number down to the previous whole number.

  • abs($value) - Returns the absolute value of a number.

  • min($numbers...) - Finds the minimum of several numbers.

  • max($numbers...) - Finds the maximum of several numbers.

Lists

Sass uses lists for values such as margin: 10px 15px 0 0 or font-face: Helvetica, Arial, sans-serif.

Lists are a series of values, separated with space or commas.

A list can contain one or more lists. For instance, "1px, 2px, 5px 6px" is made of three elements:

  • 1px
  • 2ps
  • 5px 6px

The third element is itself a list of elements.

You have access to several list functions:

  • length($list) - Returns the length of a list.

  • nth($list, $n) - Returns a specific item in a list.

  • join($list1, $list2, [$separator]) - Joins together two lists into one.

  • append($list1, $val, [$separator]) - Appends a single value onto the end of a list.

  • zip($lists...) - Combines several lists into a single multidimensional list.

  • index($list, $value) - Returns the position of a value within a list.

The @ directives

Sass supports all of CSS3's @ rules, and adds a few more features such as:

  • Control directives for the CSS compilation.
  • Use of mixins.

@import

You can create files that contain the Sass instructions that you can include in other files.
These "imported" files must have an underscore ("_") at the beginning of their names so as to not be directly compiled into CSS.

For instance:

Code Block
title_partial.scss
html, body, ul, ol {
  margin: 0;
  padding: 0;
}

Importing _partial.scss into global.scss:

Code Block
@import 'partial';
body {
  font-size: 100% Helvetica, sans-serif;
  background-color: #efefef;
}

@import automatically searches files with a .scss or .sass extension.

You can import several files with a single call: @import "rounded-corners", "text-shadow".

You can import a file from a nested block:

Code Block
/* global.scss */
#main {
  // imports _example.scss
  @import "example"; 
}

@mixin

Mixins make it possible to group CSS properties that you can reuse as many times as necessary. They can even include other mixins.

SCSS example:

Code Block
/* File _mixin.scss */
@mixin class-inclusion {
  th {
    text-align: center;
    font-weight: bold;
  }
  th, td {
    padding: 2px;
  }
}
@mixin highlighted-background {background-color: #fc0;}
@mixin header-text {font-size: 20px;}
// mixin with other mixins
@mixin compound {
  @include highlighted-background;
  @include header-text;
}

Mixins are then used with the @include directive:

Code Block
/* File global.scss */
@import "mixin.scss";
.sassEx {@include class-inclusion;}
.mycompound {@include compound;}

Mixins can have paremeters:

Code Block
/* File _mixin.scss */
// mixins with parameters and default value 
@mixin sexy-border($color, $width: 1in) {
  border: {
    color: $color;
    width: $width;
    style: dashed;
  }
}
// mixin with unknown number of arguments
@mixin box-shadow($shadows...) {
  -moz-box-shadow: $shadows;
  -webkit-box-shadow: $shadows;
  box-shadow: $shadows;
}
// mixin with unknown number of arguments and other mixin
@mixin bold-box-shadow($shadows...) {
  font-weight: bold;
  @include box-shadow($shadows...);
}

Used in:

Code Block
/* File global.scss */
@import "mixin.scss";
// arguments with default values can be omitted
.box {  include sexy-border(blue);  }
// with explicit keyword name, arguments can be passed in any order
.bigbox {  include sexy-border($width: 3in, $color:blue);  }  
// use mixin with unknown number of arguments
.shadows { @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999); }
// use mixin with variable and unknown number of arguments 
$param: 0px 4px 5px #666, 2px 6px 10px #999;
.shadows { @include box-shadow($param...);

You can directly pass a style block to a mixin in order to place in the defined style, using @content.

SCSS example:

Code Block
@mixin apply-to-ie6-only {
  * html {
    @content;
  }
}
@include apply-to-ie6-only {
  #logo {
    background-image: url(/logo.gif);
  }
}

CSS result:

Code Block
* html #logo {
  background-image: url(/logo.gif);
}

Note that variables are evaluated within the block where they are defined:

SCSS example:

Code Block
$color: white;
@mixin colors($color: blue) {
  background-color: $color; 
  @content;  
  border-color: $color;
}
.colors {
  @include colors {color: $color;}
}

CSS result:

Code Block
.colors {
  background-color: blue; 
  color: white;
  border-color: blue;
}

@media

Sass allows the nesting of definition blocks from a @media directive.

@media directives can be nested, and they can use SassScript.

For instance, in SCSS:

Code Block
.sidebar {
  width: 300px;
  @media screen and (orientation: landscape) {
    width: 500px;
  }
}
@media screen {
  .sidebar {
    @media (orientation: landscape) {
      width: 500px;
    }
  }
}
$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;
@media #{$media} and ($feature: $value) {
  .my_sidebar {
    width: 500px;
  }
}

CSS compilation result:

Code Block
.sidebar {width: 300px; }
@media screen and (orientation: landscape) {
  .sidebar {width: 500px; } 
}
@media screen and (orientation: landscape) {
  .sidebar {width: 500px; } 
}
@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
  .my_sidebar {width: 500px; } 
}

@extend

Inheritance makes it possible to import styles from one CSS selector to another.

SCSS examples:

Code Block
.message {
  border: 1px solid #ddd;
  padding: 20px;
  color: #222;
}
.success {
  @extend .message;
  border-color: green;
}
.error {
  @extend .message;
  border-color: red;
}

CSS compilation result:

Code Block
.message, .success, .error {
  border: 1px solid #ddd;
  padding: 20px;
  color: #222;
}
.success {
  border-color: green;
}
.error {
  border-color: red;
}

You can also chain inheritance:

SCSS example:

Code Block
.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
.criticalError {
  @extend .seriousError;
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
}

CSS compilation result:

Code Block
.error, .seriousError, .criticalError {
  border: 1px #f00;
  background-color: #fdd; 
}
.seriousError, .criticalError {
  border-width: 3px; 
}
.criticalError {
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%; 
}

To create a class that would only be available through inheritance, you can use % instead of @.
%-using classes are not present in the generated CSS file.

SCSS example:

Code Block
#main a%bigblue {
  color: blue;
  font-weight: bold;
  font-size: 2em;
}
.notice {
  @extend %bigblue;
}

CSS compilation result:

Code Block
#main a.notice {
  color: blue;
  font-weight: bold;
  font-size: 2em; 
}

By default, you cannot use @extend with a non-existing selector: it gives a compilation error.
To use a selector that may not yet exist in certain conditions, you should use the !optional flag:

Code Block
a.important {
  @extend .notice !optional;
}

Likewise, you cannot use @extend in all situations, for instance when using CSS directives such as @media.
You must declare your selectors ans use them within a single directive.

Example in SCSS:

Code Block
@media print {
  .error {
    border: 1px #f00;
    background-color: #fdd;
  }
  .seriousError {
    @extend .error;
    border-width: 3px;
  }
}

Non-valid example in SCSS:

Code Block
.error {
  border: 1px #f00;
  background-color: #fdd;
}
@media print {
  .seriousError {
    // INVALID EXTEND: .error is used outside of the "@media print" directive
    @extend .error;
    border-width: 3px;
  }
}

@warn and @debug

Two directives can help you debug your Sass files:

  • @debug displays the result of a SassScript expression.
  • @warn displays information messages during the CSS file compilation.

SCSS Example:

Code Block
@debug 10em + 12em;

Displays:

Code Block
Line 1 DEBUG: 22em

Other SCSS example:

Code Block
@mixin adjust-location($x, $y) {
  @if unitless($x) {
    @warn "Assuming #{$x} to be in pixels";
    $x: 1px * $x;
  }
  @if unitless($y) {
    @warn "Assuming #{$y} to be in pixels";
    $y: 1px * $y;
  }
  position: relative; left: $x; top: $y;
}

Control instructions: @if,@for, @each,@while

These instructions are mainly used in mixins of Sass libraries such as Compass.

SCSS example:

Code Block
$type: monster;
p {
  @if $type == monster {
    color: green;
  } @else {
    color: black;
  }
}
@for $i from 1 through 3 {
  .item-#{$i} {width: 2em * $i;}
}
@each $animal in puma, sea-slug, egret, salamander {
  .#{$animal}-icon {
    background-image: url('/images/#{$animal}.png');
  }
}
$i: 6;
@while $i > 0 {
  .item-#{$i} {width: 2em * $i;}
  $i: $i - 2;
}

CSS compilation result:

Code Block
p {color: green;}
.item-1 {width: 2em;}
.item-2 {width: 4em;}
.item-3 {width: 6em;}
.puma-icon {background-image: url('/images/puma.png');}
.sea-slug-icon {background-image: url('/images/sea-slug.png');}
.egret-icon {background-image: url('/images/egret.png');}
.salamander-icon {background-image: url('/images/salamander.png');}
.item-6 {width: 12em;}
.item-4 {width: 8em;}
.item-2 {width: 4em;}

@function

You can create your own functions and use it within your files. Just make sure that its name does not conflict with the evolution of Sass and Compass.

SCSS example:

Code Block
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}
#sidebar {width: grid-width(5);}

CSS result:

Code Block
#sidebar {width: 240px;}

Children Display