Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS / SASS architecture using ITCSS or similar approach #242

Open
samikeijonen opened this issue Jul 13, 2018 · 6 comments
Open

CSS / SASS architecture using ITCSS or similar approach #242

samikeijonen opened this issue Jul 13, 2018 · 6 comments

Comments

@samikeijonen
Copy link

Best practises have section for file structure, including CSS / SASS.

I'd still like to open new issue for CSS / SASS architecture which tries to take deeper dive why it matters a lot.

I've personally switched using ITCSS which aims to be scalable and maintainable architecture. I have found that very true.

As a front-end developer you have probably faced the issues with CSS:

  • Hmmm where should I add this new CSS.
  • Hmmm why the front-end is not changing even I made the change in CSS. Ok, let's add more nesting or even !important.
  • Hmmm I'll admit that my CSS structure is a huge mess. Sorry.

ITCSS or any other architecture tries to solve these issues.

What is ITCSS

ITCSS stands for Inverted Triangle CSS and it helps you to organize your project CSS files in such way that you can better deal with (not always easy-to-deal with) CSS specifics like global namespace, cascade and selectors specificity.

In practise the idea is to separate CSS codebase to several sections (layers). Every sections add more spesifity to CSS in the right order.

Here is one example how it might look like. I have added comments what sections means.

/**
 * Main stylesheet for the theme.
 *
 * Theme styles follow http://cssguidelin.es/ and are organized according to
 * Inverted Triangle CSS (ITCSS) principles put forth by Harry Roberts. In
 * short, each layer of CSS gets more specific as you move down this page.
 */

/*--------------------------------------------------------------
# Settings - Global variables like fonts and colors.
--------------------------------------------------------------*/
@import "settings/core";
@import "settings/fonts";
@import "settings/colors";


/*--------------------------------------------------------------
# Tools - Default mixins and functions.
--------------------------------------------------------------*/
@import "tools/mixins";
@import "tools/font-size";


/*--------------------------------------------------------------
# Generic - Ground-zero styles (resets, box-sizing, etc.).
--------------------------------------------------------------*/
@import "generic/normalize";
@import "generic/box-sizing";


/*--------------------------------------------------------------
# Elements - Unclassed HTML elements (type selectors).
--------------------------------------------------------------*/
@import "elements/page";
@import "elements/blockquote";
@import "elements/buttons";
@import "elements/forms";
@import "elements/headings";
@import "elements/hr";
@import "elements/links";
@import "elements/lists";
@import "elements/media";
@import "elements/misc";
@import "elements/pre-code";
@import "elements/tables";


/*--------------------------------------------------------------
# Objects - Undecorated design patterns.
--------------------------------------------------------------*/
@import "objects/animations";
@import "objects/icons";
@import "objects/layouts";
@import "objects/list-reset";
@import "objects/wrappers";


/*--------------------------------------------------------------
# Blocks - Editor related styles.
--------------------------------------------------------------*/
@import "blocks/blocks";
@import "blocks/color-palette";


/*--------------------------------------------------------------
# Components - specific UI components.
--------------------------------------------------------------*/
@import "components/archives";
@import "components/comments";
@import "components/footer";
@import "components/front-page";
@import "components/galleries";
@import "components/header";
@import "components/media";
@import "components/navigation";
@import "components/pagination";
@import "components/posts-and-pages";
@import "components/search";
@import "components/widgets";


/*--------------------------------------------------------------
# Utilities - Helpers and overrides.
--------------------------------------------------------------*/
@import "utilities/accessibility";
@import "utilities/alignments";
@import "utilities/font-sizes";
@import "utilities/helpers";

The first three layers are pretty straightforward and very common steps.

  • Settings: Add or modify variables, mostly done in the beginning of the project.
  • Tools: Most projects have mixins and functions. Mostly done in the beginning of the project but can be updated any time during the project.
  • Generic: Most projects use some kind of reset styles and box-sizing. Mostly done in the beginning of the project and not very often updated.

The next layers are more interesting.

