LEGO Component Library
This document contains two sets of instructions:
- Including LEGO in your project
- Contributing new CSS to LEGO
Including LEGO in your project
LEGO is published as an npm module called optimizely-lego
. To install:
npm install optimizely-lego --save-dev
which should add the dependency to your package.json
file.
If using Gulp for your project:
gulp;
Example Starter Code
Download LEGO starter code that includes the required file structure for new projects. Note that the paths to core/...
will only work if the above gulp task is in place.
Structure of LEGO
LEGO consists of two parts:
- Core
- Base styles used as the foundation for any site.
- This code lives in this LEGO repository and is a dependency for platform code.
- Platform (.e.g,
mobile
)- Platform or device specific built on top of Core.
- This code lives in the platform repo, pulling Core as a dependency.
For example, if you're building a mobile site, mobile.scss
would contain:
// # Mobile // Root file driving the Mobile CSS. // Compass polyfills ; // ## Core functions and mixins ;; // ## Core and p13n variables // Import `core` and `mobile` variables ;; // ## Core and mobile partials // Import `core` and `mobile` partials ;; // ## Trumps // Trumps use `!important` classes for overrides and should always be loaded last. ;;;;;;;
Contributing to LEGO
The following is for users planning to make contributions to LEGO.
Important: see CONTRIBUTING.md for details on our versioning system.
After cloning the lego
repo run:
npm start
This will run the npm start
commands found in package.json that installs the dependencies.
Cheat Sheet
gulp
: Runs the default compass watch process.gulp hook
: Installs the linter pre-commit hook (please do this!).gulp lint
: Runs the SCSS linter.gulp svg
: Builds svg sprite and demo page intodist
.gulp sass
: Builds Core-only css file for testing intodist
.gulp feature | patch | release
: For tagging releases.
Getting Started
Pre-Commit Hook & Linter
As part of the installation process above you should have run gulp hook
. This will run the task that creates a git pre-commit hook. This hook fires a SCSS linter that checks to see that any SCSS files included in the commit conform to our standards. These rules ensure the LEGO SCSS is consistent.
If the the linter finds issues you'll see messages in your terminal like this:
[13:56:12] Using gulpfile /Library/WebServer/Documents/lego/gulpfile.js
[13:56:12] Starting 'lint'...
[13:56:12] Finished 'lint' after 4.32 ms
[13:56:15] 1 issues found in /Library/WebServer/Documents/lego/src/scss/desktop/_desktop-partials.scss
[13:56:15] /Library/WebServer/Documents/lego/src/scss/desktop/_desktop-partials.scss:24 [W] Files should end with a trailing newline
Here the 'lint' process ran and found 1 issue, providing the file, line number, and reason for the problem.
You can also run:
gulp lint
at any time to check your files before you commit.
Run the Sass compile process
To output Core CSS file to the dist
directory run:
gulp sass
Generating the SVG Icon Sprite
When adding new icons to the library place the individual svg files into:
src/img/svg-icons
and then run:
gulp svg
The resulting sprite will be built to:
dist/img/svg-symbols.svg
This is the file that is included as the first child of the body on every page of Optimizely.
Philosophy
LEGO stands for Low-level Elements and Global Objects. It's a collection of CSS/HTML/JS elements and objects meant to be combined and extended to create larger interfaces, influenced primarily by Harry Robert's work on inuit.css and Johnathon Snooks SMACSS. The goals of this library are to provide code that is...
- Abstracted. Component names shouldn't be derived from the content they contain. Class names should convey structural meaning.
- Reusable. Components should be generic enough to be reused throughout the site. They should make no assumptions what page/view they will be used on. Problems solved in one area should be easily applied elsewhere.
- Mixable. Components should be able to join together to create larger blocks.
- Powered by variables. Nearly all design elements — colors, fonts, spacings, shadows — should be defined using the pre-existing variables.
By achieving these goals our code becomes...
- Scalable. Reusing patterns means new elements can be created faster and with minimal additional CSS.
- Consistent. Not only will developers be able to read each other's code more easily we'll have a better end-user experience across the product.
- Smaller and DRYer. Since we're constantly reusing low-level objects to build larger ones, often with Sass'
@extend
functionality, we cut down on CSS bloat. Less code means fewer bugs.
Writing Good Classes
In order to write HTML and CSS classes that provide meaning for developers we're using the BEM syntax. BEM stands for Block, Element, Modifier and is becoming a popular approach to building CSS and HTML that describes an object's internal relationships.
grid cell grid cell grid cell
In the example above...
- Block is represented by
lego-grid
and is the parent class of the object. - Elements are children of the object. They are named by joining the parent class name and a child class with a double underscore. In this case
lego-grid__cell
. - Modifiers are variations on the default. In this case we have a
lego-grid--gutter
. This provides spacing between the cells.
Though somewhat verbose, this syntax makes it easy to determine the child/parent relationships between bits of code, especially when different objects are mixed together. It can be tricky naming elements so some judgment is required. This becomes easier over time.
For a longer discussion Harry Roberts provides a good introduction to the syntax.
Futher Reading
- MindBEMding – getting your head ’round BEM syntax. Introduction to BEM.
- About HTML semantics and front-end architecture. What is a meaningful class name?
- OOCSS + Sass = The best way to CSS. Some examples of bulding on existing objects using
@extend
in Sass. - Hacks for dealing with specificity. Some more technical details around specificity.
- Normalising designs for better quality CSS (Video). A conference presentation about normalizing designs and the process from design to HTML.