GitHub Twitter

OrganiCSS - Logical CSS. Naturally.

OrganiCSS

OrganiCSS is a collection of mixins for writing logical CSS in different pre-processors and libraries.

Package Version
@organicss/emotion npm version
@organicss/less npm version
@organicss/scss npm version
@organicss/styled-components npm version
@organicss/stylus npm version

What is Logical CSS?

"The web has firmly shifted into an expectation of responsive, user-friendly sites and products. That fluidity has allowed the platform to scale at tremendous rates, and has fully altered entire markets and industries. But in the pursuit of supporting more and more devices, what happens if one of those devices isn't in English? Or French? Or any other language that flows from top to bottom, left to right?

Building inclusive products doesn't mean supporting devices, but supporting the people using them.

Looking at Hebrew specifically, a language written and read from right to left, there're plenty of styling challenges in handling this minor variation. Instances of text-align: left would need to be conditionally updated to text-align: right or an entirely separate set of styles is loaded, essentially creating a second unique version of the site or product.

What happens then with Japanese, where text flows from top to bottom, and content from right to left? Or Mongolian where the text flows the same, but the content is flipped to flow left to right?

This is where CSS Logical Properties shine. When writing text-align: left, it's likely because the text should be positioned where the content is expected to start. Only, as mentioned, content doesn't always start at the left. So what would be ideal is something like text-align: start to ensure our content is aligned with its expected starting point.

And that's exactly what CSS Logical Properties do."

Read more about Logical CSS

Why OrganiCSS?

OrganiCSS doesn't try to re-write CSS, but to encapsulate its modern features with direct fallbacks. The aim is to provide support for every logical property and value described at MDN: CSS Logical Properties and Values. Each property is grouped into a category, and that category becomes an OrganiCSS mixin.

Let's look at an example in SCSS.

.container {
@include margin($blockEnd: 1rem, $inline: auto);
}

This will return the resulting CSS.

.container {
margin-block-end: 1rem;
margin-inline-start: auto;
margin-inline-end: auto;

@supports not (margin-block-end: 1rem) {
margin-bottom: 1rem;
margin-left: auto;
margin-right: auto;
}
}

As browser support for logical CSS increases, the @supports query will be less and less necessary. Eventually, leaving only the modern CSS required to create the most flexible and inclusive UIs.

Getting Started

To begin using OrganiCSS, first select the flavor of choice: LESS, SCSS; Styled Components or Stylus, and install the package into your project.

npm i @organicss/emotion
npm i @organicss/less
npm i @organicss/scss
npm i @organicss/styled-components
npm i @organicss/stylus

Once the package is installed, import the mixins and include them in the styles.

@import '../node_modules/@organicss/scss';

.container {
@include padding($block: 1rem 2rem, $inline: var(--space-2));
}
import { Padding } from '@organicss/styled-components";

const Container = styled.section`
${Padding({ block: "1rem 2rem", inline: "var(--space-2)" })};
`
;

Mixins

Each mixin can be imported individually, or the whole set can be imported at once.

// import every mixin
@import '/node_modules/@organicss/scsss';

// import only a specific mixin
@import '/node_modules/@organicss/scss/margin';
// import every mixin
import OrganiCSS from '@organicss/styled-components';

// import only a specific mixin
import { Margin } from '@organicss/styled-components';

The documentation of props strips any platform-specific syntax. Note, each props would be prefaced by $ or @ in SCSS or LESS environments.

Border

@import '/node_modules/@organicss/scss/border';

.container {
@include border(...);
}
Prop CSS Property (Fallback) Example
border border border: 1px solid red
borderColor border-color borderColor: red
borderColor: red blue green orange
borderStyle border-style borderStyle: solid
borderStyle: solid dashed inset dotted
borderWidth border-width borderWidth: 3px
borderWidth: 3px 1px 5px 10px
block border-block-start/end (border-top/bottom) block: 1px solid orange
blockColor border-block-start/end-color (border-top/bottom-color) blockColor: red
blockColor: red green
blockStyle border-block-start/end-style (border-top/bottom-style) blockStyle: solid
blockStyle: solid dashed
blockWidth border-block-start/end-width (border-top/bottom-width) blockWidth: 3px
blockWidth: 3px 1px
blockEnd border-block-end (border-bottom) blockEnd: 1px solid red
blockEndColor border-block-end-color (border-bottom-color) blockEndColor: red
blockEndStyle border-block-end-style (border-bottom-style) blockEndStyle: dashed
blockEndWidth border-block-end-width (border-bottom-width) blockEndWidth: 1px
blockStart border-block-start (border-top) blockStart: 1px solid red
blockStartColor border-block-start-color (border-top-color) blockStartColor: red
blockStartStyle border-block-start-style (border-top-style) blockStartStyle: dashed
blockStartWidth border-block-start-width (border-top-width) blockStartWidth: 1px
inline border-inline-start/end (border-left/right) inline: 1px solid orange
inlineColor border-inline-start/end-color (border-left/right-color) inlineColor: red
inlineColor: red green
inlineStyle border-inline-start/end-style (border-left/right-style) inlineStyle: solid
inlineStyle: solid dashed
inlineWidth border-inline-start/end-width (border-left/right-width) inlineWidth: 3px
inlineWidth: 3px 1px
inlineEnd border-inline-end (border-right) inlineEnd: 1px solid red
inlineEndColor border-inline-end-color (border-right-color) inlineEndColor: red
inlineEndStyle border-inline-end-style (border-right-style) inlineEndStyle: dashed
inlineEndWidth border-inline-end-width (border-right-width) inlineEndWidth: 1px
inlineStart border-inline-start (border-left) inlineStart: 1px solid red
inlineStartColor border-inline-start-color (border-left-color) inlineStartColor: red
inlineStartStyle border-inline-start-style (border-left-style) inlineStartStyle: dashed
inlineStartWidth border-inline-start-width (border-left-width) inlineStartWidth: 1px

