Understanding CSS Writing Methodologies

BEM’s site also lists how the block, element and modifier segregation can also be brought into the CSS file system. The blocks like “buttons” and “inputs” can have their own folders consisting the files (.css,.js) that are associated with those blocks, which makes things easier when we want to import those blocks in other projects.

A “block” is essentially the same as an “object”(from the example before), an “element” refers to the components of the block (image, title, preview text in the above preview-post- objects). A “modifier” can be used when the state of a block or element changes, for example when you add an active class to a menu item to highlight it, the active class acts as your modifier.

In OOCSS, the very first step that Nicole proposes we do is to identify objects in CSS.

Cons of BEM:
To keep the names sane-looking, BEM advises that we keep block to element nesting shallow.

CSS Methodology

Pros of BEM:
Easy to use class names and reduction in deep CSS selectors.

Nicole also suggests to not add styles based on location, for example, instead of targeting all the links inside a particular div to highlight, give those links a highlighter class with the appropriate CSS styles. This way when you need to highlight a link in some other part of the page, you can reuse the highlighter class.

Pros of ACSS:
Styling HTML without leaving HTML.

  1. OOCSS (Object Oriented CSS)
  2. BEM (Block, Element, Modifier)
  3. ACSS (Atomic CSS)
  4. SMACSS (Scalable and Modular Architecture for CSS)

We need to separate structure and skin (ie styles that create the objects’ appearance). The two types of objects have different structures, one is in a larger box even though they look similar, with images to the left and titles to the right.

1. OOCSS

We have here two types of objects, a bigger preview of titles which we will name post-preview-primary and a sidebar with titles which we will name post-preview-secondary.

oocss

The above CSS methodologies will give you a system to manage and optimize your CSS codes. They can be combined together, like OOCSS-SMACSS, or OOCSS-BEM, or BEM-SAMCSS to suit your needs.

Let’s give the images of both objects a class post-preview-image and add the code that puts the image on the left. This stops us from having to repeat the code of where to put the image inside objects in CSS. If there are other similar objects, we reuse post-preview-image for them.

OOCSS Objects

Once you’ve identified the components, name them accordingly. For example:

“SMACSS is a way to examine your design process and as a way to fit those rigid frameworks into a flexible thought process. – Jonathan Snook”

Skin separation can also be done for simpler styles like borders or backgrounds. If you have multiple objects with the same blue border, creating a separate class for the blue border and adding it to objects will reduce the number of times the blue borders have to be coded in CSS.

Cons of SMACSS:
None I can think of.

A methodology is a system of methods. Think of a method as simply a way of doing something in a systematic manner, in a certain preset way of doing things to achieve the result we want.

The naming can be modified to what works for you. The idea is to be able to identify, blocks, elements and modifiers from the class names. Check out some of the naming system listed in the BEM site.

Our preferred methods have either been established on our own over time or influenced by others or required in our workplace or due to all of the above. But over time, CSS veterans have formulated methodologies to write CSS that are more flexible, defined, reusable, comprehensible and manageable.

2. BEM

Cons of OOCSS:
Without a fair amount of repeating visual patterns, separating structure and visual style codes seem unnecessary.

bem

SMACSS identifies 5 types of style rules namely base, layout, module, state, and theme.

Cons of ACSS:
Too many classes, not very neat and you might hate it.

  • a menu block will have the class menu
  • its items will have the class menu__item (block and element are separated by double underscore)
  • the modifier for the disabled state of the menu can have the class menu_disabled (modifier delimited by a single underscore)
  • modifier for the disabled state of a menu item can be menu__item_disabled.

For modifiers, we can also use key_value format for naming. For example, to distinguish any menu items that link to obsolete articles, we can give them the class menu__item_status_obsolete, and for styling any menu items that point to pending documents, the class name can be menu__item_status_pending.

Below is an example of classes based on ACSS and how they’re used in HTML.

To get better results, we improve our methods by planning them better, changing up the order, simplifying steps – whatever that works faster and is more efficient.

