DEV Community

Dahye Ji
Dahye Ji

Posted on

CSS Methodologies - OOCSS, SMACSS, BEM

OOCSS

: making different kinds of modules and combining them like lego blocks.

The "Object" in OOCSS refers to an HTML element or anything associated with it like CSS classes or Javascript methods.
As with any object-based programming method, the purpose of OOCSS is to encourage code reuse and, ultimately, faster and more efficient stylesheets that are easier to add and maintain.

Separation of structure from skin(visual features)

such as width, height, padding, margin belongs to structure and things that doesn't affect layout but affect elements visually like font-related properties, color, background, border will be included in skin.
Some styles like color, font, etc get repeated. When these different features are abstracted into class-based modules, they become reusable and can be applied to any element.

#button {
  width: 200px;
  height: 50px;
  padding: 10px;
  border: solid 1px #ffffff;
  background: linear-gradient(#7ad9ff, #84ffe8);
  box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

#box {
  width: 400px;
  overflow: hidden;
  border: solid 1px #000000;
  background: linear-gradient(#7ad9ff, #84ffe8);
  box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
Enter fullscreen mode Exit fullscreen mode

These elements above have styles that are unique to each but they have a number of styles in common. Instead of applying them to the non-reusable id to define styles, you can abstract the common styles.

.button {
  width: 200px;
  height: 50px;
}

.box {
  width: 400px;
  overflow: hidden;
}

.skin {
  border: solid 1px #000000;
  background: linear-gradient(#7ad9ff, #84ffe8);
  box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px
}
Enter fullscreen mode Exit fullscreen mode

All the elements are using classes now, the common styles are combined into "skin" which is reusable and there isn't repeated code now. You just have to apply the "skin" class to all elements if you want to have the same style like the first code.

Separation of container from content.

The second principle is the separation of containers from their content.
Two different buttons have have the same structure but different styles.

<main id="main">
  <button type="button" class="btn general">기본 버튼</button>
  <button type="button" class="btn warning">취소 버튼</button>
</main>
Enter fullscreen mode Exit fullscreen mode
#main .btn {
  width: 300px;
  padding: 20px 10px;
  margin: 10px;
  font-size: 18px;
  line-height: 1.5;
}

#main .general {
  background-color: aquamarine;
  color: black;
}

#main .warning {
  background-color: azure;
  color: blue;
}
Enter fullscreen mode Exit fullscreen mode

SMASS(Scalable and Modular Architecture for CSS)

ref: http://smacss.com/
The core of SMACSS is categorisation. You can categorise by it's
These are five types of categories:

  • Base: A Base rule is applied to an element using an element selector, a descendent selector, or a child selector, along with any pseudo-classes. It doesn’t include any class or ID selectors. It is defining the default styling for how that element should look in all occurrences on the page.
body, form {
    margin: 0;
    padding: 0;
}

a {
    color: #039;
}

a:hover {
    color: #03F;    
}
Enter fullscreen mode Exit fullscreen mode
  • Layout: Layout styles can also be divided into major and minor styles based on reuse. Major layout styles such as header and footer are traditionally styled using ID selectors but take the time to think about the elements that are common across all components of the page and use class selectors where appropriate. (Usually layout modules are not many so id selector can be used)
#header, #article, #footer {
    width: 960px;
    margin: auto;
}

#article {
    border: solid #CCC;
    border-width: 1px 0 0;
}
Enter fullscreen mode Exit fullscreen mode
  • Moudule: Each Module should be designed to exist as a standalone component. In doing so, the page will be more flexible. If done right, Modules can easily be moved to different parts of the layout without breaking. When defining the rule set for a module, >avoid using IDs and element selectors, sticking only to class names. A module will likely contain a number of elements and there is likely to be a desire to use descendent or child selectors to target those elements. Subclassing Modules. When we have the same module in different sections, the first instinct is to use a parent element to style that module differently.
<ul class="tabnav">
    <li class="" tabnav__item"><a href="" class="tabnav__link">탭1</a></li>
    <li><a href="">탭2</a></li>
    <li><a href="">탭3</a></li>
    <li><a href="">탭4</a></li>
</ul>
Enter fullscreen mode Exit fullscreen mode
.tabnav {
  display: flex;
}

.tabnav li {
  border-top: 1px solid black;
  border-right: 1px solid black;
  border-bottom: 1px solid black;
}

.tabnav li:first-child {
  border-left: 1px solid black;
}

.tabnav li a {
  display: block;
  padding: 10px 30px;
  text-decoration: none;
}
Enter fullscreen mode Exit fullscreen mode
  • State: States are generally applied to the same element as a layout rule or applied to the same element as a base module class. A state is something that augments and overrides all other styles.
/* .is-hidden / .is-active  => can add different class depending on the state */
.is-active {
  background-color: blanchedalmond;
}
/* pointer-events: 클릭할 수 없는 스타일 */
.is-active a {
  pointer-events: none;
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

Difference from subclass.
1.State styles can apply to layout and/or module styles; and
2.State styles indicate a JavaScript dependency.(It can be added or taken out) /

  • Theme: It is probably self-evident but a theme defines colours and images that give your application or site its look and feel. Separating the theme out into its own set of styles allows for those styles to be easily redefined for alternate themes.
// in module-name.css
.mod {
    border: 1px solid;
}

// in theme.css
.mod {
    border-color: blue;
}
Enter fullscreen mode Exit fullscreen mode

BEM(Block, Element, Modifier)

ref: http://getbem.com/
It doesn't recommend using id and element selector.(Only use class)

  • Block: Standalone entity that is meaningful on its own. (header, container, menu, checkbox, input...) *You should name classes very clear. *If want to use lowercase and more than one word for class name, you should use hyphen case(kebab case) e.g: cont-nav
  • Element: A part of a block that has no standalone meaning and is semantically tied to its block.(menu item, list item, checkbox caption, header title...). Elements inherit class name from block. *Use class name selector only *No tag name or ids *No dependency on other blocks/elements on a page
<!-- Naming -->
<div class="block">
      ...
      <span class="block__elem"></span>
    </div>
Enter fullscreen mode Exit fullscreen mode
/* Good */
.block__elem { color: #042; }

/* Bad */
.block .block__elem { color: #042; }
    div.block__elem { color: #042; }
Enter fullscreen mode Exit fullscreen mode
  • Modifier: Flags on blocks or elements. Use them to change appearance, behavior or state.(disabled, highlighted, checked, fixed, size big, color yellow...)
<!-- Good -->
<div class="block block--mod">...</div>
    <div class="block block--size-big
        block--shadow-yes">...</div>

<!-- Bad -->
<div class="block--mod">...</div>
Enter fullscreen mode Exit fullscreen mode
/* Use modifier class name as selector: */
.block--hidden { }

/* To alter elements based on a block-level modifier: */
.block--mod .block__elem { }

/* Element modifier: */
.block__elem--mod { }
Enter fullscreen mode Exit fullscreen mode

Example

<form class="form form--theme-xmas form--simple">
  <input class="form__input" type="text" />
  <input
    class="form__submit form__submit--disabled"
    type="submit" />
</form>
Enter fullscreen mode Exit fullscreen mode
.form { }
.form--theme-xmas { }
.form--simple { }
.form__input { }
.form__submit { }
.form__submit--disabled { }
Enter fullscreen mode Exit fullscreen mode

Discussion (0)