Cookies helfen uns bei der Bereitstellung unserer Dienste. Durch die Nutzung unserer Dienste erklären Sie sich damit einverstanden, dass wir Cookies setzen. Mehr erfahren.

Nebula for ibase3

A collection of conventional frontend patterns by Marc Wittenbrink.


Color Guide:

HTML    Sass (SCSS)    CSS    JavaScript / jQuery    Files


Folder Structure

skins/website/en/accessories/sass/...

  • atoms
    Atoms are the basic building blocks of matter. Applied to web interfaces, atoms are our HTML tags, such as a form label, an input or a button.
  • base
    Basic styles, standards and normalize.css.
  • misc
    Files that don't belong anywhere else.
  • molecules
    Molecules are groups of atoms bonded together and are the smallest fundamental units of a compound.
  • organisms
    Organisms are groups of molecules joined together to form a relatively complex, distinct section of an interface.
  • pages
    Pages are specific instances of templates.
  • templates
    Templates consist mostly of groups of organisms stitched together to form pages.
  • utils
    An indispensable collection of SCSS-mixins and functions.
  • variables
    The settings for the main layout and the website's colours and typography can be found here.
  • vendor
    3rd-Party stuff.

Utilities

The sass/utils-folder contains a collection of useful helper mixins and functions for many areas of application.


Basic helpers

sass/utils/_helpers.scss

@mixin x-rem

@include x-rem ( string $property , string $values [, string $main-font-size] );

This mixin enables you to use the CSS3 value `rem`, which lets you define property sizes based on the root element's font-size. It outputs properties that use rem with a px fallback.

It assumes that you use html { font-size: 62.5%; } to set up a root font-size of 10px.

.selector {
    @include x-rem(font-size, 1.3);
    @include x-rem(padding, 20px 40px);
}
.selector {
    font-size: 13px;
    font-size: 1.3rem;
    padding: 20px 40px;
    padding: 2rem 4rem;
}
  • sass/utils/_helpers.scss

Utilities for layout

sass/utils/_layout.scss

@mixin clearfix

@include clearfix;
@include cf;

The inevitable. Use class .clearfix, @include clearfix or the shorthand @include cf.

.wrapper {
    @include clearfix;
}
.wrapper:after {
    content: '';
    display: table;
    clear: both;
}
  • sass/utils/_layout.scss

@function z z-index Management

z ( string $layer );

Like managing responsive breakpoints, keeping track of your website's z-layers can be far easier and much more convenient if you gather all z-indexes into a single map. Instead of assigning the z-index values directly, write z-index: z(). This is especially helpful when you need to debug your code.

$z-layers: (
    header:    30,
    content:   10,
    footer:    20
);

.header {   z-index: z(header);   }
.content {  z-index: z(content);  }
.footer  {  z-index: z(footer);   }
  • sass/variables/_layout.scss (z-index configuration)
  • sass/utils/_layout.scss (the function)

@mixin absolute / @mixin relative / @mixin fixed Positioning mixins

@include absolute ( list $args );
@include fixed ( list $args );
@include relative ( list $args );

The Sass-mixins @mixin absolute, @mixin fixed and @mixin relative offer a convenient way to position your website's elements by shorthand. Each mixin takes one argument consisting of up to four values that match the four offset properties. If you want to leave out a property, just use the value null. Use the value auto to reset an already set property.

.example-pos1
.example-pos2
.example-pos3
.example-pos4
.example-pos1 {
    /*
        top: 10px
        right: 20px
        bottom: null
        left: 40px
    */
    @include absolute(10px 20px null 40px);
}

.example-pos2 {
    /*
        top: null
        right & left: 50px
        bottom: 20px
    */
    @include absolute(null 50px 20px);
}

.example-pos3 {
    /*
        top & bottom: 120px
        right & left: 0
    */
    @include absolute(120px 0);
}

.example-pos4 {
    /*
        top & bottom & right & left: 70px
    */
    @include absolute(70px);
}
.example-pos1 {
    top: 10px;
    right: 20px;
    left: 40px;
    position: absolute;
}

.example-pos2 {
    right: 50px;
    bottom: 20px;
    left: 50px;
    position: absolute;
}

.example-pos3 {
    top: 120px;
    right: 0;
    bottom: 120;
    left: 0;
    position: absolute;
}

.example-pos4 {
    top: 70px;
    right: 70px;
    bottom: 70px;
    left: 70px;
    position: absolute;
}
  • sass/utils/_layout.scss

@mixin center-vertical

@include center-vertical;

For vertically centering inline-block-elements with a dynamic size. Doesn’t require an extra, non-semantic HTML element.

http://hackingui.com/front-end/10-best-scss-utilities/

I am a lonely div inside another lonely div. But at least I am a vertically centered div!
<div class="example-center-vert">
    <div class="example-center-vert-item">
        I am a lonely div inside another lonely div. But at least I am a vertically centered div!
    </div>
</div>
.example-center-vert {
    @include center-vertical;
    [...]
}

.example-center-vert-item {
    @include inline-block;
    [...]
}
  • sass/utils/_layout.scss

@mixin center-both

@include center-both;

Horizontally and vertically center elements with a dynamic size. Works only in modern Browsers.

I am a lonely div inside another lonely div. But at least I am a perfectly centered div!
<div class="example-center-both">
    <div class="example-center-both-item">
        I am a lonely div inside another lonely div. But at least I am a perfectly centered div!
    </div>
</div>
.example-center-both {
    position: relative;
    [...]
}

.example-center-both-item {
    @include center-both;
    [...]
}
  • sass/utils/_layout.scss

Utilities for sizing

sass/utils/_sizing.scss

@mixin size

@include size ( string $width , string $height );

A shorthand for width and height.

.card {
    @include size(100px, 200px);
}

.icon {
    @include size(40px);
}
.card {
    width: 100px;
    height: 200px;
}

.icon {
    width: 40px;
    height: 40px;
}
  • sass/utils/_sizing.scss

@mixin size-rem

@include size-rem ( string $width , string $height );

A shorthand for width and height with rem units and px-fallback.

.card {
    @include size-rem(100px, 200px);
}

.icon {
    @include size-rem(40px);
}
.card {
    width: 100px;
    width: 10rem;
    height: 200px;
    height: 20rem;
}

.icon {
    width: 40px;
    width: 4rem;
    height: 40px;
    height: 4rem;
}
  • sass/utils/_sizing.scss
  • sass/utils/_helpers.scss (dependency @mixin x-rem)

Shorthands for @mixin x-rem Size, margin and padding specifications with REM

These mixins build upon @mixin x-rem (see above) and enable you to use the CSS3 value `rem` - which lets you define property sizes based on the font-size of the root element - and still think in pixels.

Please keep in mind to use html { font-size: 62.5%; } to set up a root font-size of 10px (therefore 10px equals 1rem, 24px equals 2.4rem and so on).

@mixin margin($values) {        @include x-rem(margin, $values);        }
@mixin margin-top($value) {     @include x-rem(margin-top, $value);     }
@mixin margin-right($value) {   @include x-rem(margin-right, $value);   }
@mixin margin-bottom($value) {  @include x-rem(margin-bottom, $value);  }
@mixin margin-left($value) {    @include x-rem(margin-left, $value);    }

@mixin padding($values) {       @include x-rem(padding, $values);       }
@mixin padding-top($value) {    @include x-rem(padding-top, $value);    }
@mixin padding-right($value) {  @include x-rem(padding-right, $value);  }
@mixin padding-bottom($value) { @include x-rem(padding-bottom, $value); }
@mixin padding-left($value) {   @include x-rem(padding-left, $value);   }

@mixin width($value) {          @include x-rem(width, $value);          }
@mixin height($value) {         @include x-rem(height, $value);         }
@mixin min-width($value) {      @include x-rem(min-width, $value);      }
@mixin min-height($value) {     @include x-rem(min-height, $value);     }
@mixin max-width($value) {      @include x-rem(max-width, $value);      }
@mixin max-height($value) {     @include x-rem(max-height, $value);     }
p {
    @include margin(16px 0);
}

.container {
    @include min-width(320px);
    @include max-width(1300px);
}
p {
    margin: 16px 0;
    margin: 1.6rem 0;
}

.container {
    min-width: 320px;
    min-width: 32rem;
    max-width: 1300px;
    max-width: 130rem;
}
  • sass/utils/_sizing.scss
  • sass/utils/_helpers.scss (dependency @mixin x-rem)

@mixin aspect-ratio

@include aspect-ratio ( [ string $width-factor , string $height-factor ] );

Creates CSS for a flexible element that remains its aspect ratio when resized.

.video-wrapper {
    @include aspect-ratio;
}

.photo-35mm-wrapper {
    @include aspect-ratio(3, 2);
}
.video-wrapper {
    width: 100%;
    height: 0;
    padding-bottom: 56.25%;
}

.photo-35mm-wrapper {
    width: 100%;
    height: 0;
    padding-bottom: 66.6666667%;
}
  • sass/utils/_sizing.scss

Utilities for typography

sass/utils/_typography.scss

@mixin font-size REM font-size and line-height

@include font-size ( list $args );

Taken from http://css-tricks.com/snippets/css/less-mixin-for-rem-font-sizing/.

Especially when dealing with responsive web design, it is recommended using relative values like em or rem for your font-size and line-height-allocations. By sticking to this principle you are able to change the size of your entire website's typography by editing only the font-size value of the <html>-Element. While em is relative to the font-size of its direct or nearest parent, rem is only relative to the html (root) font-size, making using the latter easier to scale type across the entire page.