It’s hard to determine when ACSS (Atomic CSS) was first developed since the concept has been in use for a while now. Developers have been using classes like .clearfix{overflow: hidden} for a long time. The idea in ACSS is to have a class for pretty much every reusable non-content related property-value pair we’ll need in our site, and to add those classes when needed to the HTML elements.

In this post we’re going to see what CSS writing methodologies are, some well known methodologies, and how they can be useful to us in optimizing our CSS code. Let’s start with the simplest question to get the ball rolling. What is a methodology?

3. ACSS

Take for example this structure from this site. Here’s something that is a repeating visual pattern and has its own independent HTML and/or CSS:

acss

Made famous by Yahoo, somewhere near the end of the first decade of the 21st century, ACSS’s key concepts consists of creating classes for the most atomic level of styling i.e. a property-value pair, then using them in HTML as needed.

Note: None of the concepts mentioned below should be confused with any framework, library or tool that may have the same name and concept as these methodologies. This post is only about the methodologies to write CSS.

Now let’s talk about CSS methodology. Just like with just about everything in life, we’ve a method of writing CSS too: some write reset CSS first, some place layout styles last, some start with two to three classes for styling an element, some write all the CSS codes in a single file.

The different style rules can be identified using a prefix in the class name for example, l-header (for layout) or t-header (for theme). We can also organize these different types of rules by placing them in separate files and folders.

“Basically, a CSS "object" is a repeating visual pattern, that can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript. That object can then be reused throughout a site. – Nicole Sullivan, Github (OOCSS)“

4. SMACSS

Developed in 2011 by Jonathan Snook SMACSS (Scalable and Modular Architecture for CSS) works by identifying the 5 different types of style rules. Class names and filing system are created based on these.

There’s a free online book you can read about SMACSS, or you can buy its ebook version to study it more.

smacss

We’re going to look at those formulated methodologies, which will include:

  • Base styles are the default styles directed at the basic HTML tags like <p>, <a:link>.
  • Layout styles are styles used to define the layout of the page, like coding where the header, footer and side menus will go.
  • Module styles are specific to a module like gallery or slideshow.
  • State styles are for highlighting elements with changeable states like hidden or disabled.
  • Theme is used for changing the visual scheme of the page.

There are also frameworks and libraries if you want an automated system for executing CSS methodologies such as:

 .mr-8{margin-right: 8px;} .fl-r{float:right;} <div class='mr-8 fl-r'> </div>

As you can see, the number of classes will get high with this method and the HTML will be crowded by all those classes. This method isn’t 100% effective but can be made useful if wanted. Yahoo uses this after all.

Pros of SMACSS:
Better organized code.

Developed by developers at Yandex in 2009, the key concepts for BEM (Block, Element, Modifier) encompasses identifying block, element & modifier and naming them accordingly.

Conclusion

Developed by Nicole Sullivan in 2008, the key concepts of OOCSS (Object Oriented CSS) includes CSS object identification, separation of structure and visual styles, and avoiding location based styles.

Pros of OOCSS:
Reusable visual styling codes, location flexible codes, reduction in deep nested selectors.

  • OOCSS framework
  • BEM tools
  • Organic CSS framework (follows atomic concept).


How to Optimize CSS with Code Style Guides

File Structure

 .class_1 .class_2 #id_1 #id_2 li a span { color: #bad; }

So it’s always good to set up a reasonable nesting limit, for example GitHub chose three levels in its style guide. By limiting nesting we can also force ourselves to write a better structured code.

Some style guides such as ThinkUp’s, also warns us about not using inline or embedded styles unless it’s unavoidable; it’s also a useful rule that’s worth applying.

Nesting

Just imagine a site that alternately uses px, em, and rem length measurements. It won’t only look bad in the code editor, but most likely some elements will be surprisingly small or large on that site.

Code Style Guides vs. Pattern Libraries

