• Stars
    star
    491
  • Rank 89,636 (Top 2 %)
  • Language
    HTML
  • Created almost 12 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An opinionated starting point for scalable, maintainable CSS architecture.

js-standard-style dependency Status Greenkeeper badge Build Status

Style

An opinionated starting point for scalable, maintainable CSS architecture.

Style is an approach to writing CSS born & refined over several years at Envato by the team responsible for maintaining & evolving the 9 year old Rails codebase that powers Envato Market.

Contents

Should you use it?

If you're starting a new project today, especially a JavaScript-heavy project, I'd strongly recommend investigating CSS Modules.

However Style's approach might be a better option in some cases:

  • Using the Rails Asset Pipeline
  • Views or templates authored in something other than JavaScript (e.g. PHP, Twig, ERB, Slim, etc)
  • Maintaining an existing CSS or Sass codebase
  • Simple static site projects

Getting started

Style is designed as a starting point to work with your own asset build process (eg an asset pipeline, Grunt or Gulp task). Just drop the stylesheets folder into your app & start styling!

Example build configurations are provided for Gulp & Webpack (see below for how to use them), as well as an example manifest CSS file for Rails projects.

General principles

Every Sass file is compiled in isolation

JavaScript modules have shown us the benefits of small, independent files with explicitly declared dependencies rather than relying on lots of global variables.

Sass can be written the same way. In Style, every Sass file must explicitly @import any variables, functions or mixins that it uses. There is no global Sass context shared between files. Each file is compiled to CSS in isolation before being packaged into the final bundle.

Read more about this approach.

The component paradigm

Style embraces the component paradigm, roughly as defined by SMACSS Modules. SUIT components, OOCSS components & BEM blocks are all in the same ballpark.

There are other CSS paradigms not centered around components such as AMCSS & Tachyons, each with their own merits, but I've found components easiest to work with.

Style categories

Files in the stylesheets folder are divided into several categories:

base

base contains the styles that all other styles are built upon. They are an implicit dependency of all your other styles - changing your reset styles will have a flow-on effect to all other styles, so in general they should not be changed once you start.

@font-face & @keyframe declarations are also kept here.

components

