CSS Utility Belt

Purpose

There are so many choices when it comes to CSS libraries. Then inside of that library there are a ton of different ways to use it. Some of these libraries work well right out of the box, while others require reading about how to configure it to do what you need. The purpose of this library is to be as minimal as possible while still enabling complex UIs. This library won't get rid of all of your CSS, the goal is get rid of 90% of it and the remaining 10% would live at the component level.

What makes this different than other libraries?

To be honest, not a whole lot. In fact most other CSS libraries already have a lot of this functionality, and more. So why would anyone use this? Because sometimes a limited set of options is more powerful than an infinite one. Limited options can help focus a discussion and allow quick decisions to be made, while also preventing people from focusing on trivial details.

Let's use a real life example. I was once talking with a designer about the placement of some text. They wanted the text to have a margin of 34px. We didn't use that margin size anywhere else in the application. That could have triggered an in-depth conversation about why 34px was necessary. Instead I was able to say "We don't have a margin of 34px, but we have 32px. Will that work?" The designer said sure, and we moved on. Those 2px didn't matter at the end of the day. But from a code perspective it would have created another one off style.

You could say that this is an opinionated CSS library. I've taken all of CSS and said "you will probably only need this". Will it limit your creative freedom, yeah probably. Will it help you quickly create UIs without having to decide if a 23px padding or a 24px padding looks better? 100% yes.

Getting Started

How do you get started? That's simple, in your project just run npm install css-utility-belt. From there you should be able to just import the CSS file into your main CSS file and you are done. No compilation step, no configuring. For example, in an app.scss you would add @import 'css-utility-belt';

Configuration

Oh you want to configure it? Well the only things that are configurable are the colors. The colors are easy to change though. They are defined using CSS Custom Properties. The variable names are the colors. So if you want to change the global blue color for example, you just need to set :root { --blue: #2E64FE } and you are done. Due to how CSS cascades, you just need to define these colors after you import the utility belt and it should "just work". This also means that the colors will not work on browsers that do not support CSS custom properties.

Questions

This section is to answer questions about some divergences from common CSS library practices and implementation details

Why do you use the actual color names instead of the context that they should be used in? (i.e. text-red v.s. text-error)
Context classes make a ton of sense until suddenly they don't. For instance, let's say you are making a graph and one of the labels needs to be red. You could use the text-error class, but this isn't an error. So now you have code that incorrectly indicates that this is an error. The other reason is the ease for new developers to learn the classes. If you have just started on a new team. Will you know that to get orange text you need to use the text-tertiary class or is text-orange more obvious?
Why are the class names so verbose?
This is to improve readability and code reviews. While shortening the various words would save a couple of keystrokes, it also makes it slightly harder to read the code. Developers spend way more time reading code than they do actually writing it, so optimizing for ease of reading v.s. ease of writing seemed to make the most sense. It also allows someone who has no concept of what the class names do without having to look at the rendered page. I think an example is the best way to demonstrate this. Take a look at this code snippet
<section class="background-blue padding-2 flex-column">
  <div class="border-1 border-red rounded-corners text-red padding-4 margin-bottom-2">
    Box 1
  </div>
  <div class="border-1 border-green rounded-corners text-green padding-4">
    Box 2
  </div>
</section>
I bet you have pretty good idea of what this code looks like when it is rendered, and you have never used this library before. Compare this to:
<section class="bg-blue p-2 fx-column">
  <div class="b-1 b-red rounded-corners text-red p-4 mb-2">
    Box 1
  </div>
  <div class="b-1 b-green rounded-corners text-green p-4">
    Box 2
  </div>
</section>
You could probably guess what the second code snippet does, but it would be a guess. Having confidence that you know what the code does is important. Code that you think you understand, but actually don't is where bugs start to creep in.
Why does every class use !important?
This is to make sure that nothing else overrides the style. Since these classes typically translate to one or two CSS styles, overriding a class should never be necessary. If you don't want an element to have a specific style, remove the class instead. This also almost guarantees that the HTML describes exactly what will be rendered. (Technically inline styles could override the class styles but that would mean the styles are still present in the HTML)

Examples

Background Classes

background-black
background-blue
background-gray
background-green
background-orange
background-red
background-white

Border Classes

Border styles

border-1
border-top-1
border-right-1
border-bottom-1
border-left-1
rounded-corners

Border Colors

border-black
border-blue
border-gray
border-green
border-orange
border-red
border-white

Display Classes

display-block
display: block !important;
display-inline-block
display: inline-block !important;
display-none
display: none !important;

Flex Classes

flex-column
flex-row
justify-content-start
justify-content-center
justify-content-end
justify-content-space-between
align-items-start
align-items-center
align-items-end

Overflow Classes

overflow-auto
overflow-hidden

Size Classes

height-100
min-height-0
width-100
min-width-0
min-width: 0 !important;

Spacing Classes

margin-0
margin-1
margin-2
margin-3
margin-4
margin-5
margin-auto
margin-top-0
margin-top-1
margin-top-2
margin-top-3
margin-top-4
margin-top-5
margin-top-auto
margin-right-0
margin-right-1
margin-right-2
margin-right-3
margin-right-4
margin-right-5
margin-right-auto
margin-bottom-0
margin-bottom-1
margin-bottom-2
margin-bottom-3
margin-bottom-4
margin-bottom-5
margin-bottom-auto
margin-left-0
margin-left-1
margin-left-2
margin-left-3
margin-left-4
margin-left-5
margin-left-auto
margin-x-0
margin-x-1
margin-x-2
margin-x-3
margin-x-4
margin-x-5
margin-x-auto
margin-y-0
margin-y-1
margin-y-2
margin-y-3
margin-y-4
margin-y-5
margin-y-auto
padding-0
Text
padding-1
Text
padding-2
Text
padding-3
Text
padding-4
Text
padding-5
Text
padding-top-0
Text
padding-top-1
Text
padding-top-2
Text
padding-top-3
Text
padding-top-4
Text
padding-top-5
Text
padding-right-0
Text
padding-right-1
Text
padding-right-2
Text
padding-right-3
Text
padding-right-4
Text
padding-right-5
Text
padding-bottom-0
Text
padding-bottom-1
Text
padding-bottom-2
Text
padding-bottom-3
Text
padding-bottom-4
Text
padding-bottom-5
Text
padding-left-0
Text
padding-left-1
Text
padding-left-2
Text
padding-left-3
Text
padding-left-4
Text
padding-left-5
Text
padding-x-0
Text
padding-x-1
Text
padding-x-2
Text
padding-x-3
Text
padding-x-4
Text
padding-x-5
Text
padding-y-0
Text
padding-y-1
Text
padding-y-2
Text
padding-y-3
Text
padding-y-4
Text
padding-y-5
Text

Text Classes

text-align-center
Text
text-bold
Text
text-italic
Text
text-black
Text
text-blue
Text
text-gray
Text
text-green
Text
text-orange
Text
text-red
Text
text-white
Text