DEV Community

loading...
Cover image for OhSnap! Sass Folder Structure For React

OhSnap! Sass Folder Structure For React

Gedalya Krycer
Front-End Developer and Designer with a focus on React.
Updated on ・4 min read

The "OhSnap!" series explores bite-sized tips that you can apply today.


Intro

Today we are going to walk through the folder structure of a React project that I recently completed.

I am using the node-sass npm package, and staying always from any CSS frameworks like Bulma or Bootstrap.

After some research and trial/error, I found that the below system worked well for me. Hopefully it helps you as well.


The Folder Structure

The following has been simplified for the sake of clarity, but the essential structure is still the same. You can view the actual Github repository here.

/src
• ———— /components
•      |———— /NominationContainer
•            |———— NominationContainer.js
•            |———— nominationContainer.scss  <—— (section 2)
•
•
• ———— /sassStyles  <—— (section 1)
•      |————  _animations.scss
•      |————  _functions.scss
•      |————  _global.scss
•      |————  _mixins.scss
•      |————  _typography.scss
•      |————  _variables.scss
Enter fullscreen mode Exit fullscreen mode

Section 1

This folder sits outside of the components and holds all partials and styles that can effect multiple components. As you will see in Section 2, individual components will import from these partials as needed.

• ———— /sassStyles  <—— (section 1)
•      |————  _animations.scss
•      |————  _functions.scss
•      |————  _global.scss
•      |————  _mixins.scss
•      |————  _typography.scss
•      |————  _variables.scss
Enter fullscreen mode Exit fullscreen mode

_animations.scss

This partial stores the actual @keyframe CSS animations. It helps to drastically reduce the size of component stylesheets. In our example this file stores 22 animations, which is almost 800 lines of code! That is a lot of space saved in our component files, that now just need to reference this file.

_functions.scss

This partial contains any SASS functions which process and return a value. I didn't use them in this project, but a great example of them can be found in this StackOverflow thread.

_global.scss

This partial contains styling that overrides global elements, such as the #root or body elements. In our example it is also importing the _variable.scss file to reference a color.

_mixins.scss

This partial can hold any block of code that is repeatable. In our example I am using mixins to determine breakpoint sizes. They are also using variables, so if my overall lg size changes, it will update everywhere.

_typography.scss

This partial holds major typography element styles such as h1-h6, p, and global classes or ids. As you can see in our example, I like to stay away from applying super-specific properties here, like color. This way I have the flexibility of changing it in different parts of the app, without worrying about specificity.

_variables.scss

This partial contains repeatable property values, such as brand colors and sizes. By storing #002e25 in the variable $primaryDark2Color I can apply it to properties like color and border while preserving the option to change the color globally later on.

Section 2

This is an example of an individual component with a .js file and its associated .scss file for styling.

/src
• ———— /components
•      |———— /NominationContainer
•            |———— NominationContainer.js
•            |———— nominationContainer.scss  <—— (section 2)
Enter fullscreen mode Exit fullscreen mode

nominationContainer.scss

This is an example of an individual component's .scss file and I have included its code below. Note how it imports the animations, variables, and mixin partials.

Because of this, animations just require 2 lines of code to establish the settings. Colors are based on variables and media queries are pulled from mixins.

In the future, I can just change these in their original partial files and they will update here.

@import '../../../sassStyles/variables';
@import '../../../sassStyles/animations';
@import '../../../sassStyles/mixins';

.nom-container {
    background: $primaryDark1Color;
    height: 100%;
    padding: 26px 20px;
    margin-top: 15px;
    opacity: 0;

    -webkit-animation: fade-up 1s cubic-bezier(0.165, 0.840, 0.440, 1.000) 1.4s both;
        animation: fade-up 1s cubic-bezier(0.165, 0.840, 0.440, 1.000) 1.4s both;


    @include customMinBreakPoint(1024) {
        margin-top: 0;
        padding: 26px 0 50px 0;
        -webkit-animation: fade-left 1s cubic-bezier(0.165, 0.840, 0.440, 1.000)  both;
        animation: fade-left 1s cubic-bezier(0.165, 0.840, 0.440, 1.000)  both;
    }

    &__counter-wrapper {
        display: flex;
        justify-content: center;  
        margin-bottom: 30px;
        margin-top: 0;
        opacity: 0;

        -webkit-animation: fade-up 0.9s cubic-bezier(0.165, 0.840, 0.440, 1.000) 1.6s both;
        animation: fade-up 0.9s cubic-bezier(0.165, 0.840, 0.440, 1.000) 1.6s both;

        @include customMinBreakPoint(1024) {
            justify-content: flex-end; 
            margin-right: 50px;
            margin-bottom: 75px;

            -webkit-animation: fade-up 0.9s cubic-bezier(0.165, 0.840, 0.440, 1.000) 0.25s both;
            animation: fade-up 0.9s cubic-bezier(0.165, 0.840, 0.440, 1.000) 0.25s both;
        }

        @include customMinBreakPoint(1400) {
            margin-right: 12%;
        }

        @include customMinBreakPoint(1500) {
            margin-right: 15%;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Thumbnail designed with Figma

Discussion (1)

Collapse
abid413119 profile image
Abid Al - Amin

if we import variables/mixins in multiple files it may duplicate the same CSS in multiple files. Is it an optimized solution?