@rtm/human-css-classes

0.6.4 • Public • Published

Human CSS Classes

Human CSS classes is a system of micro-attributes which allow HTML to be styled much more semantically and readably, while greatly reducing the need for individual CSS rules. The great majority of common styling needs can be met by a suitable combination of micro-attributes. In the micro-class philosophy, elements are styled within HTML by specifying one or more micro-classes, or in this case, micro-attributes. With human CSS classes, many pages may need no specific CSS rules whatsoever.

For instance, consider:

<span large dark red bold text>
<div thin light green top border>
<div one third width>

Human CSS classes provide an easy interface to using flexbox, removing the need for the baroque grid systems some frameworks and libraries try to provide. For instance, the classic float: right is written as

<div flex justify>
  <div>I'm on the left</div>
  <div>I'm on the right</div>
</div>

Background and Motivation

Our current CSS systems are a steaming pile of crap. We have thousands of lines of CSS. Half of these lines of CSS are not even used, because no one can remember what they do and are afraid to touch them. Most of the rest is redundant, verbose, and duplicative.

Because CSS systems are most often created by "UI designers", rather than engineers, basic computing principles of orthogonality, factoring, and composition are ignored.

We have developed an addiction to CSS preprocessors which merely provide some basic syntactic sugar, and, more perniciously, promote bad design practices. Huge sets of rules with complex selectors bog down the browser.

Each new page we write requires dozens or hundreds of new lines of CSS. Any UI change requires parallel changes to both HTML and CSS. We use CSS in a way which results in inconsistent UIs. We rewrite CSS over and over, since often there is no way to re-use what we have done. There is no reasonable way to understand the CSS, or convince ourselves that it is correct, or test it.

In a futile attempt to escape this maze, we bring in monstrously large, over-engineered frameworks such as Bootstrap, which add a massive surface area of new classes to learn and deal with. Just as jQuery attempts to solve JavaScript problems which no longer need solving, Bootstrap attempts to solve styling problems which no longer need solving, in particular its cumbersome and confusing grid system. In addition to added complexity for the programmer, these massive frameworks slow down build times, page loading times, and rendering times. They also make undue use of obsolete CSS features such as floats, while failing to support modern CSS features such as flexbox.

As we proliferate these obese classes, we soon run into namespacing problems. Names conflict with each other, and we end up needing weird namespace solutions which call for classes with names like Book__chapter--title. Then we start relying on preprocessors to handle these over-named classes, which "help" us by allowing us to write weird-looking, brittle rules such as

.Book {
  &__chapter {
    &--title {
      text-align: center;
      }
    }
 }

Human CSS classes are is designed to put an end to this madness.

Caveat

Human CSS classes use CSS custom properties, also known as CSS variables, in its implementation. This excludes IE11 from consideration. Note that development of custom properties is underway for Edge.

Design Principles, Concepts and Features

Micro-classes

Human CSS classes is a collection of micro-attributes: HTML attributes with very particular meaning. These attributes are assigned to HTML elements, which in this approach may have two or five or even ten attributes. We are moving the styling logic back into the HTML! The styling in the HTML becomes semnatic and readable. Instead of having a class "book-list-entry" which contains 20 properties over in some distant CSS file, we add three or four attributes to HTML which clearly identify the styling behavior of the entry. In the best case, which is readily realizable in practice, no element-specific class is necessary at all.

Combining micro-attributes

Human CSS classes use a relatively limited number of general-purpose micro-attributes. So green means green for text, or borders, or backgrounds. But what if I want to specify both text color and border color on an element? How do I know which color is which? Other micro-class frameworks solve this by a proliferation of classes such as green-border, and green-text. We take a different approach, which is to place the attributes on individual, nested HTML elements:

<div one em margin>
  <div thick dark blue border>
    <div x-light pink background>
<div five percent padding>
        <div large bold white text>
          Bob
        </div>
      </div>
    </div>
  </div>