A component:

  • Is defined in its own file (eg components/my_component.sass)
  • Is independent, reusable & disposable.
  • Implicitly depends only on your base styles (in this case, Sanitize.css + the small number of additional styles set in base)
  • Has no knowledge of its context (i.e. doesn't depend on styles from a particular parent element - it can be rendered anywhere)
  • Minimises its own depth of applicability so that it can safely contain other modules
  • Has no context-specific size or position styles. Read Objects in Space for more on this.

Simple component

Here's what a simple component, components/simple_component.sass, might look like:

.simple-component
  color: goldenrod

Complex component

Here's a slightly more complex component, modules/comment.sass:

@import 'config/colors'

.comment
  color: $fuchsia

  // Modifier classes can be used to modify a components styles for special cases
  // and different states
  &.-is-loading
    background: url(spinner.gif)

  &.-staff-comment
    font-weight: bold

// A subcomponent (some component that *must* be a child of .comment)
.comment__avatar
  margin-left: 20px
  width: 100px
// Whatever is inside a subcomponent can usually be extracted out into its own component,
// with the subcomponent simply being used to size & position a generic container.
// In this case, .comment__avatar is a container for a separate .avatar component.

Read Chainable BEM modifiers for a thorough explanation of the syntax used here for classes.

grid and layout-box

The included grid and layout-box are a good start for most layout needs, but feel free to replace them!

config

Config files define configuration variables (e.g. colors, font stacks, common sizes). They don't output any CSS of their own, but should be imported into Sass files that need them using @import.

functions and mixins

Sass functions & mixins intended to be imported into other Sass files using @import.

type

I've found that typography styles are a bit special. They're not quite component styles and they're not quite reset styles. The following use cases are common:

  • Styling a big block of raw HTML that has no classes (e.g. rendered from Markdown)
  • Applying your base typography styles to an element in a one-off situation (e.g. styling a heading that appears inside another component)

Each Sass file in type defines some styles under a component class (e.g. .type-heading) as well as applying those same styles to class-free elements that appear inside a type-raw-html block (e.g. .type-raw-html h1).

utilities

Utilities are borrowed directly from SUIT. They are helper classes that define common utility styles and can be used anywhere on any element.

!important is OK in utility classes, as you'll usually want them to override a component's styles. E.g., I'd always expect .u-hidden to hide an element even if it also has component class that specifies display: block.

I tend to use them sparingly. Don't be afraid to write float: left in a component even if you have a utility class that does the same thing. Instead of using utility classes to avoid duplicating any styles, use them in situations where you would otherwise need to define a whole new component.

Responsive design & Metaquery

Writing media queries in CSS is for chumps. Style uses metaquery so you can use named breakpoint classes in your CSS.

.my-component
  color: red

  .breakpoint-tablet &
    color: blue

  .breakpoint-widescreen &
    color: fuchsia

Some example breakpoints are defined in index.html.

Build examples

Style includes some fairly minimal examples you can use to build a final app.css stylesheet from the source files.

You'll need Node.js - I recommend installing it with nodenv.

The devDependencies in package.json are grouped by build tool (no comments in JSON 😿) - feel free to delete the dependencies you don't need.

The output CSS can be inspected in css/app.css or you can open index.html in a browser to see it in action.

Pull requests adding examples for other build tools are welcome!

Gulp

  • Install dependencies by running npm install in your terminal
  • Run a single build with npm run gulp
  • Watch & automatically recompile when you change a Sass file with npm run gulp:watch

Webpack

  • Install dependencies by running npm install in your terminal
  • Run a single build with npm run webpack
  • Watch & automatically recompile when you change a Sass file with npm run webpack:watch

Read about using Webpack to build CSS.

Contributing

Please adhere to the existing code style. JavaScript that doesn't comply with standard will cause the build to fail.

All issues, pull requests & code contributions must comply with the Contributor Code of Conduct

License

Style is released under the MIT License.

More Repositories

1

webpack-css-example

Example repo showing a webpack CSS build
JavaScript
450
star
2

sample-react-rails-app

Sample Rails app with server-rendered React components
Ruby
206
star
3

tropical

Fast, mostly-just-HTML static sites with islands of client-side JS. Click the "Use this template" button ↖️
JavaScript
162
star
4

dragster

Better HTML5 drag events
HTML
105
star
5

tropical-utils

JavaScript
33
star
6

viewloader

A tiny little framework-agnostic JS bootstrapping thing.
JavaScript
32
star
7

structurizr-mini

A static site for C4 diagrams from a Structurizr workspace
JavaScript
22
star
8

coexist

Unobtrusively server-render JS pages from non-JS frameworks.
Ruby
18
star
9

flux-jasmine-rewire-example

An example repo showing how to test Flux stores without Jest, using Jasmine & Rewire instead.
JavaScript
15
star
10

json2css-sprite-mixins

Sprite mixins from json2css' sass template, plus some retina mixins.
CSS
15
star
11

MediaElement.js-Playlist

Turn a list of media links into a playlist using MediaElement.js
JavaScript
12
star
12

cssconfracer

A stupid racing game
JavaScript
10
star
13

boilerplizzle

A fast, flexible starting point for little web projects that gives you tools like Compass, CoffeeScript & your favourite JS & CSS libraries then gets out of your way.
JavaScript
7
star
14

sample-webpack-setup

Just something I'm messing with. You shouldn't use this code. It's probably not good.
JavaScript
6
star
15

going-isomorphic-with-react

JavaScript
4
star
16

metalsmith-json-feed

A Metalsmith plugin for generating a JSON Feed from a collection.
JavaScript
3
star
17

react-style-example

react-style example for melbjs talk
JavaScript
2
star
18

metalsmith-blog-example

A Metalsmith-powered blog.
Shell
2
star
19

css-architecture-on-a-shoestring

Slides from my Decompress presentation
JavaScript
2
star
20

design-friendly-repo-starter

Boilerplate for new open source projects aimed at encouraging contributions from non-devs
1
star
21

allihoopa-mixtape

Allihoopa is dead. Long live Allihoopa.
HTML
1
star
22

panoramx

1
star
23

overthrow-dist

Overthrow doesn't include a built version of the library. This is a bower component with the latest built version.
JavaScript
1
star