Giter Club home page Giter Club logo

ccss's Introduction

CCSS

CCSS [Component CSS] is an architecture which simplifies the CSS authoring experience for large web applications.

Why?

Large web applications generally have a lot of CSS files and many developers working on them simultaneously. With the advent of so many frameworks, guidelines, tools and methodologies like OOCSS, SMACSS, BEM, etc., developers need a CSS architecture that is maintainable, manageable, and scalable.

As a frontend engineer, I believe that component-based web development is the way forward. Web components are a collection of standards that are working their way through the W3C. They allow us to bundle up markup and styles into reusable HTML elements which are truly encapsulated. What this means is we need to start thinking about component based CSS development. While the browser makers are implementing these standards, we can use soft-encapsulation in the meantime.

When?

As a developer, use it when you are setting up the CSS Architecture for a complex web application.

Contents

  1. Elements
  2. Principles
  3. Directory Structure
  4. Naming Conventions - Simplified BEM
  5. Architecture & Design
  6. Example
  7. Contributing
  8. Resources

Elements of CCSS

Below are the major elements used either fully or in a modified way to achieve the best configuration for the CCSS architecture.

SMACSS

SMACSS stands for Scalable and Modular Architecture for CSS. It is more of a style guide than a rigid framework. Read about SMACSS for background on the structure as CCSS uses it.

BEM

BEM stands for “Block”, “Element”, “Modifier”. It is a front-end methodology which is a new way of thinking when developing web interfaces. The guys at Yandex came up with BEM and more information can be found here.

SASS

SASS is CSS with superpowers. Highly recommend it but you can also use LESS if you prefer that. Please refer to the SASS documentation for more information.

Compass

Compass has no class definitions, it is an extension of SASS which provides a lot of utilities. It is used for general useful mixins, and sass compilation. Compass mixins should nearly always be used in cases where vendor prefixes are required. This again is a nice to have.

Principles of CCSS

Component-based

Write small and independent components which are reusable. A reusable css component is one which does not only exist on a specific part of the DOM tree or require the use of certain element types. If necessary, extra HTML elements should be used to make a component reusable.

Modular and Isolated

Components should have everything necessary to a certain part of the UI and have a single focus. It should also be isolated, meaning it should not directly modify or depend on another component.

Isolation is more important than code reuse across components as it can increase dependencies and tight coupling, eventually making the CSS less manageable.

Composable

When authoring CSS in a way that aims to reduce the amount of time spent writing it, one should think of it in a way to spend more time changing HTML classes on elements for modifying or adding styles. It is much easier for all developers to author css when it is like assembling lego blocks than to fight the CSS war. CSS classes are the building blocks which should be used to compose styles.

Predictable

Predictable means when you author CSS, your rules behave as you expect. This is important for large applications which has many pages. Avoid using overly complicated selectors and generic class names as these can lead to unpredictable css.

Documentation

Most people assume CSS is self-explanatory. In fact, this is usually not the case! CSS components must be documented clearly which describes how they should be used and what it does.

Directory Structure

Below is an example directory structure for easier viziualization, I have also included an example set up in this repo.

styles
    ├── bootstrap.css
    ├── ext
    │   ├── bootstrap
    │   │   ├── _settings.scss
    │   │   └── bootstrap.scss
    │   └── font-awesome
    │       └── font-awesome.scss
    ├── font-awesome.css
    ├── images.css
    ├── main.css
    └── **scss
        ├── _config.scss
        ├── base
        │   ├── _animation-classes.scss
        │   ├── _base-classes.scss
        │   ├── _base.scss
        │   └── images.scss
        ├── components
        │   ├── directives
        │   │   ├── _empty-state.scss
        │   │   ├── _legend.scss
        │   │   └── _status-message.scss
        │   ├── pages
        │   │   ├── _404.scss
        │   │   └── _redirect.scss
        │   └── standard
        │       ├── _alarm-state.scss
        │       ├── _graph-message.scss
        │       └── _panel.scss
        ├── main.scss
        ├── mixins
        │   ├── _animation.scss
        │   ├── _bem.scss
        │   └── _icon.scss
        └── themes
            └── _light.scss**

Only edit/author the files in the scss/ folder denoted in the bold above. This allows for updating external libraries easily which are in the ext/. Many applications start out with an external CSS framework like bootstrap or foundation, etc. so I added them in the example set up in the ext/ folder. It's absolutely fine to have all the CSS written from scratch and everything else mentioned above applies.

