- 7kb (gzip) with default settings.
- View the demo
Super low-level mobile-first Sass framework using the ITCSS architecture and the BEMIT naming convention.
Rather than using 'semantic classnames' that some other frameworks push, the classnames employed in Nebula explicitly describe the underlying architecture. This makes it much easier to reason about the CSS structure from your HTML, promotes code re-use and composition; which otherwise would all be severely hindered if classnames were closely coupled with content.
Ships with zero cosmetic styling; this allows every consuming project to have a completely bespoke UI with Nebula CSS doing the heavy lifting when it comes to layout and architecture. This means it is totally upto you how you structure your colours, typography and cosmetic components, however you are encouraged to follow the ITCSS structure and BEMIT naming conventions.
At the core sits a highly flexible and and extendible grid system making use of the very powerful map feature of Sass. Maps are used extensively and allow the following features to be easily extended and in some cases composed:
- Breakpoints
- Grid fractions
- Grid offsets
- Grid guttering
- List spacing
- Section spacing
- Spacing - margin & padding utilities
Nebula CSS also ships with some common yet useful abstractions such as the Flag Object, list variations and an array of useful utilities.
- Intro to ITCSS
- Dependencies
- Get started
- Default settings and config
- Breakpoints
- Grid
- Flag
- Site-wrap
- Section
- Lists
- Utilities
Nebula CSS is built upon the ITCSS architecture popularised by Harry Roberts.
ITCSS stands for Inverted Triangle architecture for CSS
It is a sane, scalable, managed architecture and is more of a school of thought than a framework.
The architecture is based on the write CSS in specificity order principle; this eliminates many of the specificity issues that occur as a project scales.
ITCSS is divided up into 7 distinct sections they are:
- Settings
- Tools
- Resets
- Base
- Objects
- Components
- Utilities
Global variables and config.
Globally used mixins and functions.
Normalize.css and any additional resets on top of Normalize.
Global baseline styles using element and attribute selectors only (No classes)
Cosmetic-free design patters, things like the grid, lists and the flag object. Think of it like the skeleton of the layout, with no visual styling applied.
Designed components, chunks of UI. Think of it like the skin on top of the skeleton, so anything with colours, borders, backgrounds etc. If in doubt whether some CSS/Sass code belongs in layout or components then put it within components. Being cosmetic free Nebula CSS does not ship with any components
Helpers and overrides. AKA Trumps.
Nebula CSS is composed of Sass files so you'll need some way to compile to CSS; we'd recommend you use a Libsass based tool, which will likely be available for your build tool of choice:
- Node Sass (NPM Scripts)
- Webpack Sass Loader (Webpack)
- Gulp Sass (Gulp)
Having a deep knowledge of Sass is not required to consume Nebula CSS, but a familiarity will greatly help you get the most out of this architecture.
This document assumes you have NodeJS installed on your machine.
Nebula's source code does not include any vendor prefixes. This gives you the freedom to configure Autoprefixer to the browsers that you intend to support.
This can be ran directly in NPM scripts as you can see happening in this projects package.json. Alternatively you can run this in your build-tool of choice.
-
npm install --save nebula-css
-
Setup an ITCSS file structure:
-
cd
into the directory where you intend to build out your ITCSS structure. -
Paste the following snippet into your terminal:
β Windows users will have to manually create and populate the files.mkdir scss && cd scss && { echo "@import 'settings';" echo "@import 'tools';" echo "@import 'resets';" echo "@import 'base';" echo "@import 'objects';" echo "@import 'components';" echo "@import 'utilities';" echo "" } > main.scss && echo "@import 'nebula-css/settings';" > _settings.scss && echo "@import 'nebula-css/tools';" > _tools.scss && echo "@import 'nebula-css/resets';" > _resets.scss && echo "@import 'nebula-css/base';" > _base.scss && echo "@import 'nebula-css/objects';" > _objects.scss && echo "@import 'nebula-css/utilities';" > _utilities.scss && touch _components.scss && cd ..
The following file structure will be created.
scss/ | βββmain.scss βββ_settings.scss βββ_tools.scss βββ_resets.scss βββ_base.scss βββ_objects.scss βββ_components.scss βββ_utilities.scss
main.scss
gets populated with the seven ITCSS layers./* main.scss */ @import 'settings'; @import 'tools'; @import 'resets'; @import 'base'; @import 'objects'; @import 'components'; @import 'utilities';
The files that
main.scss
imports are also populated with@import
statements that are pulling in the corresponding ITCSS layer from Nebula CSS. E.g./* _settings.scss */ @import 'nebula-css/settings';
It is worth noting here that to resolve the above path your Sass compiler requires Node-sass IncludePaths If your Sass Compiler does not offer IncludePaths resulting in your build failing you will have to give your imports a relative path:
/* _settings.scss */ @import '[path-to-node-modules]/nebula-css/nebula-css/settings';
As you can see this is rather verbose and ugly code but it works!
Below is an example of an NPM script configured to compile Sass and making use of
includePaths
pointing to the directory to be resolved./node-modules/nebula-css/
"scripts": { "sass": "node-sass --include-path ./node_modules/nebula-css/ -o dist src/scss/main.scss", },
See how the NPM scripts package.json are configured for the Nebula CSS Demo.
Alternatively here's an example using Gulp.
gulp.task('build:css', () => { const includePaths = ['./node_modules/nebula-css/']; return gulp.src('src/scss/**/*.scss') .pipe(sass({ includePaths })) .pipe(gulp.dest('dist')) });
-
-
Configure your build tool to build your Sass files and run Autoprefixer
-
You can now start extending Nebula with your own styling. Following with the ITCSS structure it's recommended that you create the folders for the layers that you are extending and
@import
those files.
An example structure might look like this:
scss/
|
βββmain.scss
βββ_settings.scss
βββ_tools.scss
βββ_resets.scss
βββ_base.scss
βββ_objects.scss
βββ_components.scss
βββ_utilities.scss
βββsettings/
| βββ_nebula-overrides.scss
| βββ_my-settings.scss
βββbase/
| βββ_my-base-styles.scss
βββobjects
| βββ_my-object-1.scss
| βββ_my-object-2.scss
βββcomponents/
| βββ_my-component-1.scss
| βββ_my-component-2.scss
βββutilities/
βββ_my-utility-1.scss
βββ_my-utility-2.scss
Some of the settings here make use of Sass maps it's recommended you have at least a basic understanding of how they work.
Defines the namespace to be added to classes generated by Nebula.
$nb-namespace: '' !default;
Defines the maximum width of the site wrapper o-site-wrap
$nb-site-wrap-width: 60rem !default;
The spacing unit is used throughout the entire framework for spacing and guttering. It yields consistent spacing rhythm throughout your project.
$nb-spacing-unit: 1rem !default;
Base font-sizing for body copy.
$nb-base-font-size: 1rem !default;
Breakpoints using a Sass Map. the keys sm
, md
are used to generate the responsive classnames. Being a Sass map it is possible to add or remove breakpoints and of course you can change the values.
$nb-breakpoints: (
sm: 720px,
md: 960px,
lg: 1200px
) !default;
The root font-sizing set as a percentage on the <html>
element.
The key default
being the initial sizing up until the key matching the $nb-breakpoints
key. In this case sm
So screens larger than 720px will get 100% root-font sizing. Those smaller will receive 90%.
$nb-root-sizing: (
default: 90%,
sm: 100%
) !default;
List Spacing for all kinds of lists such as inline-list
, bare-list
matrix-list
. The keys here are used to generate the BEM modifier classnames
so you can name then whatever you deem appropriate. By default you are provided with a single md
key.
$nb-list-spacing: (
md: $nb-spacing-unit
) !default;
Spacing for all sections. The Sass map here operates exactly like $nb-list-spacing
. above.
$nb-section-spacing: (
md: ($nb-spacing-unit * 2)
) !default;
The grid system uses inline-blocks. To remove the whitespace between grid-items it's required that a font-size of zero is set on the wrapping element, then the child elements are reset using $nb-base-font-size
. If you are minifying your HTML or using JSX with a framework like React it is safe to turn this off.
$nb-use-grid-zero-font-size: true !default;
Gutter sizes for the grid system. By default we have three sizes, you can add or remove these to suit your projects needs.
$nb-grid-gutter-sizes: (
sm: ($nb-spacing-unit / 2),
md: $nb-spacing-unit,
lg: ($nb-spacing-unit * 2)
) !default;
Offsets used for the grid based in fractions whereby 1/2
will yield a width of 50%
. This Sass map is also used for Push/Pull offsets on the grid. Being a Sass map you are free to add or remove whatever offsets are suitable for your project needs. Note that the keys are quoted due to a fraction being used. You can also turn off width/push/pull offsets globally saving you from bloat if any of those features are not being used.
$nb-use-width-offsets: true !default;
$nb-use-push-offsets: true !default;
$nb-use-pull-offsets: true !default;
$nb-offset-fractions: (
'1/1': 1/1,
'1/2': 1/2,
'1/3': 1/3,
'2/3': 2/3,
'1/4': 1/4,
'2/4': 2/4,
'3/4': 3/4,
'1/5': 1/5,
'2/5': 2/5,
'3/5': 3/5,
'4/5': 4/5,
'1/6': 1/6,
'2/6': 2/6,
'3/6': 3/6,
'4/6': 4/6,
'5/6': 5/6,
'1/8': 1/8,
'2/8': 2/8,
'3/8': 3/8,
'4/8': 4/8,
'5/8': 5/8,
'6/8': 6/8,
'7/8': 7/8,
'1/10': 1/10,
'2/10': 2/10,
'3/10': 3/10,
'4/10': 4/10,
'5/10': 5/10,
'6/10': 6/10,
'7/10': 7/10,
'8/10': 8/10,
'9/10': 9/10,
'1/12': 1/12,
'2/12': 2/12,
'3/12': 3/12,
'4/12': 4/12,
'5/12': 5/12,
'6/12': 6/12,
'7/12': 7/12,
'8/12': 8/12,
'9/12': 9/12,
'10/12': 10/12,
'11/12': 11/12
) !default;
Used for the Push
utility to add margin to a component.
$nb-push-sizes: (
md: $nb-spacing-unit
) !default;
Used for the Soft
utility to add padding to a component.
$nb-soft-sizes: (
md: $nb-spacing-unit
) !default;
When you install this framework it will live in your node_modules
directory and you won't want to go in there and change anything as any subsequent npm install
s will potentially overwrite those changes.
Thankfully Nebula CSS settings all have the !default
flag attached which means they can be overridden:
/*_settings.scss*/
@import 'nebula-css/settings';
@import 'settings/my-overrides';
/*/settings/_my-overrides.scss*/
$nb-breakpoints(
sm: 800px,
md: 900px,
lg: 1000px,
xl: 1100px
);
The above code will override the default $nb-breakpoints
map with your own.
The breakpoints map shown above ($nb-breakpoints
) contains all of the breakpoints used in Nebula, you can add remove and edit the breakpoints in the map. Nebula CSS features such as the lists, section, grid gutters, grid widths, push, flush, hard and soft utilities are all auto generate the CSS based on $nb-breakpoints
. The keys used in the map correlate directly to classnames generated. For example:
$nb-breakpoints: (
sm: 400px,
md: 800px,
myKey: 1000px
);
and assuming we had the following declared:
$nb-list-spacing: (
md: $nb-spacing-unit
) !default;
Will generate the following CSS classnames in our Bare list (Amongst the other objects)
.o-bare-list {}
.o-bare-list--spaced-md {}
.o-bare-list--spaced-md\@sm {}
.o-bare-list--spaced-md\@md {}
.o-bare-list--spaced-md\@myKey {}
If our List spacing increased to:
$nb-list-spacing: (
md: $nb-spacing-unit,
lg: ($nb-spacing-unit * 2)
) !default;
The following CSS classnames would be generated:
.o-bare-list {}
.o-bare-list--spaced-md {}
.o-bare-list--spaced-md\@sm {}
.o-bare-list--spaced-md\@md {}
.o-bare-list--spaced-md\@myKey {}
.o-bare-list--spaced-lg {}
.o-bare-list--spaced-lg\@sm {}
.o-bare-list--spaced-lg\@md {}
.o-bare-list--spaced-lg\@myKey {}
As we can see in these examples the @
symbol denotes that this class applies to a particular breakpoint, the chars after should map directly to a key in $nb-breakpoints
.
Also note that the @
symbol here is escaped, this is because symbols like @
are not strictly valid CSS selectors so they must be escaped. However you don't need to do this when defining your classnames in your HTML.
Nebula CSS also provides you with a mixin that can be use to interface with the defined breakpoints: nb-respond-to()
This mixin accepts a string argument. The string should match one of the maps in nb-breakpoints
. e.g.
.o-my-obj {
@include nb-respond-to('md') {
// my CSS
}
}
Being mobile first the above CSS will respond to viewports larger than the md
breakpoint (min-width media query). It is possible to pass in a prefix as part of the sring to denote a max-width breakpoint:
.o-my-obj {
@include nb-respond-to('max-md') {
// my CSS
}
}
The above CSS responding to viewports smaller than the md
breakpoint.
nb-respond-to
also accepts an optional second argument if you wish to create a second breakpoints map that you don't wish the grid, and other utilities to map over - something more component specific. By default this parameter points to $nb-breakpoints
.
The grid system employed in Nebula CSS uses fractions rather than columns yielding increased flexibility. Instead of many other popular grid systems Nebula CSS uses inline-block as opposed to floats; this results in many benefits.
- Fluid
- Infinitely nestable
- Equal height grid items based on Flexbox (IE10+)
- Vertical alignment of grid items
- Vertical gutters
- Variable gutter sizing
- horizontal reversal of grid-items
- No clearfixing required, rows of items with uneven heights tile gracefully.
- Classnames based on BEMIT fractions and responsive suffixes
- Does not require a wrapping element like most other grid systems.
- Extremely lightweight using the Sass maps found in Default settings and config unused bloat can be removed.
- Width, push and pull classes are not tied directly to the grid, and can be reused anywhere in your project.
By default the grid comes with the following sets of fractions:
- One whole
- Halves
- Thirds
- Fourths
- Fifths
- Sixths
- Eighths
- Tenths
- Twelfths
As defined in the $nb-offset-fractions
map. You can add or remove fractions on the map to suit your project requirements. The fractions map directly to the breakpoints.
By default Nebula CSS provides three gutter width variations from the nb-grid-gutter-sizes
map, again these can be removed, adjusted or added to.
With a seemingly endless number of combinations available this makes Nebula CSS's grid one of the most flexible available.
A simple grid with two grid-items one 25% wide the other 75%. By default the grid comes with no gutters.
<div class="o-grid">
<div class="o-grid__item u-1/4">
25% wide
</div>
<div class="o-grid__item u-3/4">
75% wide
</div>
</div>
Responsive breakpoints
<div class="o-grid">
<div class="o-grid__item u-1/4@sm">
25% wide at screens larger than the `sm` breakpoint.
</div>
<div class="o-grid__item u-3/4@sm">
75% wide at screens larger than the `sm` breakpoint.
</div>
</div>
Medium sized guttering
<div class="o-grid o-grid--gutter-md">
<div class="o-grid__item u-1/4">
25% wide at screens larger than the `sm` breakpoint.
</div>
<div class="o-grid__item u-3/4">
75% wide at screens larger than the `sm` breakpoint.
</div>
</div>
Varying guttering depending on the breakpoint
<div class="o-grid o-grid--gutter-sm@md o-grid--gutter-md@lg">
<div class="o-grid__item u-1/4">
25% wide
</div>
<div class="o-grid__item u-3/4">
75% wide
</div>
</div>
There are various BEM modifiers that you can add to the grid as shown below:
-
Matrix (Vertical guttering that matches horizontal) Demo
<div class="o-grid o-grid--gutter-sm o-grid--matrix" />
-
Equal height items Demo
<div class="o-grid o-grid--equal-height" />
-
Reverse item order Demo
<div class="o-grid o-grid--reverse" />
-
Vertically centered items Demo
<div class="o-grid o-grid--center" />
-
Bottom aligned items Demo
<div class="o-grid o-grid--bottom" />
-
Horizontally centered items Demo
<div class="o-grid u-text-center" />
One of most underrated CSS abstractions originally thought up by Harry Roberts is the flag object. It allows you to mix up fixed width components with fluid ones, is infinitely composable can be nested inside of the grid, or a grid nested inside of the fluid component it's incredibly versatile. Oh and it also allows you to vertically align the contents to boot.
<div class="o-flag">
<div class="o-flag__component">
<img src="my-amazing-dog.jpg" alt="">
</div>
<div class="o-flag__body">
Checkout my amazing dog!
</div>
</div>
A simple max-width centred container to wrap your content. You can see it applied throughout the demo page. The --padding
modifier adds horizontal padding to the container.
demo
<div class="o-site-wrap o-site-wrap--padding">
Main content.
</div>
Adds padding top & bottom. The md
suffix in this example maps onto a corresponding key on the $nb-section-spacing
map that denotes the spacing amount.
demo
Typically used to space sections and sub-sections of content.
<div class="o-section-md">
Main content.
</div>
Nebula CSS comes with three types of list: Bare-list, Inline-list and Matrix-list. demo
Strips a list of all default list styling. Demo
<ul class="o-bare-list">
<li>item</li>
<li>item</li>
</ul>
Spaced Demo
<ul class="o-bare-list o-bare-list--spaced-md">
<li class="o-bare-list__item">item</li>
<li class="o-bare-list__item">item</li>
</ul>
Spaced by breakpoint Demo
<ul class="o-bare-list o-bare-list--spaced-md@sm">
<li class="o-bare-list__item">item</li>
<li class="o-bare-list__item">item</li>
</ul>
Exactly like the bare list but the items are rendered horizontally. Demo
<ul class="o-inline-list">
<li>item</li>
<li>item</li>
</ul>
Spaced [Demo](https://rbrtsmith.com/nebula-css/#inline-list-spaced)
<ul class="o-inline-list o-inline-list--spaced-md">
<li class="o-inline-list__item">item</li>
<li class="o-inline-list__item">item</li>
</ul>
Spaced by breakpoint Demo
<ul class="o-inline-list o-inline-list--spaced-md@sm">
<li class="o-inline-list__item">item</li>
<li class="o-inline-list__item">item</li>
</ul>
Exactly like the inline list but the items vertical spacing matches the horizontal. Demo
Spaced
<ul class="o-matrix-list o-matrix-list--spaced-md">
<li class="o-matrix-list__item">item</li>
<li class="o-matrix-list__item">item</li>
</ul>
Spaced by breakpoint
<ul class="o-matrix-list o-matrix-list--spaced-md@sm">
<li class="o-matrix-list__item">item</li>
<li class="o-matrix-list__item">item</li>
</ul>
Throws the list items into a horizontal alignment, each having a uniformed width. Demo
<ul class="o-uniformed-list">
<li class="o-uniformed-list__item">item</li>
<li class="o-uniformed-list__item">item</li>
</ul>
Uniformed by breakpoint.
<ul class="o-uniformed-list@lg">
<li class="o-uniformed-list__item">item</li>
<li class="o-uniformed-list__item">item</li>
</ul>
Form the Utilities Layer in ITCSS, each a single responsibility class. They are intended to be used as overrides. Demo
Adds margins. Demo
Nebula CSS encourages single direction margin declarations to eliminate confusion around collapsing borders
<div class="u-push-left-md"></div>
<div class="u-push-bottom-md"></div>
<div class="u-push-left-md@sm"></div>
Removes margins
<div class="u-push-top-md"></div>
<div class="u-push-right-md"></div>
<div class="u-push-bottom-md"></div>
<div class="u-push-left-md"></div>
<div class="u-push-left-md@lg"></div>
Adds padding Demo
<div class="u-soft-md"></div>
<div class="u-soft-top-md"></div>
<div class="u-soft-right-md"></div>
<div class="u-soft-bottom-md"></div>
<div class="u-soft-left-md"></div>
<div class="u-soft-left-md@lg"></div>
Removes padding
<div class="u-hard"></div>
<div class="u-hard-top"></div>
<div class="u-hard-right"></div>
<div class="u-hard-bottom"></div>
<div class="u-hard-left"></div>
<div class="u-hard-left@lg"></div>
Adds text-alignment. Demo
<div class="u-text-left"></div>
<div class="u-text-center"></div>
<div class="u-text-right"></div>
Hidden
Hides elements, or visually hides (Still accessible.) Demo
<div class="u-hidden"></div>
<div class="u-visually-hidden"></div>