You can use this mixin to set your font-sizes and line-heights the old way - with pixel values (with or without the "px"-units) - and still write code that is fit for responsive web design.

It assumes that you use html { font-size: 62.5%; } to set up a base font-size of 10px.

Of course this mixin has a px-fallback for legacy browsers.

p {
    @include font-size(16px 24px);
}
p {
    font-size: 16px;
    font-size: 1.6rem;
    line-height: 24px;
    line-height: 2.4rem;
}
  • sass/utils/_typography.scss
  • sass/utils/_helpers.scss (dependency @mixin x-rem)

@mixin rwd-font-size Responsive Typography

@include rwd-font-size ( map $definition );

@mixin rwd-font-size is an extension of @mixin font-size (see above). It helps you setting individual font-size and line-height values tied to specific breakpoints.

Consult the next chapter "Responsive Web Design" for an explanation of the breakpoint-configuration.

$p-font-size: (
    null: (18px 26px),      // "null" is the default size
    sm:   (16px 24px),      // breakpoint "sm" (600px)
    lg:   (14px 20px)       // breakpoint "lg" (980px)
);

p {
    @include rwd-font-size($p-font-size);
}
p {
    font-size: 18px;
    font-size: 1.8rem;
    line-height: 26px;
    line-height: 2.6rem;
}

@media(min-width: 600px) {
    p {
        font-size: 16px;
        font-size: 1.6rem;
        line-height: 24px;
        line-height: 2.4rem;
    }
}

@media(min-width: 980px) {
    p {
        font-size: 14px;
        font-size: 1.4rem;
        line-height: 20px;
        line-height: 2.0rem;
    }
}
  • sass/utils/_typography.scss
  • sass/utils/_helpers.scss (dependency @mixin x-rem)

@mixin font-family

@include font-family ( string $key );
@include ff ( string $key );

Set a font-family-stack from $font-families,which can be configured in variables/_typography.scss.

@include ff can be used as a shorthand.

Text font-family

Heading font-family

Code font-family

.example-family-text {
    @include font-family('text');           // regular mixin
}

.example-family-heading {
    @include ff('heading');                 // shorthand mixin
}

.example-family-code {
    @include ff('code', $font-families);    // second parameter is optional
}
  • sass/utils/_typography.scss
  • sass/variables/_typography.scss ($font-families configuration)

@mixin truncate-text

@include truncate-text;

Taken from http://hackingui.com/front-end/10-best-scss-utilities/.

A small mixin ensuring that your text element doesn’t overflow its container and breaks nicely. It takes one parameter, which is any of the valid text-overflow values (the default value "ellipsis", "clip", or a string).

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum in posuere orci. Nam euismod gravida nunc. Ut accumsan vitae dolor interdum ullamcorper. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus.

.example-truncate {
    @include truncate-text; // parameter is optional
}
  • sass/utils/_typography.scss

@mixin remove-whitespace

@include remove-whitespace;

@include remove whitespace removes the gaps between inline-block elements by zeroing font-size and adjusting word-spacing. Use @include reset-text to set your text styles back to normal thereafter.

These
are
inline-block
<div class="rw-example">
    <div class="rw-example__item">These</div>
    <div class="rw-example__item">are</div>
    <div class="rw-example__item">inline-block</div>
</div>
.rw-example {
    @include remove-whitespace;
}

.rw-example__item {
    @include inline-block;
    border: 1px solid #f66;
    padding: 10px;
    @include rwd-font-size($p-font-size);
    @include reset-text;
}
  • sass/utils/_typography.scss

@mixin hide-text

@include hide-text;

Hide the text inside an element by using this mixin.

This text is hidden

<p class="example-hidetext">This text is hidden</p>
.example-hidetext {
    background-color: #ccf;
    width: 200px;
    height: 50px;
    @include hide-text;
}
  • sass/utils/_typography.scss

Utilities for color

sass/utils/_color.scss

@function color

color ( string $color [, string $tone , map $map ] );

Set a predefined color from $colors or another map with color definitions.

Text color

Background color

.example-color {
    color: color('primary');
}

.example-bgcolor {
    background-color: color('greyscale', 'light');
}
  • sass/utils/_colors.scss
  • sass/variables/colors.scss ($color definitions)

@function black / @function white

black ( float $opacity );
white ( float $opacity );

Returns an rgba value with the chosen opacity.

Black

White

.example-black {
    background-color: black(0.3);
}

.example-white {
    background-color: white(0.6);
}
  • sass/utils/_colors.scss

@function shade / @function tint

shade ( string $color , float $percentage );
tint ( string $color , float $percentage );
//$percentage: percentage of `$color` in returned color

Slightly darken or lighten a color, mixing it with either black or white.

