Accuraty / AccuTheme-2021

Older version superseded by AccuTheme-Bs4 (Feb 2024)
https://github.com/Accuraty/AccuTheme-Bs4
2 stars 1 forks source link

Re-examine SCSS file structure in `theme` directory #3

Open chrismlusk opened 3 years ago

chrismlusk commented 3 years ago

I'd like to explore options for organizing the SCSS files within the theme directory to see if we can make it better. First, an overview of what we have and why.

Background

AccuTheme uses a "customized-and-integrated" version of Bootstrap. What does that mean? Instead of loading all of Bootstrap and then adding custom styles, we import each Bootstrap file into our Skin so we can remove any Bootstrap stuff we don't use and so we can customize any Bootstrap stuff as needed. When we compile the styles at the end, whatever we use from Bootstrap gets bundled into Skin.css.

For easy customization, we put our own variable file before the Bootstrap files:

// AccuTheme config
@import "theme/variables";

// Bootstrap source
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/buttons";
// etc ...

Our theme's _variables.scss file is essentially a copy of Bootstrap's variables. We can update a variable value, and because our file is imported first, our custom value is used. Take this demo (which is fake, but the order of the code reflects what happens):

// AccuTheme variable file that we update
$btn-bg-color: blue;
$btn-font-weight: bold;

// Bootstrap variable file
$btn-bg-color: green !default; // the `!default` flag is how to set a fallback value
$btn-font-weight: light !default;

// Bootstrap button file
.btn {
  // we make no changes here, but it inherits our updated variables
  background: $btn-bg-color;
  font-weight: $btn-font-weight;
}

The result is a button with a blue background and bold text — and we added zero lines of code to the compiled output.

Our custom _variables.scss file is a great way to make simple changes to Bootstrap, but it doesn't cover all scenarios. What if the button needs letter spacing? There's no $btn-letter-spacing variable in Bootstrap, and we do not modify the source code in the node_modules folder. The answer is the other SCSS files within our theme directory that are similar to the Bootstrap source, in this case, components/_buttons.scss.

This file is imported into our Skin after the Bootstrap button, so we can add new style rules or override existing ones that don't have variables.

// Bootstrap button file
.btn {
  display: inline-block; // no variable provided
}

// AccuTheme button file that we update
.btn {
  display: inline-flex; // overrides Bootstrap's value
  letter-spacing: 1px; // new rule for this CSS class
}

This results in two new lines of code, but thanks to CSS's cascade (because we import the AccuTheme file after the Bootstrap file), we get our desired style for all buttons with the .btn class: an inline-flex display with 1px of letter spacing. And with the two examples combined, we changed four button styles but only added two new lines of generated code.

These two methods of customizing Bootstrap — with variables and with additions/overrides — means we end up with a Skin.scss file something like this:

// AccuTheme config
@import "theme/variables";

// Bootstrap source
@import "node_modules/bootstrap/scss/buttons";

// AccuTheme components
@import "theme/components/buttons";

That's why we have so many SCSS files in this project; every Bootstrap element has its own file in our theme directory ready to go. For convenience, I've named it the same thing as the file found in Bootstrap's source.

But rather than put all of these files at the root of the theme directory, I organized them into subfolders in attempt to categorize what the styles "do" in the design system: layout, components, base, etc. This division can be fuzzy at times, but overall, I thought it was helpful.

Problems

This can be overwhelming! And most Accuraty project don't touch the majority of these files. (When was the last time we used _badge.scss or _progress.scss? Maybe never.) So when you look through the theme/components folder, you see dozens of files — most untouched.

Bootstrap's source code (see GitHub) does not separate the SCSS into subfolders, so that difference can be confusing.

Our theme files include a mix of "customized Bootstrap styles" and "styles unique to AccuTheme." For example: layout/_footer.scss or components/_admin-menu.scss. This can also be confusing.

Solution

Split customized Bootstrap files into their own subdirectory.

theme/
├── bootstrap/
│   ├── _buttons.scss
│   ├── _containers.scss
│   ├── _forms.scss
│   └── etc.
│
├── base/
│   └── _dnn-reset.scss
│
├── components/
│   └── _admin-menu.scss
│
├── layout/
│   └── _footer.scss
│
└── _variables.scss

This creates a clear distinction between what's for Bootstrap and what's unique. You still keep the theme _variables.scss at the root and use those values everywhere for consistency. And the only change in Skin.scss is the import path:

// AccuTheme config
@import "theme/variables";

// Bootstrap's layouts and components
@import "node_modules/bootstrap/scss/buttons";

// AccuTheme Bootstrap overrides
@import "theme/bootstrap/buttons";

// AccuTheme custom elements
@import "theme/layout/footer";

Thoughts?

jeremy-farrance commented 3 years ago

I read all this and it (finally) makes sense to me. I never knew that all the variables (node_modules/bootstrap/scss/_variables.scss) being pulled in from Bootstrap had "!default" on them OR what it did. So I think this restructure helps it make sense. You should probably also consider putting a README_Bootstrap-usage-structure.md file with the contents of this explanation (above) in the theme/ folder.

chrismlusk commented 3 years ago

Will do. After writing the issue, I figured we'd want to keep a version of it in docs or wiki. Something to help when you are new to AccuTheme or need a refresher!