0.4.0 • Published 8 years ago

morass v0.4.0

Weekly downloads
1
License
MIT
Repository
github
Last release
8 years ago

MORASS

Morass is a More Obvious, Reasonable Approach to Style Sheets.

Summary

Morass provides micro-classes which make HTML files more semantic and readable, while also reducing or even eliminating the need for complex CSS rules. The great majority of common styling needs can be met by a suitable combination of micro-classes.

Our key design objective was to reduce CSS sprawl. With Morass, many pages may need no specific CSS rules whatsoever.

Where the provided micro-classes don't get the job done, Morass provides the conceptual framework for writing your own micro-classes.

In the micro-class philosophy, elements are styled withi HTML by addition micro classes, such as

<div class="x-large padding">

To create a div with extra-large text, and padding around it.

Morass provides 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 class="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 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 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 rules such as

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

Design Principles And Features

Micro-classes

Morass is a collection of micro-classes: CSS classes which often define no more than one property. These classes are assigned to HTML elements, which in this approach may have two or five or even ten classes. 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 classes 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.

In cases where the provided micro-classes do not or can not provide the functionality you need, such as box shadows perhaps, we recommend defining your own generic micro-classes, hopefully following the Morass design principles.

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.

Morass offers 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

Morass does not use or support floats, and neither should you.

Colors

In order to conform to the micro-class principle, Morass defines five standard colors: primary, secondary, success, error, and warn. Each color is itself a micro-class which sets that as the foreground color. Variants such as bg-success and border-success apply the color to backgrounds and borders. An invert micro-class swaps light and dark, so we can write

<div class="primary bg-primary invert">Light on dark</div>

These colors are exposed as hues in an HSL model, in the form of variables named --hue-success, for use in building your own colors based on them.

!important

Morass neither needs nor uses !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.

Composability

Of course if I want to define my own class for an alement, and add padding, I can do

<div class="padding my-class">

and this might be the best approach. However, 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">. SuitCSS/rework provide the ability to do this using the rework-inherit plug-in, which provides an inherit pseudo-property, as follows:

.myclass {
  color: red;
  inherit: .padding;
}

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

Micro-class groupings

This section walks through each of the main groupings of micro-classes.

Spacing

Some large proportion of CSS rules control spacing. People use top margins and bottom margins and top padding and bottom padding and special spacing elements. Morass provides simple mechanisms for controlling spacing. The spaced micro-class adds space between child elements. The padding micro-class adds padding around an element, and the margin micro-class adds margins. Variants of these (indicated by modifier micro-classes) provide more or less spacing, more or less margins, and norizontal and vertical padding.

Example of spaced children:

<div class="spaced">
  <div></div>
  <div></div>
</div>

Example of padding:

<div class="padding">
<div class="padding horizontal en">
<div class="padding top left hair">

A "hair" is a standard length used in Morass, which corresponds to 1/6 em. An "en" is half an "em".

flexbox

Morass expects most layout to be done using flexbox, and provides a solid set of micro-classes to control them. The micro-classes 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 class="flex">

<div class="flex vertical justify">
  <div class="grow">

Display and visibility

<div class="show">
<div class="inline">
<div class="hide">
<div class="visible">
<div class="invisible">

Font weight and size

<div class="bold">

And many other variations including light, normal, and heavy.

<div class="small">
<div class="large">

And many other variations, including x-large, x-small, smaller, larger, etc.

Opacity

<div class="opaque">
<div class="semi-opaque">
<div class="transparent">

Z-index

<div class="back">
<div class="front">
<div class="backmost">
<div class="frontmost">

Position

<div class="absolute">
<div class="relative">
<div class="fixed">

Text transforms

<div class="text upper">
<div class="text lower">
<div class="text capitalize">
<div class="all-caps">

Transitions

<div class="transition fast linear delay">

Note on Preprocessors

We hate CSS preprocessors. They are bulky, slow, and promote bad rule-writing practices. However, preprocessors do provide some useful functionality. The key feature is the use of variables. Since we do want to use variables, we do use a preprocessor. The preprocessor we use is suitCSS, a forward-looking system with a clear migration path to CSS4. It also supports imports, allowing us to write our code modularly, as well as auto-prefixing.

Installation

npm install --save-dev morass

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

@import "morass";

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

For your own Morass-type styles, we recommend following the Morass directory structure of elements/modifiers/variables. Note that suitCSS always uses the most recently defined variable value. Therefore, if you include your own variable definitions after importing Morass, they will take effect.

Micro-class reference

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.
bodyfont-familyBody font family.
behindz-indexSet element behind.
boldtextBold font.
boldertextIncrease boldness.
borderborderSet border.
bottompaddingPad on bottom.
bottommarginAdd margin on bottom.
capitalizetext-transformCapitalized text.
circlelistCircle list marker.
condensedletter-spacingCondense space between letters.
containbackgroundClip background image
coverbackgroundLetterbox background image
decimallistDecimal list markers.
defaultcolorsDefault color.
delaytransitionDelay transition.
dashedborderDashed border.
delay-lesstransitionShorter delay transition.
delay-moretransitionLonger delay transition.
demi-boldfont-weightWeight between normal and bold.
@desktopApply only on desktop.
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"
empadding, marginPadding or margin of 1 em.
enpadding, marginPadding or margin of 1/2 em.
emphasisfont-styleItalics.
errorcolorsError color.
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.
four-columnscolumnSplit content into 4 columns.
frontz-indexSet element in front.
frontmostz-indexSet element to very front.
full-heightdimensionOccupy full height.
full-widthdimensionOccupy full width.
grooveborderGroove-style border.
growflexAllow this item to grow.
hairpadding, marginPadding or margin of 1/6 em.
hairlinefont-weightLightest font.
half-heightdimensionOccupy half height.
half-widthdimensionOccupy half width.
headingfont-familyHeading font family.
heavyfont-weightHeaviest font.
hide, hiddendisplayHide element.
honor-newlinewhite-spaceTreat newlines as newlines.
horizontalflexRow-oriented flex container.
horizontalpadding, marginPadding or margin on left and right.
horizontaloverflowSet horizontal overflow.
:hoverApply rules in hover state
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.
invertbackgroundInvert background dark/light.
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.
mediumsizeMedium font size.
mediumborderMedium border width.
medium-weightfont-weightMedium font weight.
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.
primarycolorsPrimary color.
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.
single-spacedline-heightNormal (single) line 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.
successcolorsSuccess color.
tightspaceTighter inter-item spacing.
thickborderThick border.
thinborderThin border.
toppadding, marginPadding or margin on top.
transparentopacityZero opacity.
two-columnscolumnSplit content into 2 columns.
three-columnscolumnSplit content into 3 columns.
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.
verticalpadding, marginPadding or margin on top and bottom.
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.
warncolorsWarning color.
white-space-normalwhite-spaceRestore white space.
zeropadding, marginZero padding or margin.
0.4.0

8 years ago

0.3.0

8 years ago

0.2.0

8 years ago

0.1.4

8 years ago

0.1.3

9 years ago

0.1.2

9 years ago

0.1.1

9 years ago

0.1.0

9 years ago