- What is Logical CSS?
- Why OrganiCSS?
- Getting Started
- Mixins
- Border
- Border Radius
- Layout
- Margin
- Padding
- Position
OrganiCSS is a collection of mixins for writing logical CSS in different pre-processors and libraries.
Package | Version |
---|---|
@organicss/emotion |
|
@organicss/less |
|
@organicss/scss |
|
@organicss/styled-components |
|
@organicss/stylus |
"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."
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.
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)" })};
`;
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.
@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 |
@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 |
@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 |
@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 |
@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 |
@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% |