v6.0.0-beta.5
  • Home
  • Principles
  • Tokens
  • Layout
  • Utilities
  • Guides
  • home
  • /
  • principles

Principles

Separate structure from skin

There are many common and overlapping (responsive) layout patterns. By separating these and reusing them as much as possible, you can achieve consistency in implementation, and maintainability in code. We see this coming back in Cube CSS, on which Feo.css is (loosely) based. Feo.css gives you the tools for composable layouts using the layout layer and utility layer. Feo.css does provide a few exceptions in the utility layer:

  • Interaction classes such as click-area.
  • Helpers for typography.
  • Utilities that are not really classified as structure or skin (e.g. no-print).
Padding classes

Feo.css provides utility classes for margin, but not for padding. You might wonder why. Feo.css focuses on layout. Margin impacts how element are positioned in relation to each other. Padding does not impact structure, hence it is not part of Feo.css.

Layout, utilities, components, and ... utilities.

Feo.css is a variation of Cube CSS. It follows the a slightly different order of the different layers.

  1. Layout
  2. Utilities
  3. Components
  4. Utilities.

As you can see, on the implementation level, you go past the utility layer, twice. First you try to solve things as much as possible with layout and utilities. If that is not possible, you write components (old-school CSS yo). But keep your components light. If there is an exception (e.g. margin-top) for one implementation of your component, use a utility class! Due to this reason, Feo.css implements the following sequence of layers.

@layer global, layout, components, utilities;

Note: the components layer is not part of Feo.css at its core. But the layer is defined. For specificity reasons, make sure to scope your components correctly in the @layer components.

API-first CSS

Many classes have properties that are not the same in all scenarios. The .switcher example you want to be able to adjust the gap or the width that triggers the orientation change.

You could add a class that alters that property. That is not the case for all APIs. The example .switcher pattern used before shows that var(--token-bp-0) is used in a calculation. The token is used in a child selector (>), not directly on .switcher. Another scenario is a token that is used for multiple properties.

To avoid overwriting all these scenarios one by one, we define clear APIs through custom properties.

Let’s take the previous .switcher layout class as an example. Instead if directly setting the properties, we define two APIs for the class to control it.

.switcher {
  --layout-gap: var(--token-size-0);
  --layout-width: var(--token-bp-0);
}

With this API different methods can be used to control the results.

© Crinkles.
Powered by: 11ty & Feo.css | Github