Border Radius

@import '/node_modules/@organicss/scss/borderRadius';

.container {
@include border-radius(...);
}
Prop CSS Property (Fallback) Example
bottomLeft border-end-start-radius (border-bottom-left-radius) bottomLeft: 8px
bottomRight border-end-end-radius (border-bottom-right-radius) bottomRight: 8px
radius border-radius radius: 8px
radius: 8px 4px
radius: 8px 4px / 1em 10%
topLeft border-start-start-radius (border-top-left-radius) topLeft: 8px
topRight border-start-end-radius (border-top-right-radius) topRight: 8px

Layout

@import '/node_modules/@organicss/scss/layout';

.container {
@include layout(...);
}
Prop CSS Property (Fallback) Example
blockSize block-size (height) blockSize: 100%
captionSide caption-side captionSide: block-start
clear clear clear: inline-start
maxBlockSize max-block-size (max-height) maxBlockSize: 100%
minBlockSize min-block-size (min-height) minBlockSize: 50%
inlineSize inline-size (width) inlineSize: 100%
maxInlineSize max-inline-size (max-width) maxInlineSize: 100%
minInlineSize min-inline-size (min-width) minInlineSize: 50%
overflow overflow overflow: scroll
overflow: scroll hidden
overflowBlock overflow-block (overflow-x) overflowBlock: auto
overflowInline overflow-inline (overflow-y) overflowInline: auto
overscrollBehavior overscroll-behavior overscrollBehavior: contain
overscrollBehavior: contain auto
overscrollBehaviorBlock overscroll-behavior-block (overscroll-behavior-x) overscrollBehaviorBlock: contain
overscrollBehaviorInline overscroll-behavior-inline (overscroll-behavior-y) overscrollBehaviorInline: auto
resize resize resize: block
textAlign text-align textAlign: start
textAlignLast text-align-last textAlignLast: start

Margin

@import '/node_modules/@organicss/scss/margin';

.container {
@include margin(...);
}
Prop CSS Property (Fallback) Example
block margin-block-start/end (margin-bottom/top) block: 8px
block: 8px 16px
blockEnd margin-block-end (margin-bottom) blockEnd: 8px
blockStart margin-block-start (margin-top) blockStart: 8px
inline margin-inline-start/end (margin-left/right) inline: 8px
inline: 8px 16px
inlineEnd margin-inline-end (margin-right) inlineEnd: 8px
inlineStart margin-inline-start (margin-left) inlineStart: 8px
margin margin margin: 8px
margin: 8px 0 4px 16px
scroll scroll-margin scroll: 16px
scroll: unset 8px revert 16px
scrollBlock scroll-margin-block-start/end (scroll-margin-top/bottom) scrollBlock: 8px
scrollBlock: 8px 16px
scrollBlockEnd scroll-margin-block-end (scroll-margin-bottom) scrollBlockEnd: 8px
scrollBlockStart scroll-margin-block-start (scroll-margin-top) scrollBlockStart: 8px
scrollInline scroll-margin-inline-start/end (scroll-margin-left/right) scrollInline: 8px
scrollInline: 8px 16px
scrollInlineEnd scroll-margin-inline-end (scroll-margin-right) scrollInlineEnd: 8px
scrollInlineStart scroll-margin-inline-start (scroll-margin-left) scrollInlineStart: 8px

Padding

@import '/node_modules/@organicss/scss/padding';

.container {
@include padding(...);
}
Prop CSS Property (Fallback) Example
block padding-block-start/end (padding-bottom/top) block: 8px
block: 8px 16px
blockEnd padding-block-end (padding-bottom) blockEnd: 8px
blockStart padding-block-start (padding-top) blockStart: 8px
inline padding-inline-start/end (padding-left/right) inline: 8px
inline: 8px 16px
inlineEnd padding-inline-end (padding-right) inlineEnd: 8px
inlineStart padding-inline-start (padding-left) inlineStart: 8px
padding padding padding: 8px
padding: 8px 0 4px 16px
scroll scroll-padding scroll: 16px
scroll: unset 8px revert 16px
scrollBlock scroll-padding-block-start/end (scroll-padding-top/bottom) scrollBlock: 8px
scrollBlock: 8px 16px
scrollBlockEnd scroll-padding-block-end (scroll-padding-bottom) scrollBlockEnd: 8px
scrollBlockStart scroll-padding-block-start (scroll-padding-top) scrollBlockStart: 8px
scrollInline scroll-padding-inline-start/end (scroll-padding-left/right) scrollInline: 8px
scrollInline: 8px 16px
scrollInlineEnd scroll-padding-inline-end (scroll-padding-right) scrollInlineEnd: 8px
scrollInlineStart scroll-padding-inline-start (scroll-padding-left) scrollInlineStart: 8px

Position

@import '/node_modules/@organicss/scss/position';

.container {
@include position(...);
}
Prop CSS Property (Fallback) Example
block inset-block (top/bottom) block: 10%
block: 10% 0
blockEnd inset-block-end (bottom) blockEnd: 0
blockStart inset-block-start (top) blockStart: 10%
float float float: inline-start
inline inset-inline (left/right) inline: 10%
inline: 10% 0
inlineEnd inset-inline-end (right) inlineEnd: 0
inlineStart inset-inline-start (left) inlineStart: 10%
inset inset (top/right/bottom/left) inset: 0
inset: 0 50% 10% 10%