.class { // good margin: 0; // bad margin: 0px; // bad margin: 0em; // bad margin: 0rem; }

Commenting

We also need to make decisions about colour values (hexadecimal, rgb, or hsl), and whether we want to use shorthand properties and according to which rules. There’s an instruction that’s included in every CSS code style guide I bumped into, i.e. don’t specify units for 0 values (really, just don’t).

Putting proper code style guides into use provides us with a better organized, consistent code base, improved code readability, and more maintainable code. It’s not a coincidence that major tech companies, such as Google, AirBnB, or Dropbox make good use of them.

Mail

Nesting is a great feature in CSS, but at times it can go out of control. No one feels particularly happy, especially in the middle of a frustrating debugging process, bumping into extra long selectors like this:

ThinkUp's Style Guide

It’s important to note that the best style guides don’t only contain the styling rules themselves, but also examples of good and bad usage, as this way developers can more intuitively understand the rules.

Build Your CSS Code Style Guide

Idiomatic CSS for example establishes a meaningful commenting system that even uses some basic ASCII art, and results in beautifully organized code:

Both code style guides and pattern libraries include a styling strategy, but a different kind. Pattern libraries, such as Bootstrap, Zurb Foundation, BBC’s Global Experience Language, or MailChimp’s pattern library, provide us with a UI with premade CSS classes, typography, colour scheme, sometimes a grid system and other design patterns.

Dropbox for example requires developers to put spaces after the colon in property declarations, while Evernote uses two spaces for indentation. We can set up as many formatting rules as we are comfortable with, but never more than it’s possible to grasp.

AirBnB's Style Guide

Moreover if we want to change its colour from red to something else in the future, we can easily do it without a hassle. There are also premade CSS naming conventions, such as the BEM (Block, Element, Modifier) convention, that result in a consistent naming structure with unique and meaningful names.

The four common styles used in selector naming are .lowercase, .under_scores, .dash-es, and .lowerCamelCase. It’s okay to choose any of them but we need to follow the same logic across the whole project.

Declaration Order

When designers talk about style guides, they usually mean an agreed upon manual on the coherent look and feel of a website or an application, with a well-designed colour scheme, typography, and UI that’s used across the whole project.

In this post we will take a look at how we can smartly optimize our CSS with the help of CSS code style guides.

Naming Rules

Formatting Rules

Note that living style guide generators, such as KSS, Styledown, or Pattern Lab, generate pattern libraries and not coding style guides. While pattern libraries are also highly useful and elevate the web development process, they don’t allow us to optimize code itself.

Using only semantic selector names is also essential if we want to have meaningful code. For example, instead of .red-button (which doesn’t show what the button does) it’s better to use the .alert-button name (which says what it does), as this way, we enable developers (and our future selves) to understand what said button does.

Code formatting includes things like usage of whitespace, tabs, indentation, spacing, line breaks, etc. There’s not really a universally good or bad method in formatting, the only rule of thumb is to choose coherent rules that result in a readable code, and follow them through.

BEM Naming Convention

First, we need to figure out a logic according to which we will organize our CSS files. For smaller projects one CSS file may be enough, but for larger ones it’s always better to break up the code, and concatenate the separate files later in production.

Units and Values

In our industry there is a certain degree of uncertainty about what we can call a style guide. A List Apart for example uses it synonymously with the term pattern library in this article, but we can bump into this kind of definition in other posts as well.

Ordered things are always easier to see through, and ordering CSS declarations (properties with their values) according to a rule that makes sense results in a better organized code.

Take a look at for example WordPress’s property ordering rules, it defines the following simple but logical baseline for ordering in which properties are grouped by their meaning:

For example AirBnB shows good and bad examples to developers in the following easily digestable way:

  1. Display
  2. Positioning
  3. Box model
  4. Colors and Typography
  5. Other

Using coherent naming rules for CSS selectors is crucial if we want to understand our code months or even years later. There are many solutions out there, and there’s only one strict rule we need to follow i.e. a selector name cannot start with a number.

Deciding upon how we want to use units and values is not only important to achieve a consistent code look, but also if we don’t do so, we may end up with something weird

Commenting code is essential in all languages, but in CSS it doesn’t only facilitate debugging and documentation making, but also sections CSS rules into logical groups. We can use either the /* ... */ or the // ... notation style for comments in CSS, the important thing is to stay consistent with comments throughout our project.

The final goal of a CSS code style guide is to ensure we can work with a consistent, easily debuggable code base written by developers who all follow the same code styling rules. Creating a CSS code style guide may take a little time but it’s worth the effort, as we only have to do it once. Then we can use the same style guide across different projects.

CSS code style guides, such as Evernote’s or ThinkUp’s (or the ones mentioned in the intro) contain rules about how to write CSS including things like naming conventions, file structure, property order, code formatting, and others.

There’s another type of style guide we can use in web development as well, and it’s just as important but much more rarely discussed: style guides for the code itself. Code style guides are rather for developers than designers, and their main goal is to optimize CSS, or other code.

On the other hand, there are also publications, such as CSS Tricks or Brad Frost’s blog, that distinguish code style guides from pattern libraries. This latter approach probably takes us closer to a well-optimized website, as it allows us to handle code and design separately, so we will use this in this post.

Idiomatic CSS Commenting


How to Write Better CSS with Performance in Mind

Reflows are triggered by layout changes to an element, like changes to the geometric properties such as height or font size, the addition or removal of classes to elements, window resizing, activated :hover, DOM changes by JavaScript, etc.

Browser Rendering Workflow
  1. Recalculate Style (and render tree creation). Browser computes the styles to be applied to the elements in the DOM tree. A render tree is later created while discarding the nodes (elements) from the DOM tree that aren’t to be rendered (elements with display:none) and those that are (pseudo-elements).
  2. Layout (aka Reflow). Using the computed style from before, the browser calculates the position and geometry of each element on the page.
  3. Repaint. Once the layout is mapped, pixels are drawn to the screen.
  4. Composite Layers. During repainting, the painting might be done in different layers autonomously; those layers are then finally combined together.

If you’re animating properties of an element that can trigger Repaint directly or indirectly, it’ll be of great advantage if that element is in its own layer preventing its painting prcoess from affecting the rest of the page and triggering hardware acceleration. In hardware accelaration, the GPU will take up the task of performing the animation changes in the layer, saving the CPU extra work while speeding up the process.

1. Reduce Style Calculations

(1) So up til now, we haven’t touched on CSS file size reduction. We have mentioned that reduction in style rules (and DOM elements) make a significant performance improvement because of how much the browser will have to work less on the process of computing the styles. As a consequence of this code reduction, writing better selectors and the deletion of unused CSS, the file size will automatically decrease.

Style Calc

IMAGE: Aerotwist

If you’re animating an element that goes through layout changes, take it out of the page flow by absoutely positioning it, since Reflow in absolutely positioned elements won’t affect the rest of the elements on the page.

To avoid costly style calculations, reduce complex and deeply nested selectors so that it’s easier for the browser to figure out which element a selector is referring to. This reduces computational time.

2. Reduce Reflows

(2) It’s also advisable to not make too many consequential changes to an element’s styles in JavaScript. Instead add a class to the element (using JavaScript) that holds the new styles to make these changes – this prevents unnecessary Reflows.

To forcefully promote an element to new layer and go into hardware acceleration for animation, there are two techniques invovled:

Just like in style calculation, to reduce Reflows, avoid complex selectors and deep DOM trees (again, this is to prevent excessive cascading of Reflows).

Reflows or Layout changes in an element are very "expensive" processes, and they can be of an even bigger problem when the element that went through the layout changes has a significant amount of children (since Reflows cascade down the hierarchy).

(3) You will want to avoid Layout Thrashing as well (forced synchronous Reflows) which arises due to the accessing and modifying of the Layout properties of elements using JavaScript. Read more about how this kills performance here.

To summarise:

  • Target elements that are lower in the DOM tree when making layout changes
  • Choose absolutely positioned elements for layout changing animations
  • Avoid animating layout properties whenever possible

3. Reduce Repaints

Now let’s continue on to what we can do in the first three stages of the operation to write better-performing CSS codes.

Pixel Art

Like mentioned before, in the "Recalculate Style" stage the browser computes the styles to be applied to the elements. To do this, the browser first finds out all the selectors in the CSS that point to a given element node in the DOM tree. Then it goes through all the style rules in those selectors and decides which ones are to be actually applied to the element.

In today’s post we will ponder over the code choices we can make in CSS for improved site performance. But, before we dive into those choices, let’s first take a brief, closer look at the webpage rendering workflow in order to focus on the problematic (performance-wise) areas that are solvable via CSS.

To avoid frequent and huge repaints, use less of the properties that cause costly repaints like shadows.

If you have to change the layout styles of a component in your page, target the styles of the element that is at the lowest in the hierarchy of elements that the component is made of. This is so that the layout changes doesn’t trigger (almost) any other Reflows.

Here’s the rough flow of operations performed by the browser after DOM tree creation:

  1. add transform: translate3d(0, 0, 0); to the element, tricking the browser into triggering the hardware acceleration for animations and transitions.
  2. add the will-change property to the element, which informs the browser of the properties that are likely to change in the element in the future. Note: Sara Soueidan has an in-depth and super-helpful article on this in the Dev.Opera site.

Repaint refers to the drawing of pixels on the screen, and is an expensive process just like Reflow. Repaints can be triggered by Reflows, page scroll, changes in properties like color, visibility and opacity.

  • Avoid expensive styles that cause Repaints
  • Seek layer promotion and hardware acceleration for hefty animations and transitions.

Take Note

To summarise:

In some browsers, opacity (with a value of less than 1) and transform (value other than none) are automatically promoted to new layers, and hardware acceleration is applied for animations and transitions. Preferring these properties for animations is thusly good.

Other ways to employ include reducing the number of style rules (where possible), removing unused CSS and avoiding redundancy & overrides, so that the browser doesn’t have to go through the same style again and again during style calculations.


10 Reasons Why You Need Code Optimization

Code maintenance usually gets little respect in developer circles, but it still can be a rewarding task if we follow best practices, such as using reliable version control, dependency management, staging and testing platforms, and properly take care of documentation.

Accomplishing complete consistency is hard, as ensuring backward compatibility can eventually get in the way of improvement, but paying attention to using coherent code guidelines, compatible APIs, and consistent standards can surely lessen the pain.

Although optimization problems are not the only one developers regularly deal with, for instance there are decision problems and searching problems as well, optimization is the task that encompasses the different stages of web development probably the most.

Keeping code consistency in mind is especially important when we need to deal with legacy code, or in cases of larger projects that involve many developers.

The benefits of code optimization grow in line with the growth of our project, and as even initially small projects can become large with time, acquiring solid code optimization skills almost always have measurable positive results.

Apart from the already discussed code optimization methods, feature development can also gain momentum if we keep up with modern project management methods, for example if we use iterative lifecycle models instead of the traditional waterfall model.

Code optimization can happen on different levels, depending on how close the optimization we carry out is to machine code. In web development we can only perform higher level optimizations, as Assembly- or runtime-level optimizations are not an option for us, but we still have many opportunities.

1. Cleaner Code Base

IMAGE: Freepik

This is the reason why big projects, such as WordPress, jQuery, and Mootools, have clear coding style guides every developer involved needs to follow.

2. Higher Consistency

It frequently occurs in web development that we inherit code from someone else, and quickly understand that it is far from being optimal, whether in terms of structure, performance, or maintainability. The same thing can happen with our own previous projects that we wrote when we had much less experience in programming.

In other cases the goals of an otherwise great project change over time, and we need to prioritize other things in the application than before.

3. Faster Sites

Consistency is like housework, when it’s properly taken care of no one notices it, but when it’s neglected the whole place looks messy, and we find ourselves in chaos.

IMAGE: Freepik

Agreed upon best practices and style guides can bridge the gap between people from different backgrounds, not to mention the usual communication hardships between design and development teams in most web projects.

In software maintenance, we are already at a stage where we can catch real performance and efficiency problems, and work with real users instead of hypothetical use cases.

4. Better Code Readability

Luckily we have many well-tested techniques on our hands that can make refactoring a smooth-running process.

IMAGE: Freepik

Debugging takes up a significant portion of the web development workflow, and it’s usually a tedious or even daunting task. It’s hard enough if we have to debug our own code, but it’s much worse when we need to find the bugs in someone else’s, especially if it’s something like neverending spaghetti code that uses nothing but functions.

  • using coherent naming conventions with meaningful names, such as BEM
  • consistent formatting with logical utilization of indentation, whitespace and vertical spacing
  • avoiding unnecessary noise, such as self-explanatory, obvious comments

It’s basically impossible to completely avoid technical debt, as even good decisions can be less desired consequences in the future, but if we diligently optimize our code, we will surely be burdened with a much smaller technical debt.

5. More Efficient Refactoring

Faster code entails shorter page load times as well, which is a big deal in both of the worlds of search engine optimization and conversion marketing. Research says that “nearly half of web users expect a site to load in 2 seconds or less, and they tend to abandon a site that isn’t loaded within 3 seconds”, so speed is clearly not an area that we can safely ignore.

Smart design and architectural patterns, such as using objects and different modules, and clear coding guidelines can facilitate the debugging process, even if most likely it still won’t be our most beloved task.

Code optimization is also workflow optimization, as if team members speak a common language and share the same declared goals, they will also be able to work together without much less hassle.

Optimizing code is similar to buying a faster car. As a result, our code executes more rapidly, and our site or application consumes less memory than before. Although the optimization process may require additional time and money, the result is a better experience, not just for developers but also for end users.

6. More Straightforward Debugging

Whatever technique we choose to go along with, there’s a rule of thumb that every code optimization endeavour needs to follow: we always have to carry out the optimization in a way that doesn’t change the meaning of the code.

As a project matures, and more and more developers start to work on it, duplications and overlaps usually sooner or later appear, and suddenly we realize we hardly comprehend what’s going on.

7. Improved Workflow

We can protect ourselves from the pain of dealing with indecipherable code if we apply certain code optimization techniques, such as:

Constant innovation is the core of staying relevant in our field, as in if we haven’t show anything new to our users in a while we can quickly be left behind. Extending a project, and adding new features to it is usually much faster if we work with a well-optimized, clean code base.

Although building something from the ground up tend to be more fun than maintaining pre-existing code, sometimes we still need to perform ongoing code maintenance. Working with already existing systems can also give us new views on code optimization, as it’s a different experience than early optimizations in a new project.

8. Easier Code Maintenance

It’s not a coincidence that keeping the DRY (Don’t Repeat Yourself) principle in mind is one of the cornerstones of effective software development. A well-strutured, carefully optimized code base in which we are able to reuse the same elements multiple times is always sleeker and tidier, and therefore is much easier to understand and work with.

IMAGE: Freepik

These less-than-optimal decisions usually manifest themselves in the form of quick fixes, copy and paste programming, hard coding, cargo-cult programming, and other coding antipatterns and sloppy work habits.

We can optimize our code at the architectural level with smart design patterns, at the source code level by utilizing best coding practices and using appropriate tools, and we can also improve the performance of our team by introducing coding style guides into our workflow.

Readability is an important aspect of code maintainability. Untidy code with ad hoc formatting is hard to read, therefore hard to understand, especially for developers who are new to a project.

9. Quicker Feature Development

The term "technical debt" was coined by Ward Cunningham, the programmer who also developed the first wiki. It compares the consequences of our bad programming decisions that accummulate over time to financial debt in which people pay interest in the future in order to quickly get money in the present.

10. Smaller Technical Debt

We speak about refactoring when we change (clean up) existing code in order to optimize it without changing any of its functionalities. Refactoring needs to be performed with great care, as if it’s done in the wrong way, we can easily end up with a code base that’s even less optimal than the original was.

Many web development projects are run by distributed teams, such as open source communities or remote teams. One of the hardest things in managing such a workflow is to find a way that makes communication effective enough to enable team members to easily understand each other, and not to have to constantly discuss defaults.

While we write code, we continuously make decisions and choose between solutions that may seem equivalent at first. Later it usually turns out that some choices result in a more efficient program than others, so a quest for best coding practices and optimization techniques naturally arises, and we begin to see the whole development process as an optimization problem to solve.