Elements - Unclassed HTML elements (type selectors).

Elements means bare HTML elements like a or blockquote. For example:

blockquote {
	border-left: 0.25rem solid;
	font-style: italic;
	margin: 0 0 $global-spacing-unit-4;
	padding-left: $global-spacing-unit-3;

	p {
		@include font-size(1.25rem);

		&:last-of-type {
			margin-bottom: 0;
		}
	}
}

HTML elements have lower specifity than classes and that's the reason why they are kept in their own layer at the top.

However I have done one exception where classes might be good idea in this layer. If the HTML element hold one or two rules it can have utility class in the same place. For example:

h1,
.h1 {
	font-size: var(--font-size-h1);
	line-height: var(--line-height-heading);
}

Objects - Undecorated design patterns

Object can be renamed as Layouts also. It can hold base Grid styles or wrapper max width styles etc. I sometimes struggle what to put here.

Blocks - Editor related styles

This layer is optional but demonstrates how we can add new layers anywhere we like and still maintain the sanity. In this example I have put all the Gutenberg Block styles in to it's own layer. These styles are outputted in the front-end and in the editor so everything Block based can be updated in the same place.

Components - specific UI components.

Most of the work happens in the components layer. These can overwrite any styles declared before without nesting at all. Not even one level of nesting which is a good thing of BEM naming convension.

Utilities - Helpers and overrides.

Utilities or helper classes should always come last so that they can overwrite any styles declared before. That's the purpose of helper classes :) For example:

.uppercase {
	text-transform: uppercase;
}

Conclusion

This is just one approach but at least for me helps organize styles without always fighting with CSS spesifity.

The main CSS or SASS file is also a documentation on it's own and helps developers to add styles in the right layer.

Vendor or Plugins folder would be one very common layer to add. In most cases this should be before Components layer.

Yet alone ITCSS is not a silver bullet. Projects needs guidelines how to write CSS / SASS and in many cases naming convention like BEM helps organizing component level styles. I can add own issues for those if needed.

@JodiWarren
Copy link
Contributor

I thoroughly agree with this article. If a broad consensus is reached for it, we should ensure that https://github.com/10up/theme-scaffold is updated in this style to make it easy for people to follow the correct behaviour.

I don't specifically follow ITCSS, though reading this I probably should. The things that I keep in mind with SCSS/CSS organisation:

  • Be proactive about creating new module files for any discrete module.
  • Put effort into placing new selectors/styles into their correct file.
  • Don't be afraid to create new sections which aren't currently that populated. If it makes it easier for someone to find the specific class they're looking for in the future, it's the right choice.
  • Understand CSS specificity, and where possible, order your imports to follow it.

@tlovett1
Copy link
Member

tlovett1 commented Aug 7, 2018

This makes a lot of sense to me. Curious to hear @timwright12's opinion as well as others.

@timwright12
Copy link
Contributor

This falls under the "massive can of words" category. I actually use a general version of this methodology. We've approached the topic many times on the team and there is no consensus beyond agreement on the basic directory structure we now have in the scaffolding - and it took quite a long time to agree on that.

If the directory structure is clear and consistent, that's what's most important. We don't do micro-mangey things on the FE team unless there is something that is negatively affect projects, workflows, or onboarding.

@joesnellpdx
Copy link
Collaborator

I think adding something like this into best practices would be a good idea. Best practices often are not 'rules' but pattern suggestions to follow. I think having an explanation of structure like this would be helpful - especially for new hires.

Well done @samikeijonen !

@timwright12
Copy link
Contributor

I agree, if we can pull out some of the really specific items and tailor it more to best practice recommendations, it would be a good fit in the docs

@samikeijonen
Copy link
Author

agreement on the basic directory structure we now have in the scaffolding

It's not that much about directory structure itself, or at least how to name them and what files to put inside them.

Instead it emphasise CSS architecture, structure, and which order CSS would be outputted. In other words there would be logical reason for everything.

I'm sure current approach in theme scaffold is already doing this but as a new dev here, I just didn't picked that up by reading the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants