Skip to content

SCSS Overview

This page covers essential concepts and practices for Terra developers, focusing on CSS and BEM methodology. We will explore how to structure and organize CSS code using BEM, establish styling rules, and maintain continuous collaboration with the UX/UI Design Team. Key topics include:

  • BEM Methodology: Learn the principles of Block, Element, Modifier (BEM) for modular and scalable CSS code, enhancing reusability and maintainability.
  • Design Systems: Understand the importance of design systems as reusable component libraries that promote consistent design and streamline communication between designers and developers.
  • Naming Conventions: Discover our standardized naming conventions for components and foundations, ensuring clarity and consistency in our projects.
  • Coding Style Guidelines: Follow best practices for code formatting and style to maintain clean, readable, and maintainable code throughout the development process.

This structured approach facilitates effective communication, simplifies the setup process, and ensures seamless integration of dynamic imports when required. For any questions or clarifications, please reach out to your manager for guidance and assistance.

B.E.M

BEM (Block, Element, Modifier) is a methodology for organizing and structuring CSS (or SCSS) code in a modular and scalable manner. It aims to enhance code reusability, maintainability, and collaboration in larger projects.

At its core, BEM divides components into three main entities: blocks, elements, and modifiers.

Blocks: Blocks are standalone entities that represent reusable components or major sections of a website or application. They are independent and self-contained. For example, a navigation bar, a card, or a button can be considered as blocks. Blocks are named using lowercase letters and hyphens to separate words (e.g., “navigation-bar”).

Elements: Elements are the parts or elements within a block that cannot function independently. They are closely tied to the block they belong to. For example, within a navigation bar block, elements could include items, logo, or menu buttons. Element names are also written in lowercase and separated from the block name with a double underscore (e.g., “navigation-bar__item”).

Modifiers: Modifiers are variations or states of a block or element. They alter the appearance or behavior of the component without creating a new block or element. Modifiers are indicated using a double hyphen and are added to the block or element they modify (e.g., “navigation-bar—second” or “navigation-bar__item—is-active”). They allow for easy customization and flexibility.

Example of BEM:

.navigation-bar {
// Block styles
&__item {
// Element styles
}
&--second {
// Modifier styles
}
}

As you can see words &__item or &--second are used to describe markup. In our case we have a reserved word guide so all developers do it following the same pattern.

Example of BEM at Terra

.c--card-a {
// Block styles
&__title {
// Element styles
}
&--second {
// Modifier styles
}
}

Design Systems

A design system is a comprehensive set of reusable components, akin to Lego pieces, that can be combined to create various digital products. These components come in different colors, variations, and scales.

Beyond being a toolbox of UI components, a design system also serves as a communication tool, explaining the design rationale and intended purposes of our elements. It should include clear standards and an implementation guide to ensure proper usage and understanding of the components.

A design system is dynamic and evolves to meet new needs, requiring continuous collaboration between designers and developers. It enhances brand recognition and facilitates project scalability, team growth, and transitions, as seen with Terra.

By establishing a common language, design systems bridge the gap between designers and developers, ensuring everyone understands components like the sidebar submenu. This common understanding significantly improves communication and collaboration within and between teams.

In summary, a design system is a versatile collection of reusable components that supports communication, collaboration, project scalability, and a shared understanding among team members.

Naming conventions

The UX/UI team is responsible for naming components, which are divided into three main groups: foundations, components and utilities.

  • Foundations: These are the blueprints for all components and layouts, represented by the prefix f--{{name-of-foundation-type}} in HTML/CSS.

  • Components: These are the building blocks of the page, represented by the prefix c--{{name-of-component-type}}.

  • Utilities: These are tools to create specific/special CSS rules, represented by the prefix u--{{name-of-utility-type}}.

Throughout development, the UX/UI team oversees these components until they hand off to the development team, sharing a Figma file as reference.

Component Naming Convention:

  • All component classes start with “c—“.
  • Components are named with the component name followed by a letter (e.g., “c—card-a”).
  • The last letter of each component must be alphabetically ordered, and this order should always be respected, avoiding gaps in the sequence (e.g., going from card-d to card-f without card-e). In case a component is removed due to project development needs, it must be flagged and adjusted to maintain this consistency.
  • The CSS class for a component uses the block name followed by two underscores and the element name (e.g., “c—card-a__title”).
  • Reserved words are used for each element.
  • Avoid excessively nested components; create separate components if necessary.
  • If a component has user interaction through JavaScript, add js—**** to identify it.

This naming convention ensures consistency and clarity, promoting structured component creation and effective collaboration between the UX/UI and development teams.

Coding style guidelines

Indentation: Use soft tabs with 2 spaces for indentation.

  • Selectors: Avoid using ID selectors.
  • Multiple Selectors: When using multiple selectors one rule declaration, place each selector on its own line.
.c--card-a {
&__title,
&__subtitle,
&__content {
// Rule for multiple selector
}
}
  • Opening Brace: Put a space before the opening brace { in rule declarations.
  • Property Syntax: In properties, put a space after the : character, but not before.
  • Closing Brace: Place closing braces } of rule declarations on a new line.
  • Blank Lines: Include blank lines between rule declarations.

By adhering to these guidelines, you will ensure consistent and readable code formatting.

Modifiers

Apply modifiers wisely. They can be used both for the entire component as well as for some of its internal elements.

For modifiers, we use naming conventions to ensure clarity. Typically, we use names like —second, —third, etc., to label modifiers. However, in cases where there are multiple types of modifiers—such as background color, order, or font size—naming can be more specific, like —background-second, —order-second, or —font-second. Modifier names should only start with —is-X when they indicate a state or action, such as —is-active or —is-hidden.

.c--layout-a {
@extend .f--background-a;
&__wrapper {
@extend .u--text-center;
// wrapper modifier
&--second {
@extend .u--text-left;
}
}
// whole component modifier
&--second {
@extend .f--background-b;
}
}

Media queries

Media queries should always be placed within the element that is being modified inside the component, not separately and generically. SCSS, unlike regular CSS, allows you to create a rule and add a media query right below it, applying the necessary overrides.

.c--layout-a {
@extend .f--background-a;
&__wrapper {
@extend .u--text-center;
@media all and ($viewport-type: $tablets) {
text-align: left;
}
}
}