The directory components/ has desired efficacy in an AngularJS application but please feel free to customize it. More information is in Architecture section.

In the HTML page, include all the .css files from style/ folder which are generated after the SCSS compiles using grunt, compass, etc. Never alter them.

Naming Conventions - Simplified BEM

  • u-className Global base/utility classes
  • img-className Global image classes
  • animate-className Global animation classes
  • ComponentName Standard Components (B)
  • ComponentName-elementName Conponent's Element (E)
  • ComponentName--modifierName Component's Modifier (M)

Note the UpperCamelCase Component name to indicate that it is the master element and denotes the boundary of the component. Whereas the element and modifier names are elementName and modifierName respectively. Do not use - to separate out component names as it signifies the start of an element/element name.

Architecture and Design

Grunt

Grunt is a great task runner that can automate most of the tasks. Highly recommend using it to configure and compile the CSS. There are also other task runners but in general use it to compile all the necessary SCSS files into CSS, to watch for changes and recompile when changes are detected.

File organization

Please take a look the the directory structure which is derived from smacss. Notice the ext/ where all the external frameworks like bootstrap reside. Anything under ext/ should not be overridden as it makes it easier to upgrade and maintain the external CSS frameworks. If you want to override please refer to base/ folder for framework overrides file or add it.

base/ is where global base styles used application wide exits.

_base.scss Base styles for element selectors only. These are sort of "CSS resets"

_base-classes.scss These are all utility classes used application wide across many pages, views, and components. Prefix class names with u-

images.scss Use this as a SCSS compilation source. It should define and inline all site images as Data URIs. /app/styles/images.css is generated from this file.

_animate.scss All animation classes used application wide.

_bootstrap-overrides.scss Framework overrides only. Sometimes the level of specificity of framework selectors is so high that overriding them requires long specific selectors. Overriding at a global level should not be done in the context of a SCSS component, instead all global overrides go here.

Components

Any unit of reusable CSS not mentioned above is considered a "component". We use AngularJS so I categorized them to 3 types of CSS components: view/page, directive, and standard; and hence the directory structure which is derived from SMACSS. In the example setup in the github repository, I created explicit folders to be clear. If your application is small, you may put them in one folder. All components follow the modified BEM naming convention in combination with the CamelCase. This got me great wins in encouraging other team members to follow BEM style syntax. It also avoided a lot of confusion when moving away from using the typical BEM style with -, --, & __ symbols which generate class names like module-name__child-name--modifier-name!

Another important thing would be to make sure CSS class definition order in a component reflects the html view. This makes it easier to scan, style, edit and apply classes easily. Finally, it's a good idea to have an extensive style-guide for the web application and follow guidelines for CSS and SASS (avoid @extends).

Example

Refer to the code for an example set-up of the CSS.

Here is an example component in SASS.

.ProductRating {
  // nested element
  @include e(title) {
    ...
  }
  // nested element
  @include e(star) {
    ...
    // nested element's modifier
    @include m(active) {
      ...
    }
  }
}

It compiles to the following CSS:

.ProductRating {
  ...
}
// nested element
.ProductRating-title {
  ...
}
// nested element
.ProductRating-star {
  ...
}
// nested element's modifier
.ProductRating-star--active {
  ...
}

Your HTML might look something like below.

<div class="ProductRating">
  <img alt="Company logo" class="img-logo">
  <h3 class="ProductRating-title">Title</h3>
  <div class="u-starHolder">
    <span class="ProductRating-star ProductRating-star--active"></span>
    <span class="ProductRating-star ProductRating-star--active"></span>
    <span class="ProductRating-star ProductRating-star--active"></span>
    <span class="ProductRating-star"></span>
  </div>
</div>

Refer to the simplified BEM mixin which uses reference selector to achieve this and is simpler than @at-root. Working with BEM got way easier in version Sass 3.3> which gives us the ability to write maintainable code that is easy to understand.

Contributing

Contributions in the form of issues/PRs for adding more examples, improvements with post processing, clarifications, etc. are most helpful.

Thanks for the initial contributions from @jonrahoi @ksheedlo @leemunroe and @eddywashere.

Resources and Credits

CSS
General
Credits

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.