0.6.4 • Published 6 years ago

@rtm/human-css-classes v0.6.4

Weekly downloads
-
License
MIT
Repository
github
Last release
6 years ago

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.

NameModuleDescription
absolutepositionAbsolute positioniong.
align-bottomflexAlign flex items to bottom.
align-centerflexAlign flex items to left.
align-centerrubyAlign ruby to center.
align-leftflexAlign flex items to left.
align-middleflexAlign flex items to middle.
align-rightflexAlign flex items to right.
align-startrubyAlign ruby to start.
align-topflexAlign flex items to top.
alphalistAlpha list markers.
backmostz-indexSet element to very back.
backgroundbackgroundSet background color.
behindz-indexSet element behind.
boldtextBold font.
boldertextIncrease boldness.
borderborderSet border.
bottompaddingPad on bottom.
bottommarginAdd margin on bottom.
capitalizetext-transformCapitalized text.
circlelistCircle list marker.
column(s)columnsNumber of columns.
condensedletter-spacingCondense space between letters.
containbackgroundClip background image
coverbackgroundLetterbox background image
decimallistDecimal list markers.
delaytransitionDelay transition.
dashedborderDashed border.
delay-lesstransitionShorter delay transition.
delay-moretransitionLonger delay transition.
demi-boldfont-weightWeight between normal and bold.
disclistDisc list marker.
dottedborderDotted border.
double-spacedline-heightDouble line spacing.
easetransitionTransition timing "ease".
ease-intransitionTransition timing "ease-in"
ease-outtransitionTransition timing "ease-out"
ease-in-outtransitionTransition timing "ease-in-out"
emphasisfont-styleItalics.
expandedletter-spacingExpand space between letters.
expanded-moreletter-spacingMore space between letters.
extra-boldfont-weightFont weight 800.
extra-lightfont-weightExtra-light font.
fasttransitionFast transition.
fastertransitionVery fast transition.
firstflexPlace item first in flex order.
fixedpositionFixed positioniong.
flexflexSet up flex container.
frontz-indexSet element in front.
frontmostz-indexSet element to very front.
grooveborderGroove-style border.
growflexAllow this item to grow.
hairpadding, marginPadding or margin of 1/6 em.
hairlinefont-weightLightest font.
heavyfont-weightHeaviest font.
heightdimensionsSet element height.
hide, hiddendisplayHide element.
honor-newlinewhite-spaceTreat newlines as newlines.
horizontalflexRow-oriented flex container.
horizontaloverflowSet horizontal overflow.
in-frontz-indexSet element in front.
indentindentIndent text.
indent-moreindentIndent text more.
inlineflexSet up inline flex container.
inlinedisplayInline display.
inline-blockdisplayInline block display.
insetborderInset-style border.
insidelistInside list markers.
inter-characterrubyRuby between characters.
invisiblevisibilityMake invisible.
italicfont-styleItalics.
justifyflexJustify flexbox items.
justifyrubyJustify ruby.
justify-gapflexJustify flexbox items with gap.
justify-gaprubyJustify ruby with gap.
justify-hflexJustify flexbox items horizontally.
justify-h-gapflexJustify flexbox items horizontally with gap.
justify-vflexJustify flexbox items vertically.
justify-v-gapflexJustify flexbox items vertically with gap.
justifyflexJustify flexbox items.
largesizelarge font size
largersizelarger font-size
lastflexPlace item last in flex order.
leftpadding, marginPadding or margin on left.
leftrubyRuby to left.
lighttextLight font (300).
lightertextDecrease boldness.
lineartransitionTransition timing "linear"
listlistDefine list.
loosespaceLooser inter-item spacing.
lowertext-transformLower-cased text.
lowerlistLower-cased list markers.
marginmarginAdd margin to element.
max-heightdimensionsSet maximum element height.
max-widthdimensionsSet maximum element width.
mediumsizeMedium font size.
mediumborderMedium border width.
medium-weightfont-weightMedium font weight.
min-heightdimensionsSet minimum element height.
min-widthdimensionsSet minimum element width.
monospacefontMonospaced font.
norepeatbackgroundDo not repeat background.
nonelistNo list markers.
nowrapwhite-spaceDo not wrap.
opaqueopacityFull opacity.
outsetborderOutset-style border.
outsidelistOutside list markers.
overrubyRuby on top.
overflowoverflowSet overflow behavior.
paddingpaddingPad an element.
pointercursorPointing cursor.
preserve-whitespacewhite-spaceDo not collapse whitespace.
relativepositionRelative positioniong.
repeat-xbackgroundRepeat background in x direction.
repeat-ybackgroundRepeat background in y direction.
resizeresizeAllow resizing of element.
resize-xresizeAllow resizing of element horizontally.
resize-yresizeAllow resizing of element vertically.
reverseflexReverse flex order.
ridgeborderRidge-style border.
rightpadding, marginPadding or margin on right.
rightrubyRuby to right.
romanlistRoman list markers.
roundedborderRounded border.
rounded-moreborderMore rounded border.
self-baselineflexAlign flex child to baseline.
self-bottomflexAlign flex child to bottom.
self-centerflexAlign flex child to center.
self-leftflexAlign flex child to left.
self-middleflexAlign flex child to middle.
self-rightflexAlign flex child to right.
self-stretchflexStretch flex child.
self-topflexAlign flex child to top.
semi-boldfont-weightWeight between normal and bold.
semi-opaqueopacity50% opacity.
showdisplayDisplay as block.
singlespacingSingle spacing.
slowtransitionSlow transition.
slowertransitionVery slow transition.
smallsizeSmall font size.
smallersizeSmaller font size
small-capsfont-variantSmall caps font variant.
solidborderSolid border.
space-and-a-halfline-height1.5 line spacing.
squarelistSquare list marker.
step-starttransitionTransition timing "step-start"
step-endtransitionTransition timing "step-end"
strongfont-weightBold text.
tightspaceTighter inter-item spacing.
thickborderThick border.
thinborderThin border.
toppadding, marginPadding or margin on top.
transparentopacityZero opacity.
ultra-boldfont-weightBolder than bold.
ultra-lightfont-weightExtra-light font.
underrubyRuby on bottom.
underlinefont-decorationUnderline text.
uppertext-transformUppercased text.
upperlistUppercased list marker.
verticalflexColumn-oriented flex container.
verticaloverflowSet vertical
visiblevisibilityMake visible.
wrapflexWrap flexbox items.
x-boldfont-weightFont weight 800.
x-growflexAllow this item to grow more.
x-lightfont-weightExtra-light font.
x-loosespaceVery loose inter-item spacing.
x-smallsizeVery small font size.
x-largesizeVery large font size.
x-strongfont-weightVery bold text.
xx-boldfont-weightFont weight 900.
xx-largesizeVery very large font size.
xx-smallsizeVery very small font-size.
widthdimensionsSet 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.

0.6.4

6 years ago

0.6.3

6 years ago

0.6.2

6 years ago

0.6.1

6 years ago

0.6.0

6 years ago

0.5.0

7 years ago