SCSS & Styles
At Terra, we write SCSS (Sassy CSS) using a structured approach that leverages utilities, foundation variables, and @extend to create maintainable, consistent stylesheets.
SCSS File Structure
Section titled “SCSS File Structure”Component stylesheets live in organized folders within the src/scss/ directory:
src/scss/├── framework/│ ├── _var/│ │ └── _vars.scss # Foundation variables│ ├── components/│ │ ├── cta/│ │ │ └── _c--cta-a.scss # Your component│ │ ├── card/│ │ └── hero/│ ├── foundation/│ │ ├── background/│ │ ├── color/│ │ ├── font/ # Font utilities│ │ ├── gap/│ │ ├── grid/ # Grid system│ │ ├── reset/│ │ ├── spaces/ # Spacing utilities│ │ └── _foundation.scss│ ├── utilities/│ │ └── _utilities.scss # Utility classes│ └── global-components/ # Pre-built components└── style.scss # Main entry fileCreating a Simple Component
Section titled “Creating a Simple Component”Let’s build a CTA component (c—cta-a) step-by-step. This component will have:
- 10-column grid centered with justify-center utility
- Title, subtitle, and button
- Background color and border
01: HTML Structure
Section titled “01: HTML Structure”<section class="c--cta-a u--pt-10 u--pb-10"> <div class="f--container"> <div class="f--row u--justify-content-center"> <div class="f--col-10 f--col-tablets-12"> <div class="c--cta-a__wrapper"> <h2 class="c--cta-a__wrapper__title"> Ready to Transform Your Business? </h2> <p class="c--cta-a__wrapper__subtitle"> Join thousands of companies already using our platform. </p> <a href="/contact" class="c--cta-a__wrapper__button"> Get Started Today </a> </div> </div> </div> </div></section>Key elements:
.f--container- Centers the content.f--row u--justify-content-center- Creates flex row with centered content.f--col-10- 10 columns wide (83.33%)- BEM naming -
.c--cta-a__wrapper__title
02: SCSS Structure
Section titled “02: SCSS Structure”Create the file: src/scss/framework/components/cta/_c--cta-a.scss
@use "sass:map";@use "@scss/framework/_var/_vars.scss" as *;@use "@scssUtilities/utilities.scss";@use "@scssFoundation/foundation.scss";
.c--cta-a { @extend .u--position-relative; @extend .u--overflow-hidden; background-color: map.get($color-options, a); // Navy background border: 2px solid map.get($color-options, c); // Brand border border-radius: $measure * 2; // 16px border radius
&__wrapper { @extend .u--display-flex; @extend .u--flex-direction-column; @extend .u--align-items-center; @extend .f--sp-e; // Bottom spacing gap: $measure * 3; // 24px gap between items padding: $measure * 8 $measure * 5; // 64px top/bottom, 40px left/right
@media all and ($viewport-type: $tablets) { padding: $measure * 6 $measure * 4; // 48px / 32px on tablets gap: $measure * 2; // 16px gap on tablets }
&__title { @extend .f--font-c; // Large font size @extend .f--color-w; @extend .u--font-semibold; @extend .u--text-align-center; @extend .u--margin-0; }
&__subtitle { @extend .f--font-f; // Base font size @extend .f--color-w; @extend .u--text-align-center; @extend .u--margin-0; opacity: 0.9; }
&__button { @extend .u--display-inline-block; @extend .f--font-g; @extend .u--font-semibold; background-color: map.get($color-options, c); // Brand color color: map.get($color-options, w); // White text padding: $measure * 2 $measure * 4; // 16px / 32px border-radius: $measure; // 8px text-decoration: none; transition: transform $time-a $ease-standard-a, background-color $time-a $ease-standard-a;
@media all and (hover: hover) and (pointer: fine) { &:hover { transform: translateY(-2px); background-color: map.get($color-options, d); // Darker on hover } } } }}Understanding the SCSS
Section titled “Understanding the SCSS”Imports
Section titled “Imports”@use "sass:map"; // Sass map utilities@use "@scss/framework/_var/_vars.scss" as *; // Variables@use "@scssUtilities/utilities.scss"; // Utility classes@use "@scssFoundation/foundation.scss"; // Foundation systemsWhy these imports?
- sass:map - Access color palettes with
map.get() - _vars.scss - Contains spacing (
$measure), colors ($color-options), timing ($time-a) - utilities.scss - Provides
.u--classes for common patterns - foundation.scss - Typography (
.f--font-*), spacing (.f--sp-*)
Foundation Variables
Section titled “Foundation Variables”Terra provides a comprehensive variable system for consistent design:
Colors
Section titled “Colors”// Access colors from the color palettebackground-color: map.get($color-options, a); // Navyborder-color: map.get($color-options, c); // Brand colorcolor: map.get($color-options, w); // WhiteCommon color keys (random examples):
a- Primary navyc- Brand accent colorw- Whitef- Light gray (borders)h- Text gray
Spacing
Section titled “Spacing”All spacing uses the $measure unit (8px base):
padding: $measure * 8 $measure * 5; // 64px / 40pxgap: $measure * 3; // 24pxborder-radius: $measure * 2; // 16pxCommon multipliers:
$measure * 1= 8px$measure * 2= 16px$measure * 3= 24px$measure * 4= 32px$measure * 5= 40px$measure * 8= 64px
Typography
Section titled “Typography”Use foundation classes for consistent type (random examples):
@extend .f--font-a; // Largest (70px)@extend .f--font-b; // Very large (60px)@extend .f--font-c; // Large (48px)@extend .f--font-d; // Medium-large (32px)@extend .f--font-f; // Base (18px)@extend .f--font-g; // Small (16px)Timing & Easing
Section titled “Timing & Easing”For smooth animations:
transition: transform $time-a $ease-standard-a;// $time-a = 0.3s// $ease-standard-a = cubic-bezier(0.4, 0.0, 0.2, 1)Available timing:
$time-a- Standard (0.3s)$time-b- Fast (0.2s)$time-c- Slow (0.5s)
Utility Classes with @extend
Section titled “Utility Classes with @extend”Instead of writing CSS from scratch, we @extend utility classes:
@extend .u--display-flex; // display: flex@extend .u--flex-direction-column; // flex-direction: column@extend .u--align-items-center; // align-items: center@extend .u--position-relative; // position: relative@extend .u--text-align-center; // text-align: centerBenefits:
- ✅ Smaller CSS bundle (classes are reused)
- ✅ Consistency across components
- ✅ Less code to write
- ✅ Centralized updates
Proper Nesting with BEM
Section titled “Proper Nesting with BEM”.c--cta-a { // Block-level styles background-color: map.get($color-options, a);
&__wrapper { // Element styles padding: $measure * 8 $measure * 5;
&__title { // Sub-element styles @extend .f--font-c; }
&__subtitle { // Another sub-element @extend .f--font-f; }
&__button { // Button element padding: $measure * 2 $measure * 4; } }}Compiled output:
.c--cta-a { ... }.c--cta-a__wrapper { ... }.c--cta-a__wrapper__title { ... }.c--cta-a__wrapper__subtitle { ... }.c--cta-a__wrapper__button { ... }Responsive Design
Section titled “Responsive Design”Use breakpoint variables for media queries:
// Desktop firstpadding: $measure * 8 $measure * 5;
// Tablets and below@media all and ($viewport-type: $tablets) { padding: $measure * 6 $measure * 4;}
// Mobile@media all and ($viewport-type: $mobile) { padding: $measure * 5 $measure * 3;}Available breakpoints:
$tablets- 810px and below$tabletm- 1024px and below$mobile- 580px and below$laptop- 1570px and below
Hover States
Section titled “Hover States”Always wrap hover states to avoid issues on touch devices:
@media all and (hover: hover) and (pointer: fine) { &:hover { transform: translateY(-2px); background-color: map.get($color-options, d); }}Why this media query?
hover: hover- Device supports true hoverpointer: fine- Device has precise pointer (mouse)- Prevents sticky hover states on mobile/touch devices
How Utilities Work
Section titled “How Utilities Work”Utility classes are pre-built, single-purpose classes that handle common CSS patterns.
Common Utilities
Section titled “Common Utilities”Display:
@extend .u--display-block;@extend .u--display-flex;@extend .u--display-inline-block;@extend .u--display-none;Flexbox:
@extend .u--flex-direction-column;@extend .u--flex-direction-row;@extend .u--align-items-center;@extend .u--justify-content-center;@extend .u--justify-content-space-between;Spacing:
@extend .u--mb-3; // margin-bottom: $measure * 3@extend .u--mt-5; // margin-top: $measure * 5@extend .u--pt-10; // padding-top: $measure * 10@extend .u--pb-7; // padding-bottom: $measure * 7Typography:
@extend .u--text-align-center;@extend .u--text-align-left;@extend .u--font-bold;@extend .u--font-semibold;Position:
@extend .u--position-relative;@extend .u--position-absolute;@extend .u--overflow-hidden;Foundation System
Section titled “Foundation System”Foundation classes provide design system tokens:
Typography Foundation
Section titled “Typography Foundation”// Font sizes@extend .f--font-a; // h1 size@extend .f--font-b; // h2 size@extend .f--font-c; // h3 size@extend .f--font-f; // body size
// Font colors@extend .f--color-a; // Primary text color@extend .f--color-w; // White text@extend .f--color-h; // Gray textSpacing Foundation
Section titled “Spacing Foundation”// Bottom spacing (margin-bottom)@extend .f--sp-a; // Small spacing@extend .f--sp-c; // Medium spacing@extend .f--sp-e; // Large spacingRegistering Your SCSS
Section titled “Registering Your SCSS”After creating your component SCSS, register it in the main style.scss:
File: src/scss/style.scss
// ... other imports
@use "@scssComponents/cta/_c--cta-a.scss";@use "@scssComponents/cta/_c--cta-b.scss";
// ... rest of importsImport Order:
- Keep similar components grouped (all CTAs together)
- Maintain alphabetical order within groups
- Remove test components before production
Global Components
Section titled “Global Components”Terra provides a pre-built HTML and SCSS framework called Global Components that offers readily usable components. You can easily integrate these components into your projects by simply copying and pasting the code. This framework streamlines the development process by offering a collection of pre-designed elements for increased efficiency and consistency.
📚 Global Components Documentation
Example: Global Card Component
Section titled “Example: Global Card Component”Here’s how to use g--card-08 from the Global Components library:
HTML:
<div class="g--card-08"> <h3 class="g--card-08__item-primary">Investment Banking</h3> <div class="g--card-08__list-group"> <p class="g--card-08__list-group__item">Learn More</p> </div></div>SCSS:
@use "sass:map";@use "@scss/framework/_var/_vars.scss" as *;@use "@scssGlobalComponents/_global-vars.scss" as *;@use "@scssFoundation/_foundation.scss";
.g--card-08 { @include make-card-08(); @include make-card-08-modifier( $item-primary-options: ( "className": f--font-b f--color-c, ), $list-group-item-options: ( "className": f--font-d f--color-h, ), );
&--second { @include make-card-08-modifier( $list-group-item-options: ( "className": f--font-f, "color": map.get($color-options, f) ), ); }}Key features:
- Uses
@includemixins from Global Components - Leverages modifier patterns for variations
- Integrates with Terra’s foundation variables
- Allows customization through options
Best Practices
Section titled “Best Practices”✅ Do’s
Section titled “✅ Do’s”Use foundation variables:
// ✅ Goodpadding: $measure * 5;color: map.get($color-options, a);
// ❌ Badpadding: 40px;color: #1a1536;Extend utilities when possible:
// ✅ Good@extend .u--display-flex;@extend .u--align-items-center;
// ❌ Bad - writing CSS that already existsdisplay: flex;align-items: center;Use responsive breakpoints:
// ✅ Goodpadding: $measure * 8;
@media all and ($viewport-type: $tablets) { padding: $measure * 6;}
// ❌ Bad - hardcoded breakpoint@media (max-width: 768px) { padding: 48px;}Wrap hover states:
// ✅ Good@media all and (hover: hover) and (pointer: fine) { &:hover { transform: scale(1.05); }}
// ❌ Bad - causes issues on touch devices&:hover { transform: scale(1.05);}❌ Don’ts
Section titled “❌ Don’ts”Don’t hardcode values:
// ❌ Wrongpadding: 37px;color: #ff5733;font-size: 21px;Don’t skip BEM nesting:
// ❌ Wrong.c--card { }.card__title { } // Doesn't follow block name
// ✅ Correct.c--card { }.c--card__title { }Don’t create deep nesting:
// ❌ Wrong - too deep.c--card__wrapper__content__inner__title { }
// ✅ Correct - flatter structure.c--card__title { }Next Step
Section titled “Next Step”Now that you understand SCSS structure and styling, let’s learn how to add interactivity with JavaScript.
→ Continue to JavaScript
Knowledge Check
Test your understanding of this section
Loading questions...