</div>

Although this does result in more deeply nested HTML, it also has major advantages. Each element has a single, well-defined purpose, and as mentioned above we need only generic attributes such as blue which work everywhere.

Colors

Human CSS classes uses a companion library for human CSS colors. This HSL-based library allows you to easily think of colors in terms of their hue, lightness, and saturation, using micro-attributes for hues (red), as well as saturations such as ``brightand ligthnesses such asdark`.

See that library for more details.

Units and measures

Many micro-class frameworks suffer from a proliferation of classes such as width-75. This limits the user to only the classes the designer provides. In contrast, human CSS classes provide separate micro-attributes for numbers, lengths, and units, via a companion library for human CSS numbers so we can write

<div 50% width>
<div two rem border>
<div three columns>

All standard CSS units are provided as micro-attributes. including lengths such as px, em, and rem. Common numbers and percentages may also be used as micro-attributes, in addition to built-in attributes such as 1/2.

See that library for more details.

Text

The text micro-attribute grouping provides control over text color, fonts, alignment, and so on. It is introduced by the micro-attribute text. text is combined with micro-attributes for color, font size using standard synonyms such as large (or any length), font weight using standard synonyms such as bold, and others.

Other text features include italic, underline, upper, lower, capitalize, small-caps, and so on.

Borders, margins, outlines, and padding

Borders, margins, outlines, and padding are introduced by the border, margin, outline, and padding micro-attributes. The attributes top, left, bottom, and right may be given to indicate which side or sides are to be affected. A number or length, or keyword such as thick or thin, specifies the size of the border, margin, outline, or padding. For borders and outlines, the standard types such as solid and dotted are available as micro-attributes. Colors may also be specified for borders and padding.

Background

The background micro-atteribute provides a background of the specified color.

<div beige background>

Sizes

Box sizes are indicated with micro-attributes such as width and height, which are given together with other micro-attributes indicating the size, as a length, percentage, or keyword such as half.

<div half width>
<div 40% height>
<div max-height 50 vh>

Spacing

People commonly use top margins and bottom margins and top padding and bottom padding and special spacing elements to space out their elements. Human CSS classes provide a simple mechanisms for controlling spacing. The spaced micro-attribute adds space between child elements. Variants of these (indicated by modifier micro-attributes) provide more or less spacing.

Example of spaced children:

<div spaced>
  <div></div>
  <div></div>
</div>

flexbox

Human CSS classes expect most layout to be done using flexbox, and provides a solid set of micro-attributes to control them. The micro-attributes available include ones to control direction, wrapping, and alignment. You'll no longer need to struggle with trying to remember the names or meanings or values of properties like align-items.

Examples of flexbox:

<div flex wrap>
  <div basis one-third>
  <div basis one-third>
  <div basis one-third>

<div flex vertical justify align-center>

Display and visibility

<div show>
<div inline>
<div hide>
<div visible>
<div invisible>

Opacity

<div opaque>
<div semi-opaque>
<div transparent>
<div opacity 0.8>

Z-index

<div back>
<div front>
<div backmost>
<div frontmost>

Position

<div absolute>
<div relative>
<div fixed>

Transitions

<div transition fast linear delay>

Things not supported

The following CSS features require more complex properties which are not well-suited to the micro-class approach, and therefore are not (currently) supported:

  1. Animations or more complex transitions
  2. Box shadows and text shadows
  3. Properties involving URLs, such as background-image
  4. Pseudo-classes
  5. Pseudo-elements

Installation

npm install --save-dev @rtm/human-css-classes

Then, in some file that the suitCSS compilation will process:

@import "@rtm/human-css-classes";

To use the pre-built version, use dist/index.css or dist/index.min.css. Notice, however, that this will not handle any variables you define yourself.

Note that postCSS always uses the most recently defined variable value. Therefore, if you include your own variable definitions after importing human CSS classes, they will not take effect.

Micro-attribute reference

This table omits the micro-attributes from the human CSS numbers and human CSS colors libraries.

Name Module Description
absolute position Absolute positioniong.
align-bottom flex Align flex items to bottom.
align-center flex Align flex items to left.
align-center ruby Align ruby to center.
align-left flex Align flex items to left.
align-middle flex Align flex items to middle.
align-right flex Align flex items to right.
align-start ruby Align ruby to start.
align-top flex Align flex items to top.
alpha list Alpha list markers.
backmost z-index Set element to very back.
background background Set background color.
behind z-index Set element behind.
bold text Bold font.
bolder text Increase boldness.
border border Set border.
bottom padding Pad on bottom.
bottom margin Add margin on bottom.
capitalize text-transform Capitalized text.
circle list Circle list marker.
column(s) columns Number of columns.
condensed letter-spacing Condense space between letters.
contain background Clip background image
cover background Letterbox background image
decimal list Decimal list markers.
delay transition Delay transition.
dashed border Dashed border.
delay-less transition Shorter delay transition.
delay-more transition Longer delay transition.
demi-bold font-weight Weight between normal and bold.
disc list Disc list marker.
dotted border Dotted border.
double-spaced line-height Double line spacing.
ease transition Transition timing "ease".
ease-in transition Transition timing "ease-in"
ease-out transition Transition timing "ease-out"
ease-in-out transition Transition timing "ease-in-out"
emphasis font-style Italics.
expanded letter-spacing Expand space between letters.
expanded-more letter-spacing More space between letters.
extra-bold font-weight Font weight 800.
extra-light font-weight Extra-light font.
fast transition Fast transition.
faster transition Very fast transition.
first flex Place item first in flex order.
fixed position Fixed positioniong.
flex flex Set up flex container.
front z-index Set element in front.
frontmost z-index Set element to very front.
groove border Groove-style border.
grow flex Allow this item to grow.
hair padding, margin Padding or margin of 1/6 em.
hairline font-weight Lightest font.
heavy font-weight Heaviest font.
height dimensions Set element height.
hide, hidden display Hide element.
honor-newline white-space Treat newlines as newlines.
horizontal flex Row-oriented flex container.
horizontal overflow Set horizontal overflow.
in-front z-index Set element in front.
indent indent Indent text.
indent-more indent Indent text more.
inline flex Set up inline flex container.
inline display Inline display.
inline-block display Inline block display.
inset border Inset-style border.
inside list Inside list markers.
inter-character ruby Ruby between characters.
invisible visibility Make invisible.
italic font-style Italics.
justify flex Justify flexbox items.
justify ruby Justify ruby.
justify-gap flex Justify flexbox items with gap.
justify-gap ruby Justify ruby with gap.
justify-h flex Justify flexbox items horizontally.
justify-h-gap flex Justify flexbox items horizontally with gap.
justify-v flex Justify flexbox items vertically.
justify-v-gap flex Justify flexbox items vertically with gap.
justify flex Justify flexbox items.
large size large font size
larger size larger font-size
last flex Place item last in flex order.
left padding, margin Padding or margin on left.
left ruby Ruby to left.
light text Light font (300).
lighter text Decrease boldness.
linear transition Transition timing "linear"
list list Define list.
loose space Looser inter-item spacing.
lower text-transform Lower-cased text.
lower list Lower-cased list markers.
margin margin Add margin to element.
max-height dimensions Set maximum element height.
max-width dimensions Set maximum element width.
medium size Medium font size.
medium border Medium border width.
medium-weight font-weight Medium font weight.
min-height dimensions Set minimum element height.
min-width dimensions Set minimum element width.
monospace font Monospaced font.
norepeat background Do not repeat background.
none list No list markers.
nowrap white-space Do not wrap.
opaque opacity Full opacity.
outset border Outset-style border.
outside list Outside list markers.
over ruby Ruby on top.
overflow overflow Set overflow behavior.
padding padding Pad an element.
pointer cursor Pointing cursor.
preserve-whitespace white-space Do not collapse whitespace.
relative position Relative positioniong.
repeat-x background Repeat background in x direction.
repeat-y background Repeat background in y direction.
resize resize Allow resizing of element.
resize-x resize Allow resizing of element horizontally.
resize-y resize Allow resizing of element vertically.
reverse flex Reverse flex order.
ridge border Ridge-style border.
right padding, margin Padding or margin on right.
right ruby Ruby to right.
roman list Roman list markers.
rounded border Rounded border.
rounded-more border More rounded border.
self-baseline flex Align flex child to baseline.
self-bottom flex Align flex child to bottom.
self-center flex Align flex child to center.
self-left flex Align flex child to left.
self-middle flex Align flex child to middle.
self-right flex Align flex child to right.
self-stretch flex Stretch flex child.
self-top flex Align flex child to top.
semi-bold font-weight Weight between normal and bold.
semi-opaque opacity 50% opacity.
show display Display as block.
single spacing Single spacing.
slow transition Slow transition.
slower transition Very slow transition.
small size Small font size.
smaller size Smaller font size
small-caps font-variant Small caps font variant.
solid border Solid border.
space-and-a-half line-height 1.5 line spacing.
square list Square list marker.
step-start transition Transition timing "step-start"
step-end transition Transition timing "step-end"
strong font-weight Bold text.
tight space Tighter inter-item spacing.
thick border Thick border.
thin border Thin border.
top padding, margin Padding or margin on top.
transparent opacity Zero opacity.
ultra-bold font-weight Bolder than bold.
ultra-light font-weight Extra-light font.
under ruby Ruby on bottom.
underline font-decoration Underline text.
upper text-transform Uppercased text.
upper list Uppercased list marker.
vertical flex Column-oriented flex container.
vertical overflow Set vertical
visible visibility Make visible.
wrap flex Wrap flexbox items.
x-bold font-weight Font weight 800.
x-grow flex Allow this item to grow more.
x-light font-weight Extra-light font.
x-loose space Very loose inter-item spacing.
x-small size Very small font size.
x-large size Very large font size.
x-strong font-weight Very bold text.
xx-bold font-weight Font weight 900.
xx-large size Very very large font size.
xx-small size Very very small font-size.
width dimensions Set element width.

Other notes

Defininig your own classes

What if I want to include the padding functionality into my own class definition? We would caution against this approach, which goes against the grain of the micro-class philosophy. However, it does have the "advantage" of allowing me to simply say <div class="my-class">. You can do this using the postcss-inherit plug-in, which provides an @inherit pseudo-property, as follows:

.myclass {
  color: red;
  @inherit: .padding .2 .em;
}

If you really want to go this route, you'll have to make sure to add postcss-inherit to your package, and arrange for it to be added to the list of plug-ins used in the preprocessing step.

Performance

CSS is rarely the major bottleneck in application performance. Of course there may be exceptions involving huge systems, or poorly written CSS rules, or use of CSS properites with known performance implications.

Human CSS classes offer improved performance because the dozens or hundreds of CSS files often seen in poorly-engineered applications are much smaller (or not needed at all). This reduces both download and processing time.

Floats

We do not use or support floats, and neither should you.

!important

We neither need nor use !important, and we recommend you do not either.

Inline styles

Some element-specific styling can obviously not be handled with micro-classes, background-image for example. If a page has only one or two such cases, we suggest inlining the rule with the style attribute. We are not religious zealots, and this can be a better approach than creating a separate CSS file and defining an additional class merely in order to target the element.

Readme

Keywords

Package Sidebar

Install

npm i @rtm/human-css-classes

Weekly Downloads

4

Version

0.6.4

License

MIT

Last publish

Collaborators

  • rtm