shade(#00ff00, 30);

tint(#ff0000, 50);

.example-shade {
    background-color: shade(#00ff00, 30);
}

.example-tint {
    background-color: tint(#ff0000, 50);
}
  • sass/utils/_colors.scss

@mixin gradient-transition

@include gradient-transition ( string $start-color , string $end-color , string $duration );

@mixin gradient-transition creates a :hover-transition-effect with a gradient.

.button {
    @include gradient-transition($grey5, $grey4, 0.25s);
    [...]
}
  • sass/utils/_colors.scss

@mixin link-colors

@include link-colors ( string $link [ , string $visited , string $hover , string $active ] );

Set the color values for :link, :visited, :hover and :active states.

.example-linkcolors {
    @include link-colors(#00f, #00c, #009, #000);
}
  • sass/utils/_colors.scss

JavaScript features

Columns with synced heights

This feature makes use of the syncHeight Plugin for YAML, which automatically syncs the height properties of the elements that match the given selector.

The code is further extended in js/utils/syncheight.js for responsive web design. There you can define the breakpoints at which your synced columns will become unsynced by editing the array unSyncAtBreakpoints. In the example below, the breakpoints called mobile and xs are elements of this array. Therefore, the heights of the columns will only be synced if the width of the screen is high enough to activate at least the min-width-breakpoint sm.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque a ligula vitae risus vulputate venenatis. Donec luctus, sapien non maximus interdum, risus elit condimentum enim, a commodo metus ipsum vel erat.
Maecenas ac purus vitae leo pellentesque congue a id nisi. Phasellus ultrices interdum tellus eget auctor. Morbi tristique lectus sed mi malesuada, in sagittis massa consequat. Sed sed accumsan nisl. Sed bibendum gravida lorem eu tristique. Aliquam facilisis congue venenatis. Proin dui neque, commodo eget leo eget, pretium ornare lacus.
Ut pretium orci arcu, vitae pharetra neque pharetra sed.
<div class="sync-height">
    <div class="sync-me">
        ...
    </div>
    <div class="sync-me">
        ...
    </div>
</div>
  • js/vendor/jquery.syncheight.js
  • js/utils/syncheight.js

Objects

@mixin accordion

@include accordion ( [ string $color , string $hover-color ] );

Styles for an accordion ui-element. See section Accordion for more information.

  • sass/utils/objects/_accordion.scss

@mixin alert-message

@include alert-message ( string $text-color , string $bg-color , string $border-color);

Styles for an alert message ui-element. See section Alert Messages for more information.

  • sass/utils/objects/_alert.scss

@mixin carousel

@include carousel ( [ percentage $aspect-ratio , string $caption-color, string $caption-bg-color ] );

Styles for a carousel ui-element. See section Carousel for more information.

  • sass/utils/objects/_carousel.scss

@mixin dropdown-content
@mixin dropdown-content-list
@mixin dropdown

@include dropdown-content ( [ string $content-padding , string $bg-color , string $border , string $border-color , string $box-shadow ] );
@include dropdown-content-list ( [ string $padding , string $option-padding , string $color , string $hover-color , string $active-color , string $hover-bg-color , string $active-bg-color ] );
@include dropdown ( [ map $params ] );

Styles for a dropdown ui-element. See section Dropdowns for more information.

  • sass/utils/objects/_dropdown.scss

@mixin reset-list

@include reset-list;

Resets list styles (list-style-type, padding).

  • This
  • list
  • is
  • resetted
<ul class="example-reset-list">
    <li>This</li>
    <li>list</li>
    <li>is</li>
    <li>resetted</li>
</ul>
.example-reset-list {
    @include reset-list;
}
  • sass/utils/objects/_list.scss

@mixin no-list
@mixin comma-separated-list

@include no-list;
@include comma-separated-list;

While @mixin no-list removes all list-specific styles from an <ul> or <ol>, @mixin comma-separated-list makes the style-resetted list items look like a real, comma-separated list.

  • This
  • list
  • is
  • comma
  • separated
<ul class="example-comma-separated">
    <li>This</li>
    <li>list</li>
    <li>is</li>
    <li>comma</li>
    <li>separated</li>
</ul>
.example-comma-separated {
    @include no-list;
    @include comma-separated-list;
}
  • sass/utils/objects/_list.scss

@mixin embed-container

@include embed-container ( [ string $width-factor , string $height-factor ] );

@mixin embed-container makes use of @mixin aspect-ratio (see above) to output CSS for an element containing a video or another element that has to be resized proportionally.

<div class="example-embedcontainer">
    <iframe src="https://www.youtube.com/embed/IBMKyNJvNV8" frameborder="0" allowfullscreen></iframe>
</div>
.example-embedcontainer {
    @include embed-container;
}
  • sass/utils/objects/_embed-container.scss

@mixin hamburger

@include hamburger ( [ map $params ] );

@mixin hamburger outputs styles for a pure-CSS hamburger icon. See tab "SCSS" for an explanation of the parameters.

<div class="example-hamburgericon" role="button">
    <div class="example-hamburgericon__bar"></div>
    <div class="example-hamburgericon__bar"></div>
    <div class="example-hamburgericon__bar"></div>
</div>
.example-hamburgericon {
    @include hamburger((
        height: 16px,       // height of icon
        width: 22px,        // width of icon
        bar-height: 2px,    // thickness of bars
        color: #333,        // icon color
    ));
}
  • sass/utils/objects/_hamburger.scss

@mixin loading-spinner

@include loading spinner ( [ map $params ] );

Creates CSS for a loading animation. See tab "SCSS" for an explanation of the parameters.

<div class="example-spinner"></div>
.example-spinner {
    @include loading-spinner((
        size: 40px,                 // size of spinner
        border-width: 4px,          // thickness of spinner
        color1: rgba($black, 0.1),  // base color
        color2: color('primary'),   // highlight color
        duration: 1s                // duration of a single animation passing
    ));
}
  • sass/utils/objects/_loading.scss

@mixin triangle

@include triangle ( [ string $direction , string $size , string $color ] );
@include triangle-absolute ( [ string $direction , string $size , string $color ] );

@mixin triangle creates a right angled triangle pointing to a direction specified by $direction. @mixin triangle-absolute further provides styles for absolute positioning of pseudo-elements.

What a pretty triangle!
<span class="triangled">What a pretty triangle!</span>
.triangled {
    position: relative;
    [...]
    &:before {
        @include triangle-absolute(bottom, 10px, $blue1);
        bottom: -10px;
        left: 50%;
        transform: translate(-50%, 0);
    }
}
  • sass/utils/objects/_triangle.scss

Responsive Web Design

Mixins, functions and classes that may help you building a responsive website can be found in utils/_responsive.scss.

$breakpoints Global breakpoint configuration

When creating a responsive site, use the Sass-map $breakpoints in sass/variables/_layout.scss to map names to the values, making breakpoint management easier. By sticking to this map you are able to keep track of your breakpoint values and to change your media queries globally without accidently overlooking one.

Add more breakpoints as you like or change the names and values entirely. But make sure to order the values in an upward direction, starting with the smallest one, followed by the second smallest one and so on. You may benefit from the following mixins and classes that rely on $breakpoints.

$breakpoints: (
    xs: 400px,  /* iPhone 6 Plus    */
    sm: 600px,  /* Nexus 7          */
    md: 730px,  /* iPad             */
    lg: 980px,  /* Desktop 1024     */
    xl: 1200px  /* Widescreen       */
);
  • sass/variables/_layout.scss

@mixin bp-min min-width breakpoint mixin

Dynamic breakpoint mixin for responsive webdesign. Use it to create min-width media queries tied to your $breakpoints (see above).

Lazy people (like me) can also use @mixin bp which is a shorthand for @mixin bp-min.

$breakpoints: (
    xs: 400px,
    sm: 600px,
    md: 730px,
    lg: 980px,
    xl: 1200px
);

.wrapper {
    /* Styles for mobile resolution */

    @include bp(xs) {
        /* Styles for extra-small resolution */
    }

    @include bp(sm) {
        /* Styles for small resolution */
    }

    @include bp(md) {
        /* Styles for medium resolution */
    }

    @include bp(lg) {
        /* Styles for large resolution */
    }

    @include bp(xl) {
        /* Styles for extra large resolution */
    }
}
.wrapper {
    /* Styles for mobile resolution */
}

@media (min-width: 400px) {
    .wrapper {
        /* Styles for extra-small resolution */
    }
}

@media (min-width: 600px) {
    .wrapper {
        /* Styles for small resolution */
    }
}

@media (min-width: 730px) {
    .wrapper {
        /* Styles for medium resolution */
    }
}

@media (min-width: 980px) {
    .wrapper {
        /* Styles for large resolution */
    }
}

@media (min-width: 1200px) {
    .wrapper {
        /* Styles for extra large resolution */
    }
}
  • sass/variables/_layout.scss (breakpoint configuration)
  • sass/utils/_responsive.scss (the mixin)

@mixin bp-max max-width breakpoint mixin

Another dynamic breakpoint mixin creating max-width media queries instead. It will minus off 1px from the max-width query to ensure that your breakpoints don't overlap each other.

$breakpoints: (
    xs: 400px,
    sm: 600px,
    md: 730px,
    lg: 980px,
    xl: 1200px
);

.wrapper {
    /* Styles for extra large resolution */

    @include bp-max(xl) {
        /* Styles for large resolution */
    }

    @include bp-max(lg) {
        /* Styles for medium resolution */
    }

    @include bp-max(md) {
        /* Styles for small resolution */
    }

    @include bp-max(sm) {
        /* Styles for extra-small resolution */
    }

    @include bp-max(xs) {
        /* Styles for mobile resolution */
    }
}
.wrapper {
    /* Styles for extra large resolution */
}

@media (max-width: 1199px) {
    .wrapper {
        /* Styles for large resolution */
    }
}

@media (max-width: 979px) {
    .wrapper {
        /* Styles for medium resolution */
    }
}

@media (max-width: 729px) {
    .wrapper {
        /* Styles for small resolution */
    }
}

@media (max-width: 599px) {
    .wrapper {
        /* Styles for extra-small resolution */
    }
}

@media (max-width: 399px) {
    .wrapper {
        /* Styles for mobile resolution */
    }
}
  • sass/variables/_layout.scss (breakpoint configuration)
  • sass/utils/_responsive.scss (the mixin)

@mixin bp-min-max min-width and max-width breakpoint mixin

Dynamic breakpoint mixin creating min- and max-width media queries. It will minus off 1px from the max-width query to ensure that your breakpoints don't overlap each other.

You may also use @mixin bp-both as a shorthand.

$breakpoints: (
    xs: 400px,
    sm: 600px,
    md: 730px,
    lg: 980px,
    xl: 1200px
);

.wrapper {
    /* General styles */

    @include bp-min-max(xs, sm) {
        /* Styles for between extra small and small resolution */
    }

    @include bp-min-max(sm, md) {
        /* Styles for between small and medium resolution */
    }

    @include bp-min-max(md, lg) {
        /* Styles for between medium and large resolution */
    }

    @include bp-min-max(sm, xl) {
        /* Styles for between small and extra large resolution */
    }
}
.wrapper {
    /* General styles */
}

@media (min-width: 400px) and (max-width: 599px) {
    .wrapper {
        /* Styles for between extra small and small resolution */
    }
}

@media (min-width: 600px) and (max-width: 729px) {
    .wrapper {
        /* Styles for between small and medium resolution */
    }
}

@media (min-width: 730px) and (max-width: 979px) {
    .wrapper {
        /* Styles for between medium and large resolution */
    }
}

@media (min-width: 600px) and (max-width: 1199px) {
    .wrapper {
        /* Styles for between small and extra large resolution */
    }
}
  • sass/variables/_layout.scss (breakpoint configuration)
  • sass/utils/_responsive.scss (the mixin)

@mixin hd

"Retina" mixin.

.logo {
    background: url('logo-100x50.png');

    @include hd {
        background: url('logo-200x100.png');
        background-size: 100px 50px;
    }
}
.logo {
    background: url('logo-100x50.png');
}

@media (-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {

    .logo {
        background: url('logo-200x100.png');
        background-size: 100px 50px;
    }
}
  • sass/utils/_responsive.scss

Responsive helper classes

Based on the names and values of your $breakpoints-map (see above), helper classes are generated that help you letting block-level-elements appear or vanish at specific min-width breakpoints.

Currently visible (.block- and .inline-classes are set to display: none by default for the purpose of this example):

.hide-xs
.hide-sm
.hide-md
.hide-lg
.hide-xl
.block-xs
.block-sm
.block-md
.block-lg
.block-xl
.inline-xs
.inline-sm
.inline-md
.inline-lg
.inline-xl

(Resize browser window to change values)

/*
breakpoint configuation
*/
$breakpoints: (
    xs: 400px,
    sm: 600px,
    md: 730px,
    lg: 980px,
    xl: 1200px
);

/*
The following classes are generated according to the breakpoint configuation above:
*/
.hide-xs {...}      /* hidden at 400px and above    */
.hide-sm {...}      /* hidden at 600px and above    */
.hide-md {...}      /* hidden at 730px and above    */
.hide-lg {...}      /* hidden at 980px and above    */
.hide-xl {...}      /* hidden at 1200px and above   */
.block-xs {...}     /* display: block at 400px and above   */
.block-sm {...}     /* display: block at 600px and above   */
.block-md {...}     /* display: block at 730px and above   */
.block-lg {...}     /* display: block at 980px and above   */
.block-xl {...}     /* display: block at 1200px and above  */
.inline-xs {...}    /* display: inline at 400px and above   */
.inline-sm {...}    /* display: inline at 600px and above   */
.inline-md {...}    /* display: inline at 730px and above   */
.inline-lg {...}    /* display: inline at 980px and above   */
.inline-xl {...}    /* display: inline at 1200px and above  */

  • sass/variables/_layout.scss (breakpoint configuration)
  • sass/base/_standards.scss (the generator)

#responsive status

This feature allows you to add jQuery code to your responsive web design, such as - for example - programming a menu that not only looks and but also behaves differently in various screen resolutions. Once again the editable Sass-map $breakpoints (see above) is the starting point for this feature.

The HTML-element <span id="responsive-status"></span> has to be placed inside your main layout file. Its css-attribute font-family will be set to the name of the currently active min-width breakpoint. This attribute can be read via JavaScript-Code, so your scripts can react to specific screen resolutions. The jQuery-Code below is located in the file js/utils/responsive.js. You may have to change the function checkResponsiveStatus or more specifically the switch(status)-expression so that the cases match the names of your breakpoints in $breakpoints which your jQuery code should react to.

As an additional gimmick, the class-attribute of the <body>-tag will be set to a value being the name of the currently active min-width breakpoint, prefixed with "responsive-". For example it says <body class="responsive-md"> for the breakpoint called "md". This helps you to make your responsive site compatible to legacy browsers if necessary.

Current status:
<body>-classname: responsive-

(Resize browser window to change values)

<span id="responsive-status"></span>
$breakpoints: (
    xs: 400px,
    sm: 600px,
    md: 730px,
    lg: 980px,
    xl: 1200px
);

#responsive-status {
    display: none;
    font-family: "mobile";
}
@each $breakpoint in $breakpoints {
    $name: nth($breakpoint, 1);
    $width: nth($breakpoint, 2);
    @media (min-width: $width) {
        #responsive-status {
            font-family: "#{$name}";
        }
    }
}
function checkResponsiveStatus() {
    var currBreakpoint = $('#responsive-status').css('font-family');

    if (currBreakpoint != lastBreakpoint) {

        // Set <body> classname to responsive-{name of current breakpoint}
        $('body').removeClass (function (index, css) {
            return (css.match (/(^|\s)responsive-\S+/g) || []).join(' ');
        });
        $('body').addClass("responsive-" + currBreakpoint);

        // Just for presentation (may be deleted)
        $('.example-rs').html(currBreakpoint);

        // Call functions tied to current breakpoint
        // Add your own cases if you like
        switch(currBreakpoint) {
            case "mobile":
                console.log("JavaScript-Code for mobile resolution");
                break;

            case "xs":
                console.log("JavaScript-Code for extra small (xs) resolution");
                break;

            case "sm":
                console.log("JavaScript-Code for small (sm) resolution");
                break;

            case "md":
                console.log("JavaScript-Code for medium (md) resolution");
                break;

            case "lg":
                console.log("JavaScript-Code for large (lg) resolution");
                break;

            case "xl":
                console.log("JavaScript-Code for extra large (xl) resolution");
                break;
        }
    }

    lastBreakpoint = currBreakpoint;

    return currBreakpoint;
}

var lastBreakpoint = false,
    currBreakpoint = false;

$(document).ready(function() {

    // Groessenaenderung des Browserfensters abfangen
    $( window ).bind( "resize", function(){
        currBreakpoint = checkResponsiveStatus();
    });

    // Seite initialisieren
    currBreakpoint = checkResponsiveStatus();

});
  • sass/variables/_layout.scss (breakpoint configuration)
  • sass/base/_standards.scss (SCSS-code)
  • templates/layout_main.html (HTML-code)
  • js/responsive.js (jQuery-Code)

Grid

When building a responsive website, I recommend using the Sass-map $breakpoints (see above) to keep track of your responsive breakpoints. Also, use the mixin @mixin bp-min (see above) to write your @media-queries.

Susy

Responsive grid system.

Official Website: http://susy.oddbird.net/
A good Susy tutorial: http://www.smashingmagazine.com/2015/07/smarter-grids-with-sass-and-susy/

(none)
@include bp(xs) { @include span(6); }
@include bp(sm) { @include span(4); }
(none)
@include bp(xs) { @include span(6) last; }
@include bp(sm) { @include span(4); }
@include bp(sm) { @include span(4) last; }

(none)
@include bp(xs) { @include span(6); }
@include bp(sm) { @include span(4); }
@include bp(md) { @include span(3); }
(none)
@include bp(xs) { @include span(6 last); }
@include bp(sm) { @include span(8 last); }
@include bp(md) { @include span(9 last); }
<div class="container">
    <div class="sidebar">
        ...
    </div>
    <div class="content">
        ...
    </div>
</div>
/*
# Susy settings

Global settings for susy grid system.
http://susydocs.oddbird.net/en/latest/settings/
*/
$susy: (
    columns:            12,
    gutters:            1/3,
    container:          $max-width,
    global-box-sizing:  border-box
);

.container {
    @include container;
}

.sidebar {
    @include bp(xs) {   @include span(6);   }
    @include bp(sm) {   @include span(4);   }
    @include bp(md) {   @include span(3);   }
}

.content {
    @include bp(xs) {   @include span(6 last);  }
    @include bp(sm) {   @include span(8 last);  }
    @include bp(md) {   @include span(9 last);  }
}
  • sass/variables/_layout.scss (config vars)
  • bower_components/susy/ (grid system code)

Basics

Headings and body copy

Heading 1 <h1>

Heading 2 <h2>

Heading 3 <h3>

Heading 4 <h4>

Heading 5 <h5>
Heading 6 <h6>

Heading 4 with class .h2 <h4 class="h2">

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum in posuere orci. Nam euismod gravida nunc. Ut accumsan vitae dolor interdum ullamcorper. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus. Duis a euismod erat. Sed faucibus ultricies sem, varius fringilla velit ullamcorper sit amet.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum in posuere orci. Nam euismod gravida nunc. Ut accumsan vitae dolor interdum ullamcorper. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus. Duis a euismod erat. Sed faucibus ultricies sem, varius fringilla velit ullamcorper sit amet.

<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4;</h4>
<h4 class="h2">Heading 4 with class .h2</h4>
<p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum in posuere orci. Nam euismod gravida nunc. Ut accumsan vitae dolor interdum ullamcorper. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus. Duis a euismod erat. Sed faucibus ultricies sem, varius fringilla velit ullamcorper sit amet.
</p>
<p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum in posuere orci. Nam euismod gravida nunc. Ut accumsan vitae dolor interdum ullamcorper. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus. Duis a euismod erat. Sed faucibus ultricies sem, varius fringilla velit ullamcorper sit amet.
</p>
  • sass/variables/_typography.scss
  • sass/atoms/_heading.scss
  • sass/atoms/_paragraph.scss

Lead body copy

Make a paragraph stand out by adding class="lead".

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus. Duis a euismod erat.

<p class="lead">
    Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus. Duis a euismod erat.
</p>
  • sass/variables/_typography.scss
  • sass/atoms/_paragraph.scss

Small text

Create small text by adding class="small".

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus. Duis a euismod erat.

<p class="small">
    Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus. Ut luctus, lacus quis finibus bibendum, tortor nisl tristique mauris, eu efficitur nisi felis sit amet lacus. Duis a euismod erat.
</p>
  • sass/variables/_typography.scss
  • sass/atoms/_paragraph.scss

Unordered list

  • Eins
    • Eins.Eins
    • Eins.Zwei
  • Zwei
  • Drei
  • Vier
<ul>
    <li>Eins
        <ul>
            <li>Eins.Eins</li>
            <li>Eins.Zwei</li>
        </ul>
    </li>
    <li>Zwei</li>
    <li>Drei</li>
    <li>Vier</li>
</ul>
  • sass/molecules/_list.scss

Ordered list

  1. Eins
    1. Eins.Eins
    2. Eins.Zwei
  2. Zwei
  3. Drei
  4. Vier
<ol>
    <li>Eins
        <ol>
            <li>Eins.Eins</li>
            <li>Eins.Zwei</li>
        </ol>
    </li>
    <li>Zwei</li>
    <li>Drei</li>
    <li>Vier</li>
</ol>
  • sass/molecules/_list.scss

Floating elements & lightboxes

Use the classes .floatleft and .floatright to create floating elements, such as - for example - photos inside an article. Note that these elements will only begin to float when a specific $breakpoint (see above) is reached ("sm" being the default). When floating, these elements will never grow larger than 50% of the available space.

Nebula now uses Magnific Popup for lightboxes. Use class .lightbox when linking to a document, .lightbox-image when linking to an image and .lightbox-iframe when linking to an iframe.

.floatleft Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc luctus dolor a nulla sollicitudin luctus. Aenean in dolor sem. Donec erat neque, pharetra ut massa ut, feugiat maximus tortor. Aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse potenti. Pellentesque ac lacus vel diam tempus tempus. Nulla vel placerat quam. Fusce vel egestas elit. Pellentesque maximus erat ut tortor sollicitudin tincidunt. Nunc quis est id risus posuere pretium. Praesent ut nisi non ipsum molestie tincidunt. Aliquam mollis mauris sed velit ultricies, in blandit eros ultricies. Phasellus pulvinar dolor vel lacinia mollis. Donec tempor justo ac tellus molestie, pellentesque rutrum augue porta. Integer efficitur mi eu porta imperdiet. Nullam tincidunt urna id pellentesque tempus.

.floatright Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc luctus dolor a nulla sollicitudin luctus. Aenean in dolor sem. Donec erat neque, pharetra ut massa ut, feugiat maximus tortor. Aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse potenti. Pellentesque ac lacus vel diam tempus tempus. Nulla vel placerat quam. Fusce vel egestas elit. Pellentesque maximus erat ut tortor sollicitudin tincidunt. Nunc quis est id risus posuere pretium. Praesent ut nisi non ipsum molestie tincidunt. Aliquam mollis mauris sed velit ultricies, in blandit eros ultricies. Phasellus pulvinar dolor vel lacinia mollis. Donec tempor justo ac tellus molestie, pellentesque rutrum augue porta. Integer efficitur mi eu porta imperdiet. Nullam tincidunt urna id pellentesque tempus.

.floatleft Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc luctus dolor a nulla sollicitudin luctus. Aenean in dolor sem. Donec erat neque, pharetra ut massa ut, feugiat maximus tortor. Aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse potenti. Pellentesque ac lacus vel diam tempus tempus. Nulla vel placerat quam. Fusce vel egestas elit. Pellentesque maximus erat ut tortor sollicitudin tincidunt. Nunc quis est id risus posuere pretium. Praesent ut nisi non ipsum molestie tincidunt. Aliquam mollis mauris sed velit ultricies, in blandit eros ultricies. Phasellus pulvinar dolor vel lacinia mollis. Donec tempor justo ac tellus molestie, pellentesque rutrum augue porta. Integer efficitur mi eu porta imperdiet. Nullam tincidunt urna id pellentesque tempus.

Open YouTube video
Open Vimeo video
Open Google Map

<p>
    <img class="floatleft" src="img/picture.png" alt=".floatleft">
    Lorem ipsum dolor sit amet...
</p>
<p>
    <img class="floatright" src="img/picture.png" alt=".floatright">
    Aliquam mollis mauris sed ...
</p>
  • sass/base/_layout.scss (floating elements-styles for website)
  • sass/organisms/_lightbox.scss

Responsive video embeds

Embed videos from YouTube, Video, Dailymotion etc. into fluid layouts. The videos maintain an aspect ratio of 16:9 regardless of the available display size.

If you need another aspect ratio, use @mixin embed-container($width, $height) on your embed div. For example @include embed-container(4, 3); for a classic 4:3 ratio.

<div class="embed-container">
    <iframe src="https://player.vimeo.com/video/59361603" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
  • sass/atoms/_embed-container.scss
  • sass/utils/objects/_embed-container.scss (dependency)
  • sass/utils/_sizing.scss (dependency)

Carousel

Single image carousel

This carousel is powered by slick (http://kenwheeler.github.io/slick/). Please refer to its documentation for more info.

<div class="carousel carousel--single">
    <ul class="slick" data-slick='{"autoplay": true, "autoplaySpeed": 8000, "speed": 1000}'>

        <li class="carousel__item">
            <img src="temp/explorer/files/root/placeholder/headers/header01.jpg">
            <div class="carousel__caption">Beach</div>
        </li>

        [...]

    </ul>
</div>
// http://kenwheeler.github.io/slick/

$(function() {
    $('.carousel--single .slick').slick();
});
  • Mandatory:
    • bower_components/slick-carousel/**/*
  • Optional (but needed for this demo):
    • sass/utils/objects/_carousel.scss
    • javascript/components/carousel.js

Multi image carousel


Forms

Best practice forms

Based on Form Kitchen Sink

This example meets the following requirements:

  • Container independent, flexible widths in percent
  • Responsive, linearizable, mobile-ready
  • Browser support: IE9 and up, Chrome latest, Safari latest, Firefox latest, Opera latest, major mobile browsers
  • 2 variants: labels left (for most forms) and labels above (small or narrow forms)
  • Doesn't break with multi-line labels
  • Client-side validation via HTML5 input types and JavaScript support
  • Inline error messages
  • Backend/templating friendly
    • Suitable for using label/input/error includes/snippets
    • Slim and flexible markup

Update 05/07/2016: Included styles from formalize CSS to achieve consistent styling of form elements across all major browsers.

Form kitchen sink

Labels left: Suitable for most forms
Labels above: Better for short or narrow forms

Switch label position
Salutation
Link button
Your rating
<form>
    <fieldset class="wideform">
        <div class="formrow">
            <label class="label req" for="firstname">First/last name</label>
            <div class="formitem col-1of2">
                <label class="label req" for="firstname">First name</label>
                <input class="formfield" type="text" name="firstname" id="firstname" placeholder="Placeholder" required="required" x-autocompletetype="given-name"/>
            </div>
            <div class="formitem col-1of2">
                <label class="label req" for="firstname">Last name</label>
                <input class="formfield" type="text" name="lastname" id="lastname" placeholder="... with polyfill" required="required" x-autocompletetype="family-name"/>
            </div>
        </div>
        <div class="formrow">
            <div class="formitem col-1of3">
                <label class="label" for="zip">Zip</label>
                <input class="formfield" type="text" name="zip" id="zip" pattern="[0-9]" x-autocompletetype="postal-code"/>
            </div>
            <div class="formitem col-2of3">
                <label class="label" for="zip">City</label>
                <input class="formfield" type="text" name="city" id="city" x-autocompletetype="city"/>
            </div>
        </div>
    </fieldset>
</form>
  • sass/atoms/_form-field.scss
  • sass/atoms/_form-error.scss
  • sass/atoms/_form-placeholder.scss
  • sass/molecules/_form-item.scss
  • sass/molecules/_form-row.scss
  • sass/molecules/_form-ticks.scss
  • sass/molecules/_fieldset.scss
  • sass/organisms/_form.scss
  • (sass/molecules/_form-rating.scss)
  • js/components/form.js

Easygrid

Very basic, selfmade grid. Classes are mandatory for "form kitchen sink" (see above).

.col-1of4
.col-1of4
.col-1of4
.col-1of4
.col-1of1
.col-1of2
.col-1of2
.col-1of3
.col-2of3
.col-1of4
.col-3of4
.col-2of5
.col-3of5
.col-1of5
.col-4of5
<div class="grid">
    <div class="col-1of5">
        ...
    </div>
    <div class="col-4of5">
        ...
    </div>
</div>
  • sass/organisms/_form.scss

Custom radiobuttons and checkboxes

Use <div class="custom-ticks"> or <div class="ticks custom-ticks"> as a wrapper around a group of checkboxes and radiobuttons to activate custom styling.

<form action="#" method="get">
    <div class="formrow">
        <div class="formitem">
            <div class="ticks custom-ticks">
                <label>
                    <input type="radio" name="salutation" id="salutation-mrs" value="mrs">
                    <span>Mrs.</span>
                </label>

                [...]

            </div>
        </div>
    </div>
    <div class="formrow">
        <div class="formitem">
            <div class="ticks custom-ticks">
                <label>
                    <input type="checkbox" name="newsletter" id="custom-newsletter">
                    <span>Subscribe to newsletter</span>
                </label>
            </div>
        </div>
    </div>
</form>
  • sass/molecules/_form-ticks-custom.scss

Custom select boxes

Use <div class="custom-select"> as a wrapper around a single select box to activate custom styling.

By default it is styled similar to the regular (non-custom-) select box.

<form action="#" method="get">
    <div class="formrow">
        <div class="formitem">
            <div class="custom-select">
                <select class="formfield">
                    <option value="cocacola">Coca Cola</option>
                    <option value="pepsicola">Pepsi Cola</option>
                    <option value="africola">Afri Cola</option>
                    <option value="rivercola">River Cola</option>
                    <option value="lidlcola">Die unleckere Cola vom Lidl</option>
                </select>
            </div>
        </div>
    </div>
</form>
  • sass/atoms/_form-field-custom.scss
  • javascript/components/_form-custom.js

Custom text inputs

Use <div class="custom-input"> as a wrapper around a single input (text, password, number, tel, email, url, date, time, month, week, datetime, datetime-local) or textarea to activate custom styling.

By default it is styled like the regular (non-custom-) form fields.

<form action="#" method="get">
    <div class="formrow">
        <div class="formitem">
            <label class="label" for="custominput">Custom input</label>
            <div class="custom-input">
                <input class="formfield" type="text" id="custominput">
            </div>
        </div>
    </div>
    <div class="formrow">
        <div class="formitem">
            <label class="label" for="customarea">Custom textarea</label>
            <div class="custom-input">
                <textarea class="formfield" cols="40" rows="5" id="customarea"></textarea>
            </div>
        </div>
    </div>
</form>
  • sass/atoms/_form-field-custom.scss
  • javascript/components/_form-custom.js

Floating labels

Add class .floatlabel to the .formitem-Element to have its label floated. Doesn't work within forms or fieldsets with class .wideform.

<form action="#" method="get" id="form2">
    <div class="formrow">
        <div class="formitem col-1of2 floatlabel">
            <label class="label req" for="firstname2">First name</label>
            <input class="formfield" type="text" name="firstname" id="firstname2" required="required" x-autocompletetype="given-name"/>
        </div>
        <div class="formitem col-1of2 floatlabel">
            <label class="label req" for="lastname2">Last name</label>
            <input class="formfield" type="text" name="lastname" id="lastname2" required="required" x-autocompletetype="family-name"/>
        </div>
    </div>
</form>
  • sass/atoms/_form-floatlabel.scss
  • js/components/form-floatlabels.js

Password helper

Wrap your <input type="password"> into a div with class .password-helper to create a button that can switch the type of the password-field to "text" and back to "password" when clicked.

This not only helps clueless people to master the password field but makes it just a little bit more convenient for everyone.

<form action="#" method="get" id="form2">
    <div class="formrow">
        <div class="formitem col-1of2">
            <label class="label req" for="password1">Password</label>
            <div class="password-helper">
                <input class="formfield" type="password" name="password" id="password1" required="required" />
            </div>
        </div>
        <div class="formitem col-1of2">
            <label class="label req" for="password2">Password again</label>
            <div class="password-helper">
                <input class="formfield" type="password" name="password2" id="password2" required="required" />
            </div>
        </div>
    </div>
</form>
  • sass/molecules/_form-password-helper.scss
  • js/components/form-password-helper.js

Form notice

You can use two kinds of notices to aid the user filling out your forms.

The first helps setting a password in two password text inputs, the latter being a confirmation field that has to be filled out exactly like the first. Add class .form-notice-password to the first field and .form-notice-password-again to the second. Both fields have to be followed by two corresponding message-elements, possessing the classes .form-notice .form-notice--incomplete and .form-notice .form-notice--success. See the HTML-Tab for details.

The second king of notice displays while the corresponding field is focused and will be hidden as soon as the focus is lost. Use class .form-notice-focused on the input field, followed by the message-element having class .form-notice.

Wrap your <fieldset> in <div class="form-notices"> to make space for the notices.

Your password must contain six or more characters
Please repeat your password in this field
This notice is shown as long as the field is focused
<div class="form-notices">

    <fieldset>
        <form action="#" method="get" id="form2">
            <div class="formrow">
                <div class="formitem">
                    <label class="label req" for="password1">Password</label>
                    <input class="formfield form-notice-password" type="password" name="password" id="password1" required="required" />
                    <div class="form-notice form-notice--incomplete">Your password must contain six or more characters</div>
                    <div class="form-notice form-notice--success">✔</div>

                </div>
            </div>
            <div class="formrow">
                <div class="formitem">
                    <label class="label req" for="password2">Password again</label>
                    <input class="formfield form-notice-password-again" type="password" name="password2" id="password2" required="required" />
                    <div class="form-notice form-notice--incomplete">Please repeat your password in this field</div>
                    <div class="form-notice form-notice--success">✔</div>
                </div>
            </div>
        </form>
    </fieldset>

    <fieldset>
        <div class="formrow">
            <div class="formitem">
                <label class="label" for="notice-salutation">Please focus this field</label>
                <input class="formfield form-notice-focused">
                <div class="form-notice">This notice is shown as long as the field is focused</div>
            </div>
        </div>
    </fieldset>

</div>
  • sass/molecules/_form-password-helper.scss
  • js/components/form-password-helper.js

Form field groups

Taken from Bootstrap.

Spice up your forms by adding text or buttons before, after or on both sides of any text-based <input> field. Use .formgroup with .formgroup__addon or .formgroup__btn to prepend or append elements to a single textual <input>.

Type your E-Mail-Address here:
@gmail.com
<form action="#" method="get" id="form2">
    <div class="formrow">
        <div class="formitem">
            <label class="label" for="email3">Basic formgroup-addons</label>
            <div class="formgroup">
                <div class="formgroup__addon">Type your E-Mail-Address here:</div>
                <input class="formfield" type="email" name="email3" id="email3" />
                <div class="formgroup__addon">@gmail.com</div>
            </div>
        </div>
    </div>
    <div class="formrow">
        <div class="formitem col-1of2">
            <label class="label" for="addoncheck">With checkbox</label>
            <div class="formgroup">
                <div class="formgroup__addon">
                    <input type="checkbox" />
                </div>
                <input class="formfield" type="text" name="addoncheck" id="addoncheck" />
            </div>
        </div>
        <div class="formitem col-1of2">
            <label class="label" for="addonradio">With radio button</label>
            <div class="formgroup">
                <div class="formgroup__addon">
                    <input type="radio" />
                </div>
                <input class="formfield" type="text" name="addonradio" id="addonradio" />
            </div>
        </div>
    </div>
    <div class="formrow">
        <div class="formitem col-1of2">
            <label class="label" for="addonbtn">Button</label>
            <div class="formgroup">
                <input class="formfield" type="text" name="addonbtn" id="addonbtn" placeholder="Suchbegriff" />
                <div class="formgroup__btn">
                    <button class="btn">Los!</button>
                </div>
            </div>
        </div>
        <div class="formitem col-1of2">
            <label class="label" for="addonbtngrp">Button group</label>
            <div class="formgroup">
                <div class="formgroup__btn">
                    <button class="btn">A</button>
                    <button class="btn">B</button>
                    <button class="btn">C</button>
                </div>
                <input class="formfield" type="text" name="addonbtngrp" id="addonbtngrp" />
            </div>
        </div>
    </div>
</form>
  • sass/molecules/_form-group.scss

Buttons

Basic button

Create a button by using the class .btn.

<button class="btn">I am a button</button>
  • sass/atoms/_button.scss

Color variants

Use .btn--primary, .btn--decline or .btn--accept to give your button its purpose.

<button class="btn">Normal button</button>
<button class="btn btn--primary">Primary button</button>
<button class="btn btn--decline">Decline button</button>
<button class="btn btn--accept">Accept button</button>
  • sass/atoms/_button.scss

Size variants

You may alter its size with .btn--sm or .btn--lg.

<button class="btn btn--sm">Small button</button>
<button class="btn btn--lg">Large button</button>
  • sass/atoms/_button.scss

Disabled buttons

Add class .disabled or add the disabled attribute to <button> buttons to make it look unclickable.

<button class="btn disabled">Disabled button</button>
<button class="btn btn--primary disabled">Disabled button</button>
<button class="btn btn--decline disabled">Disabled button</button>
<button class="btn btn--accept disabled">Disabled button</button>
  • sass/atoms/_button.scss

Round buttons

Add shapes with .btn--prev, .btn--next or .btn--round.

<button class="btn btn--prev"><i class="fa fa-angle-left"></i> Prev button</button>
<button class="btn btn--next">Next button <i class="fa fa-angle-right"></i></button>
<button class="btn btn--round">Round button</button>
  • sass/atoms/_button.scss

Full button

A .btn--full spans the available horizontal space.

<button class="btn btn--full">Full button</button>
  • sass/atoms/_button.scss

Button group

Setup a button group by wrapping your buttons with .btn-group.

<div class="btn-group">
    <button class="btn">Grouped</button>
    <button class="btn">buttons</button>
    ...
</div>
  • sass/molecules/_button-group.scss

Combinations

You may combine every colour with every size and every shape.


<button class="btn btn--sm btn--round">Small and round button</button>
<br>
<div class="btn-group">
    <button class="btn btn--decline btn--prev"><i class="fa fa-times"></i> Abort</button>
    <button class="btn btn--accept btn--next"><i class="fa fa-check"></i> Okay</button>
</div>
<button class="btn btn--lg btn--primary btn--full">Big, primary and full button</button>
  • sass/atoms/_button.scss

New colors and sizes

All information for button-sizes and -colors is stored in two Sass maps called $button-color-map (which contains all color-variants) and $button-size-map (which contains all size-variants) in sass/components/_buttons.scss. Edit these maps accordingly to change existing or add new CSS classes for button colors and sizes.

// SCSS:
$button-color-map: (
    [...]
    'btn--dark': (
        'color':                #ccc,
        'border-color':         #000,
        'bg-color':             #333,
        'hover-color':          #ccc,
        'hover-border-color':   #000,
        'hover-bg-color':       #222,
        'active-color':         #ccc,
        'active-border-color':  #000,
        'active-bg-color':      #111,
        'font-family':          'button'
    )
);
<!-- HTML: -->
<button class="btn btn--dark">Dark button</button>
// SCSS:
$button-size-map: (
    [...]
    'btn--giant': (
        'font-size':            60px,
        'padding-top':          40px,
        'padding-right':        80px,
        'padding-bottom':       40px,
        'padding-left':         80px,
        'height':               auto,
        'next-border-radius':   70px
    )
);
<!-- HTML: -->
<button class="btn btn--giant">Giant button</button>

@mixin create-button A mixin to assign button styles to an element

With this mixin you will be able to assign button styles, predefined via $button-color-map and $button-size-map to an element. This will be handy - for example - when creating a responsive site where an element has to look like a button only at a specific breakpoint.

<a class="you-will-be-a-button" href="...">See? I am a button.</a>.you-will-be-a-button {
    @include create-button('btn--primary', 'btn--lg');
}
  • sass/atoms/_button.scss

Loading button

Add class .btn--loading to display a loading animation when clicked. Or also add class .loading to activate the animation manually.

<button class="btn btn--loading">Click me</button>
  • sass/atoms/_button.scss

Tabs

Create a tabbed section by adding a <div class="js-tabs">. Use class .tabs to apply styles. Place your tabs into ul.tabs__list and add the corresponding content panes having .tabs__content and an id matching the href-Attribute of the tab-links.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam malesuada fermentum mi. Integer ut massa dignissim, fermentum odio a, scelerisque sem. Cras ut mi sed mi iaculis tempor ac ut est. Nulla iaculis eu lectus in luctus. Ut pretium felis sit amet quam rutrum malesuada. Phasellus gravida quam nunc, nec faucibus turpis feugiat et. Sed nec sem a nunc pellentesque volutpat. Duis pharetra varius blandit. Nulla posuere lorem dui, vel suscipit mauris tincidunt eget. Proin sed finibus justo. Integer vel aliquet nulla, a fermentum ex.

Vivamus sed aliquet nisl, sit amet mollis leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam tempor orci id lectus condimentum feugiat. In eleifend urna elit, et semper odio dapibus eu. Fusce imperdiet faucibus lectus. Donec lobortis tempus arcu, in lacinia purus. Curabitur placerat elementum porta.

Phasellus rhoncus ipsum in nulla mattis hendrerit. Vestibulum magna nunc, luctus at luctus a, sodales eget ligula. Vivamus eget massa ac dolor vehicula gravida eu ac quam. Ut eu ante bibendum, facilisis lectus eu, imperdiet felis. In nec nibh et nunc tincidunt malesuada. Duis a porta ligula, sit amet scelerisque purus. Etiam scelerisque sed lectus nec dictum. Duis at justo nunc. Ut justo est, eleifend eu libero vitae, gravida congue lacus. Cras nec neque id nisl dapibus tincidunt. Etiam id vehicula nisi, ut rutrum mauris. In sollicitudin non ex sit amet facilisis. Cras mauris arcu, sagittis vel bibendum eu, ornare sit amet felis. Phasellus accumsan enim ligula, vitae suscipit mi blandit sed. Ut lobortis risus non aliquet venenatis. Etiam eros mauris, eleifend non leo nec, dictum mollis magna.

<div class="tabs js-tabs">
    <ul class="tabs__list">
        <li><a href="/de-DE/example-1#tab1">Tab 1</a></li>
        <li><a href="/de-DE/example-1#tab2">Tab 2</a></li>
        <li><a href="/de-DE/example-1#tab3">Tab 3</a></li>
    </ul>
    <div id="tab1" class="tabs__content">...</div>
    <div id="tab2" class="tabs__content">...</div>
    <div id="tab3" class="tabs__content">...</div>
</div>
  • sass/molecules/_tabs.scss
  • js/components/tabs.js

Accordion

Place at least one combination of .accordion__toggle and .accordion__content inside a .js-accordion to create...well...an accordion. Use class .accordion to apply styles. Use padding instead of margin for .accordion__toggle and .accordion__content to ensure a soft animation.

Initially closed accordion

Lorem ipsum dolor sit amet, consectetur adipiscing elit

Phasellus finibus maximus libero, eget tincidunt nisl dapibus vitae. Vestibulum sem purus, sollicitudin ut consectetur eget, dignissim eget mi. Curabitur scelerisque dui non tellus auctor, sed euismod sapien molestie. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam nec ornare sapien. Etiam eu dolor aliquam, sollicitudin nibh quis, tempor nisl. Quisque eget turpis suscipit, imperdiet nisi eget, elementum lorem. Aliquam ultrices, metus in egestas elementum, purus sapien elementum tortor, vitae tempus nulla quam in purus.

Ut a molestie tellus

Phasellus sit amet accumsan massa. Aliquam erat volutpat. Ut iaculis posuere mattis. Sed porttitor pellentesque sapien, eu bibendum arcu sagittis nec. Donec auctor justo ut rhoncus suscipit. Ut laoreet finibus felis non molestie. Donec dapibus orci in erat interdum auctor. Maecenas vulputate nisl nec blandit accumsan. Praesent vitae ultrices tellus. Nullam ultricies neque et urna placerat rhoncus.

<div class="accordion js-accordion">
    <h4 class="accordion__toggle">
        ...
    </h4>
    <p class="accordion__content">
        ...
    </p>
    ...
</div>
  • sass/molecules/_accordion.scss
  • js/components/accordion.js

Initially open accordion

Add class .accordion__toggle--open to an .accordion__toggle to have its .accordion__content initially opened at page load.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Phasellus finibus maximus libero, eget tincidunt nisl dapibus vitae. Vestibulum sem purus, sollicitudin ut consectetur eget, dignissim eget mi. Curabitur scelerisque dui non tellus auctor, sed euismod sapien molestie. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam nec ornare sapien. Etiam eu dolor aliquam, sollicitudin nibh quis, tempor nisl. Quisque eget turpis suscipit, imperdiet nisi eget, elementum lorem. Aliquam ultrices, metus in egestas elementum, purus sapien elementum tortor, vitae tempus nulla quam in purus.

Ut a molestie tellus

Phasellus sit amet accumsan massa. Aliquam erat volutpat. Ut iaculis posuere mattis. Sed porttitor pellentesque sapien, eu bibendum arcu sagittis nec. Donec auctor justo ut rhoncus suscipit. Ut laoreet finibus felis non molestie. Donec dapibus orci in erat interdum auctor. Maecenas vulputate nisl nec blandit accumsan. Praesent vitae ultrices tellus. Nullam ultricies neque et urna placerat rhoncus.

<div class="accordion js-accordion">
    <h4 class="accordion__toggle accordion__toggle--open">
        ...
    </h4>
    <p class="accordion__content">
        ...
    </p>
    ...
</div>
  • sass/molecules/_accordion.scss
  • js/components/accordion.js

Accordion with open first element

Adding class .js-accordion--openfirst or attribute data-accordion="openfirst" to the .js-accordion will open its first child element automatically at initialization.

Lorem ipsum dolor sit amet, consectetur adipiscing elit

Phasellus finibus maximus libero, eget tincidunt nisl dapibus vitae. Vestibulum sem purus, sollicitudin ut consectetur eget, dignissim eget mi. Curabitur scelerisque dui non tellus auctor, sed euismod sapien molestie. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam nec ornare sapien. Etiam eu dolor aliquam, sollicitudin nibh quis, tempor nisl. Quisque eget turpis suscipit, imperdiet nisi eget, elementum lorem. Aliquam ultrices, metus in egestas elementum, purus sapien elementum tortor, vitae tempus nulla quam in purus.

Ut a molestie tellus

Phasellus sit amet accumsan massa. Aliquam erat volutpat. Ut iaculis posuere mattis. Sed porttitor pellentesque sapien, eu bibendum arcu sagittis nec. Donec auctor justo ut rhoncus suscipit. Ut laoreet finibus felis non molestie. Donec dapibus orci in erat interdum auctor. Maecenas vulputate nisl nec blandit accumsan. Praesent vitae ultrices tellus. Nullam ultricies neque et urna placerat rhoncus.

<div class="accordion js-accordion" data-accordion="openfirst">
    <h4 class="accordion__toggle">
        ...
    </h4>
    <p class="accordion__content">
        ...
    </p>
    ...
</div>
  • sass/molecules/_accordion.scss
  • js/components/accordion.js

Autoclose feature

Add class .js-accordion--autoclose or add attribute data-accordion="autoclose" to the .js-accordion to ensure that not more than one accordion element can be opened simultaneously.

Lorem ipsum dolor sit amet, consectetur adipiscing elit

Phasellus finibus maximus libero, eget tincidunt nisl dapibus vitae. Vestibulum sem purus, sollicitudin ut consectetur eget, dignissim eget mi. Curabitur scelerisque dui non tellus auctor, sed euismod sapien molestie. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam nec ornare sapien. Etiam eu dolor aliquam, sollicitudin nibh quis, tempor nisl. Quisque eget turpis suscipit, imperdiet nisi eget, elementum lorem. Aliquam ultrices, metus in egestas elementum, purus sapien elementum tortor, vitae tempus nulla quam in purus.

Ut a molestie tellus

Phasellus sit amet accumsan massa. Aliquam erat volutpat. Ut iaculis posuere mattis. Sed porttitor pellentesque sapien, eu bibendum arcu sagittis nec. Donec auctor justo ut rhoncus suscipit. Ut laoreet finibus felis non molestie. Donec dapibus orci in erat interdum auctor. Maecenas vulputate nisl nec blandit accumsan. Praesent vitae ultrices tellus. Nullam ultricies neque et urna placerat rhoncus.

Nam ut gravida purus, vitae ullamcorper leo

Proin urna risus, rutrum vitae sem condimentum, elementum gravida nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus elementum euismod sodales. Sed sodales aliquam velit sed cursus. Praesent venenatis faucibus turpis vitae eleifend. Pellentesque lacinia in lectus id pulvinar. Vestibulum euismod nulla quis nulla semper, at pellentesque augue congue. Vestibulum sed sodales odio. Vivamus vitae feugiat nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam eu est vitae nulla aliquam varius. Mauris lectus dui, fermentum sit amet mi sed, volutpat commodo nisi. Vivamus aliquam semper nibh, faucibus tempus lectus egestas in.

<div class="accordion js-accordion" data-accordion="autoclose">
    <h4 class="accordion__toggle">
        ...
    </h4>
    <p class="accordion__content">
        ...
    </p>
    <h4 class="accordion__toggle">
        ...
    </h4>
    <p class="accordion__content">
        ...
    </p>
    ...
</div>
  • sass/molecules/_accordion.scss
  • js/components/accordion.js

Tables

Based on Bootstrap.

Default table styles

These styles only work on a <table> that either has class .table--default or no class at all.

Lorem ipsum dolor sit amet consectetur adipiscing elit
1st Vestibulum in posuere orci Nam euismod
2nd Vestibulum in posuere orci Nam euismod
3rd Vestibulum in posuere orci Nam euismod
tfoot tfoot tfoot tfoot
<table>
    ...
</table>
  • sass/molecules/_table.scss

Basic table

Create a <table>. Use class .table to apply some nice styles.

Lorem ipsum dolor sit amet consectetur adipiscing elit
1st Vestibulum in posuere orci Nam euismod
2nd Vestibulum in posuere orci Nam euismod
3rd Vestibulum in posuere orci Nam euismod
tfoot tfoot tfoot tfoot
<table class="table">
    ...
</table>
  • sass/molecules/_table.scss

Table variations

Apply some more borders by adding the class .table--bordered. Add zebra-striping to any row within tbody with the class .table--striped. Or enable a hover state on table rows with with .table--hover.

Lorem ipsum dolor sit amet consectetur adipiscing elit
1st Vestibulum in posuere orci Nam euismod
2nd Vestibulum in posuere orci Nam euismod
3rd Vestibulum in posuere orci Nam euismod
tfoot tfoot tfoot tfoot
<table class="table table--bordered table--striped table--hover">
    ...
</table>
  • sass/molecules/_table.scss

Contextual classes

Use contextual classes to color table rows or individual cells.

Lorem ipsum ---------- dolor sit ---------- amet consectetur ---------- adipiscing elit ----------
.active Vestibulum in posuere orci Nam euismod
2nd Vestibulum in posuere orci Nam euismod
.info Vestibulum in posuere orci Nam euismod
4th Vestibulum in posuere orci Nam euismod
.success Vestibulum in posuere orci Nam euismod
6th Vestibulum in posuere orci Nam euismod
.warning Vestibulum in posuere orci Nam euismod
8th Vestibulum in posuere orci Nam euismod
.error Vestibulum in posuere orci Nam euismod
<!-- On rows -->
<tr class="active">...</tr>
<tr class="success">...</tr>
<tr class="warning">...</tr>
<tr class="error">...</tr>
<tr class="info">...</tr>

<!-- On cells (`td` or `th`) -->
<tr>
  <td class="active">...</td>
  <td class="success">...</td>
  <td class="warning">...</td>
  <td class="error">...</td>
  <td class="info">...</td>
</tr>
  • sass/molecules/_table.scss

Responsive tables (scroll)

Create responsive tables by wrapping any .table in .table--responsive-scroll to make them scroll horizontally on small devices (change the appropriate max-width media query by editing the Sass-variable $table-breakpoint). You will not see any difference in these tables on any larger screen.

Lorem ipsum ---------- dolor sit ---------- amet consectetur ---------- adipiscing elit ----------
1st Vestibulum in posuere orci Nam euismod
2nd Vestibulum in posuere orci Nam euismod
3rd Vestibulum in posuere orci Nam euismod
tfoot tfoot tfoot tfoot
<div class="table--responsive-scroll">
    <table class="table">
        ...
    </table>
</div>
  • sass/molecules/_table.scss

Responsive tables (vertical)

You may also create responsive tables by wrapping a .table in .table--responsive-vertical. The table-cells will be displayed vertically on small devices (change the appropriate max-width media query by editing the Sass-variable $table-breakpoint). For correct display you must add 'data-title' to each <td> and <th> of the <tbody>.

Name Gender Age Occupation Game
Master Chief Male unknown Spartan Halo
Lara Croft Female 32 Tomb Raider Tomb Raider
Solid Snake Male 60 Secret Operative Metal Gear Solid
Samus Aran Female 25 Astronaut Metroid
<div class="table--responsive-vertical">
    <table class="table">
        <thead>
            <tr>
                <th>Name</th>
                <th>Gender</th>
                <th>Age</th>
                <th>Occupation</th>
                <th>Game</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th data-title="Name">Master Chief</th>
                <td data-title="Gender">Male</td>
                <td data-title="Age">unknown</td>
                <td data-title="Occupation">Spartan</td>
                <td data-title="Game">Halo</td>
            </tr>
        </tbody>
    </table>
</div>
  • sass/molecules/_table.scss

Tooltips

These pure CSS tooltips are easy to implement and still allow you to place the content in the HTML. They grab their text content from an HTML5 data-tooltip property on the element (although this can be changed to any other attribute you prefer, including the standard title).

.tooltip creates a tooltip. Use the classes .tooltip--bottom and .tooltip--multiline for tooltip variations, which are shown below. Use .tooltip--error, .tooltip--warning and .tooltip--success for color variants.

<a href="..." class="tooltip" data-tooltip="Thank you!">Standard tooltip</a>
<a href="..." class="tooltip tooltip--bottom" data-tooltip="Many thanks!">Bottom tooltip</a>
<a href="..." class="tooltip tooltip--multiline" data-tooltip="As of today, Nebula tooltips officially support multiline text!">Multiline tooltip</a>
<a href="..." class="tooltip tooltip--error" data-tooltip="Something went wrong!">Error tooltip</a>
<a href="..." class="tooltip tooltip--warning" data-tooltip="Look out!">Warning tooltip</a>
<a href="..." class="tooltip tooltip--success" data-tooltip="Yay!">Success tooltip</a>
<a href="..." class="tooltip tooltip--bottom tooltip--multiline tooltip--error" data-tooltip="Ain't these some fantastic new tooltips? They surely are!">Bottom multiline error tooltip</a>
  • sass/atoms/_tooltips.scss
  • sass/utils/_helpers.scss (dependencies @mixin triangle and @mixin triangle-absolute)

Predefined variants

These colourful message-elements will surely grab the attention of your site's visitors. Use the basic class .alert-message in combination with either .info, .warning, .error or .success to create your desired alert-message.

This is an info-text.

Warning!

Something went wrong...

Entry successfully created!

<div class="alert-message info">
    ...
</div>
<div class="alert-message warning">
    ...
</div>
<div class="alert-message error">
    ...
</div>
<div class="alert-message success">
    ...
</div>
  • sass/atoms/_alert.scss
  • js/components/alert.js

Dropdowns

Inspired by Bootstrap.

Dropdown

A dropdown will be opened by clicking its trigger. It is always wrapped in .js-dropdown. Use class .dropdown to apply styles. Inside, a .dropdown__toggle will function as toggle for the dropdown, followed by a <ul> containing a menu or .dropdown__content containing other stuff.

Add class .js-dropdown--switch to the .js-dropdown-element to close the containing dropdown immediately as soon as another dropdown is opened.

Use classes .dropdown--left, .dropdown--center or .dropdown--right to add an arrow and align the dropdown with your desired direction.

Dropup

Add the class .dropdown--upwards to the parent to let it expand upwards.

<div class="dropdown dropdown--upwards js-dropdown">
    <button class="btn dropdown__toggle">
        Open dropup
        <span class="dropdown__caret"></span>
    </button>
    <ul>
        <li><a href="...">Option 1</a></li>
        <li><a href="...">Option 2</a></li>
        <li><a href="...">Option 3</a></li>
        <li class="dropdown__divider"></li>
        <li><a href="...">Seperated option 4</a></li>
    </ul>
</div>
  • sass/molecules/_dropdown.scss
  • sass/utils/objects/_dropdown.scss
  • javascript/components/dropdown.js

Slidedown

Dropdowns that are opened by mouseover instead of click are called "Slidedowns" in Nebula-terminology. A delay of 100ms prevents unwanted opening. They will be closed automatically when the mouse-cursor isn't hovering over them for at least 1000ms.

A slidedown is always wrapped in .js-slidedown. Use class .dropdown to apply styles. Inside, a .dropdown__toggle will function as toggle for the slidedown, followed by a <ul> containing a menu or .dropdown__content containing other stuff.

Add class .js-slidedown--switch to the .js-slidedown-element to close the containing slidedown immediately as soon as another slidedown is opened.

By default the href-Attribute on the toggle will be ignored if you tap on it via touchscreen. This ensures that the slidedown content can be accessed on a touchscreen device. However, if you don't want this to happen, use class .js-slidedown--ignore-touch. By doing this, the slidedown does not open at all if the toggle is tapped. Instead the link specified in the href of the toggle will be opened.

<!-- Regular Slidedown -->
<div class="dropdown js-slidedown">
    <button class="btn dropdown__toggle">
        Open slidedown
        <span class="dropdown__caret"></span>
    </button>
    <ul>
        <li><a href="...">Option 1</a></li>
        <li><a href="...">Option 2</a></li>
        <li><a href="...">Option 3</a></li>
        <li class="dropdown__divider"></li>
        <li><a href="...">Seperated option 4</a></li>
    </ul>
</div>

<!-- .slidedown--switch -->
<div class="dropdown js-slidedown js-slidedown--switch">
    <button class="btn dropdown__toggle">
        Open slidedown
        <span class="dropdown__caret"></span>
    </button>
    <ul>
        [...]
    </ul>
</div>
  • sass/molecules/_dropdown.scss
  • sass/utils/objects/_dropdown.scss
  • javascript/components/slidedown.js

Slideup

Add the class .dropdown--upwards to the parent to let it expand upwards.

<div class="dropdown dropdown--upwards js-slidedown">
    <button class="btn dropdown__toggle">
        Open dropup
        <span class="dropdown__caret"></span>
    </button>
    <ul>
        <li><a href="...">Option 1</a></li>
        <li><a href="...">Option 2</a></li>
        <li><a href="...">Option 3</a></li>
        <li class="dropdown__divider"></li>
        <li><a href="...">Seperated option 4</a></li>
    </ul>
</div>
  • sass/molecules/_dropdown.scss
  • sass/utils/objects/_dropdown.scss
  • javascript/components/slidedown.js

Multi-level slidedown

Just add some additional levels to your .js-slidedown's <ul>.

<div class="dropdown js-slidedown js-slidedown--switch">
    <button class="btn dropdown__toggle">
        Open slidedown
        <span class="dropdown__caret"></span>
    </button>
    <ul>
        <li><a href="javascript://">Option 1</a></li>
        <li><a href="javascript://">Option 2</a>
            <ul>
                <li><a href="javascript://">Option 2.1</a>
                    <ul>
                        <li><a href="javascript://">Option 2.1.1</a></li>
                        <li><a href="javascript://">Option 2.1.2</a></li>
                        [...]
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>
  • sass/molecules/_dropdown.scss
  • sass/utils/objects/_dropdown.scss
  • javascript/components/slidedown.js

Multi-level dropdown/slidedown-combination

This pattern behaves like a real menu, opening and closing by click while the submenus open on mouseover.

Just add a multi-level <ul> like in the example above, but instead of assigning the class .js-slidedown add the classes .js-dropdown and .js-dropdown-slidedown. The script will take care of the rest.

<div class="dropdown js-dropdown js-dropdown-slidedown">
    <button class="btn dropdown__toggle">
        Open slidedown
        <span class="dropdown__caret"></span>
    </button>
    <ul>
        <li><a href="javascript://">Option 1</a></li>
        <li><a href="javascript://">Option 2</a>
            <ul>
                <li><a href="javascript://">Option 2.1</a>
                    <ul>
                        <li><a href="javascript://">Option 2.1.1</a></li>
                        <li><a href="javascript://">Option 2.1.2</a></li>
                        [...]
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>
  • sass/molecules/_dropdown.scss
  • sass/utils/objects/_dropdown.scss
  • js/components/dropdown.js
  • js/components/slidedown.js