Skip to content

Commit

Permalink
Leverage CSS cascade layers to fix and user-proof styles order
Browse files Browse the repository at this point in the history
As long as `layers.scss` (layers order definition) is called first, our Sass
styles can be imported in any order.

It solves the incorrect (but unavoidable, due to the way we compile CSS) call
order of styles in our `index.js`.

Also, developers can now extend the CSS cascade instead of just prepending or
appending their styles to ours.

For example:

```css
/* My custom app styles */
@layer foundation.elements {
  code {
    background-color: silver;
  }
}
```
  • Loading branch information
adamkudrna committed Mar 6, 2024
1 parent 654e775 commit 8a3a9a1
Show file tree
Hide file tree
Showing 7 changed files with 1,110 additions and 1,087 deletions.
41 changes: 22 additions & 19 deletions src/docs/getting-started/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,29 @@ performance).

## CSS

React UI honors [ITCSS][itcss] principles to make sure that its CSS code base
will work and perform well even in large scale. There are four CSS layers:

1. **Theme:** a collection of hundreds of CSS custom properties that define the
look of your app. See [Theming][theming] for more.
2. **Foundation:** mandatory ground-zero CSS for React UI components. Includes
global resets and fixes rendering inconsistencies across browsers with
`normalize.css`. (Not to be confused with the Foundation CSS framework.)
3. **Components:** React UI components' styles. Components utilize [CSS modules]
to avoid class name conflicts and to keep the class names scoped.
4. **CSS helpers:** tiny CSS classes that can handle details like
[typography][typography], [spacing][spacing], [colors][colors], etc. Class
name notation is [inspired by Bootstrap][bootstrap-utilities], so if you are
familiar with Bootstrap, you will feel at home here.

All layers are written in Sass and compiled to CSS. You can import them all in
a **ready-to-use CSS bundle** like this:
React UI styles are written in Sass and compiled to CSS. You can import them
in a **ready-to-use CSS bundle** like this:

```js
import '@react-ui-org/react-ui/dist/react-ui.css';
```

Under the hood, there are several CSS layers:

1. **Layers definition:** establish [CSS cascade layers][mdn-cascade-layers].
2. **Theme:** a collection of hundreds of [design tokens][design-tokens]
written in form of [CSS custom properties][mdn-custom-properties] that
define the look and feel of your app. See [Theming][theming] for more.
3. **Foundation:** mandatory ground-zero CSS for React UI components. Includes
global resets and fixes rendering inconsistencies across browsers with
`normalize.css`. (Not to be confused with the Foundation CSS framework!)
4. **Components:** React UI components' styles. Components utilize [CSS modules]
to avoid class name conflicts and to keep the class names scoped.
5. **CSS helpers:** tiny CSS classes that can handle details like
[typography][typography], [spacing][spacing], [colors][colors], etc. Class
name notation is [inspired by Bootstrap utilities][bootstrap-utilities], so
if you are familiar with Bootstrap, you will feel at home here.

### Sass

👉 As of now, we don't provide a way to import the Sass files directly.
Expand Down Expand Up @@ -118,11 +119,13 @@ React UI is also available on CDN:

👉 Consider using a specific version instead of `latest` in production.

[itcss]: https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/
[mdn-cascade-layers]: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers
[mdn-custom-properties]: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
[design-tokens]: /docs/foundation/design-tokens
[theming]: /docs/customize/theming/overview
[controlled-components]: https://reactjs.org/docs/forms.html#controlled-components
[typography]: /docs/css-helpers/typography
[spacing]: /docs/css-helpers/spacing
[colors]: /docs/css-helpers/colors
[bootstrap-utilities]: https://getbootstrap.com/docs/5.1/utilities/
[bootstrap-utilities]: https://getbootstrap.com/docs/5.3/utilities/api/
[CSS modules]: https://github.com/css-modules/css-modules
39 changes: 22 additions & 17 deletions src/foundation.scss
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
// Mandatory themeable CSS layer to prepare ground for components.
// Structured according to ITCSS methodology, ie. most importantly in ascending specificity.

@use "sass:meta";

//
// 1. Generic
// ==========
// Generic
// =======
//
// Ground-zero styles.

@use "styles/generic/box-sizing";
@use "normalize.css/normalize.css";
@use "styles/generic/focus";
@use "styles/generic/forms";
@use "styles/generic/reset";
@use "styles/generic/shared";
@layer foundation.generic {
@include meta.load-css("styles/generic/box-sizing");
@include meta.load-css("normalize.css/normalize.css");
@include meta.load-css("styles/generic/focus");
@include meta.load-css("styles/generic/forms");
@include meta.load-css("styles/generic/reset");
@include meta.load-css("styles/generic/shared");
}

//
// 2. Elements
// ===========
// Elements
// ========
//
// Unclassed HTML elements (type selectors).

@use "styles/elements/code";
@use "styles/elements/links";
@use "styles/elements/lists";
@use "styles/elements/page";
@use "styles/elements/rulers";
@use "styles/elements/small";
@layer foundation.elements {
@include meta.load-css("styles/elements/code");
@include meta.load-css("styles/elements/links");
@include meta.load-css("styles/elements/lists");
@include meta.load-css("styles/elements/page");
@include meta.load-css("styles/elements/rulers");
@include meta.load-css("styles/elements/small");
}
20 changes: 12 additions & 8 deletions src/helpers.scss
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
// Optional layer with helper CSS classes to easily adjust visual details.
// Structured according to ITCSS methodology, ie. most importantly in ascending specificity.
// This file should be imported as the very last of your stylesheets.

@use "sass:meta";

//
// 1. Helpers
// ==========
// Helpers
// =======
//
// General purpose helpers for common situations. They can compose multiple CSS rules to do a bit
// more complicated tasks.

@use "styles/helpers/animation";
@layer helpers {
@include meta.load-css("styles/helpers/animation");
}

//
// 2. Utilities
// ============
// Utilities
// =========
//
// Utility classes to tweak small details like typography, margins or padding. They do just one
// thing: they set a single CSS rule and use the otherwise disallowed `!important` to enforce it.
// Also they are often responsive (can be adjusted for individual breakpoints).

@use "styles/utilities";
@layer utilities {
@include meta.load-css("styles/utilities");
}
8 changes: 3 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// Global definitions
// These need to be imported here to be placed in the distribution CSS file.
// Component styles are imported in the component files themselves.
import './theme.scss';
import './foundation.scss';
import './helpers.scss';
// The styles need to be imported here to be placed in the distribution CSS file.
// Component styles are imported in the components themselves below.
import './index.scss';

// Components
export { Alert } from './components/Alert';
Expand Down
7 changes: 7 additions & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// First establish cascade layers:
@forward "layers"; // Must come first for the cascade layers to work as intended.

// Then import the rest of the files, already organized by layer:
@forward "theme";
@forward "foundation";
@forward "helpers";
4 changes: 4 additions & 0 deletions src/layers.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Establish CSS cascade layers.
// ⚠️ WARNING: This file must be called before other React UI styles for the cascade layers to work as intended.

@layer theme, foundation, helpers, components, utilities;
Loading

0 comments on commit 8a3a9a1

Please sign in to comment.